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. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
43 #include "basic-block.h"
44 #include "integrate.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 #include "cfglayout.h"
54 #include "sched-int.h"
55 #include "tree-gimple.h"
59 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
62 #include "gstab.h" /* for N_SLINE */
65 #ifndef TARGET_NO_PROTOTYPE
66 #define TARGET_NO_PROTOTYPE 0
69 #define min(A,B) ((A) < (B) ? (A) : (B))
70 #define max(A,B) ((A) > (B) ? (A) : (B))
72 /* Structure used to define the rs6000 stack */
73 typedef struct rs6000_stack
{
74 int first_gp_reg_save
; /* first callee saved GP register used */
75 int first_fp_reg_save
; /* first callee saved FP register used */
76 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
77 int lr_save_p
; /* true if the link reg needs to be saved */
78 int cr_save_p
; /* true if the CR reg needs to be saved */
79 unsigned int vrsave_mask
; /* mask of vec registers to save */
80 int toc_save_p
; /* true if the TOC needs to be saved */
81 int push_p
; /* true if we need to allocate stack space */
82 int calls_p
; /* true if the function makes any calls */
83 int world_save_p
; /* true if we're saving *everything*:
84 r13-r31, cr, f14-f31, vrsave, v20-v31 */
85 enum rs6000_abi abi
; /* which ABI to use */
86 int gp_save_offset
; /* offset to save GP regs from initial SP */
87 int fp_save_offset
; /* offset to save FP regs from initial SP */
88 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
89 int lr_save_offset
; /* offset to save LR from initial SP */
90 int cr_save_offset
; /* offset to save CR from initial SP */
91 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
92 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
93 int toc_save_offset
; /* offset to save the TOC pointer */
94 int varargs_save_offset
; /* offset to save the varargs registers */
95 int ehrd_offset
; /* offset to EH return data */
96 int reg_size
; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size
; /* variable save area size */
98 int parm_size
; /* outgoing parameter size */
99 int save_size
; /* save area size */
100 int fixed_size
; /* fixed size of stack frame */
101 int gp_size
; /* size of saved GP registers */
102 int fp_size
; /* size of saved FP registers */
103 int altivec_size
; /* size of saved AltiVec registers */
104 int cr_size
; /* size to hold CR if not in save_size */
105 int lr_size
; /* size to hold LR if not in save_size */
106 int vrsave_size
; /* size to hold VRSAVE if not in save_size */
107 int altivec_padding_size
; /* size of altivec alignment padding if
109 int spe_gp_size
; /* size of 64-bit GPR save size for SPE */
110 int spe_padding_size
;
111 int toc_size
; /* size to hold TOC if not in save_size */
112 HOST_WIDE_INT total_size
; /* total bytes allocated for stack */
113 int spe_64bit_regs_used
;
116 /* A C structure for machine-specific, per-function data.
117 This is added to the cfun structure. */
118 typedef struct machine_function
GTY(())
120 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
121 int ra_needs_full_frame
;
122 /* Some local-dynamic symbol. */
123 const char *some_ld_name
;
124 /* Whether the instruction chain has been scanned already. */
125 int insn_chain_scanned_p
;
126 /* Flags if __builtin_return_address (0) was used. */
128 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
129 varargs save area. */
130 HOST_WIDE_INT varargs_save_offset
;
133 /* Target cpu type */
135 enum processor_type rs6000_cpu
;
136 struct rs6000_cpu_select rs6000_select
[3] =
138 /* switch name, tune arch */
139 { (const char *)0, "--with-cpu=", 1, 1 },
140 { (const char *)0, "-mcpu=", 1, 1 },
141 { (const char *)0, "-mtune=", 1, 0 },
144 /* Always emit branch hint bits. */
145 static GTY(()) bool rs6000_always_hint
;
147 /* Schedule instructions for group formation. */
148 static GTY(()) bool rs6000_sched_groups
;
150 /* Support for -msched-costly-dep option. */
151 const char *rs6000_sched_costly_dep_str
;
152 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
154 /* Support for -minsert-sched-nops option. */
155 const char *rs6000_sched_insert_nops_str
;
156 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
158 /* Support targetm.vectorize.builtin_mask_for_load. */
159 static GTY(()) tree altivec_builtin_mask_for_load
;
161 /* Size of long double */
162 int rs6000_long_double_type_size
;
164 /* Whether -mabi=altivec has appeared */
165 int rs6000_altivec_abi
;
167 /* Nonzero if we want SPE ABI extensions. */
170 /* Nonzero if floating point operations are done in the GPRs. */
171 int rs6000_float_gprs
= 0;
173 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
174 int rs6000_darwin64_abi
;
176 /* Set to nonzero once AIX common-mode calls have been defined. */
177 static GTY(()) int common_mode_defined
;
179 /* Save information from a "cmpxx" operation until the branch or scc is
181 rtx rs6000_compare_op0
, rs6000_compare_op1
;
182 int rs6000_compare_fp_p
;
184 /* Label number of label created for -mrelocatable, to call to so we can
185 get the address of the GOT section */
186 int rs6000_pic_labelno
;
189 /* Which abi to adhere to */
190 const char *rs6000_abi_name
;
192 /* Semantics of the small data area */
193 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
195 /* Which small data model to use */
196 const char *rs6000_sdata_name
= (char *)0;
198 /* Counter for labels which are to be placed in .fixup. */
199 int fixuplabelno
= 0;
202 /* Bit size of immediate TLS offsets and string from which it is decoded. */
203 int rs6000_tls_size
= 32;
204 const char *rs6000_tls_size_string
;
206 /* ABI enumeration available for subtarget to use. */
207 enum rs6000_abi rs6000_current_abi
;
209 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
213 const char *rs6000_debug_name
;
214 int rs6000_debug_stack
; /* debug stack applications */
215 int rs6000_debug_arg
; /* debug argument handling */
217 /* Value is TRUE if register/mode pair is acceptable. */
218 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
220 /* Built in types. */
222 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
223 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
225 const char *rs6000_traceback_name
;
227 traceback_default
= 0,
233 /* Flag to say the TOC is initialized */
235 char toc_label_name
[10];
237 /* Alias set for saves and restores from the rs6000 stack. */
238 static GTY(()) int rs6000_sr_alias_set
;
240 /* Control alignment for fields within structures. */
241 /* String from -malign-XXXXX. */
242 int rs6000_alignment_flags
;
244 /* True for any options that were explicitly set. */
246 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
247 bool alignment
; /* True if -malign- was used. */
248 bool abi
; /* True if -mabi= was used. */
249 bool spe
; /* True if -mspe= was used. */
250 bool float_gprs
; /* True if -mfloat-gprs= was used. */
251 bool isel
; /* True if -misel was used. */
252 bool long_double
; /* True if -mlong-double- was used. */
253 } rs6000_explicit_options
;
255 struct builtin_description
257 /* mask is not const because we're going to alter it below. This
258 nonsense will go away when we rewrite the -march infrastructure
259 to give us more target flag bits. */
261 const enum insn_code icode
;
262 const char *const name
;
263 const enum rs6000_builtins code
;
266 /* Target cpu costs. */
268 struct processor_costs
{
269 const int mulsi
; /* cost of SImode multiplication. */
270 const int mulsi_const
; /* cost of SImode multiplication by constant. */
271 const int mulsi_const9
; /* cost of SImode mult by short constant. */
272 const int muldi
; /* cost of DImode multiplication. */
273 const int divsi
; /* cost of SImode division. */
274 const int divdi
; /* cost of DImode division. */
275 const int fp
; /* cost of simple SFmode and DFmode insns. */
276 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
277 const int sdiv
; /* cost of SFmode division (fdivs). */
278 const int ddiv
; /* cost of DFmode division (fdiv). */
281 const struct processor_costs
*rs6000_cost
;
283 /* Processor costs (relative to an add) */
285 /* Instruction size costs on 32bit processors. */
287 struct processor_costs size32_cost
= {
288 COSTS_N_INSNS (1), /* mulsi */
289 COSTS_N_INSNS (1), /* mulsi_const */
290 COSTS_N_INSNS (1), /* mulsi_const9 */
291 COSTS_N_INSNS (1), /* muldi */
292 COSTS_N_INSNS (1), /* divsi */
293 COSTS_N_INSNS (1), /* divdi */
294 COSTS_N_INSNS (1), /* fp */
295 COSTS_N_INSNS (1), /* dmul */
296 COSTS_N_INSNS (1), /* sdiv */
297 COSTS_N_INSNS (1), /* ddiv */
300 /* Instruction size costs on 64bit processors. */
302 struct processor_costs size64_cost
= {
303 COSTS_N_INSNS (1), /* mulsi */
304 COSTS_N_INSNS (1), /* mulsi_const */
305 COSTS_N_INSNS (1), /* mulsi_const9 */
306 COSTS_N_INSNS (1), /* muldi */
307 COSTS_N_INSNS (1), /* divsi */
308 COSTS_N_INSNS (1), /* divdi */
309 COSTS_N_INSNS (1), /* fp */
310 COSTS_N_INSNS (1), /* dmul */
311 COSTS_N_INSNS (1), /* sdiv */
312 COSTS_N_INSNS (1), /* ddiv */
315 /* Instruction costs on RIOS1 processors. */
317 struct processor_costs rios1_cost
= {
318 COSTS_N_INSNS (5), /* mulsi */
319 COSTS_N_INSNS (4), /* mulsi_const */
320 COSTS_N_INSNS (3), /* mulsi_const9 */
321 COSTS_N_INSNS (5), /* muldi */
322 COSTS_N_INSNS (19), /* divsi */
323 COSTS_N_INSNS (19), /* divdi */
324 COSTS_N_INSNS (2), /* fp */
325 COSTS_N_INSNS (2), /* dmul */
326 COSTS_N_INSNS (19), /* sdiv */
327 COSTS_N_INSNS (19), /* ddiv */
330 /* Instruction costs on RIOS2 processors. */
332 struct processor_costs rios2_cost
= {
333 COSTS_N_INSNS (2), /* mulsi */
334 COSTS_N_INSNS (2), /* mulsi_const */
335 COSTS_N_INSNS (2), /* mulsi_const9 */
336 COSTS_N_INSNS (2), /* muldi */
337 COSTS_N_INSNS (13), /* divsi */
338 COSTS_N_INSNS (13), /* divdi */
339 COSTS_N_INSNS (2), /* fp */
340 COSTS_N_INSNS (2), /* dmul */
341 COSTS_N_INSNS (17), /* sdiv */
342 COSTS_N_INSNS (17), /* ddiv */
345 /* Instruction costs on RS64A processors. */
347 struct processor_costs rs64a_cost
= {
348 COSTS_N_INSNS (20), /* mulsi */
349 COSTS_N_INSNS (12), /* mulsi_const */
350 COSTS_N_INSNS (8), /* mulsi_const9 */
351 COSTS_N_INSNS (34), /* muldi */
352 COSTS_N_INSNS (65), /* divsi */
353 COSTS_N_INSNS (67), /* divdi */
354 COSTS_N_INSNS (4), /* fp */
355 COSTS_N_INSNS (4), /* dmul */
356 COSTS_N_INSNS (31), /* sdiv */
357 COSTS_N_INSNS (31), /* ddiv */
360 /* Instruction costs on MPCCORE processors. */
362 struct processor_costs mpccore_cost
= {
363 COSTS_N_INSNS (2), /* mulsi */
364 COSTS_N_INSNS (2), /* mulsi_const */
365 COSTS_N_INSNS (2), /* mulsi_const9 */
366 COSTS_N_INSNS (2), /* muldi */
367 COSTS_N_INSNS (6), /* divsi */
368 COSTS_N_INSNS (6), /* divdi */
369 COSTS_N_INSNS (4), /* fp */
370 COSTS_N_INSNS (5), /* dmul */
371 COSTS_N_INSNS (10), /* sdiv */
372 COSTS_N_INSNS (17), /* ddiv */
375 /* Instruction costs on PPC403 processors. */
377 struct processor_costs ppc403_cost
= {
378 COSTS_N_INSNS (4), /* mulsi */
379 COSTS_N_INSNS (4), /* mulsi_const */
380 COSTS_N_INSNS (4), /* mulsi_const9 */
381 COSTS_N_INSNS (4), /* muldi */
382 COSTS_N_INSNS (33), /* divsi */
383 COSTS_N_INSNS (33), /* divdi */
384 COSTS_N_INSNS (11), /* fp */
385 COSTS_N_INSNS (11), /* dmul */
386 COSTS_N_INSNS (11), /* sdiv */
387 COSTS_N_INSNS (11), /* ddiv */
390 /* Instruction costs on PPC405 processors. */
392 struct processor_costs ppc405_cost
= {
393 COSTS_N_INSNS (5), /* mulsi */
394 COSTS_N_INSNS (4), /* mulsi_const */
395 COSTS_N_INSNS (3), /* mulsi_const9 */
396 COSTS_N_INSNS (5), /* muldi */
397 COSTS_N_INSNS (35), /* divsi */
398 COSTS_N_INSNS (35), /* divdi */
399 COSTS_N_INSNS (11), /* fp */
400 COSTS_N_INSNS (11), /* dmul */
401 COSTS_N_INSNS (11), /* sdiv */
402 COSTS_N_INSNS (11), /* ddiv */
405 /* Instruction costs on PPC440 processors. */
407 struct processor_costs ppc440_cost
= {
408 COSTS_N_INSNS (3), /* mulsi */
409 COSTS_N_INSNS (2), /* mulsi_const */
410 COSTS_N_INSNS (2), /* mulsi_const9 */
411 COSTS_N_INSNS (3), /* muldi */
412 COSTS_N_INSNS (34), /* divsi */
413 COSTS_N_INSNS (34), /* divdi */
414 COSTS_N_INSNS (5), /* fp */
415 COSTS_N_INSNS (5), /* dmul */
416 COSTS_N_INSNS (19), /* sdiv */
417 COSTS_N_INSNS (33), /* ddiv */
420 /* Instruction costs on PPC601 processors. */
422 struct processor_costs ppc601_cost
= {
423 COSTS_N_INSNS (5), /* mulsi */
424 COSTS_N_INSNS (5), /* mulsi_const */
425 COSTS_N_INSNS (5), /* mulsi_const9 */
426 COSTS_N_INSNS (5), /* muldi */
427 COSTS_N_INSNS (36), /* divsi */
428 COSTS_N_INSNS (36), /* divdi */
429 COSTS_N_INSNS (4), /* fp */
430 COSTS_N_INSNS (5), /* dmul */
431 COSTS_N_INSNS (17), /* sdiv */
432 COSTS_N_INSNS (31), /* ddiv */
435 /* Instruction costs on PPC603 processors. */
437 struct processor_costs ppc603_cost
= {
438 COSTS_N_INSNS (5), /* mulsi */
439 COSTS_N_INSNS (3), /* mulsi_const */
440 COSTS_N_INSNS (2), /* mulsi_const9 */
441 COSTS_N_INSNS (5), /* muldi */
442 COSTS_N_INSNS (37), /* divsi */
443 COSTS_N_INSNS (37), /* divdi */
444 COSTS_N_INSNS (3), /* fp */
445 COSTS_N_INSNS (4), /* dmul */
446 COSTS_N_INSNS (18), /* sdiv */
447 COSTS_N_INSNS (33), /* ddiv */
450 /* Instruction costs on PPC604 processors. */
452 struct processor_costs ppc604_cost
= {
453 COSTS_N_INSNS (4), /* mulsi */
454 COSTS_N_INSNS (4), /* mulsi_const */
455 COSTS_N_INSNS (4), /* mulsi_const9 */
456 COSTS_N_INSNS (4), /* muldi */
457 COSTS_N_INSNS (20), /* divsi */
458 COSTS_N_INSNS (20), /* divdi */
459 COSTS_N_INSNS (3), /* fp */
460 COSTS_N_INSNS (3), /* dmul */
461 COSTS_N_INSNS (18), /* sdiv */
462 COSTS_N_INSNS (32), /* ddiv */
465 /* Instruction costs on PPC604e processors. */
467 struct processor_costs ppc604e_cost
= {
468 COSTS_N_INSNS (2), /* mulsi */
469 COSTS_N_INSNS (2), /* mulsi_const */
470 COSTS_N_INSNS (2), /* mulsi_const9 */
471 COSTS_N_INSNS (2), /* muldi */
472 COSTS_N_INSNS (20), /* divsi */
473 COSTS_N_INSNS (20), /* divdi */
474 COSTS_N_INSNS (3), /* fp */
475 COSTS_N_INSNS (3), /* dmul */
476 COSTS_N_INSNS (18), /* sdiv */
477 COSTS_N_INSNS (32), /* ddiv */
480 /* Instruction costs on PPC620 processors. */
482 struct processor_costs ppc620_cost
= {
483 COSTS_N_INSNS (5), /* mulsi */
484 COSTS_N_INSNS (4), /* mulsi_const */
485 COSTS_N_INSNS (3), /* mulsi_const9 */
486 COSTS_N_INSNS (7), /* muldi */
487 COSTS_N_INSNS (21), /* divsi */
488 COSTS_N_INSNS (37), /* divdi */
489 COSTS_N_INSNS (3), /* fp */
490 COSTS_N_INSNS (3), /* dmul */
491 COSTS_N_INSNS (18), /* sdiv */
492 COSTS_N_INSNS (32), /* ddiv */
495 /* Instruction costs on PPC630 processors. */
497 struct processor_costs ppc630_cost
= {
498 COSTS_N_INSNS (5), /* mulsi */
499 COSTS_N_INSNS (4), /* mulsi_const */
500 COSTS_N_INSNS (3), /* mulsi_const9 */
501 COSTS_N_INSNS (7), /* muldi */
502 COSTS_N_INSNS (21), /* divsi */
503 COSTS_N_INSNS (37), /* divdi */
504 COSTS_N_INSNS (3), /* fp */
505 COSTS_N_INSNS (3), /* dmul */
506 COSTS_N_INSNS (17), /* sdiv */
507 COSTS_N_INSNS (21), /* ddiv */
510 /* Instruction costs on PPC750 and PPC7400 processors. */
512 struct processor_costs ppc750_cost
= {
513 COSTS_N_INSNS (5), /* mulsi */
514 COSTS_N_INSNS (3), /* mulsi_const */
515 COSTS_N_INSNS (2), /* mulsi_const9 */
516 COSTS_N_INSNS (5), /* muldi */
517 COSTS_N_INSNS (17), /* divsi */
518 COSTS_N_INSNS (17), /* divdi */
519 COSTS_N_INSNS (3), /* fp */
520 COSTS_N_INSNS (3), /* dmul */
521 COSTS_N_INSNS (17), /* sdiv */
522 COSTS_N_INSNS (31), /* ddiv */
525 /* Instruction costs on PPC7450 processors. */
527 struct processor_costs ppc7450_cost
= {
528 COSTS_N_INSNS (4), /* mulsi */
529 COSTS_N_INSNS (3), /* mulsi_const */
530 COSTS_N_INSNS (3), /* mulsi_const9 */
531 COSTS_N_INSNS (4), /* muldi */
532 COSTS_N_INSNS (23), /* divsi */
533 COSTS_N_INSNS (23), /* divdi */
534 COSTS_N_INSNS (5), /* fp */
535 COSTS_N_INSNS (5), /* dmul */
536 COSTS_N_INSNS (21), /* sdiv */
537 COSTS_N_INSNS (35), /* ddiv */
540 /* Instruction costs on PPC8540 processors. */
542 struct processor_costs ppc8540_cost
= {
543 COSTS_N_INSNS (4), /* mulsi */
544 COSTS_N_INSNS (4), /* mulsi_const */
545 COSTS_N_INSNS (4), /* mulsi_const9 */
546 COSTS_N_INSNS (4), /* muldi */
547 COSTS_N_INSNS (19), /* divsi */
548 COSTS_N_INSNS (19), /* divdi */
549 COSTS_N_INSNS (4), /* fp */
550 COSTS_N_INSNS (4), /* dmul */
551 COSTS_N_INSNS (29), /* sdiv */
552 COSTS_N_INSNS (29), /* ddiv */
555 /* Instruction costs on POWER4 and POWER5 processors. */
557 struct processor_costs power4_cost
= {
558 COSTS_N_INSNS (3), /* mulsi */
559 COSTS_N_INSNS (2), /* mulsi_const */
560 COSTS_N_INSNS (2), /* mulsi_const9 */
561 COSTS_N_INSNS (4), /* muldi */
562 COSTS_N_INSNS (18), /* divsi */
563 COSTS_N_INSNS (34), /* divdi */
564 COSTS_N_INSNS (3), /* fp */
565 COSTS_N_INSNS (3), /* dmul */
566 COSTS_N_INSNS (17), /* sdiv */
567 COSTS_N_INSNS (17), /* ddiv */
571 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
572 static const char *rs6000_invalid_within_doloop (rtx
);
573 static rtx
rs6000_generate_compare (enum rtx_code
);
574 static void rs6000_maybe_dead (rtx
);
575 static void rs6000_emit_stack_tie (void);
576 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
577 static rtx
spe_synthesize_frame_save (rtx
);
578 static bool spe_func_has_64bit_regs_p (void);
579 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
581 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
582 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int);
583 static unsigned rs6000_hash_constant (rtx
);
584 static unsigned toc_hash_function (const void *);
585 static int toc_hash_eq (const void *, const void *);
586 static int constant_pool_expr_1 (rtx
, int *, int *);
587 static bool constant_pool_expr_p (rtx
);
588 static bool legitimate_indexed_address_p (rtx
, int);
589 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
590 static struct machine_function
* rs6000_init_machine_status (void);
591 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
592 static bool no_global_regs_above (int);
593 #ifdef HAVE_GAS_HIDDEN
594 static void rs6000_assemble_visibility (tree
, int);
596 static int rs6000_ra_ever_killed (void);
597 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
598 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
599 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
600 static const char *rs6000_mangle_fundamental_type (tree
);
601 extern const struct attribute_spec rs6000_attribute_table
[];
602 static void rs6000_set_default_type_attributes (tree
);
603 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
604 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
605 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
607 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
608 static bool rs6000_return_in_memory (tree
, tree
);
609 static void rs6000_file_start (void);
611 static unsigned int rs6000_elf_section_type_flags (tree
, const char *, int);
612 static void rs6000_elf_asm_out_constructor (rtx
, int);
613 static void rs6000_elf_asm_out_destructor (rtx
, int);
614 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
615 static void rs6000_elf_select_section (tree
, int, unsigned HOST_WIDE_INT
);
616 static void rs6000_elf_unique_section (tree
, int);
617 static void rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
618 unsigned HOST_WIDE_INT
);
619 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
621 static bool rs6000_elf_in_small_data_p (tree
);
624 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
625 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
626 static void rs6000_xcoff_select_section (tree
, int, unsigned HOST_WIDE_INT
);
627 static void rs6000_xcoff_unique_section (tree
, int);
628 static void rs6000_xcoff_select_rtx_section (enum machine_mode
, rtx
,
629 unsigned HOST_WIDE_INT
);
630 static const char * rs6000_xcoff_strip_name_encoding (const char *);
631 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
632 static void rs6000_xcoff_file_start (void);
633 static void rs6000_xcoff_file_end (void);
635 static int rs6000_variable_issue (FILE *, int, rtx
, int);
636 static bool rs6000_rtx_costs (rtx
, int, int, int *);
637 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
638 static bool is_microcoded_insn (rtx
);
639 static int is_dispatch_slot_restricted (rtx
);
640 static bool is_cracked_insn (rtx
);
641 static bool is_branch_slot_insn (rtx
);
642 static int rs6000_adjust_priority (rtx
, int);
643 static int rs6000_issue_rate (void);
644 static bool rs6000_is_costly_dependence (rtx
, rtx
, rtx
, int, int);
645 static rtx
get_next_active_insn (rtx
, rtx
);
646 static bool insn_terminates_group_p (rtx
, enum group_termination
);
647 static bool is_costly_group (rtx
*, rtx
);
648 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
649 static int redefine_groups (FILE *, int, rtx
, rtx
);
650 static int pad_groups (FILE *, int, rtx
, rtx
);
651 static void rs6000_sched_finish (FILE *, int);
652 static int rs6000_use_sched_lookahead (void);
653 static tree
rs6000_builtin_mask_for_load (void);
655 static void def_builtin (int, const char *, tree
, int);
656 static void rs6000_init_builtins (void);
657 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
658 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
659 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
660 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
661 static void altivec_init_builtins (void);
662 static void rs6000_common_init_builtins (void);
663 static void rs6000_init_libfuncs (void);
665 static void enable_mask_for_builtins (struct builtin_description
*, int,
666 enum rs6000_builtins
,
667 enum rs6000_builtins
);
668 static tree
build_opaque_vector_type (tree
, int);
669 static void spe_init_builtins (void);
670 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
671 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
672 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
673 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
674 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
675 static rs6000_stack_t
*rs6000_stack_info (void);
676 static void debug_stack_info (rs6000_stack_t
*);
678 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
679 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
680 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
681 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
682 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
683 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
684 const char *, tree
, rtx
);
685 static rtx
altivec_expand_lv_builtin (enum insn_code
, tree
, rtx
);
686 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
687 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
688 static rtx
altivec_expand_vec_set_builtin (tree
);
689 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
690 static int get_element_number (tree
, tree
);
691 static bool rs6000_handle_option (size_t, const char *, int);
692 static void rs6000_parse_tls_size_option (void);
693 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
694 static int first_altivec_reg_to_save (void);
695 static unsigned int compute_vrsave_mask (void);
696 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
697 static void is_altivec_return_reg (rtx
, void *);
698 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
699 int easy_vector_constant (rtx
, enum machine_mode
);
700 static bool rs6000_is_opaque_type (tree
);
701 static rtx
rs6000_dwarf_register_span (rtx
);
702 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
703 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
704 static rtx
rs6000_tls_get_addr (void);
705 static rtx
rs6000_got_sym (void);
706 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
707 static const char *rs6000_get_some_local_dynamic_name (void);
708 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
709 static rtx
rs6000_complex_function_value (enum machine_mode
);
710 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
711 enum machine_mode
, tree
);
712 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
714 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
715 tree
, HOST_WIDE_INT
);
716 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
719 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
722 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, tree
, int, bool);
723 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
724 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
725 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
726 enum machine_mode
, tree
,
728 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
730 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
732 static const char *invalid_arg_for_unprototyped_fn (tree
, tree
, tree
);
734 static void macho_branch_islands (void);
735 static void add_compiler_branch_island (tree
, tree
, int);
736 static int no_previous_def (tree function_name
);
737 static tree
get_prev_label (tree function_name
);
738 static void rs6000_darwin_file_start (void);
741 static tree
rs6000_build_builtin_va_list (void);
742 static tree
rs6000_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
743 static bool rs6000_must_pass_in_stack (enum machine_mode
, tree
);
744 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
745 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
747 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
749 static int get_vsel_insn (enum machine_mode
);
750 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
751 static tree
rs6000_stack_protect_fail (void);
753 const int INSN_NOT_AVAILABLE
= -1;
754 static enum machine_mode
rs6000_eh_return_filter_mode (void);
756 /* Hash table stuff for keeping track of TOC entries. */
758 struct toc_hash_struct
GTY(())
760 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
761 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
763 enum machine_mode key_mode
;
767 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
769 /* Default register names. */
770 char rs6000_reg_names
[][8] =
772 "0", "1", "2", "3", "4", "5", "6", "7",
773 "8", "9", "10", "11", "12", "13", "14", "15",
774 "16", "17", "18", "19", "20", "21", "22", "23",
775 "24", "25", "26", "27", "28", "29", "30", "31",
776 "0", "1", "2", "3", "4", "5", "6", "7",
777 "8", "9", "10", "11", "12", "13", "14", "15",
778 "16", "17", "18", "19", "20", "21", "22", "23",
779 "24", "25", "26", "27", "28", "29", "30", "31",
780 "mq", "lr", "ctr","ap",
781 "0", "1", "2", "3", "4", "5", "6", "7",
783 /* AltiVec registers. */
784 "0", "1", "2", "3", "4", "5", "6", "7",
785 "8", "9", "10", "11", "12", "13", "14", "15",
786 "16", "17", "18", "19", "20", "21", "22", "23",
787 "24", "25", "26", "27", "28", "29", "30", "31",
790 "spe_acc", "spefscr",
791 /* Soft frame pointer. */
795 #ifdef TARGET_REGNAMES
796 static const char alt_reg_names
[][8] =
798 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
799 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
800 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
801 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
802 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
803 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
804 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
805 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
806 "mq", "lr", "ctr", "ap",
807 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
809 /* AltiVec registers. */
810 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
811 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
812 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
813 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
816 "spe_acc", "spefscr",
817 /* Soft frame pointer. */
822 #ifndef MASK_STRICT_ALIGN
823 #define MASK_STRICT_ALIGN 0
825 #ifndef TARGET_PROFILE_KERNEL
826 #define TARGET_PROFILE_KERNEL 0
829 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
830 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
832 /* Initialize the GCC target structure. */
833 #undef TARGET_ATTRIBUTE_TABLE
834 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
835 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
836 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
838 #undef TARGET_ASM_ALIGNED_DI_OP
839 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
841 /* Default unaligned ops are only provided for ELF. Find the ops needed
842 for non-ELF systems. */
843 #ifndef OBJECT_FORMAT_ELF
845 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
847 #undef TARGET_ASM_UNALIGNED_HI_OP
848 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
849 #undef TARGET_ASM_UNALIGNED_SI_OP
850 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
851 #undef TARGET_ASM_UNALIGNED_DI_OP
852 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
855 #undef TARGET_ASM_UNALIGNED_HI_OP
856 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
857 #undef TARGET_ASM_UNALIGNED_SI_OP
858 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
859 #undef TARGET_ASM_UNALIGNED_DI_OP
860 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
861 #undef TARGET_ASM_ALIGNED_DI_OP
862 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
866 /* This hook deals with fixups for relocatable code and DI-mode objects
868 #undef TARGET_ASM_INTEGER
869 #define TARGET_ASM_INTEGER rs6000_assemble_integer
871 #ifdef HAVE_GAS_HIDDEN
872 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
873 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
876 #undef TARGET_HAVE_TLS
877 #define TARGET_HAVE_TLS HAVE_AS_TLS
879 #undef TARGET_CANNOT_FORCE_CONST_MEM
880 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
882 #undef TARGET_ASM_FUNCTION_PROLOGUE
883 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
884 #undef TARGET_ASM_FUNCTION_EPILOGUE
885 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
887 #undef TARGET_SCHED_VARIABLE_ISSUE
888 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
890 #undef TARGET_SCHED_ISSUE_RATE
891 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
892 #undef TARGET_SCHED_ADJUST_COST
893 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
894 #undef TARGET_SCHED_ADJUST_PRIORITY
895 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
896 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
897 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
898 #undef TARGET_SCHED_FINISH
899 #define TARGET_SCHED_FINISH rs6000_sched_finish
901 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
902 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
904 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
905 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
907 #undef TARGET_INIT_BUILTINS
908 #define TARGET_INIT_BUILTINS rs6000_init_builtins
910 #undef TARGET_EXPAND_BUILTIN
911 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
913 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
914 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
916 #undef TARGET_INIT_LIBFUNCS
917 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
920 #undef TARGET_BINDS_LOCAL_P
921 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
924 #undef TARGET_ASM_OUTPUT_MI_THUNK
925 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
927 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
928 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
930 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
931 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
933 #undef TARGET_INVALID_WITHIN_DOLOOP
934 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
936 #undef TARGET_RTX_COSTS
937 #define TARGET_RTX_COSTS rs6000_rtx_costs
938 #undef TARGET_ADDRESS_COST
939 #define TARGET_ADDRESS_COST hook_int_rtx_0
941 #undef TARGET_VECTOR_OPAQUE_P
942 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
944 #undef TARGET_DWARF_REGISTER_SPAN
945 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
947 /* On rs6000, function arguments are promoted, as are function return
949 #undef TARGET_PROMOTE_FUNCTION_ARGS
950 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
951 #undef TARGET_PROMOTE_FUNCTION_RETURN
952 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
954 #undef TARGET_RETURN_IN_MEMORY
955 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
957 #undef TARGET_SETUP_INCOMING_VARARGS
958 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
960 /* Always strict argument naming on rs6000. */
961 #undef TARGET_STRICT_ARGUMENT_NAMING
962 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
963 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
964 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
965 #undef TARGET_SPLIT_COMPLEX_ARG
966 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
967 #undef TARGET_MUST_PASS_IN_STACK
968 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
969 #undef TARGET_PASS_BY_REFERENCE
970 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
971 #undef TARGET_ARG_PARTIAL_BYTES
972 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
974 #undef TARGET_BUILD_BUILTIN_VA_LIST
975 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
977 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
978 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
980 #undef TARGET_EH_RETURN_FILTER_MODE
981 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
983 #undef TARGET_VECTOR_MODE_SUPPORTED_P
984 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
986 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
987 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
989 #undef TARGET_HANDLE_OPTION
990 #define TARGET_HANDLE_OPTION rs6000_handle_option
992 #undef TARGET_DEFAULT_TARGET_FLAGS
993 #define TARGET_DEFAULT_TARGET_FLAGS \
994 (TARGET_DEFAULT | MASK_SCHED_PROLOG)
996 #undef TARGET_STACK_PROTECT_FAIL
997 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
999 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1000 The PowerPC architecture requires only weak consistency among
1001 processors--that is, memory accesses between processors need not be
1002 sequentially consistent and memory accesses among processors can occur
1003 in any order. The ability to order memory accesses weakly provides
1004 opportunities for more efficient use of the system bus. Unless a
1005 dependency exists, the 604e allows read operations to precede store
1007 #undef TARGET_RELAXED_ORDERING
1008 #define TARGET_RELAXED_ORDERING true
1011 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1012 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1015 struct gcc_target targetm
= TARGET_INITIALIZER
;
1018 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1021 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1023 /* The GPRs can hold any mode, but values bigger than one register
1024 cannot go past R31. */
1025 if (INT_REGNO_P (regno
))
1026 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1028 /* The float registers can only hold floating modes and DImode. */
1029 if (FP_REGNO_P (regno
))
1031 (SCALAR_FLOAT_MODE_P (mode
)
1032 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1033 || (GET_MODE_CLASS (mode
) == MODE_INT
1034 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
);
1036 /* The CR register can only hold CC modes. */
1037 if (CR_REGNO_P (regno
))
1038 return GET_MODE_CLASS (mode
) == MODE_CC
;
1040 if (XER_REGNO_P (regno
))
1041 return mode
== PSImode
;
1043 /* AltiVec only in AldyVec registers. */
1044 if (ALTIVEC_REGNO_P (regno
))
1045 return ALTIVEC_VECTOR_MODE (mode
);
1047 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1048 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1051 /* We cannot put TImode anywhere except general register and it must be
1052 able to fit within the register set. */
1054 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1057 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1059 rs6000_init_hard_regno_mode_ok (void)
1063 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1064 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1065 if (rs6000_hard_regno_mode_ok (r
, m
))
1066 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1069 /* If not otherwise specified by a target, make 'long double' equivalent to
1072 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1073 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1076 /* Override command line options. Mostly we process the processor
1077 type and sometimes adjust other TARGET_ options. */
1080 rs6000_override_options (const char *default_cpu
)
1083 struct rs6000_cpu_select
*ptr
;
1086 /* Simplifications for entries below. */
1089 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1090 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1093 /* This table occasionally claims that a processor does not support
1094 a particular feature even though it does, but the feature is slower
1095 than the alternative. Thus, it shouldn't be relied on as a
1096 complete description of the processor's support.
1098 Please keep this list in order, and don't forget to update the
1099 documentation in invoke.texi when adding a new processor or
1103 const char *const name
; /* Canonical processor name. */
1104 const enum processor_type processor
; /* Processor type enum value. */
1105 const int target_enable
; /* Target flags to enable. */
1106 } const processor_target_table
[]
1107 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1108 {"403", PROCESSOR_PPC403
,
1109 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1110 {"405", PROCESSOR_PPC405
,
1111 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
},
1112 {"405fp", PROCESSOR_PPC405
, POWERPC_BASE_MASK
| MASK_MULHW
},
1113 {"440", PROCESSOR_PPC440
,
1114 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
},
1115 {"440fp", PROCESSOR_PPC440
, POWERPC_BASE_MASK
| MASK_MULHW
},
1116 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1117 {"601", PROCESSOR_PPC601
,
1118 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1119 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1120 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1121 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1122 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1123 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1124 {"620", PROCESSOR_PPC620
,
1125 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1126 {"630", PROCESSOR_PPC630
,
1127 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1128 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1129 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1130 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1131 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1132 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1133 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1134 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1135 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1136 /* 8548 has a dummy entry for now. */
1137 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1138 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1139 {"970", PROCESSOR_POWER4
,
1140 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1141 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1142 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1143 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1144 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1145 {"G5", PROCESSOR_POWER4
,
1146 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1147 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1148 {"power2", PROCESSOR_POWER
,
1149 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1150 {"power3", PROCESSOR_PPC630
,
1151 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1152 {"power4", PROCESSOR_POWER4
,
1153 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1154 {"power5", PROCESSOR_POWER5
,
1155 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1156 | MASK_MFCRF
| MASK_POPCNTB
},
1157 {"power5+", PROCESSOR_POWER5
,
1158 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1159 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1160 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1161 {"powerpc64", PROCESSOR_POWERPC64
,
1162 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1163 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1164 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1165 {"rios2", PROCESSOR_RIOS2
,
1166 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1167 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1168 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1169 {"rs64", PROCESSOR_RS64A
,
1170 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1173 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1175 /* Some OSs don't support saving the high part of 64-bit registers on
1176 context switch. Other OSs don't support saving Altivec registers.
1177 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1178 settings; if the user wants either, the user must explicitly specify
1179 them and we won't interfere with the user's specification. */
1182 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1183 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
1184 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1185 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
)
1188 rs6000_init_hard_regno_mode_ok ();
1190 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1191 #ifdef OS_MISSING_POWERPC64
1192 if (OS_MISSING_POWERPC64
)
1193 set_masks
&= ~MASK_POWERPC64
;
1195 #ifdef OS_MISSING_ALTIVEC
1196 if (OS_MISSING_ALTIVEC
)
1197 set_masks
&= ~MASK_ALTIVEC
;
1200 /* Don't override by the processor default if given explicitly. */
1201 set_masks
&= ~target_flags_explicit
;
1203 /* Identify the processor type. */
1204 rs6000_select
[0].string
= default_cpu
;
1205 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1207 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1209 ptr
= &rs6000_select
[i
];
1210 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1212 for (j
= 0; j
< ptt_size
; j
++)
1213 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1215 if (ptr
->set_tune_p
)
1216 rs6000_cpu
= processor_target_table
[j
].processor
;
1218 if (ptr
->set_arch_p
)
1220 target_flags
&= ~set_masks
;
1221 target_flags
|= (processor_target_table
[j
].target_enable
1228 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1235 /* If we are optimizing big endian systems for space, use the load/store
1236 multiple and string instructions. */
1237 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1238 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1240 /* Don't allow -mmultiple or -mstring on little endian systems
1241 unless the cpu is a 750, because the hardware doesn't support the
1242 instructions used in little endian mode, and causes an alignment
1243 trap. The 750 does not cause an alignment trap (except when the
1244 target is unaligned). */
1246 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1248 if (TARGET_MULTIPLE
)
1250 target_flags
&= ~MASK_MULTIPLE
;
1251 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1252 warning (0, "-mmultiple is not supported on little endian systems");
1257 target_flags
&= ~MASK_STRING
;
1258 if ((target_flags_explicit
& MASK_STRING
) != 0)
1259 warning (0, "-mstring is not supported on little endian systems");
1263 /* Set debug flags */
1264 if (rs6000_debug_name
)
1266 if (! strcmp (rs6000_debug_name
, "all"))
1267 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1268 else if (! strcmp (rs6000_debug_name
, "stack"))
1269 rs6000_debug_stack
= 1;
1270 else if (! strcmp (rs6000_debug_name
, "arg"))
1271 rs6000_debug_arg
= 1;
1273 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1276 if (rs6000_traceback_name
)
1278 if (! strncmp (rs6000_traceback_name
, "full", 4))
1279 rs6000_traceback
= traceback_full
;
1280 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1281 rs6000_traceback
= traceback_part
;
1282 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1283 rs6000_traceback
= traceback_none
;
1285 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1286 rs6000_traceback_name
);
1289 if (!rs6000_explicit_options
.long_double
)
1290 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1292 /* Set Altivec ABI as default for powerpc64 linux. */
1293 if (TARGET_ELF
&& TARGET_64BIT
)
1295 rs6000_altivec_abi
= 1;
1296 TARGET_ALTIVEC_VRSAVE
= 1;
1299 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1300 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1302 rs6000_darwin64_abi
= 1;
1304 darwin_one_byte_bool
= 1;
1306 /* Default to natural alignment, for better performance. */
1307 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1310 /* Handle -mtls-size option. */
1311 rs6000_parse_tls_size_option ();
1313 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1314 SUBTARGET_OVERRIDE_OPTIONS
;
1316 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1317 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1319 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1320 SUB3TARGET_OVERRIDE_OPTIONS
;
1326 error ("AltiVec and E500 instructions cannot coexist");
1328 /* The e500 does not have string instructions, and we set
1329 MASK_STRING above when optimizing for size. */
1330 if ((target_flags
& MASK_STRING
) != 0)
1331 target_flags
= target_flags
& ~MASK_STRING
;
1333 else if (rs6000_select
[1].string
!= NULL
)
1335 /* For the powerpc-eabispe configuration, we set all these by
1336 default, so let's unset them if we manually set another
1337 CPU that is not the E500. */
1338 if (!rs6000_explicit_options
.abi
)
1340 if (!rs6000_explicit_options
.spe
)
1342 if (!rs6000_explicit_options
.float_gprs
)
1343 rs6000_float_gprs
= 0;
1344 if (!rs6000_explicit_options
.isel
)
1346 if (!rs6000_explicit_options
.long_double
)
1347 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1350 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1351 && rs6000_cpu
!= PROCESSOR_POWER5
);
1352 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1353 || rs6000_cpu
== PROCESSOR_POWER5
);
1355 rs6000_sched_restricted_insns_priority
1356 = (rs6000_sched_groups
? 1 : 0);
1358 /* Handle -msched-costly-dep option. */
1359 rs6000_sched_costly_dep
1360 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1362 if (rs6000_sched_costly_dep_str
)
1364 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1365 rs6000_sched_costly_dep
= no_dep_costly
;
1366 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1367 rs6000_sched_costly_dep
= all_deps_costly
;
1368 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1369 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1370 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1371 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1373 rs6000_sched_costly_dep
= atoi (rs6000_sched_costly_dep_str
);
1376 /* Handle -minsert-sched-nops option. */
1377 rs6000_sched_insert_nops
1378 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1380 if (rs6000_sched_insert_nops_str
)
1382 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1383 rs6000_sched_insert_nops
= sched_finish_none
;
1384 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1385 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1386 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1387 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1389 rs6000_sched_insert_nops
= atoi (rs6000_sched_insert_nops_str
);
1392 #ifdef TARGET_REGNAMES
1393 /* If the user desires alternate register names, copy in the
1394 alternate names now. */
1395 if (TARGET_REGNAMES
)
1396 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1399 /* Set aix_struct_return last, after the ABI is determined.
1400 If -maix-struct-return or -msvr4-struct-return was explicitly
1401 used, don't override with the ABI default. */
1402 if (!rs6000_explicit_options
.aix_struct_ret
)
1403 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1405 if (TARGET_LONG_DOUBLE_128
1406 && (DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_DARWIN
))
1407 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1409 /* Allocate an alias set for register saves & restores from stack. */
1410 rs6000_sr_alias_set
= new_alias_set ();
1413 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1415 /* We can only guarantee the availability of DI pseudo-ops when
1416 assembling for 64-bit targets. */
1419 targetm
.asm_out
.aligned_op
.di
= NULL
;
1420 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1423 /* Set branch target alignment, if not optimizing for size. */
1426 if (rs6000_sched_groups
)
1428 if (align_functions
<= 0)
1429 align_functions
= 16;
1430 if (align_jumps
<= 0)
1432 if (align_loops
<= 0)
1435 if (align_jumps_max_skip
<= 0)
1436 align_jumps_max_skip
= 15;
1437 if (align_loops_max_skip
<= 0)
1438 align_loops_max_skip
= 15;
1441 /* Arrange to save and restore machine status around nested functions. */
1442 init_machine_status
= rs6000_init_machine_status
;
1444 /* We should always be splitting complex arguments, but we can't break
1445 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1446 if (DEFAULT_ABI
!= ABI_AIX
)
1447 targetm
.calls
.split_complex_arg
= NULL
;
1449 /* Initialize rs6000_cost with the appropriate target costs. */
1451 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1455 case PROCESSOR_RIOS1
:
1456 rs6000_cost
= &rios1_cost
;
1459 case PROCESSOR_RIOS2
:
1460 rs6000_cost
= &rios2_cost
;
1463 case PROCESSOR_RS64A
:
1464 rs6000_cost
= &rs64a_cost
;
1467 case PROCESSOR_MPCCORE
:
1468 rs6000_cost
= &mpccore_cost
;
1471 case PROCESSOR_PPC403
:
1472 rs6000_cost
= &ppc403_cost
;
1475 case PROCESSOR_PPC405
:
1476 rs6000_cost
= &ppc405_cost
;
1479 case PROCESSOR_PPC440
:
1480 rs6000_cost
= &ppc440_cost
;
1483 case PROCESSOR_PPC601
:
1484 rs6000_cost
= &ppc601_cost
;
1487 case PROCESSOR_PPC603
:
1488 rs6000_cost
= &ppc603_cost
;
1491 case PROCESSOR_PPC604
:
1492 rs6000_cost
= &ppc604_cost
;
1495 case PROCESSOR_PPC604e
:
1496 rs6000_cost
= &ppc604e_cost
;
1499 case PROCESSOR_PPC620
:
1500 rs6000_cost
= &ppc620_cost
;
1503 case PROCESSOR_PPC630
:
1504 rs6000_cost
= &ppc630_cost
;
1507 case PROCESSOR_PPC750
:
1508 case PROCESSOR_PPC7400
:
1509 rs6000_cost
= &ppc750_cost
;
1512 case PROCESSOR_PPC7450
:
1513 rs6000_cost
= &ppc7450_cost
;
1516 case PROCESSOR_PPC8540
:
1517 rs6000_cost
= &ppc8540_cost
;
1520 case PROCESSOR_POWER4
:
1521 case PROCESSOR_POWER5
:
1522 rs6000_cost
= &power4_cost
;
1530 /* Implement targetm.vectorize.builtin_mask_for_load. */
1532 rs6000_builtin_mask_for_load (void)
1535 return altivec_builtin_mask_for_load
;
1540 /* Handle generic options of the form -mfoo=yes/no.
1541 NAME is the option name.
1542 VALUE is the option value.
1543 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1544 whether the option value is 'yes' or 'no' respectively. */
1546 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
1550 else if (!strcmp (value
, "yes"))
1552 else if (!strcmp (value
, "no"))
1555 error ("unknown -m%s= option specified: '%s'", name
, value
);
1558 /* Validate and record the size specified with the -mtls-size option. */
1561 rs6000_parse_tls_size_option (void)
1563 if (rs6000_tls_size_string
== 0)
1565 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
1566 rs6000_tls_size
= 16;
1567 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
1568 rs6000_tls_size
= 32;
1569 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
1570 rs6000_tls_size
= 64;
1572 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
1576 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1578 if (DEFAULT_ABI
== ABI_DARWIN
)
1579 /* The Darwin libraries never set errno, so we might as well
1580 avoid calling them when that's the only reason we would. */
1581 flag_errno_math
= 0;
1583 /* Double growth factor to counter reduced min jump length. */
1584 set_param_value ("max-grow-copy-bb-insns", 16);
1587 /* Implement TARGET_HANDLE_OPTION. */
1590 rs6000_handle_option (size_t code
, const char *arg
, int value
)
1595 target_flags
&= ~(MASK_POWER
| MASK_POWER2
1596 | MASK_MULTIPLE
| MASK_STRING
);
1597 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
1598 | MASK_MULTIPLE
| MASK_STRING
);
1600 case OPT_mno_powerpc
:
1601 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
1602 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1603 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
1604 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1607 target_flags
&= ~(MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
1608 | MASK_NO_SUM_IN_TOC
);
1609 target_flags_explicit
|= (MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
1610 | MASK_NO_SUM_IN_TOC
);
1611 #ifdef TARGET_USES_SYSV4_OPT
1612 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1613 just the same as -mminimal-toc. */
1614 target_flags
|= MASK_MINIMAL_TOC
;
1615 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1619 #ifdef TARGET_USES_SYSV4_OPT
1621 /* Make -mtoc behave like -mminimal-toc. */
1622 target_flags
|= MASK_MINIMAL_TOC
;
1623 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1627 #ifdef TARGET_USES_AIX64_OPT
1632 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
1633 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
1634 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
1637 #ifdef TARGET_USES_AIX64_OPT
1642 target_flags
&= ~MASK_POWERPC64
;
1643 target_flags_explicit
|= MASK_POWERPC64
;
1646 case OPT_minsert_sched_nops_
:
1647 rs6000_sched_insert_nops_str
= arg
;
1650 case OPT_mminimal_toc
:
1653 target_flags
&= ~(MASK_NO_FP_IN_TOC
| MASK_NO_SUM_IN_TOC
);
1654 target_flags_explicit
|= (MASK_NO_FP_IN_TOC
| MASK_NO_SUM_IN_TOC
);
1661 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
1662 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
1669 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1670 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1674 case OPT_mpowerpc_gpopt
:
1675 case OPT_mpowerpc_gfxopt
:
1678 target_flags
|= MASK_POWERPC
;
1679 target_flags_explicit
|= MASK_POWERPC
;
1683 case OPT_maix_struct_return
:
1684 case OPT_msvr4_struct_return
:
1685 rs6000_explicit_options
.aix_struct_ret
= true;
1689 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
1693 rs6000_explicit_options
.isel
= true;
1694 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
1698 rs6000_explicit_options
.spe
= true;
1699 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
1700 /* No SPE means 64-bit long doubles, even if an E500. */
1702 rs6000_long_double_type_size
= 64;
1706 rs6000_debug_name
= arg
;
1709 #ifdef TARGET_USES_SYSV4_OPT
1711 rs6000_abi_name
= arg
;
1715 rs6000_sdata_name
= arg
;
1718 case OPT_mtls_size_
:
1719 rs6000_tls_size_string
= arg
;
1722 case OPT_mrelocatable
:
1725 target_flags
|= MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
;
1726 target_flags_explicit
|= MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
;
1730 case OPT_mrelocatable_lib
:
1733 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
1734 | MASK_NO_FP_IN_TOC
;
1735 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
1736 | MASK_NO_FP_IN_TOC
;
1740 target_flags
&= ~MASK_RELOCATABLE
;
1741 target_flags_explicit
|= MASK_RELOCATABLE
;
1747 rs6000_explicit_options
.abi
= true;
1748 if (!strcmp (arg
, "altivec"))
1750 rs6000_altivec_abi
= 1;
1753 else if (! strcmp (arg
, "no-altivec"))
1754 rs6000_altivec_abi
= 0;
1755 else if (! strcmp (arg
, "spe"))
1758 rs6000_altivec_abi
= 0;
1759 if (!TARGET_SPE_ABI
)
1760 error ("not configured for ABI: '%s'", arg
);
1762 else if (! strcmp (arg
, "no-spe"))
1765 /* These are here for testing during development only, do not
1766 document in the manual please. */
1767 else if (! strcmp (arg
, "d64"))
1769 rs6000_darwin64_abi
= 1;
1770 warning (0, "Using darwin64 ABI");
1772 else if (! strcmp (arg
, "d32"))
1774 rs6000_darwin64_abi
= 0;
1775 warning (0, "Using old darwin ABI");
1780 error ("unknown ABI specified: '%s'", arg
);
1786 rs6000_select
[1].string
= arg
;
1790 rs6000_select
[2].string
= arg
;
1793 case OPT_mtraceback_
:
1794 rs6000_traceback_name
= arg
;
1797 case OPT_mfloat_gprs_
:
1798 rs6000_explicit_options
.float_gprs
= true;
1799 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
1800 rs6000_float_gprs
= 1;
1801 else if (! strcmp (arg
, "double"))
1802 rs6000_float_gprs
= 2;
1803 else if (! strcmp (arg
, "no"))
1804 rs6000_float_gprs
= 0;
1807 error ("invalid option for -mfloat-gprs: '%s'", arg
);
1812 case OPT_mlong_double_
:
1813 rs6000_explicit_options
.long_double
= true;
1814 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1815 if (value
!= 64 && value
!= 128)
1817 error ("Unknown switch -mlong-double-%s", arg
);
1818 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1822 rs6000_long_double_type_size
= value
;
1825 case OPT_msched_costly_dep_
:
1826 rs6000_sched_costly_dep_str
= arg
;
1830 rs6000_explicit_options
.alignment
= true;
1831 if (! strcmp (arg
, "power"))
1833 /* On 64-bit Darwin, power alignment is ABI-incompatible with
1834 some C library functions, so warn about it. The flag may be
1835 useful for performance studies from time to time though, so
1836 don't disable it entirely. */
1837 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1838 warning (0, "-malign-power is not supported for 64-bit Darwin;"
1839 " it is incompatible with the installed C and C++ libraries");
1840 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
1842 else if (! strcmp (arg
, "natural"))
1843 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1846 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
1854 /* Do anything needed at the start of the asm file. */
1857 rs6000_file_start (void)
1861 const char *start
= buffer
;
1862 struct rs6000_cpu_select
*ptr
;
1863 const char *default_cpu
= TARGET_CPU_DEFAULT
;
1864 FILE *file
= asm_out_file
;
1866 default_file_start ();
1868 #ifdef TARGET_BI_ARCH
1869 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
1873 if (flag_verbose_asm
)
1875 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
1876 rs6000_select
[0].string
= default_cpu
;
1878 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1880 ptr
= &rs6000_select
[i
];
1881 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1883 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
1888 if (PPC405_ERRATUM77
)
1890 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
1894 #ifdef USING_ELFOS_H
1895 switch (rs6000_sdata
)
1897 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
1898 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
1899 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
1900 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
1903 if (rs6000_sdata
&& g_switch_value
)
1905 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
1915 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
1923 /* Return nonzero if this function is known to have a null epilogue. */
1926 direct_return (void)
1928 if (reload_completed
)
1930 rs6000_stack_t
*info
= rs6000_stack_info ();
1932 if (info
->first_gp_reg_save
== 32
1933 && info
->first_fp_reg_save
== 64
1934 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
1935 && ! info
->lr_save_p
1936 && ! info
->cr_save_p
1937 && info
->vrsave_mask
== 0
1945 /* Return the number of instructions it takes to form a constant in an
1946 integer register. */
1949 num_insns_constant_wide (HOST_WIDE_INT value
)
1951 /* signed constant loadable with {cal|addi} */
1952 if (CONST_OK_FOR_LETTER_P (value
, 'I'))
1955 /* constant loadable with {cau|addis} */
1956 else if (CONST_OK_FOR_LETTER_P (value
, 'L'))
1959 #if HOST_BITS_PER_WIDE_INT == 64
1960 else if (TARGET_POWERPC64
)
1962 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1963 HOST_WIDE_INT high
= value
>> 31;
1965 if (high
== 0 || high
== -1)
1971 return num_insns_constant_wide (high
) + 1;
1973 return (num_insns_constant_wide (high
)
1974 + num_insns_constant_wide (low
) + 1);
1983 num_insns_constant (rtx op
, enum machine_mode mode
)
1985 HOST_WIDE_INT low
, high
;
1987 switch (GET_CODE (op
))
1990 #if HOST_BITS_PER_WIDE_INT == 64
1991 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
1992 && mask64_operand (op
, mode
))
1996 return num_insns_constant_wide (INTVAL (op
));
2004 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2005 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2006 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2009 if (mode
== VOIDmode
|| mode
== DImode
)
2011 high
= CONST_DOUBLE_HIGH (op
);
2012 low
= CONST_DOUBLE_LOW (op
);
2019 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2020 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2021 high
= l
[WORDS_BIG_ENDIAN
== 0];
2022 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2026 return (num_insns_constant_wide (low
)
2027 + num_insns_constant_wide (high
));
2030 if ((high
== 0 && low
>= 0)
2031 || (high
== -1 && low
< 0))
2032 return num_insns_constant_wide (low
);
2034 else if (mask64_operand (op
, mode
))
2038 return num_insns_constant_wide (high
) + 1;
2041 return (num_insns_constant_wide (high
)
2042 + num_insns_constant_wide (low
) + 1);
2051 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2052 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2053 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2054 all items are set to the same value and contain COPIES replicas of the
2055 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2056 operand and the others are set to the value of the operand's msb. */
2059 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2061 enum machine_mode mode
= GET_MODE (op
);
2062 enum machine_mode inner
= GET_MODE_INNER (mode
);
2065 unsigned nunits
= GET_MODE_NUNITS (mode
);
2066 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2067 unsigned mask
= GET_MODE_MASK (inner
);
2069 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2070 HOST_WIDE_INT val
= INTVAL (last
);
2071 HOST_WIDE_INT splat_val
= val
;
2072 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2074 /* Construct the value to be splatted, if possible. If not, return 0. */
2075 for (i
= 2; i
<= copies
; i
*= 2)
2077 HOST_WIDE_INT small_val
;
2079 small_val
= splat_val
>> bitsize
;
2081 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2083 splat_val
= small_val
;
2086 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2087 if (EASY_VECTOR_15 (splat_val
))
2090 /* Also check if we can splat, and then add the result to itself. Do so if
2091 the value is positive, of if the splat instruction is using OP's mode;
2092 for splat_val < 0, the splat and the add should use the same mode. */
2093 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2094 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2100 /* Check if VAL is present in every STEP-th element, and the
2101 other elements are filled with its most significant bit. */
2102 for (i
= 0; i
< nunits
- 1; ++i
)
2104 HOST_WIDE_INT desired_val
;
2105 if (((i
+ 1) & (step
- 1)) == 0)
2108 desired_val
= msb_val
;
2110 if (desired_val
!= INTVAL (CONST_VECTOR_ELT (op
, i
)))
2118 /* Return true if OP is of the given MODE and can be synthesized
2119 with a vspltisb, vspltish or vspltisw. */
2122 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2124 unsigned step
, copies
;
2126 if (mode
== VOIDmode
)
2127 mode
= GET_MODE (op
);
2128 else if (mode
!= GET_MODE (op
))
2131 /* Start with a vspltisw. */
2132 step
= GET_MODE_NUNITS (mode
) / 4;
2135 if (vspltis_constant (op
, step
, copies
))
2138 /* Then try with a vspltish. */
2144 if (vspltis_constant (op
, step
, copies
))
2147 /* And finally a vspltisb. */
2153 if (vspltis_constant (op
, step
, copies
))
2159 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2160 result is OP. Abort if it is not possible. */
2163 gen_easy_altivec_constant (rtx op
)
2165 enum machine_mode mode
= GET_MODE (op
);
2166 int nunits
= GET_MODE_NUNITS (mode
);
2167 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2168 unsigned step
= nunits
/ 4;
2169 unsigned copies
= 1;
2171 /* Start with a vspltisw. */
2172 if (vspltis_constant (op
, step
, copies
))
2173 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2175 /* Then try with a vspltish. */
2181 if (vspltis_constant (op
, step
, copies
))
2182 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2184 /* And finally a vspltisb. */
2190 if (vspltis_constant (op
, step
, copies
))
2191 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2197 output_vec_const_move (rtx
*operands
)
2200 enum machine_mode mode
;
2205 mode
= GET_MODE (dest
);
2210 if (zero_constant (vec
, mode
))
2211 return "vxor %0,%0,%0";
2213 splat_vec
= gen_easy_altivec_constant (vec
);
2214 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2215 operands
[1] = XEXP (splat_vec
, 0);
2216 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2219 switch (GET_MODE (splat_vec
))
2222 return "vspltisw %0,%1";
2225 return "vspltish %0,%1";
2228 return "vspltisb %0,%1";
2235 gcc_assert (TARGET_SPE
);
2237 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2238 pattern of V1DI, V4HI, and V2SF.
2240 FIXME: We should probably return # and add post reload
2241 splitters for these, but this way is so easy ;-). */
2242 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2243 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2244 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
2245 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
2247 return "li %0,%1\n\tevmergelo %0,%0,%0";
2249 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2252 /* Initialize vector TARGET to VALS. */
2255 rs6000_expand_vector_init (rtx target
, rtx vals
)
2257 enum machine_mode mode
= GET_MODE (target
);
2258 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2259 int n_elts
= GET_MODE_NUNITS (mode
);
2260 int n_var
= 0, one_var
= -1;
2261 bool all_same
= true, all_const_zero
= true;
2265 for (i
= 0; i
< n_elts
; ++i
)
2267 x
= XVECEXP (vals
, 0, i
);
2268 if (!CONSTANT_P (x
))
2269 ++n_var
, one_var
= i
;
2270 else if (x
!= CONST0_RTX (inner_mode
))
2271 all_const_zero
= false;
2273 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
2279 if (mode
!= V4SFmode
&& all_const_zero
)
2281 /* Zero register. */
2282 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2283 gen_rtx_XOR (mode
, target
, target
)));
2286 else if (mode
!= V4SFmode
&& easy_vector_constant (vals
, mode
))
2288 /* Splat immediate. */
2289 emit_insn (gen_rtx_SET (VOIDmode
, target
, vals
));
2293 ; /* Splat vector element. */
2296 /* Load from constant pool. */
2297 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
2302 /* Store value to stack temp. Load vector element. Splat. */
2305 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2306 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
2307 XVECEXP (vals
, 0, 0));
2308 x
= gen_rtx_UNSPEC (VOIDmode
,
2309 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2310 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2312 gen_rtx_SET (VOIDmode
,
2315 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
2316 gen_rtx_PARALLEL (VOIDmode
,
2317 gen_rtvec (1, const0_rtx
)));
2318 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2319 gen_rtx_VEC_DUPLICATE (mode
, x
)));
2323 /* One field is non-constant. Load constant then overwrite
2327 rtx copy
= copy_rtx (vals
);
2329 /* Load constant part of vector, substitute neighboring value for
2331 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
2332 rs6000_expand_vector_init (target
, copy
);
2334 /* Insert variable. */
2335 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
2339 /* Construct the vector in memory one field at a time
2340 and load the whole vector. */
2341 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2342 for (i
= 0; i
< n_elts
; i
++)
2343 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
2344 i
* GET_MODE_SIZE (inner_mode
)),
2345 XVECEXP (vals
, 0, i
));
2346 emit_move_insn (target
, mem
);
2349 /* Set field ELT of TARGET to VAL. */
2352 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
2354 enum machine_mode mode
= GET_MODE (target
);
2355 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2356 rtx reg
= gen_reg_rtx (mode
);
2358 int width
= GET_MODE_SIZE (inner_mode
);
2361 /* Load single variable value. */
2362 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2363 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
2364 x
= gen_rtx_UNSPEC (VOIDmode
,
2365 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2366 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2368 gen_rtx_SET (VOIDmode
,
2372 /* Linear sequence. */
2373 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
2374 for (i
= 0; i
< 16; ++i
)
2375 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
2377 /* Set permute mask to insert element into target. */
2378 for (i
= 0; i
< width
; ++i
)
2379 XVECEXP (mask
, 0, elt
*width
+ i
)
2380 = GEN_INT (i
+ 0x10);
2381 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
2382 x
= gen_rtx_UNSPEC (mode
,
2383 gen_rtvec (3, target
, reg
,
2384 force_reg (V16QImode
, x
)),
2386 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
2389 /* Extract field ELT from VEC into TARGET. */
2392 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
2394 enum machine_mode mode
= GET_MODE (vec
);
2395 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2398 /* Allocate mode-sized buffer. */
2399 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2401 /* Add offset to field within buffer matching vector element. */
2402 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
2404 /* Store single field into mode-sized buffer. */
2405 x
= gen_rtx_UNSPEC (VOIDmode
,
2406 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
2407 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2409 gen_rtx_SET (VOIDmode
,
2412 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
2415 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2416 implement ANDing by the mask IN. */
2418 build_mask64_2_operands (rtx in
, rtx
*out
)
2420 #if HOST_BITS_PER_WIDE_INT >= 64
2421 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
2424 gcc_assert (GET_CODE (in
) == CONST_INT
);
2429 /* Assume c initially something like 0x00fff000000fffff. The idea
2430 is to rotate the word so that the middle ^^^^^^ group of zeros
2431 is at the MS end and can be cleared with an rldicl mask. We then
2432 rotate back and clear off the MS ^^ group of zeros with a
2434 c
= ~c
; /* c == 0xff000ffffff00000 */
2435 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
2436 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
2437 c
= ~c
; /* c == 0x00fff000000fffff */
2438 c
&= -lsb
; /* c == 0x00fff00000000000 */
2439 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2440 c
= ~c
; /* c == 0xff000fffffffffff */
2441 c
&= -lsb
; /* c == 0xff00000000000000 */
2443 while ((lsb
>>= 1) != 0)
2444 shift
++; /* shift == 44 on exit from loop */
2445 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
2446 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
2447 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
2451 /* Assume c initially something like 0xff000f0000000000. The idea
2452 is to rotate the word so that the ^^^ middle group of zeros
2453 is at the LS end and can be cleared with an rldicr mask. We then
2454 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2456 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
2457 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
2458 c
= ~c
; /* c == 0x00fff0ffffffffff */
2459 c
&= -lsb
; /* c == 0x00fff00000000000 */
2460 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2461 c
= ~c
; /* c == 0xff000fffffffffff */
2462 c
&= -lsb
; /* c == 0xff00000000000000 */
2464 while ((lsb
>>= 1) != 0)
2465 shift
++; /* shift == 44 on exit from loop */
2466 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
2467 m1
>>= shift
; /* m1 == 0x0000000000000fff */
2468 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
2471 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2472 masks will be all 1's. We are guaranteed more than one transition. */
2473 out
[0] = GEN_INT (64 - shift
);
2474 out
[1] = GEN_INT (m1
);
2475 out
[2] = GEN_INT (shift
);
2476 out
[3] = GEN_INT (m2
);
2484 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2487 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
2489 /* Reject (subreg:SI (reg:DF)). */
2490 if (GET_CODE (op
) == SUBREG
2492 && REG_P (SUBREG_REG (op
))
2493 && GET_MODE (SUBREG_REG (op
)) == DFmode
)
2496 /* Reject (subreg:DF (reg:DI)). */
2497 if (GET_CODE (op
) == SUBREG
2499 && REG_P (SUBREG_REG (op
))
2500 && GET_MODE (SUBREG_REG (op
)) == DImode
)
2506 /* Darwin, AIX increases natural record alignment to doubleword if the first
2507 field is an FP double while the FP fields remain word aligned. */
2510 rs6000_special_round_type_align (tree type
, int computed
, int specified
)
2512 tree field
= TYPE_FIELDS (type
);
2514 /* Skip all non field decls */
2515 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
2516 field
= TREE_CHAIN (field
);
2518 if (field
== NULL
|| field
== type
|| DECL_MODE (field
) != DFmode
)
2519 return MAX (computed
, specified
);
2521 return MAX (MAX (computed
, specified
), 64);
2524 /* Return 1 for an operand in small memory on V.4/eabi. */
2527 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
2528 enum machine_mode mode ATTRIBUTE_UNUSED
)
2533 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
2536 if (DEFAULT_ABI
!= ABI_V4
)
2539 if (GET_CODE (op
) == SYMBOL_REF
)
2542 else if (GET_CODE (op
) != CONST
2543 || GET_CODE (XEXP (op
, 0)) != PLUS
2544 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
2545 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
2550 rtx sum
= XEXP (op
, 0);
2551 HOST_WIDE_INT summand
;
2553 /* We have to be careful here, because it is the referenced address
2554 that must be 32k from _SDA_BASE_, not just the symbol. */
2555 summand
= INTVAL (XEXP (sum
, 1));
2556 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
2559 sym_ref
= XEXP (sum
, 0);
2562 return SYMBOL_REF_SMALL_P (sym_ref
);
2568 /* Return true if either operand is a general purpose register. */
2571 gpr_or_gpr_p (rtx op0
, rtx op1
)
2573 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
2574 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
2578 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2581 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
2583 switch (GET_CODE (op
))
2586 if (RS6000_SYMBOL_REF_TLS_P (op
))
2588 else if (CONSTANT_POOL_ADDRESS_P (op
))
2590 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
2598 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
2607 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
2608 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
2610 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
2619 constant_pool_expr_p (rtx op
)
2623 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
2627 toc_relative_expr_p (rtx op
)
2631 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
2635 legitimate_constant_pool_address_p (rtx x
)
2638 && GET_CODE (x
) == PLUS
2639 && GET_CODE (XEXP (x
, 0)) == REG
2640 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
2641 && constant_pool_expr_p (XEXP (x
, 1)));
2645 rs6000_legitimate_small_data_p (enum machine_mode mode
, rtx x
)
2647 return (DEFAULT_ABI
== ABI_V4
2648 && !flag_pic
&& !TARGET_TOC
2649 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
2650 && small_data_operand (x
, mode
));
2653 /* SPE offset addressing is limited to 5-bits worth of double words. */
2654 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2657 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
2659 unsigned HOST_WIDE_INT offset
, extra
;
2661 if (GET_CODE (x
) != PLUS
)
2663 if (GET_CODE (XEXP (x
, 0)) != REG
)
2665 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
2667 if (legitimate_constant_pool_address_p (x
))
2669 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
2672 offset
= INTVAL (XEXP (x
, 1));
2680 /* AltiVec vector modes. Only reg+reg addressing is valid and
2681 constant offset zero should not occur due to canonicalization.
2682 Allow any offset when not strict before reload. */
2689 /* SPE vector modes. */
2690 return SPE_CONST_OFFSET_OK (offset
);
2693 if (TARGET_E500_DOUBLE
)
2694 return SPE_CONST_OFFSET_OK (offset
);
2697 /* On e500v2, we may have:
2699 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2701 Which gets addressed with evldd instructions. */
2702 if (TARGET_E500_DOUBLE
)
2703 return SPE_CONST_OFFSET_OK (offset
);
2705 if (mode
== DFmode
|| !TARGET_POWERPC64
)
2707 else if (offset
& 3)
2713 if (mode
== TFmode
|| !TARGET_POWERPC64
)
2715 else if (offset
& 3)
2726 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
2730 legitimate_indexed_address_p (rtx x
, int strict
)
2734 if (GET_CODE (x
) != PLUS
)
2740 if (!REG_P (op0
) || !REG_P (op1
))
2743 return ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
2744 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
2745 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
2746 && INT_REG_OK_FOR_INDEX_P (op0
, strict
)));
2750 legitimate_indirect_address_p (rtx x
, int strict
)
2752 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
2756 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
2758 if (!TARGET_MACHO
|| !flag_pic
2759 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
2763 if (GET_CODE (x
) != LO_SUM
)
2765 if (GET_CODE (XEXP (x
, 0)) != REG
)
2767 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
2771 return CONSTANT_P (x
);
2775 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
2777 if (GET_CODE (x
) != LO_SUM
)
2779 if (GET_CODE (XEXP (x
, 0)) != REG
)
2781 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
2783 /* Restrict addressing for DI because of our SUBREG hackery. */
2784 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DImode
))
2788 if (TARGET_ELF
|| TARGET_MACHO
)
2790 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
2794 if (GET_MODE_NUNITS (mode
) != 1)
2796 if (GET_MODE_BITSIZE (mode
) > 64
2797 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
2798 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& mode
== DFmode
)))
2801 return CONSTANT_P (x
);
2808 /* Try machine-dependent ways of modifying an illegitimate address
2809 to be legitimate. If we find one, return the new, valid address.
2810 This is used from only one place: `memory_address' in explow.c.
2812 OLDX is the address as it was before break_out_memory_refs was
2813 called. In some cases it is useful to look at this to decide what
2816 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
2818 It is always safe for this function to do nothing. It exists to
2819 recognize opportunities to optimize the output.
2821 On RS/6000, first check for the sum of a register with a constant
2822 integer that is out of range. If so, generate code to add the
2823 constant with the low-order 16 bits masked to the register and force
2824 this result into another register (this can be done with `cau').
2825 Then generate an address of REG+(CONST&0xffff), allowing for the
2826 possibility of bit 16 being a one.
2828 Then check for the sum of a register and something not constant, try to
2829 load the other things into a register and return the sum. */
2832 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
2833 enum machine_mode mode
)
2835 if (GET_CODE (x
) == SYMBOL_REF
)
2837 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
2839 return rs6000_legitimize_tls_address (x
, model
);
2842 if (GET_CODE (x
) == PLUS
2843 && GET_CODE (XEXP (x
, 0)) == REG
2844 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2845 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000)
2847 HOST_WIDE_INT high_int
, low_int
;
2849 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2850 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
2851 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
2852 GEN_INT (high_int
)), 0);
2853 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
2855 else if (GET_CODE (x
) == PLUS
2856 && GET_CODE (XEXP (x
, 0)) == REG
2857 && GET_CODE (XEXP (x
, 1)) != CONST_INT
2858 && GET_MODE_NUNITS (mode
) == 1
2859 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2861 || (((mode
!= DImode
&& mode
!= DFmode
) || TARGET_E500_DOUBLE
)
2863 && (TARGET_POWERPC64
|| mode
!= DImode
)
2866 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
2867 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
2869 else if (ALTIVEC_VECTOR_MODE (mode
))
2873 /* Make sure both operands are registers. */
2874 if (GET_CODE (x
) == PLUS
)
2875 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
2876 force_reg (Pmode
, XEXP (x
, 1)));
2878 reg
= force_reg (Pmode
, x
);
2881 else if (SPE_VECTOR_MODE (mode
)
2882 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
2883 || mode
== DImode
)))
2887 /* We accept [reg + reg] and [reg + OFFSET]. */
2889 if (GET_CODE (x
) == PLUS
)
2891 rtx op1
= XEXP (x
, 0);
2892 rtx op2
= XEXP (x
, 1);
2894 op1
= force_reg (Pmode
, op1
);
2896 if (GET_CODE (op2
) != REG
2897 && (GET_CODE (op2
) != CONST_INT
2898 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))))
2899 op2
= force_reg (Pmode
, op2
);
2901 return gen_rtx_PLUS (Pmode
, op1
, op2
);
2904 return force_reg (Pmode
, x
);
2910 && GET_CODE (x
) != CONST_INT
2911 && GET_CODE (x
) != CONST_DOUBLE
2913 && GET_MODE_NUNITS (mode
) == 1
2914 && (GET_MODE_BITSIZE (mode
) <= 32
2915 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) && mode
== DFmode
)))
2917 rtx reg
= gen_reg_rtx (Pmode
);
2918 emit_insn (gen_elf_high (reg
, x
));
2919 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
2921 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
2924 && ! MACHO_DYNAMIC_NO_PIC_P
2926 && GET_CODE (x
) != CONST_INT
2927 && GET_CODE (x
) != CONST_DOUBLE
2929 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) || mode
!= DFmode
)
2933 rtx reg
= gen_reg_rtx (Pmode
);
2934 emit_insn (gen_macho_high (reg
, x
));
2935 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
2938 && constant_pool_expr_p (x
)
2939 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
2941 return create_TOC_reference (x
);
2947 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
2948 We need to emit DTP-relative relocations. */
2951 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
2956 fputs ("\t.long\t", file
);
2959 fputs (DOUBLE_INT_ASM_OP
, file
);
2964 output_addr_const (file
, x
);
2965 fputs ("@dtprel+0x8000", file
);
2968 /* Construct the SYMBOL_REF for the tls_get_addr function. */
2970 static GTY(()) rtx rs6000_tls_symbol
;
2972 rs6000_tls_get_addr (void)
2974 if (!rs6000_tls_symbol
)
2975 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
2977 return rs6000_tls_symbol
;
2980 /* Construct the SYMBOL_REF for TLS GOT references. */
2982 static GTY(()) rtx rs6000_got_symbol
;
2984 rs6000_got_sym (void)
2986 if (!rs6000_got_symbol
)
2988 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
2989 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
2990 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
2993 return rs6000_got_symbol
;
2996 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2997 this (thread-local) address. */
3000 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
3004 dest
= gen_reg_rtx (Pmode
);
3005 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
3011 tlsreg
= gen_rtx_REG (Pmode
, 13);
3012 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
3016 tlsreg
= gen_rtx_REG (Pmode
, 2);
3017 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
3021 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
3025 tmp
= gen_reg_rtx (Pmode
);
3028 tlsreg
= gen_rtx_REG (Pmode
, 13);
3029 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
3033 tlsreg
= gen_rtx_REG (Pmode
, 2);
3034 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
3038 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
3040 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
3045 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
3047 /* We currently use relocations like @got@tlsgd for tls, which
3048 means the linker will handle allocation of tls entries, placing
3049 them in the .got section. So use a pointer to the .got section,
3050 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3051 or to secondary GOT sections used by 32-bit -fPIC. */
3053 got
= gen_rtx_REG (Pmode
, 2);
3057 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
3060 rtx gsym
= rs6000_got_sym ();
3061 got
= gen_reg_rtx (Pmode
);
3063 rs6000_emit_move (got
, gsym
, Pmode
);
3066 rtx tempLR
, tmp3
, mem
;
3069 tempLR
= gen_reg_rtx (Pmode
);
3070 tmp1
= gen_reg_rtx (Pmode
);
3071 tmp2
= gen_reg_rtx (Pmode
);
3072 tmp3
= gen_reg_rtx (Pmode
);
3073 mem
= gen_const_mem (Pmode
, tmp1
);
3075 first
= emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, gsym
));
3076 emit_move_insn (tmp1
, tempLR
);
3077 emit_move_insn (tmp2
, mem
);
3078 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
3079 last
= emit_move_insn (got
, tmp3
);
3080 REG_NOTES (last
) = gen_rtx_EXPR_LIST (REG_EQUAL
, gsym
,
3082 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
3084 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
,
3090 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
3092 r3
= gen_rtx_REG (Pmode
, 3);
3094 insn
= gen_tls_gd_64 (r3
, got
, addr
);
3096 insn
= gen_tls_gd_32 (r3
, got
, addr
);
3099 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3100 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3101 insn
= emit_call_insn (insn
);
3102 CONST_OR_PURE_CALL_P (insn
) = 1;
3103 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3104 insn
= get_insns ();
3106 emit_libcall_block (insn
, dest
, r3
, addr
);
3108 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
3110 r3
= gen_rtx_REG (Pmode
, 3);
3112 insn
= gen_tls_ld_64 (r3
, got
);
3114 insn
= gen_tls_ld_32 (r3
, got
);
3117 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3118 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3119 insn
= emit_call_insn (insn
);
3120 CONST_OR_PURE_CALL_P (insn
) = 1;
3121 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3122 insn
= get_insns ();
3124 tmp1
= gen_reg_rtx (Pmode
);
3125 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3127 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
3128 if (rs6000_tls_size
== 16)
3131 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
3133 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
3135 else if (rs6000_tls_size
== 32)
3137 tmp2
= gen_reg_rtx (Pmode
);
3139 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
3141 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
3144 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
3146 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
3150 tmp2
= gen_reg_rtx (Pmode
);
3152 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
3154 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
3156 insn
= gen_rtx_SET (Pmode
, dest
,
3157 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
3163 /* IE, or 64 bit offset LE. */
3164 tmp2
= gen_reg_rtx (Pmode
);
3166 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
3168 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
3171 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
3173 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
3181 /* Return 1 if X contains a thread-local symbol. */
3184 rs6000_tls_referenced_p (rtx x
)
3186 if (! TARGET_HAVE_TLS
)
3189 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
3192 /* Return 1 if *X is a thread-local symbol. This is the same as
3193 rs6000_tls_symbol_ref except for the type of the unused argument. */
3196 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
3198 return RS6000_SYMBOL_REF_TLS_P (*x
);
3201 /* The convention appears to be to define this wherever it is used.
3202 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3203 is now used here. */
3204 #ifndef REG_MODE_OK_FOR_BASE_P
3205 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3208 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3209 replace the input X, or the original X if no replacement is called for.
3210 The output parameter *WIN is 1 if the calling macro should goto WIN,
3213 For RS/6000, we wish to handle large displacements off a base
3214 register by splitting the addend across an addiu/addis and the mem insn.
3215 This cuts number of extra insns needed from 3 to 1.
3217 On Darwin, we use this to generate code for floating point constants.
3218 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3219 The Darwin code is inside #if TARGET_MACHO because only then is
3220 machopic_function_base_name() defined. */
3222 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
3223 int opnum
, int type
,
3224 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
3226 /* We must recognize output that we have already generated ourselves. */
3227 if (GET_CODE (x
) == PLUS
3228 && GET_CODE (XEXP (x
, 0)) == PLUS
3229 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3230 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3231 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3233 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3234 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3235 opnum
, (enum reload_type
)type
);
3241 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
3242 && GET_CODE (x
) == LO_SUM
3243 && GET_CODE (XEXP (x
, 0)) == PLUS
3244 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
3245 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
3246 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
3247 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
3248 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
3249 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
3250 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
3252 /* Result of previous invocation of this function on Darwin
3253 floating point constant. */
3254 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3255 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3256 opnum
, (enum reload_type
)type
);
3262 /* Force ld/std non-word aligned offset into base register by wrapping
3264 if (GET_CODE (x
) == PLUS
3265 && GET_CODE (XEXP (x
, 0)) == REG
3266 && REGNO (XEXP (x
, 0)) < 32
3267 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3268 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3269 && (INTVAL (XEXP (x
, 1)) & 3) != 0
3270 && !ALTIVEC_VECTOR_MODE (mode
)
3271 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
3272 && TARGET_POWERPC64
)
3274 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
3275 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3276 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3277 opnum
, (enum reload_type
) type
);
3282 if (GET_CODE (x
) == PLUS
3283 && GET_CODE (XEXP (x
, 0)) == REG
3284 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
3285 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3286 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3287 && !SPE_VECTOR_MODE (mode
)
3288 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
3290 && !ALTIVEC_VECTOR_MODE (mode
))
3292 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
3293 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
3295 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3297 /* Check for 32-bit overflow. */
3298 if (high
+ low
!= val
)
3304 /* Reload the high part into a base reg; leave the low part
3305 in the mem directly. */
3307 x
= gen_rtx_PLUS (GET_MODE (x
),
3308 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
3312 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3313 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3314 opnum
, (enum reload_type
)type
);
3319 if (GET_CODE (x
) == SYMBOL_REF
3320 && !ALTIVEC_VECTOR_MODE (mode
)
3322 && DEFAULT_ABI
== ABI_DARWIN
3323 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
3325 && DEFAULT_ABI
== ABI_V4
3328 /* Don't do this for TFmode, since the result isn't offsettable.
3329 The same goes for DImode without 64-bit gprs. */
3331 && (mode
!= DImode
|| TARGET_POWERPC64
))
3336 rtx offset
= gen_rtx_CONST (Pmode
,
3337 gen_rtx_MINUS (Pmode
, x
,
3338 machopic_function_base_sym ()));
3339 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3340 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
3341 gen_rtx_HIGH (Pmode
, offset
)), offset
);
3345 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3346 gen_rtx_HIGH (Pmode
, x
), x
);
3348 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3349 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3350 opnum
, (enum reload_type
)type
);
3355 /* Reload an offset address wrapped by an AND that represents the
3356 masking of the lower bits. Strip the outer AND and let reload
3357 convert the offset address into an indirect address. */
3359 && ALTIVEC_VECTOR_MODE (mode
)
3360 && GET_CODE (x
) == AND
3361 && GET_CODE (XEXP (x
, 0)) == PLUS
3362 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3363 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3364 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3365 && INTVAL (XEXP (x
, 1)) == -16)
3373 && constant_pool_expr_p (x
)
3374 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
3376 (x
) = create_TOC_reference (x
);
3384 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3385 that is a valid memory address for an instruction.
3386 The MODE argument is the machine mode for the MEM expression
3387 that wants to use this address.
3389 On the RS/6000, there are four valid address: a SYMBOL_REF that
3390 refers to a constant pool entry of an address (or the sum of it
3391 plus a constant), a short (16-bit signed) constant plus a register,
3392 the sum of two registers, or a register indirect, possibly with an
3393 auto-increment. For DFmode and DImode with a constant plus register,
3394 we must ensure that both words are addressable or PowerPC64 with offset
3397 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3398 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3399 adjacent memory cells are accessed by adding word-sized offsets
3400 during assembly output. */
3402 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
3404 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3406 && ALTIVEC_VECTOR_MODE (mode
)
3407 && GET_CODE (x
) == AND
3408 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3409 && INTVAL (XEXP (x
, 1)) == -16)
3412 if (RS6000_SYMBOL_REF_TLS_P (x
))
3414 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
3416 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
3417 && !ALTIVEC_VECTOR_MODE (mode
)
3418 && !SPE_VECTOR_MODE (mode
)
3419 /* Restrict addressing for DI because of our SUBREG hackery. */
3420 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DImode
))
3422 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
3424 if (rs6000_legitimate_small_data_p (mode
, x
))
3426 if (legitimate_constant_pool_address_p (x
))
3428 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3430 && GET_CODE (x
) == PLUS
3431 && GET_CODE (XEXP (x
, 0)) == REG
3432 && (XEXP (x
, 0) == virtual_stack_vars_rtx
3433 || XEXP (x
, 0) == arg_pointer_rtx
)
3434 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3436 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
3440 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3442 || ((mode
!= DFmode
|| TARGET_E500_DOUBLE
) && mode
!= TFmode
))
3443 && (TARGET_POWERPC64
|| mode
!= DImode
)
3444 && legitimate_indexed_address_p (x
, reg_ok_strict
))
3446 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
3451 /* Go to LABEL if ADDR (a legitimate address expression)
3452 has an effect that depends on the machine mode it is used for.
3454 On the RS/6000 this is true of all integral offsets (since AltiVec
3455 modes don't allow them) or is a pre-increment or decrement.
3457 ??? Except that due to conceptual problems in offsettable_address_p
3458 we can't really report the problems of integral offsets. So leave
3459 this assuming that the adjustable offset must be valid for the
3460 sub-words of a TFmode operand, which is what we had before. */
3463 rs6000_mode_dependent_address (rtx addr
)
3465 switch (GET_CODE (addr
))
3468 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
3470 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
3471 return val
+ 12 + 0x8000 >= 0x10000;
3480 return TARGET_UPDATE
;
3489 /* Return number of consecutive hard regs needed starting at reg REGNO
3490 to hold something of mode MODE.
3491 This is ordinarily the length in words of a value of mode MODE
3492 but can be less for certain modes in special long registers.
3494 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3495 scalar instructions. The upper 32 bits are only available to the
3498 POWER and PowerPC GPRs hold 32 bits worth;
3499 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3502 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
3504 if (FP_REGNO_P (regno
))
3505 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
3507 if (TARGET_E500_DOUBLE
&& mode
== DFmode
)
3510 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
3511 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
3513 if (ALTIVEC_REGNO_P (regno
))
3515 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
3517 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3520 /* Change register usage conditional on target flags. */
3522 rs6000_conditional_register_usage (void)
3526 /* Set MQ register fixed (already call_used) if not POWER
3527 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3532 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3534 fixed_regs
[13] = call_used_regs
[13]
3535 = call_really_used_regs
[13] = 1;
3537 /* Conditionally disable FPRs. */
3538 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
3539 for (i
= 32; i
< 64; i
++)
3540 fixed_regs
[i
] = call_used_regs
[i
]
3541 = call_really_used_regs
[i
] = 1;
3543 /* The TOC register is not killed across calls in a way that is
3544 visible to the compiler. */
3545 if (DEFAULT_ABI
== ABI_AIX
)
3546 call_really_used_regs
[2] = 0;
3548 if (DEFAULT_ABI
== ABI_V4
3549 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3551 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3553 if (DEFAULT_ABI
== ABI_V4
3554 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3556 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3557 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3558 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3560 if (DEFAULT_ABI
== ABI_DARWIN
3561 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
3562 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3563 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3564 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3566 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
3567 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3568 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3571 global_regs
[VSCR_REGNO
] = 1;
3575 global_regs
[SPEFSCR_REGNO
] = 1;
3576 fixed_regs
[FIXED_SCRATCH
]
3577 = call_used_regs
[FIXED_SCRATCH
]
3578 = call_really_used_regs
[FIXED_SCRATCH
] = 1;
3581 if (! TARGET_ALTIVEC
)
3583 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
3584 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3585 call_really_used_regs
[VRSAVE_REGNO
] = 1;
3588 if (TARGET_ALTIVEC_ABI
)
3589 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
3590 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3593 /* Try to output insns to set TARGET equal to the constant C if it can
3594 be done in less than N insns. Do all computations in MODE.
3595 Returns the place where the output has been placed if it can be
3596 done and the insns have been emitted. If it would take more than N
3597 insns, zero is returned and no insns and emitted. */
3600 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
3601 rtx source
, int n ATTRIBUTE_UNUSED
)
3603 rtx result
, insn
, set
;
3604 HOST_WIDE_INT c0
, c1
;
3611 dest
= gen_reg_rtx (mode
);
3612 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
3616 result
= no_new_pseudos
? dest
: gen_reg_rtx (SImode
);
3618 emit_insn (gen_rtx_SET (VOIDmode
, result
,
3619 GEN_INT (INTVAL (source
)
3620 & (~ (HOST_WIDE_INT
) 0xffff))));
3621 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
3622 gen_rtx_IOR (SImode
, result
,
3623 GEN_INT (INTVAL (source
) & 0xffff))));
3628 switch (GET_CODE (source
))
3631 c0
= INTVAL (source
);
3636 #if HOST_BITS_PER_WIDE_INT >= 64
3637 c0
= CONST_DOUBLE_LOW (source
);
3640 c0
= CONST_DOUBLE_LOW (source
);
3641 c1
= CONST_DOUBLE_HIGH (source
);
3649 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
3656 insn
= get_last_insn ();
3657 set
= single_set (insn
);
3658 if (! CONSTANT_P (SET_SRC (set
)))
3659 set_unique_reg_note (insn
, REG_EQUAL
, source
);
3664 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3665 fall back to a straight forward decomposition. We do this to avoid
3666 exponential run times encountered when looking for longer sequences
3667 with rs6000_emit_set_const. */
3669 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
3671 if (!TARGET_POWERPC64
)
3673 rtx operand1
, operand2
;
3675 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
3677 operand2
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
!= 0,
3679 emit_move_insn (operand1
, GEN_INT (c1
));
3680 emit_move_insn (operand2
, GEN_INT (c2
));
3684 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
3687 ud2
= (c1
& 0xffff0000) >> 16;
3688 #if HOST_BITS_PER_WIDE_INT >= 64
3692 ud4
= (c2
& 0xffff0000) >> 16;
3694 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
3695 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
3698 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
3700 emit_move_insn (dest
, GEN_INT (ud1
));
3703 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
3704 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
3707 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
3710 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
3712 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3714 else if ((ud4
== 0xffff && (ud3
& 0x8000))
3715 || (ud4
== 0 && ! (ud3
& 0x8000)))
3718 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
3721 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
3724 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud2
)));
3725 emit_move_insn (dest
, gen_rtx_ASHIFT (DImode
, dest
, GEN_INT (16)));
3727 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3732 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
3735 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
3738 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud3
)));
3740 emit_move_insn (dest
, gen_rtx_ASHIFT (DImode
, dest
, GEN_INT (32)));
3742 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
,
3743 GEN_INT (ud2
<< 16)));
3745 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3751 /* Helper for the following. Get rid of [r+r] memory refs
3752 in cases where it won't work (TImode, TFmode). */
3755 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
3757 if (GET_CODE (operands
[0]) == MEM
3758 && GET_CODE (XEXP (operands
[0], 0)) != REG
3759 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
3760 && ! reload_in_progress
)
3762 = replace_equiv_address (operands
[0],
3763 copy_addr_to_reg (XEXP (operands
[0], 0)));
3765 if (GET_CODE (operands
[1]) == MEM
3766 && GET_CODE (XEXP (operands
[1], 0)) != REG
3767 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
3768 && ! reload_in_progress
)
3770 = replace_equiv_address (operands
[1],
3771 copy_addr_to_reg (XEXP (operands
[1], 0)));
3774 /* Emit a move from SOURCE to DEST in mode MODE. */
3776 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
3780 operands
[1] = source
;
3782 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
3783 if (GET_CODE (operands
[1]) == CONST_DOUBLE
3784 && ! FLOAT_MODE_P (mode
)
3785 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
3787 /* FIXME. This should never happen. */
3788 /* Since it seems that it does, do the safe thing and convert
3790 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
3792 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
3793 || FLOAT_MODE_P (mode
)
3794 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
3795 || CONST_DOUBLE_LOW (operands
[1]) < 0)
3796 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
3797 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
3799 /* Check if GCC is setting up a block move that will end up using FP
3800 registers as temporaries. We must make sure this is acceptable. */
3801 if (GET_CODE (operands
[0]) == MEM
3802 && GET_CODE (operands
[1]) == MEM
3804 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
3805 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
3806 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
3807 ? 32 : MEM_ALIGN (operands
[0])))
3808 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
3810 : MEM_ALIGN (operands
[1]))))
3811 && ! MEM_VOLATILE_P (operands
[0])
3812 && ! MEM_VOLATILE_P (operands
[1]))
3814 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
3815 adjust_address (operands
[1], SImode
, 0));
3816 emit_move_insn (adjust_address (operands
[0], SImode
, 4),
3817 adjust_address (operands
[1], SImode
, 4));
3821 if (!no_new_pseudos
&& GET_CODE (operands
[0]) == MEM
3822 && !gpc_reg_operand (operands
[1], mode
))
3823 operands
[1] = force_reg (mode
, operands
[1]);
3825 if (mode
== SFmode
&& ! TARGET_POWERPC
3826 && TARGET_HARD_FLOAT
&& TARGET_FPRS
3827 && GET_CODE (operands
[0]) == MEM
)
3831 if (reload_in_progress
|| reload_completed
)
3832 regnum
= true_regnum (operands
[1]);
3833 else if (GET_CODE (operands
[1]) == REG
)
3834 regnum
= REGNO (operands
[1]);
3838 /* If operands[1] is a register, on POWER it may have
3839 double-precision data in it, so truncate it to single
3841 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
3844 newreg
= (no_new_pseudos
? operands
[1] : gen_reg_rtx (mode
));
3845 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
3846 operands
[1] = newreg
;
3850 /* Recognize the case where operand[1] is a reference to thread-local
3851 data and load its address to a register. */
3852 if (rs6000_tls_referenced_p (operands
[1]))
3854 enum tls_model model
;
3855 rtx tmp
= operands
[1];
3858 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
3860 addend
= XEXP (XEXP (tmp
, 0), 1);
3861 tmp
= XEXP (XEXP (tmp
, 0), 0);
3864 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
3865 model
= SYMBOL_REF_TLS_MODEL (tmp
);
3866 gcc_assert (model
!= 0);
3868 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
3871 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
3872 tmp
= force_operand (tmp
, operands
[0]);
3877 /* Handle the case where reload calls us with an invalid address. */
3878 if (reload_in_progress
&& mode
== Pmode
3879 && (! general_operand (operands
[1], mode
)
3880 || ! nonimmediate_operand (operands
[0], mode
)))
3883 /* 128-bit constant floating-point values on Darwin should really be
3884 loaded as two parts. */
3885 if ((DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_DARWIN
)
3886 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
3887 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
3889 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
3890 know how to get a DFmode SUBREG of a TFmode. */
3891 rs6000_emit_move (simplify_gen_subreg (DImode
, operands
[0], mode
, 0),
3892 simplify_gen_subreg (DImode
, operands
[1], mode
, 0),
3894 rs6000_emit_move (simplify_gen_subreg (DImode
, operands
[0], mode
,
3895 GET_MODE_SIZE (DImode
)),
3896 simplify_gen_subreg (DImode
, operands
[1], mode
,
3897 GET_MODE_SIZE (DImode
)),
3902 /* FIXME: In the long term, this switch statement should go away
3903 and be replaced by a sequence of tests based on things like
3909 if (CONSTANT_P (operands
[1])
3910 && GET_CODE (operands
[1]) != CONST_INT
)
3911 operands
[1] = force_const_mem (mode
, operands
[1]);
3915 rs6000_eliminate_indexed_memrefs (operands
);
3920 if (CONSTANT_P (operands
[1])
3921 && ! easy_fp_constant (operands
[1], mode
))
3922 operands
[1] = force_const_mem (mode
, operands
[1]);
3933 if (CONSTANT_P (operands
[1])
3934 && !easy_vector_constant (operands
[1], mode
))
3935 operands
[1] = force_const_mem (mode
, operands
[1]);
3940 /* Use default pattern for address of ELF small data */
3943 && DEFAULT_ABI
== ABI_V4
3944 && (GET_CODE (operands
[1]) == SYMBOL_REF
3945 || GET_CODE (operands
[1]) == CONST
)
3946 && small_data_operand (operands
[1], mode
))
3948 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
3952 if (DEFAULT_ABI
== ABI_V4
3953 && mode
== Pmode
&& mode
== SImode
3954 && flag_pic
== 1 && got_operand (operands
[1], mode
))
3956 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
3960 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
3964 && CONSTANT_P (operands
[1])
3965 && GET_CODE (operands
[1]) != HIGH
3966 && GET_CODE (operands
[1]) != CONST_INT
)
3968 rtx target
= (no_new_pseudos
? operands
[0] : gen_reg_rtx (mode
));
3970 /* If this is a function address on -mcall-aixdesc,
3971 convert it to the address of the descriptor. */
3972 if (DEFAULT_ABI
== ABI_AIX
3973 && GET_CODE (operands
[1]) == SYMBOL_REF
3974 && XSTR (operands
[1], 0)[0] == '.')
3976 const char *name
= XSTR (operands
[1], 0);
3978 while (*name
== '.')
3980 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
3981 CONSTANT_POOL_ADDRESS_P (new_ref
)
3982 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
3983 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
3984 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
3985 SYMBOL_REF_DECL (new_ref
) = SYMBOL_REF_DECL (operands
[1]);
3986 operands
[1] = new_ref
;
3989 if (DEFAULT_ABI
== ABI_DARWIN
)
3992 if (MACHO_DYNAMIC_NO_PIC_P
)
3994 /* Take care of any required data indirection. */
3995 operands
[1] = rs6000_machopic_legitimize_pic_address (
3996 operands
[1], mode
, operands
[0]);
3997 if (operands
[0] != operands
[1])
3998 emit_insn (gen_rtx_SET (VOIDmode
,
3999 operands
[0], operands
[1]));
4003 emit_insn (gen_macho_high (target
, operands
[1]));
4004 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
4008 emit_insn (gen_elf_high (target
, operands
[1]));
4009 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
4013 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4014 and we have put it in the TOC, we just need to make a TOC-relative
4017 && GET_CODE (operands
[1]) == SYMBOL_REF
4018 && constant_pool_expr_p (operands
[1])
4019 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
4020 get_pool_mode (operands
[1])))
4022 operands
[1] = create_TOC_reference (operands
[1]);
4024 else if (mode
== Pmode
4025 && CONSTANT_P (operands
[1])
4026 && ((GET_CODE (operands
[1]) != CONST_INT
4027 && ! easy_fp_constant (operands
[1], mode
))
4028 || (GET_CODE (operands
[1]) == CONST_INT
4029 && num_insns_constant (operands
[1], mode
) > 2)
4030 || (GET_CODE (operands
[0]) == REG
4031 && FP_REGNO_P (REGNO (operands
[0]))))
4032 && GET_CODE (operands
[1]) != HIGH
4033 && ! legitimate_constant_pool_address_p (operands
[1])
4034 && ! toc_relative_expr_p (operands
[1]))
4036 /* Emit a USE operation so that the constant isn't deleted if
4037 expensive optimizations are turned on because nobody
4038 references it. This should only be done for operands that
4039 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4040 This should not be done for operands that contain LABEL_REFs.
4041 For now, we just handle the obvious case. */
4042 if (GET_CODE (operands
[1]) != LABEL_REF
)
4043 emit_insn (gen_rtx_USE (VOIDmode
, operands
[1]));
4046 /* Darwin uses a special PIC legitimizer. */
4047 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
4050 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
4052 if (operands
[0] != operands
[1])
4053 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4058 /* If we are to limit the number of things we put in the TOC and
4059 this is a symbol plus a constant we can add in one insn,
4060 just put the symbol in the TOC and add the constant. Don't do
4061 this if reload is in progress. */
4062 if (GET_CODE (operands
[1]) == CONST
4063 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
4064 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
4065 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
4066 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
4067 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
4068 && ! side_effects_p (operands
[0]))
4071 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
4072 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
4074 sym
= force_reg (mode
, sym
);
4076 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
4078 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
4082 operands
[1] = force_const_mem (mode
, operands
[1]);
4085 && constant_pool_expr_p (XEXP (operands
[1], 0))
4086 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4087 get_pool_constant (XEXP (operands
[1], 0)),
4088 get_pool_mode (XEXP (operands
[1], 0))))
4091 = gen_const_mem (mode
,
4092 create_TOC_reference (XEXP (operands
[1], 0)));
4093 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
4099 rs6000_eliminate_indexed_memrefs (operands
);
4103 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4105 gen_rtx_SET (VOIDmode
,
4106 operands
[0], operands
[1]),
4107 gen_rtx_CLOBBER (VOIDmode
,
4108 gen_rtx_SCRATCH (SImode
)))));
4117 /* Above, we may have called force_const_mem which may have returned
4118 an invalid address. If we can, fix this up; otherwise, reload will
4119 have to deal with it. */
4120 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
4121 operands
[1] = validize_mem (operands
[1]);
4124 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4127 /* Nonzero if we can use a floating-point register to pass this arg. */
4128 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4129 (SCALAR_FLOAT_MODE_P (MODE) \
4130 && (CUM)->fregno <= FP_ARG_MAX_REG \
4131 && TARGET_HARD_FLOAT && TARGET_FPRS)
4133 /* Nonzero if we can use an AltiVec register to pass this arg. */
4134 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4135 (ALTIVEC_VECTOR_MODE (MODE) \
4136 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4137 && TARGET_ALTIVEC_ABI \
4140 /* Return a nonzero value to say to return the function value in
4141 memory, just as large structures are always returned. TYPE will be
4142 the data type of the value, and FNTYPE will be the type of the
4143 function doing the returning, or @code{NULL} for libcalls.
4145 The AIX ABI for the RS/6000 specifies that all structures are
4146 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4147 specifies that structures <= 8 bytes are returned in r3/r4, but a
4148 draft put them in memory, and GCC used to implement the draft
4149 instead of the final standard. Therefore, aix_struct_return
4150 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4151 compatibility can change DRAFT_V4_STRUCT_RET to override the
4152 default, and -m switches get the final word. See
4153 rs6000_override_options for more details.
4155 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4156 long double support is enabled. These values are returned in memory.
4158 int_size_in_bytes returns -1 for variable size objects, which go in
4159 memory always. The cast to unsigned makes -1 > 8. */
4162 rs6000_return_in_memory (tree type
, tree fntype ATTRIBUTE_UNUSED
)
4164 /* In the darwin64 abi, try to use registers for larger structs
4166 if (rs6000_darwin64_abi
4167 && TREE_CODE (type
) == RECORD_TYPE
4168 && int_size_in_bytes (type
) > 0)
4170 CUMULATIVE_ARGS valcum
;
4174 valcum
.fregno
= FP_ARG_MIN_REG
;
4175 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
4176 /* Do a trial code generation as if this were going to be passed
4177 as an argument; if any part goes in memory, we return NULL. */
4178 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
4181 /* Otherwise fall through to more conventional ABI rules. */
4184 if (AGGREGATE_TYPE_P (type
)
4185 && (aix_struct_return
4186 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
4189 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4190 modes only exist for GCC vector types if -maltivec. */
4191 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
4192 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
4195 /* Return synthetic vectors in memory. */
4196 if (TREE_CODE (type
) == VECTOR_TYPE
4197 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
4199 static bool warned_for_return_big_vectors
= false;
4200 if (!warned_for_return_big_vectors
)
4202 warning (0, "GCC vector returned by reference: "
4203 "non-standard ABI extension with no compatibility guarantee");
4204 warned_for_return_big_vectors
= true;
4209 if (DEFAULT_ABI
== ABI_V4
&& TYPE_MODE (type
) == TFmode
)
4215 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4216 for a call to a function whose data type is FNTYPE.
4217 For a library call, FNTYPE is 0.
4219 For incoming args we set the number of arguments in the prototype large
4220 so we never return a PARALLEL. */
4223 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
4224 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
4225 int libcall
, int n_named_args
)
4227 static CUMULATIVE_ARGS zero_cumulative
;
4229 *cum
= zero_cumulative
;
4231 cum
->fregno
= FP_ARG_MIN_REG
;
4232 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
4233 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
4234 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
4235 ? CALL_LIBCALL
: CALL_NORMAL
);
4236 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
4237 cum
->stdarg
= fntype
4238 && (TYPE_ARG_TYPES (fntype
) != 0
4239 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
4240 != void_type_node
));
4242 cum
->nargs_prototype
= 0;
4243 if (incoming
|| cum
->prototype
)
4244 cum
->nargs_prototype
= n_named_args
;
4246 /* Check for a longcall attribute. */
4247 if ((!fntype
&& rs6000_default_long_calls
)
4249 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
4250 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
4251 cum
->call_cookie
|= CALL_LONG
;
4253 if (TARGET_DEBUG_ARG
)
4255 fprintf (stderr
, "\ninit_cumulative_args:");
4258 tree ret_type
= TREE_TYPE (fntype
);
4259 fprintf (stderr
, " ret code = %s,",
4260 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
4263 if (cum
->call_cookie
& CALL_LONG
)
4264 fprintf (stderr
, " longcall,");
4266 fprintf (stderr
, " proto = %d, nargs = %d\n",
4267 cum
->prototype
, cum
->nargs_prototype
);
4272 && TARGET_ALTIVEC_ABI
4273 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
4275 error ("cannot return value in vector register because"
4276 " altivec instructions are disabled, use -maltivec"
4281 /* Return true if TYPE must be passed on the stack and not in registers. */
4284 rs6000_must_pass_in_stack (enum machine_mode mode
, tree type
)
4286 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
4287 return must_pass_in_stack_var_size (mode
, type
);
4289 return must_pass_in_stack_var_size_or_pad (mode
, type
);
4292 /* If defined, a C expression which determines whether, and in which
4293 direction, to pad out an argument with extra space. The value
4294 should be of type `enum direction': either `upward' to pad above
4295 the argument, `downward' to pad below, or `none' to inhibit
4298 For the AIX ABI structs are always stored left shifted in their
4302 function_arg_padding (enum machine_mode mode
, tree type
)
4304 #ifndef AGGREGATE_PADDING_FIXED
4305 #define AGGREGATE_PADDING_FIXED 0
4307 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4308 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4311 if (!AGGREGATE_PADDING_FIXED
)
4313 /* GCC used to pass structures of the same size as integer types as
4314 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4315 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4316 passed padded downward, except that -mstrict-align further
4317 muddied the water in that multi-component structures of 2 and 4
4318 bytes in size were passed padded upward.
4320 The following arranges for best compatibility with previous
4321 versions of gcc, but removes the -mstrict-align dependency. */
4322 if (BYTES_BIG_ENDIAN
)
4324 HOST_WIDE_INT size
= 0;
4326 if (mode
== BLKmode
)
4328 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
4329 size
= int_size_in_bytes (type
);
4332 size
= GET_MODE_SIZE (mode
);
4334 if (size
== 1 || size
== 2 || size
== 4)
4340 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
4342 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
4346 /* Fall back to the default. */
4347 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
4350 /* If defined, a C expression that gives the alignment boundary, in bits,
4351 of an argument with the specified mode and type. If it is not defined,
4352 PARM_BOUNDARY is used for all arguments.
4354 V.4 wants long longs to be double word aligned.
4355 Doubleword align SPE vectors.
4356 Quadword align Altivec vectors.
4357 Quadword align large synthetic vector types. */
4360 function_arg_boundary (enum machine_mode mode
, tree type
)
4362 if (DEFAULT_ABI
== ABI_V4
&& GET_MODE_SIZE (mode
) == 8)
4364 else if (SPE_VECTOR_MODE (mode
)
4365 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4366 && int_size_in_bytes (type
) >= 8
4367 && int_size_in_bytes (type
) < 16))
4369 else if (ALTIVEC_VECTOR_MODE (mode
)
4370 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4371 && int_size_in_bytes (type
) >= 16))
4373 else if (rs6000_darwin64_abi
&& mode
== BLKmode
4374 && type
&& TYPE_ALIGN (type
) > 64)
4377 return PARM_BOUNDARY
;
4380 /* For a function parm of MODE and TYPE, return the starting word in
4381 the parameter area. NWORDS of the parameter area are already used. */
4384 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
4387 unsigned int parm_offset
;
4389 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
4390 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
4391 return nwords
+ (-(parm_offset
+ nwords
) & align
);
4394 /* Compute the size (in words) of a function argument. */
4396 static unsigned long
4397 rs6000_arg_size (enum machine_mode mode
, tree type
)
4401 if (mode
!= BLKmode
)
4402 size
= GET_MODE_SIZE (mode
);
4404 size
= int_size_in_bytes (type
);
4407 return (size
+ 3) >> 2;
4409 return (size
+ 7) >> 3;
4412 /* Use this to flush pending int fields. */
4415 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
4416 HOST_WIDE_INT bitpos
)
4418 unsigned int startbit
, endbit
;
4419 int intregs
, intoffset
;
4420 enum machine_mode mode
;
4422 if (cum
->intoffset
== -1)
4425 intoffset
= cum
->intoffset
;
4426 cum
->intoffset
= -1;
4428 if (intoffset
% BITS_PER_WORD
!= 0)
4430 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4432 if (mode
== BLKmode
)
4434 /* We couldn't find an appropriate mode, which happens,
4435 e.g., in packed structs when there are 3 bytes to load.
4436 Back intoffset back to the beginning of the word in this
4438 intoffset
= intoffset
& -BITS_PER_WORD
;
4442 startbit
= intoffset
& -BITS_PER_WORD
;
4443 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4444 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4445 cum
->words
+= intregs
;
4448 /* The darwin64 ABI calls for us to recurse down through structs,
4449 looking for elements passed in registers. Unfortunately, we have
4450 to track int register count here also because of misalignments
4451 in powerpc alignment mode. */
4454 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
4456 HOST_WIDE_INT startbitpos
)
4460 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4461 if (TREE_CODE (f
) == FIELD_DECL
)
4463 HOST_WIDE_INT bitpos
= startbitpos
;
4464 tree ftype
= TREE_TYPE (f
);
4465 enum machine_mode mode
= TYPE_MODE (ftype
);
4467 if (DECL_SIZE (f
) != 0
4468 && host_integerp (bit_position (f
), 1))
4469 bitpos
+= int_bit_position (f
);
4471 /* ??? FIXME: else assume zero offset. */
4473 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4474 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
4475 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4477 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4478 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4479 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4481 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
4483 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4487 else if (cum
->intoffset
== -1)
4488 cum
->intoffset
= bitpos
;
4492 /* Update the data in CUM to advance over an argument
4493 of mode MODE and data type TYPE.
4494 (TYPE is null for libcalls where that information may not be available.)
4496 Note that for args passed by reference, function_arg will be called
4497 with MODE and TYPE set to that of the pointer to the arg, not the arg
4501 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4502 tree type
, int named
, int depth
)
4506 /* Only tick off an argument if we're not recursing. */
4508 cum
->nargs_prototype
--;
4510 if (TARGET_ALTIVEC_ABI
4511 && (ALTIVEC_VECTOR_MODE (mode
)
4512 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4513 && int_size_in_bytes (type
) == 16)))
4517 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
4520 if (!TARGET_ALTIVEC
)
4521 error ("cannot pass argument in vector register because"
4522 " altivec instructions are disabled, use -maltivec"
4525 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4526 even if it is going to be passed in a vector register.
4527 Darwin does the same for variable-argument functions. */
4528 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4529 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
4539 /* Vector parameters must be 16-byte aligned. This places
4540 them at 2 mod 4 in terms of words in 32-bit mode, since
4541 the parameter save area starts at offset 24 from the
4542 stack. In 64-bit mode, they just have to start on an
4543 even word, since the parameter save area is 16-byte
4544 aligned. Space for GPRs is reserved even if the argument
4545 will be passed in memory. */
4547 align
= (2 - cum
->words
) & 3;
4549 align
= cum
->words
& 1;
4550 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
4552 if (TARGET_DEBUG_ARG
)
4554 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
4556 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
4557 cum
->nargs_prototype
, cum
->prototype
,
4558 GET_MODE_NAME (mode
));
4562 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
4564 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
4567 else if (rs6000_darwin64_abi
4569 && TREE_CODE (type
) == RECORD_TYPE
4570 && (size
= int_size_in_bytes (type
)) > 0)
4572 /* Variable sized types have size == -1 and are
4573 treated as if consisting entirely of ints.
4574 Pad to 16 byte boundary if needed. */
4575 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
4576 && (cum
->words
% 2) != 0)
4578 /* For varargs, we can just go up by the size of the struct. */
4580 cum
->words
+= (size
+ 7) / 8;
4583 /* It is tempting to say int register count just goes up by
4584 sizeof(type)/8, but this is wrong in a case such as
4585 { int; double; int; } [powerpc alignment]. We have to
4586 grovel through the fields for these too. */
4588 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
4589 rs6000_darwin64_record_arg_advance_flush (cum
,
4590 size
* BITS_PER_UNIT
);
4593 else if (DEFAULT_ABI
== ABI_V4
)
4595 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
4596 && (mode
== SFmode
|| mode
== DFmode
))
4598 if (cum
->fregno
<= FP_ARG_V4_MAX_REG
)
4603 cum
->words
+= cum
->words
& 1;
4604 cum
->words
+= rs6000_arg_size (mode
, type
);
4609 int n_words
= rs6000_arg_size (mode
, type
);
4610 int gregno
= cum
->sysv_gregno
;
4612 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4613 (r7,r8) or (r9,r10). As does any other 2 word item such
4614 as complex int due to a historical mistake. */
4616 gregno
+= (1 - gregno
) & 1;
4618 /* Multi-reg args are not split between registers and stack. */
4619 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
4621 /* Long long and SPE vectors are aligned on the stack.
4622 So are other 2 word items such as complex int due to
4623 a historical mistake. */
4625 cum
->words
+= cum
->words
& 1;
4626 cum
->words
+= n_words
;
4629 /* Note: continuing to accumulate gregno past when we've started
4630 spilling to the stack indicates the fact that we've started
4631 spilling to the stack to expand_builtin_saveregs. */
4632 cum
->sysv_gregno
= gregno
+ n_words
;
4635 if (TARGET_DEBUG_ARG
)
4637 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
4638 cum
->words
, cum
->fregno
);
4639 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
4640 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
4641 fprintf (stderr
, "mode = %4s, named = %d\n",
4642 GET_MODE_NAME (mode
), named
);
4647 int n_words
= rs6000_arg_size (mode
, type
);
4648 int start_words
= cum
->words
;
4649 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
4651 cum
->words
= align_words
+ n_words
;
4653 if (SCALAR_FLOAT_MODE_P (mode
)
4654 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4655 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4657 if (TARGET_DEBUG_ARG
)
4659 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
4660 cum
->words
, cum
->fregno
);
4661 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
4662 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
4663 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
4664 named
, align_words
- start_words
, depth
);
4670 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
4677 r1
= gen_rtx_REG (DImode
, gregno
);
4678 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
4679 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
4682 r1
= gen_rtx_REG (DImode
, gregno
);
4683 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
4684 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
4685 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
4686 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
4693 /* Determine where to put a SIMD argument on the SPE. */
4695 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4698 int gregno
= cum
->sysv_gregno
;
4700 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
4701 are passed and returned in a pair of GPRs for ABI compatibility. */
4702 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DCmode
))
4704 int n_words
= rs6000_arg_size (mode
, type
);
4706 /* Doubles go in an odd/even register pair (r5/r6, etc). */
4708 gregno
+= (1 - gregno
) & 1;
4710 /* Multi-reg args are not split between registers and stack. */
4711 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
4714 return spe_build_register_parallel (mode
, gregno
);
4718 int n_words
= rs6000_arg_size (mode
, type
);
4720 /* SPE vectors are put in odd registers. */
4721 if (n_words
== 2 && (gregno
& 1) == 0)
4724 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
4727 enum machine_mode m
= SImode
;
4729 r1
= gen_rtx_REG (m
, gregno
);
4730 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
4731 r2
= gen_rtx_REG (m
, gregno
+ 1);
4732 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
4733 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
4740 if (gregno
<= GP_ARG_MAX_REG
)
4741 return gen_rtx_REG (mode
, gregno
);
4747 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
4748 structure between cum->intoffset and bitpos to integer registers. */
4751 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
4752 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
4754 enum machine_mode mode
;
4756 unsigned int startbit
, endbit
;
4757 int this_regno
, intregs
, intoffset
;
4760 if (cum
->intoffset
== -1)
4763 intoffset
= cum
->intoffset
;
4764 cum
->intoffset
= -1;
4766 /* If this is the trailing part of a word, try to only load that
4767 much into the register. Otherwise load the whole register. Note
4768 that in the latter case we may pick up unwanted bits. It's not a
4769 problem at the moment but may wish to revisit. */
4771 if (intoffset
% BITS_PER_WORD
!= 0)
4773 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4775 if (mode
== BLKmode
)
4777 /* We couldn't find an appropriate mode, which happens,
4778 e.g., in packed structs when there are 3 bytes to load.
4779 Back intoffset back to the beginning of the word in this
4781 intoffset
= intoffset
& -BITS_PER_WORD
;
4788 startbit
= intoffset
& -BITS_PER_WORD
;
4789 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4790 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4791 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
4793 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
4796 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
4800 intoffset
/= BITS_PER_UNIT
;
4803 regno
= GP_ARG_MIN_REG
+ this_regno
;
4804 reg
= gen_rtx_REG (mode
, regno
);
4806 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
4809 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
4813 while (intregs
> 0);
4816 /* Recursive workhorse for the following. */
4819 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, tree type
,
4820 HOST_WIDE_INT startbitpos
, rtx rvec
[],
4825 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4826 if (TREE_CODE (f
) == FIELD_DECL
)
4828 HOST_WIDE_INT bitpos
= startbitpos
;
4829 tree ftype
= TREE_TYPE (f
);
4830 enum machine_mode mode
= TYPE_MODE (ftype
);
4832 if (DECL_SIZE (f
) != 0
4833 && host_integerp (bit_position (f
), 1))
4834 bitpos
+= int_bit_position (f
);
4836 /* ??? FIXME: else assume zero offset. */
4838 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4839 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
4840 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4845 case SCmode
: mode
= SFmode
; break;
4846 case DCmode
: mode
= DFmode
; break;
4847 case TCmode
: mode
= TFmode
; break;
4851 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
4853 = gen_rtx_EXPR_LIST (VOIDmode
,
4854 gen_rtx_REG (mode
, cum
->fregno
++),
4855 GEN_INT (bitpos
/ BITS_PER_UNIT
));
4859 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
4861 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
4863 = gen_rtx_EXPR_LIST (VOIDmode
,
4864 gen_rtx_REG (mode
, cum
->vregno
++),
4865 GEN_INT (bitpos
/ BITS_PER_UNIT
));
4867 else if (cum
->intoffset
== -1)
4868 cum
->intoffset
= bitpos
;
4872 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
4873 the register(s) to be used for each field and subfield of a struct
4874 being passed by value, along with the offset of where the
4875 register's value may be found in the block. FP fields go in FP
4876 register, vector fields go in vector registers, and everything
4877 else goes in int registers, packed as in memory.
4879 This code is also used for function return values. RETVAL indicates
4880 whether this is the case.
4882 Much of this is taken from the SPARC V9 port, which has a similar
4883 calling convention. */
4886 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, tree type
,
4887 int named
, bool retval
)
4889 rtx rvec
[FIRST_PSEUDO_REGISTER
];
4890 int k
= 1, kbase
= 1;
4891 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
4892 /* This is a copy; modifications are not visible to our caller. */
4893 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
4894 CUMULATIVE_ARGS
*cum
= ©_cum
;
4896 /* Pad to 16 byte boundary if needed. */
4897 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
4898 && (cum
->words
% 2) != 0)
4905 /* Put entries into rvec[] for individual FP and vector fields, and
4906 for the chunks of memory that go in int regs. Note we start at
4907 element 1; 0 is reserved for an indication of using memory, and
4908 may or may not be filled in below. */
4909 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
4910 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
4912 /* If any part of the struct went on the stack put all of it there.
4913 This hack is because the generic code for
4914 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
4915 parts of the struct are not at the beginning. */
4919 return NULL_RTX
; /* doesn't go in registers at all */
4921 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
4923 if (k
> 1 || cum
->use_stack
)
4924 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
4929 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
4932 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
4936 rtx rvec
[GP_ARG_NUM_REG
+ 1];
4938 if (align_words
>= GP_ARG_NUM_REG
)
4941 n_units
= rs6000_arg_size (mode
, type
);
4943 /* Optimize the simple case where the arg fits in one gpr, except in
4944 the case of BLKmode due to assign_parms assuming that registers are
4945 BITS_PER_WORD wide. */
4947 || (n_units
== 1 && mode
!= BLKmode
))
4948 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
4951 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
4952 /* Not all of the arg fits in gprs. Say that it goes in memory too,
4953 using a magic NULL_RTX component.
4954 FIXME: This is not strictly correct. Only some of the arg
4955 belongs in memory, not all of it. However, there isn't any way
4956 to do this currently, apart from building rtx descriptions for
4957 the pieces of memory we want stored. Due to bugs in the generic
4958 code we can't use the normal function_arg_partial_nregs scheme
4959 with the PARALLEL arg description we emit here.
4960 In any case, the code to store the whole arg to memory is often
4961 more efficient than code to store pieces, and we know that space
4962 is available in the right place for the whole arg. */
4963 /* FIXME: This should be fixed since the conversion to
4964 TARGET_ARG_PARTIAL_BYTES. */
4965 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
4970 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
4971 rtx off
= GEN_INT (i
++ * 4);
4972 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
4974 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
4976 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
4979 /* Determine where to put an argument to a function.
4980 Value is zero to push the argument on the stack,
4981 or a hard register in which to store the argument.
4983 MODE is the argument's machine mode.
4984 TYPE is the data type of the argument (as a tree).
4985 This is null for libcalls where that information may
4987 CUM is a variable of type CUMULATIVE_ARGS which gives info about
4988 the preceding args and about the function being called. It is
4989 not modified in this routine.
4990 NAMED is nonzero if this argument is a named parameter
4991 (otherwise it is an extra parameter matching an ellipsis).
4993 On RS/6000 the first eight words of non-FP are normally in registers
4994 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
4995 Under V.4, the first 8 FP args are in registers.
4997 If this is floating-point and no prototype is specified, we use
4998 both an FP and integer register (or possibly FP reg and stack). Library
4999 functions (when CALL_LIBCALL is set) always have the proper types for args,
5000 so we can pass the FP value just in one register. emit_library_function
5001 doesn't support PARALLEL anyway.
5003 Note that for args passed by reference, function_arg will be called
5004 with MODE and TYPE set to that of the pointer to the arg, not the arg
5008 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5009 tree type
, int named
)
5011 enum rs6000_abi abi
= DEFAULT_ABI
;
5013 /* Return a marker to indicate whether CR1 needs to set or clear the
5014 bit that V.4 uses to say fp args were passed in registers.
5015 Assume that we don't need the marker for software floating point,
5016 or compiler generated library calls. */
5017 if (mode
== VOIDmode
)
5020 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
5022 || (cum
->nargs_prototype
< 0
5023 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
5025 /* For the SPE, we need to crxor CR6 always. */
5027 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
5028 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5029 return GEN_INT (cum
->call_cookie
5030 | ((cum
->fregno
== FP_ARG_MIN_REG
)
5031 ? CALL_V4_SET_FP_ARGS
5032 : CALL_V4_CLEAR_FP_ARGS
));
5035 return GEN_INT (cum
->call_cookie
);
5038 if (rs6000_darwin64_abi
&& mode
== BLKmode
5039 && TREE_CODE (type
) == RECORD_TYPE
)
5041 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
5042 if (rslt
!= NULL_RTX
)
5044 /* Else fall through to usual handling. */
5047 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5048 if (TARGET_64BIT
&& ! cum
->prototype
)
5050 /* Vector parameters get passed in vector register
5051 and also in GPRs or memory, in absence of prototype. */
5054 align_words
= (cum
->words
+ 1) & ~1;
5056 if (align_words
>= GP_ARG_NUM_REG
)
5062 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5064 return gen_rtx_PARALLEL (mode
,
5066 gen_rtx_EXPR_LIST (VOIDmode
,
5068 gen_rtx_EXPR_LIST (VOIDmode
,
5069 gen_rtx_REG (mode
, cum
->vregno
),
5073 return gen_rtx_REG (mode
, cum
->vregno
);
5074 else if (TARGET_ALTIVEC_ABI
5075 && (ALTIVEC_VECTOR_MODE (mode
)
5076 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5077 && int_size_in_bytes (type
) == 16)))
5079 if (named
|| abi
== ABI_V4
)
5083 /* Vector parameters to varargs functions under AIX or Darwin
5084 get passed in memory and possibly also in GPRs. */
5085 int align
, align_words
, n_words
;
5086 enum machine_mode part_mode
;
5088 /* Vector parameters must be 16-byte aligned. This places them at
5089 2 mod 4 in terms of words in 32-bit mode, since the parameter
5090 save area starts at offset 24 from the stack. In 64-bit mode,
5091 they just have to start on an even word, since the parameter
5092 save area is 16-byte aligned. */
5094 align
= (2 - cum
->words
) & 3;
5096 align
= cum
->words
& 1;
5097 align_words
= cum
->words
+ align
;
5099 /* Out of registers? Memory, then. */
5100 if (align_words
>= GP_ARG_NUM_REG
)
5103 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5104 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5106 /* The vector value goes in GPRs. Only the part of the
5107 value in GPRs is reported here. */
5109 n_words
= rs6000_arg_size (mode
, type
);
5110 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
5111 /* Fortunately, there are only two possibilities, the value
5112 is either wholly in GPRs or half in GPRs and half not. */
5115 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
5118 else if (TARGET_SPE_ABI
&& TARGET_SPE
5119 && (SPE_VECTOR_MODE (mode
)
5120 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
5121 || mode
== DCmode
))))
5122 return rs6000_spe_function_arg (cum
, mode
, type
);
5124 else if (abi
== ABI_V4
)
5126 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5127 && (mode
== SFmode
|| mode
== DFmode
))
5129 if (cum
->fregno
<= FP_ARG_V4_MAX_REG
)
5130 return gen_rtx_REG (mode
, cum
->fregno
);
5136 int n_words
= rs6000_arg_size (mode
, type
);
5137 int gregno
= cum
->sysv_gregno
;
5139 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5140 (r7,r8) or (r9,r10). As does any other 2 word item such
5141 as complex int due to a historical mistake. */
5143 gregno
+= (1 - gregno
) & 1;
5145 /* Multi-reg args are not split between registers and stack. */
5146 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5149 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5150 return rs6000_mixed_function_arg (mode
, type
,
5151 gregno
- GP_ARG_MIN_REG
);
5152 return gen_rtx_REG (mode
, gregno
);
5157 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5159 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
5161 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5165 enum machine_mode fmode
= mode
;
5166 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
5168 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
5170 /* Currently, we only ever need one reg here because complex
5171 doubles are split. */
5172 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
&& fmode
== TFmode
);
5174 /* Long double split over regs and memory. */
5178 /* Do we also need to pass this arg in the parameter save
5181 && (cum
->nargs_prototype
<= 0
5182 || (DEFAULT_ABI
== ABI_AIX
5184 && align_words
>= GP_ARG_NUM_REG
)));
5186 if (!needs_psave
&& mode
== fmode
)
5187 return gen_rtx_REG (fmode
, cum
->fregno
);
5192 /* Describe the part that goes in gprs or the stack.
5193 This piece must come first, before the fprs. */
5194 if (align_words
< GP_ARG_NUM_REG
)
5196 unsigned long n_words
= rs6000_arg_size (mode
, type
);
5198 if (align_words
+ n_words
> GP_ARG_NUM_REG
5199 || (TARGET_32BIT
&& TARGET_POWERPC64
))
5201 /* If this is partially on the stack, then we only
5202 include the portion actually in registers here. */
5203 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
5206 if (align_words
+ n_words
> GP_ARG_NUM_REG
5207 && (TARGET_32BIT
&& TARGET_POWERPC64
))
5208 /* Not all of the arg fits in gprs. Say that it
5209 goes in memory too, using a magic NULL_RTX
5210 component. Also see comment in
5211 rs6000_mixed_function_arg for why the normal
5212 function_arg_partial_nregs scheme doesn't work
5214 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
5218 r
= gen_rtx_REG (rmode
,
5219 GP_ARG_MIN_REG
+ align_words
);
5220 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
5221 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5223 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
5227 /* The whole arg fits in gprs. */
5228 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5229 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5233 /* It's entirely in memory. */
5234 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5237 /* Describe where this piece goes in the fprs. */
5238 r
= gen_rtx_REG (fmode
, cum
->fregno
);
5239 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5241 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5243 else if (align_words
< GP_ARG_NUM_REG
)
5245 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5246 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5248 if (mode
== BLKmode
)
5251 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5258 /* For an arg passed partly in registers and partly in memory, this is
5259 the number of bytes passed in registers. For args passed entirely in
5260 registers or entirely in memory, zero. When an arg is described by a
5261 PARALLEL, perhaps using more than one register type, this function
5262 returns the number of bytes used by the first element of the PARALLEL. */
5265 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5266 tree type
, bool named
)
5271 if (DEFAULT_ABI
== ABI_V4
)
5274 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
5275 && cum
->nargs_prototype
>= 0)
5278 /* In this complicated case we just disable the partial_nregs code. */
5279 if (rs6000_darwin64_abi
&& mode
== BLKmode
5280 && TREE_CODE (type
) == RECORD_TYPE
5281 && int_size_in_bytes (type
) > 0)
5284 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5286 if (USE_FP_FOR_ARG_P (cum
, mode
, type
)
5287 /* If we are passing this arg in the fixed parameter save area
5288 (gprs or memory) as well as fprs, then this function should
5289 return the number of bytes passed in the parameter save area
5290 rather than bytes passed in fprs. */
5292 && (cum
->nargs_prototype
<= 0
5293 || (DEFAULT_ABI
== ABI_AIX
5295 && align_words
>= GP_ARG_NUM_REG
))))
5297 if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3) > FP_ARG_MAX_REG
+ 1)
5298 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
5299 else if (cum
->nargs_prototype
>= 0)
5303 if (align_words
< GP_ARG_NUM_REG
5304 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
5305 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
5307 if (ret
!= 0 && TARGET_DEBUG_ARG
)
5308 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
5313 /* A C expression that indicates when an argument must be passed by
5314 reference. If nonzero for an argument, a copy of that argument is
5315 made in memory and a pointer to the argument is passed instead of
5316 the argument itself. The pointer is passed in whatever way is
5317 appropriate for passing a pointer to that type.
5319 Under V.4, aggregates and long double are passed by reference.
5321 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5322 reference unless the AltiVec vector extension ABI is in force.
5324 As an extension to all ABIs, variable sized types are passed by
5328 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
5329 enum machine_mode mode
, tree type
,
5330 bool named ATTRIBUTE_UNUSED
)
5332 if (DEFAULT_ABI
== ABI_V4
&& mode
== TFmode
)
5334 if (TARGET_DEBUG_ARG
)
5335 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
5342 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
5344 if (TARGET_DEBUG_ARG
)
5345 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
5349 if (int_size_in_bytes (type
) < 0)
5351 if (TARGET_DEBUG_ARG
)
5352 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
5356 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5357 modes only exist for GCC vector types if -maltivec. */
5358 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
5360 if (TARGET_DEBUG_ARG
)
5361 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
5365 /* Pass synthetic vectors in memory. */
5366 if (TREE_CODE (type
) == VECTOR_TYPE
5367 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5369 static bool warned_for_pass_big_vectors
= false;
5370 if (TARGET_DEBUG_ARG
)
5371 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
5372 if (!warned_for_pass_big_vectors
)
5374 warning (0, "GCC vector passed by reference: "
5375 "non-standard ABI extension with no compatibility guarantee");
5376 warned_for_pass_big_vectors
= true;
5385 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
5388 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
5393 for (i
= 0; i
< nregs
; i
++)
5395 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
5396 if (reload_completed
)
5398 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
5401 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
5402 i
* GET_MODE_SIZE (reg_mode
));
5405 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
5409 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
5413 /* Perform any needed actions needed for a function that is receiving a
5414 variable number of arguments.
5418 MODE and TYPE are the mode and type of the current parameter.
5420 PRETEND_SIZE is a variable that should be set to the amount of stack
5421 that must be pushed by the prolog to pretend that our caller pushed
5424 Normally, this macro will push all remaining incoming registers on the
5425 stack and set PRETEND_SIZE to the length of the registers pushed. */
5428 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5429 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
5432 CUMULATIVE_ARGS next_cum
;
5433 int reg_size
= TARGET_32BIT
? 4 : 8;
5434 rtx save_area
= NULL_RTX
, mem
;
5435 int first_reg_offset
, set
;
5437 /* Skip the last named argument. */
5439 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
5441 if (DEFAULT_ABI
== ABI_V4
)
5443 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
5447 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
5448 HOST_WIDE_INT offset
= 0;
5450 /* Try to optimize the size of the varargs save area.
5451 The ABI requires that ap.reg_save_area is doubleword
5452 aligned, but we don't need to allocate space for all
5453 the bytes, only those to which we actually will save
5455 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
5456 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
5457 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5458 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5459 && cfun
->va_list_fpr_size
)
5462 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
5463 * UNITS_PER_FP_WORD
;
5464 if (cfun
->va_list_fpr_size
5465 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5466 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
5468 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5469 * UNITS_PER_FP_WORD
;
5473 offset
= -((first_reg_offset
* reg_size
) & ~7);
5474 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
5476 gpr_reg_num
= cfun
->va_list_gpr_size
;
5477 if (reg_size
== 4 && (first_reg_offset
& 1))
5480 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
5483 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
5485 - (int) (GP_ARG_NUM_REG
* reg_size
);
5487 if (gpr_size
+ fpr_size
)
5490 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
5491 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
5492 reg_save_area
= XEXP (reg_save_area
, 0);
5493 if (GET_CODE (reg_save_area
) == PLUS
)
5495 gcc_assert (XEXP (reg_save_area
, 0)
5496 == virtual_stack_vars_rtx
);
5497 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
5498 offset
+= INTVAL (XEXP (reg_save_area
, 1));
5501 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
5504 cfun
->machine
->varargs_save_offset
= offset
;
5505 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
5510 first_reg_offset
= next_cum
.words
;
5511 save_area
= virtual_incoming_args_rtx
;
5513 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
5514 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
5517 set
= get_varargs_alias_set ();
5518 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
5519 && cfun
->va_list_gpr_size
)
5521 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
5523 if (va_list_gpr_counter_field
)
5525 /* V4 va_list_gpr_size counts number of registers needed. */
5526 if (nregs
> cfun
->va_list_gpr_size
)
5527 nregs
= cfun
->va_list_gpr_size
;
5531 /* char * va_list instead counts number of bytes needed. */
5532 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
5533 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
5536 mem
= gen_rtx_MEM (BLKmode
,
5537 plus_constant (save_area
,
5538 first_reg_offset
* reg_size
));
5539 MEM_NOTRAP_P (mem
) = 1;
5540 set_mem_alias_set (mem
, set
);
5541 set_mem_align (mem
, BITS_PER_WORD
);
5543 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
5547 /* Save FP registers if needed. */
5548 if (DEFAULT_ABI
== ABI_V4
5549 && TARGET_HARD_FLOAT
&& TARGET_FPRS
5551 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5552 && cfun
->va_list_fpr_size
)
5554 int fregno
= next_cum
.fregno
, nregs
;
5555 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
5556 rtx lab
= gen_label_rtx ();
5557 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
5558 * UNITS_PER_FP_WORD
);
5561 (gen_rtx_SET (VOIDmode
,
5563 gen_rtx_IF_THEN_ELSE (VOIDmode
,
5564 gen_rtx_NE (VOIDmode
, cr1
,
5566 gen_rtx_LABEL_REF (VOIDmode
, lab
),
5570 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
5571 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
5573 mem
= gen_rtx_MEM (DFmode
, plus_constant (save_area
, off
));
5574 MEM_NOTRAP_P (mem
) = 1;
5575 set_mem_alias_set (mem
, set
);
5576 set_mem_align (mem
, GET_MODE_ALIGNMENT (DFmode
));
5577 emit_move_insn (mem
, gen_rtx_REG (DFmode
, fregno
));
5584 /* Create the va_list data type. */
5587 rs6000_build_builtin_va_list (void)
5589 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
5591 /* For AIX, prefer 'char *' because that's what the system
5592 header files like. */
5593 if (DEFAULT_ABI
!= ABI_V4
)
5594 return build_pointer_type (char_type_node
);
5596 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
5597 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
5599 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
5600 unsigned_char_type_node
);
5601 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
5602 unsigned_char_type_node
);
5603 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5605 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
5606 short_unsigned_type_node
);
5607 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
5609 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
5612 va_list_gpr_counter_field
= f_gpr
;
5613 va_list_fpr_counter_field
= f_fpr
;
5615 DECL_FIELD_CONTEXT (f_gpr
) = record
;
5616 DECL_FIELD_CONTEXT (f_fpr
) = record
;
5617 DECL_FIELD_CONTEXT (f_res
) = record
;
5618 DECL_FIELD_CONTEXT (f_ovf
) = record
;
5619 DECL_FIELD_CONTEXT (f_sav
) = record
;
5621 TREE_CHAIN (record
) = type_decl
;
5622 TYPE_NAME (record
) = type_decl
;
5623 TYPE_FIELDS (record
) = f_gpr
;
5624 TREE_CHAIN (f_gpr
) = f_fpr
;
5625 TREE_CHAIN (f_fpr
) = f_res
;
5626 TREE_CHAIN (f_res
) = f_ovf
;
5627 TREE_CHAIN (f_ovf
) = f_sav
;
5629 layout_type (record
);
5631 /* The correct type is an array type of one element. */
5632 return build_array_type (record
, build_index_type (size_zero_node
));
5635 /* Implement va_start. */
5638 rs6000_va_start (tree valist
, rtx nextarg
)
5640 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
5641 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
5642 tree gpr
, fpr
, ovf
, sav
, t
;
5644 /* Only SVR4 needs something special. */
5645 if (DEFAULT_ABI
!= ABI_V4
)
5647 std_expand_builtin_va_start (valist
, nextarg
);
5651 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
5652 f_fpr
= TREE_CHAIN (f_gpr
);
5653 f_res
= TREE_CHAIN (f_fpr
);
5654 f_ovf
= TREE_CHAIN (f_res
);
5655 f_sav
= TREE_CHAIN (f_ovf
);
5657 valist
= build_va_arg_indirect_ref (valist
);
5658 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
5659 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
5660 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
5661 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
5663 /* Count number of gp and fp argument registers used. */
5664 words
= current_function_args_info
.words
;
5665 n_gpr
= MIN (current_function_args_info
.sysv_gregno
- GP_ARG_MIN_REG
,
5667 n_fpr
= MIN (current_function_args_info
.fregno
- FP_ARG_MIN_REG
,
5670 if (TARGET_DEBUG_ARG
)
5671 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
5672 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
5673 words
, n_gpr
, n_fpr
);
5675 if (cfun
->va_list_gpr_size
)
5677 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
5678 build_int_cst (NULL_TREE
, n_gpr
));
5679 TREE_SIDE_EFFECTS (t
) = 1;
5680 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5683 if (cfun
->va_list_fpr_size
)
5685 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
5686 build_int_cst (NULL_TREE
, n_fpr
));
5687 TREE_SIDE_EFFECTS (t
) = 1;
5688 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5691 /* Find the overflow area. */
5692 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
5694 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
,
5695 build_int_cst (NULL_TREE
, words
* UNITS_PER_WORD
));
5696 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
5697 TREE_SIDE_EFFECTS (t
) = 1;
5698 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5700 /* If there were no va_arg invocations, don't set up the register
5702 if (!cfun
->va_list_gpr_size
5703 && !cfun
->va_list_fpr_size
5704 && n_gpr
< GP_ARG_NUM_REG
5705 && n_fpr
< FP_ARG_V4_MAX_REG
)
5708 /* Find the register save area. */
5709 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
5710 if (cfun
->machine
->varargs_save_offset
)
5711 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
5712 build_int_cst (NULL_TREE
, cfun
->machine
->varargs_save_offset
));
5713 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
5714 TREE_SIDE_EFFECTS (t
) = 1;
5715 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5718 /* Implement va_arg. */
5721 rs6000_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
5723 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
5724 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
5725 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
5726 tree lab_false
, lab_over
, addr
;
5728 tree ptrtype
= build_pointer_type (type
);
5730 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
5732 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
5733 return build_va_arg_indirect_ref (t
);
5736 if (DEFAULT_ABI
!= ABI_V4
)
5738 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
5740 tree elem_type
= TREE_TYPE (type
);
5741 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
5742 int elem_size
= GET_MODE_SIZE (elem_mode
);
5744 if (elem_size
< UNITS_PER_WORD
)
5746 tree real_part
, imag_part
;
5747 tree post
= NULL_TREE
;
5749 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
5751 /* Copy the value into a temporary, lest the formal temporary
5752 be reused out from under us. */
5753 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
5754 append_to_statement_list (post
, pre_p
);
5756 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
5759 return build (COMPLEX_EXPR
, type
, real_part
, imag_part
);
5763 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
5766 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
5767 f_fpr
= TREE_CHAIN (f_gpr
);
5768 f_res
= TREE_CHAIN (f_fpr
);
5769 f_ovf
= TREE_CHAIN (f_res
);
5770 f_sav
= TREE_CHAIN (f_ovf
);
5772 valist
= build_va_arg_indirect_ref (valist
);
5773 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
5774 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
5775 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
5776 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
5778 size
= int_size_in_bytes (type
);
5779 rsize
= (size
+ 3) / 4;
5782 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5783 && (TYPE_MODE (type
) == SFmode
|| TYPE_MODE (type
) == DFmode
))
5785 /* FP args go in FP registers, if present. */
5790 if (TYPE_MODE (type
) == DFmode
)
5795 /* Otherwise into GP registers. */
5804 /* Pull the value out of the saved registers.... */
5807 addr
= create_tmp_var (ptr_type_node
, "addr");
5808 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
5810 /* AltiVec vectors never go in registers when -mabi=altivec. */
5811 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5815 lab_false
= create_artificial_label ();
5816 lab_over
= create_artificial_label ();
5818 /* Long long and SPE vectors are aligned in the registers.
5819 As are any other 2 gpr item such as complex int due to a
5820 historical mistake. */
5824 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), reg
,
5825 size_int (n_reg
- 1));
5826 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, u
);
5829 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
5830 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
5831 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
5832 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
5833 gimplify_and_add (t
, pre_p
);
5837 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
5839 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, size_int (n_reg
));
5840 u
= build1 (CONVERT_EXPR
, integer_type_node
, u
);
5841 u
= build2 (MULT_EXPR
, integer_type_node
, u
, size_int (sav_scale
));
5842 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, u
);
5844 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
5845 gimplify_and_add (t
, pre_p
);
5847 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
5848 gimplify_and_add (t
, pre_p
);
5850 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
5851 append_to_statement_list (t
, pre_p
);
5855 /* Ensure that we don't find any more args in regs.
5856 Alignment has taken care of the n_reg == 2 case. */
5857 t
= build (MODIFY_EXPR
, TREE_TYPE (reg
), reg
, size_int (8));
5858 gimplify_and_add (t
, pre_p
);
5862 /* ... otherwise out of the overflow area. */
5864 /* Care for on-stack alignment if needed. */
5868 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
5869 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
5870 build_int_cst (NULL_TREE
, -align
));
5872 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
5874 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
5875 gimplify_and_add (u
, pre_p
);
5877 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
5878 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
5879 gimplify_and_add (t
, pre_p
);
5883 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
5884 append_to_statement_list (t
, pre_p
);
5887 addr
= fold_convert (ptrtype
, addr
);
5888 return build_va_arg_indirect_ref (addr
);
5894 def_builtin (int mask
, const char *name
, tree type
, int code
)
5896 if (mask
& target_flags
)
5898 if (rs6000_builtin_decls
[code
])
5901 rs6000_builtin_decls
[code
] =
5902 lang_hooks
.builtin_function (name
, type
, code
, BUILT_IN_MD
,
5907 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
5909 static const struct builtin_description bdesc_3arg
[] =
5911 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
5912 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
5913 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
5914 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
5915 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
5916 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
5917 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
5918 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
5919 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
5920 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
5921 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
5922 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
5923 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
5924 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
5925 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
5926 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
5927 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
5928 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
5929 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
5930 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
5931 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
5932 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
5933 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
5935 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
5936 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
5937 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
5938 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
5939 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
5940 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
5941 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
5942 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
5943 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
5944 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
5945 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
5946 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
5947 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
5948 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
5949 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
5952 /* DST operations: void foo (void *, const int, const char). */
5954 static const struct builtin_description bdesc_dst
[] =
5956 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
5957 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
5958 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
5959 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
5961 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
5962 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
5963 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
5964 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
5967 /* Simple binary operations: VECc = foo (VECa, VECb). */
5969 static struct builtin_description bdesc_2arg
[] =
5971 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
5972 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
5973 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
5974 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
5975 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
5976 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
5977 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
5978 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
5979 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
5980 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
5981 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
5982 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
5983 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
5984 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
5985 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
5986 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
5987 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
5988 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
5989 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
5990 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
5991 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
5992 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
5993 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
5994 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
5995 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
5996 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
5997 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
5998 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
5999 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
6000 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
6001 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
6002 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
6003 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
6004 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
6005 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
6006 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
6007 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
6008 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
6009 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
6010 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
6011 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
6012 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
6013 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
6014 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
6015 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
6016 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
6017 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
6018 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
6019 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
6020 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
6021 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
6022 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
6023 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
6024 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
6025 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
6026 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
6027 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
6028 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
6029 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
6030 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
6031 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
6032 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
6033 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
6034 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
6035 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
6036 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
6037 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
6038 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
6039 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
6040 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
6041 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
6042 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
6043 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
6044 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
6045 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
6046 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
6047 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
6048 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
6049 { MASK_ALTIVEC
, CODE_FOR_altivec_vslb
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
6050 { MASK_ALTIVEC
, CODE_FOR_altivec_vslh
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
6051 { MASK_ALTIVEC
, CODE_FOR_altivec_vslw
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
6052 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
6053 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
6054 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
6055 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
6056 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
6057 { MASK_ALTIVEC
, CODE_FOR_lshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
6058 { MASK_ALTIVEC
, CODE_FOR_lshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
6059 { MASK_ALTIVEC
, CODE_FOR_lshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
6060 { MASK_ALTIVEC
, CODE_FOR_ashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
6061 { MASK_ALTIVEC
, CODE_FOR_ashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
6062 { MASK_ALTIVEC
, CODE_FOR_ashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
6063 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
6064 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
6065 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
6066 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
6067 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
6068 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
6069 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
6070 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
6071 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
6072 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
6073 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
6074 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
6075 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
6076 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
6077 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
6078 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
6079 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
6080 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
6081 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
6083 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
6084 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
6085 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
6086 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
6087 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
6088 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
6089 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
6090 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
6091 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
6092 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
6093 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
6094 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
6095 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
6096 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
6097 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
6098 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
6099 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
6100 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
6101 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
6102 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
6103 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
6104 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
6105 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
6106 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
6107 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
6108 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
6109 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
6110 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
6111 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
6112 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
6113 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
6114 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
6115 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
6116 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
6117 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
6118 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
6119 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
6120 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
6121 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
6122 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
6123 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
6124 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
6125 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
6126 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
6127 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
6128 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
6129 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
6130 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
6131 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
6132 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
6133 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
6134 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
6135 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
6136 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
6137 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
6138 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
6139 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
6140 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
6141 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
6142 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
6143 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
6144 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
6145 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
6146 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
6147 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
6148 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
6149 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
6150 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
6151 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
6152 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
6153 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
6154 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
6155 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
6156 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
6157 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
6158 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
6159 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
6160 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
6161 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
6162 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
6163 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
6164 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
6165 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
6166 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
6167 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
6168 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
6169 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
6170 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
6171 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
6172 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
6173 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
6174 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
6175 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
6176 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
6177 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
6178 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
6179 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
6180 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
6181 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
6182 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
6183 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
6184 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
6185 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
6186 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
6187 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
6188 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
6189 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
6190 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
6191 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
6192 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
6193 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
6194 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
6195 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
6196 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
6197 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
6198 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
6199 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
6200 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
6201 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
6202 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
6203 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
6204 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
6205 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
6206 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
6207 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
6208 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
6209 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
6211 /* Place holder, leave as first spe builtin. */
6212 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
6213 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
6214 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
6215 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
6216 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
6217 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
6218 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
6219 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
6220 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
6221 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
6222 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
6223 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
6224 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
6225 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
6226 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
6227 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
6228 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
6229 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
6230 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
6231 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
6232 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
6233 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
6234 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
6235 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
6236 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
6237 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
6238 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
6239 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
6240 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
6241 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
6242 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
6243 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
6244 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
6245 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
6246 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
6247 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
6248 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
6249 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
6250 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
6251 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
6252 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
6253 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
6254 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
6255 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
6256 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
6257 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
6258 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
6259 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
6260 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
6261 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
6262 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
6263 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
6264 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
6265 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
6266 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
6267 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
6268 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
6269 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
6270 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
6271 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
6272 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
6273 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
6274 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
6275 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
6276 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
6277 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
6278 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
6279 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
6280 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
6281 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
6282 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
6283 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
6284 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
6285 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
6286 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
6287 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
6288 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
6289 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
6290 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
6291 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
6292 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
6293 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
6294 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
6295 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
6296 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
6297 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
6298 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
6299 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
6300 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
6301 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
6302 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
6303 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
6304 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
6305 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
6306 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
6307 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
6308 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
6309 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
6310 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
6311 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
6312 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
6313 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
6314 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
6315 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
6316 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
6317 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
6318 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
6319 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
6320 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
6322 /* SPE binary operations expecting a 5-bit unsigned literal. */
6323 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
6325 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
6326 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
6327 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
6328 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
6329 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
6330 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
6331 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
6332 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
6333 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
6334 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
6335 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
6336 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
6337 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
6338 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
6339 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
6340 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
6341 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
6342 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
6343 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
6344 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
6345 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
6346 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
6347 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
6348 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
6349 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
6350 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
6352 /* Place-holder. Leave as last binary SPE builtin. */
6353 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
6356 /* AltiVec predicates. */
6358 struct builtin_description_predicates
6360 const unsigned int mask
;
6361 const enum insn_code icode
;
6363 const char *const name
;
6364 const enum rs6000_builtins code
;
6367 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
6369 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
6370 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
6371 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
6372 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
6373 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
6374 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
6375 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
6376 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
6377 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
6378 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
6379 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
6380 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
6381 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
6383 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
6384 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
6385 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
6388 /* SPE predicates. */
6389 static struct builtin_description bdesc_spe_predicates
[] =
6391 /* Place-holder. Leave as first. */
6392 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
6393 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
6394 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
6395 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
6396 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
6397 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
6398 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
6399 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
6400 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
6401 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
6402 /* Place-holder. Leave as last. */
6403 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
6406 /* SPE evsel predicates. */
6407 static struct builtin_description bdesc_spe_evsel
[] =
6409 /* Place-holder. Leave as first. */
6410 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
6411 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
6412 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
6413 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
6414 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
6415 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
6416 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
6417 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
6418 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
6419 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
6420 /* Place-holder. Leave as last. */
6421 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
6424 /* ABS* operations. */
6426 static const struct builtin_description bdesc_abs
[] =
6428 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
6429 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
6430 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
6431 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
6432 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
6433 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
6434 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
6437 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6440 static struct builtin_description bdesc_1arg
[] =
6442 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
6443 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
6444 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
6445 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
6446 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
6447 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
6448 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
6449 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
6450 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
6451 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
6452 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
6453 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
6454 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
6455 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
6456 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
6457 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
6458 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
6460 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
6461 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
6462 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
6463 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
6464 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
6465 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
6466 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
6467 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
6468 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
6469 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
6470 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
6471 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
6472 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
6473 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
6474 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
6475 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
6476 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
6477 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
6478 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
6480 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6481 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6482 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
6483 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
6484 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
6485 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
6486 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
6487 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
6488 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
6489 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
6490 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
6491 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
6492 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
6493 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
6494 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
6495 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
6496 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
6497 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
6498 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
6499 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
6500 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
6501 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
6502 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
6503 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
6504 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
6505 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
6506 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
6507 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
6508 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
6509 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
6511 /* Place-holder. Leave as last unary SPE builtin. */
6512 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
}
6516 rs6000_expand_unop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6519 tree arg0
= TREE_VALUE (arglist
);
6520 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6521 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6522 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6524 if (icode
== CODE_FOR_nothing
)
6525 /* Builtin not supported on this processor. */
6528 /* If we got invalid arguments bail out before generating bad rtl. */
6529 if (arg0
== error_mark_node
)
6532 if (icode
== CODE_FOR_altivec_vspltisb
6533 || icode
== CODE_FOR_altivec_vspltish
6534 || icode
== CODE_FOR_altivec_vspltisw
6535 || icode
== CODE_FOR_spe_evsplatfi
6536 || icode
== CODE_FOR_spe_evsplati
)
6538 /* Only allow 5-bit *signed* literals. */
6539 if (GET_CODE (op0
) != CONST_INT
6540 || INTVAL (op0
) > 15
6541 || INTVAL (op0
) < -16)
6543 error ("argument 1 must be a 5-bit signed literal");
6549 || GET_MODE (target
) != tmode
6550 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6551 target
= gen_reg_rtx (tmode
);
6553 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6554 op0
= copy_to_mode_reg (mode0
, op0
);
6556 pat
= GEN_FCN (icode
) (target
, op0
);
6565 altivec_expand_abs_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6567 rtx pat
, scratch1
, scratch2
;
6568 tree arg0
= TREE_VALUE (arglist
);
6569 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6570 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6571 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6573 /* If we have invalid arguments, bail out before generating bad rtl. */
6574 if (arg0
== error_mark_node
)
6578 || GET_MODE (target
) != tmode
6579 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6580 target
= gen_reg_rtx (tmode
);
6582 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6583 op0
= copy_to_mode_reg (mode0
, op0
);
6585 scratch1
= gen_reg_rtx (mode0
);
6586 scratch2
= gen_reg_rtx (mode0
);
6588 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
6597 rs6000_expand_binop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6600 tree arg0
= TREE_VALUE (arglist
);
6601 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6602 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6603 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6604 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6605 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6606 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6608 if (icode
== CODE_FOR_nothing
)
6609 /* Builtin not supported on this processor. */
6612 /* If we got invalid arguments bail out before generating bad rtl. */
6613 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6616 if (icode
== CODE_FOR_altivec_vcfux
6617 || icode
== CODE_FOR_altivec_vcfsx
6618 || icode
== CODE_FOR_altivec_vctsxs
6619 || icode
== CODE_FOR_altivec_vctuxs
6620 || icode
== CODE_FOR_altivec_vspltb
6621 || icode
== CODE_FOR_altivec_vsplth
6622 || icode
== CODE_FOR_altivec_vspltw
6623 || icode
== CODE_FOR_spe_evaddiw
6624 || icode
== CODE_FOR_spe_evldd
6625 || icode
== CODE_FOR_spe_evldh
6626 || icode
== CODE_FOR_spe_evldw
6627 || icode
== CODE_FOR_spe_evlhhesplat
6628 || icode
== CODE_FOR_spe_evlhhossplat
6629 || icode
== CODE_FOR_spe_evlhhousplat
6630 || icode
== CODE_FOR_spe_evlwhe
6631 || icode
== CODE_FOR_spe_evlwhos
6632 || icode
== CODE_FOR_spe_evlwhou
6633 || icode
== CODE_FOR_spe_evlwhsplat
6634 || icode
== CODE_FOR_spe_evlwwsplat
6635 || icode
== CODE_FOR_spe_evrlwi
6636 || icode
== CODE_FOR_spe_evslwi
6637 || icode
== CODE_FOR_spe_evsrwis
6638 || icode
== CODE_FOR_spe_evsubifw
6639 || icode
== CODE_FOR_spe_evsrwiu
)
6641 /* Only allow 5-bit unsigned literals. */
6643 if (TREE_CODE (arg1
) != INTEGER_CST
6644 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
6646 error ("argument 2 must be a 5-bit unsigned literal");
6652 || GET_MODE (target
) != tmode
6653 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6654 target
= gen_reg_rtx (tmode
);
6656 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6657 op0
= copy_to_mode_reg (mode0
, op0
);
6658 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6659 op1
= copy_to_mode_reg (mode1
, op1
);
6661 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6670 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
6671 tree arglist
, rtx target
)
6674 tree cr6_form
= TREE_VALUE (arglist
);
6675 tree arg0
= TREE_VALUE (TREE_CHAIN (arglist
));
6676 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6677 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6678 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6679 enum machine_mode tmode
= SImode
;
6680 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6681 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6684 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
6686 error ("argument 1 of __builtin_altivec_predicate must be a constant");
6690 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
6692 gcc_assert (mode0
== mode1
);
6694 /* If we have invalid arguments, bail out before generating bad rtl. */
6695 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6699 || GET_MODE (target
) != tmode
6700 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6701 target
= gen_reg_rtx (tmode
);
6703 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6704 op0
= copy_to_mode_reg (mode0
, op0
);
6705 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6706 op1
= copy_to_mode_reg (mode1
, op1
);
6708 scratch
= gen_reg_rtx (mode0
);
6710 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
6711 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
6716 /* The vec_any* and vec_all* predicates use the same opcodes for two
6717 different operations, but the bits in CR6 will be different
6718 depending on what information we want. So we have to play tricks
6719 with CR6 to get the right bits out.
6721 If you think this is disgusting, look at the specs for the
6722 AltiVec predicates. */
6724 switch (cr6_form_int
)
6727 emit_insn (gen_cr6_test_for_zero (target
));
6730 emit_insn (gen_cr6_test_for_zero_reverse (target
));
6733 emit_insn (gen_cr6_test_for_lt (target
));
6736 emit_insn (gen_cr6_test_for_lt_reverse (target
));
6739 error ("argument 1 of __builtin_altivec_predicate is out of range");
6747 altivec_expand_lv_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6750 tree arg0
= TREE_VALUE (arglist
);
6751 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6752 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6753 enum machine_mode mode0
= Pmode
;
6754 enum machine_mode mode1
= Pmode
;
6755 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6756 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6758 if (icode
== CODE_FOR_nothing
)
6759 /* Builtin not supported on this processor. */
6762 /* If we got invalid arguments bail out before generating bad rtl. */
6763 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6767 || GET_MODE (target
) != tmode
6768 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6769 target
= gen_reg_rtx (tmode
);
6771 op1
= copy_to_mode_reg (mode1
, op1
);
6773 if (op0
== const0_rtx
)
6775 addr
= gen_rtx_MEM (tmode
, op1
);
6779 op0
= copy_to_mode_reg (mode0
, op0
);
6780 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
6783 pat
= GEN_FCN (icode
) (target
, addr
);
6793 spe_expand_stv_builtin (enum insn_code icode
, tree arglist
)
6795 tree arg0
= TREE_VALUE (arglist
);
6796 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6797 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6798 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6799 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6800 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6802 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
6803 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
6804 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
6806 /* Invalid arguments. Bail before doing anything stoopid! */
6807 if (arg0
== error_mark_node
6808 || arg1
== error_mark_node
6809 || arg2
== error_mark_node
)
6812 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
6813 op0
= copy_to_mode_reg (mode2
, op0
);
6814 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
6815 op1
= copy_to_mode_reg (mode0
, op1
);
6816 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
6817 op2
= copy_to_mode_reg (mode1
, op2
);
6819 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
6826 altivec_expand_stv_builtin (enum insn_code icode
, tree arglist
)
6828 tree arg0
= TREE_VALUE (arglist
);
6829 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6830 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6831 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6832 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6833 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6835 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6836 enum machine_mode mode1
= Pmode
;
6837 enum machine_mode mode2
= Pmode
;
6839 /* Invalid arguments. Bail before doing anything stoopid! */
6840 if (arg0
== error_mark_node
6841 || arg1
== error_mark_node
6842 || arg2
== error_mark_node
)
6845 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
6846 op0
= copy_to_mode_reg (tmode
, op0
);
6848 op2
= copy_to_mode_reg (mode2
, op2
);
6850 if (op1
== const0_rtx
)
6852 addr
= gen_rtx_MEM (tmode
, op2
);
6856 op1
= copy_to_mode_reg (mode1
, op1
);
6857 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
6860 pat
= GEN_FCN (icode
) (addr
, op0
);
6867 rs6000_expand_ternop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6870 tree arg0
= TREE_VALUE (arglist
);
6871 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6872 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6873 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6874 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6875 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6876 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6877 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6878 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6879 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
6881 if (icode
== CODE_FOR_nothing
)
6882 /* Builtin not supported on this processor. */
6885 /* If we got invalid arguments bail out before generating bad rtl. */
6886 if (arg0
== error_mark_node
6887 || arg1
== error_mark_node
6888 || arg2
== error_mark_node
)
6891 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
6892 || icode
== CODE_FOR_altivec_vsldoi_v4si
6893 || icode
== CODE_FOR_altivec_vsldoi_v8hi
6894 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
6896 /* Only allow 4-bit unsigned literals. */
6898 if (TREE_CODE (arg2
) != INTEGER_CST
6899 || TREE_INT_CST_LOW (arg2
) & ~0xf)
6901 error ("argument 3 must be a 4-bit unsigned literal");
6907 || GET_MODE (target
) != tmode
6908 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6909 target
= gen_reg_rtx (tmode
);
6911 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6912 op0
= copy_to_mode_reg (mode0
, op0
);
6913 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6914 op1
= copy_to_mode_reg (mode1
, op1
);
6915 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
6916 op2
= copy_to_mode_reg (mode2
, op2
);
6918 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6926 /* Expand the lvx builtins. */
6928 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
6930 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6931 tree arglist
= TREE_OPERAND (exp
, 1);
6932 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6934 enum machine_mode tmode
, mode0
;
6936 enum insn_code icode
;
6940 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
6941 icode
= CODE_FOR_altivec_lvx_v16qi
;
6943 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
6944 icode
= CODE_FOR_altivec_lvx_v8hi
;
6946 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
6947 icode
= CODE_FOR_altivec_lvx_v4si
;
6949 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
6950 icode
= CODE_FOR_altivec_lvx_v4sf
;
6959 arg0
= TREE_VALUE (arglist
);
6960 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6961 tmode
= insn_data
[icode
].operand
[0].mode
;
6962 mode0
= insn_data
[icode
].operand
[1].mode
;
6965 || GET_MODE (target
) != tmode
6966 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6967 target
= gen_reg_rtx (tmode
);
6969 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6970 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
6972 pat
= GEN_FCN (icode
) (target
, op0
);
6979 /* Expand the stvx builtins. */
6981 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
6984 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6985 tree arglist
= TREE_OPERAND (exp
, 1);
6986 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6988 enum machine_mode mode0
, mode1
;
6990 enum insn_code icode
;
6994 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
6995 icode
= CODE_FOR_altivec_stvx_v16qi
;
6997 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
6998 icode
= CODE_FOR_altivec_stvx_v8hi
;
7000 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
7001 icode
= CODE_FOR_altivec_stvx_v4si
;
7003 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
7004 icode
= CODE_FOR_altivec_stvx_v4sf
;
7011 arg0
= TREE_VALUE (arglist
);
7012 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7013 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7014 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7015 mode0
= insn_data
[icode
].operand
[0].mode
;
7016 mode1
= insn_data
[icode
].operand
[1].mode
;
7018 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7019 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
7020 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
7021 op1
= copy_to_mode_reg (mode1
, op1
);
7023 pat
= GEN_FCN (icode
) (op0
, op1
);
7031 /* Expand the dst builtins. */
7033 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
7036 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7037 tree arglist
= TREE_OPERAND (exp
, 1);
7038 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7039 tree arg0
, arg1
, arg2
;
7040 enum machine_mode mode0
, mode1
, mode2
;
7041 rtx pat
, op0
, op1
, op2
;
7042 struct builtin_description
*d
;
7047 /* Handle DST variants. */
7048 d
= (struct builtin_description
*) bdesc_dst
;
7049 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
7050 if (d
->code
== fcode
)
7052 arg0
= TREE_VALUE (arglist
);
7053 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7054 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7055 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7056 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7057 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
7058 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
7059 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
7060 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
7062 /* Invalid arguments, bail out before generating bad rtl. */
7063 if (arg0
== error_mark_node
7064 || arg1
== error_mark_node
7065 || arg2
== error_mark_node
)
7070 if (TREE_CODE (arg2
) != INTEGER_CST
7071 || TREE_INT_CST_LOW (arg2
) & ~0x3)
7073 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
7077 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
7078 op0
= copy_to_mode_reg (Pmode
, op0
);
7079 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
7080 op1
= copy_to_mode_reg (mode1
, op1
);
7082 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
7092 /* Expand vec_init builtin. */
7094 altivec_expand_vec_init_builtin (tree type
, tree arglist
, rtx target
)
7096 enum machine_mode tmode
= TYPE_MODE (type
);
7097 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
7098 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
7099 rtvec v
= rtvec_alloc (n_elt
);
7101 gcc_assert (VECTOR_MODE_P (tmode
));
7103 for (i
= 0; i
< n_elt
; ++i
, arglist
= TREE_CHAIN (arglist
))
7105 rtx x
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
7106 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
7109 gcc_assert (arglist
== NULL
);
7111 if (!target
|| !register_operand (target
, tmode
))
7112 target
= gen_reg_rtx (tmode
);
7114 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
7118 /* Return the integer constant in ARG. Constrain it to be in the range
7119 of the subparts of VEC_TYPE; issue an error if not. */
7122 get_element_number (tree vec_type
, tree arg
)
7124 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
7126 if (!host_integerp (arg
, 1)
7127 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
7129 error ("selector must be an integer constant in the range 0..%wi", max
);
7136 /* Expand vec_set builtin. */
7138 altivec_expand_vec_set_builtin (tree arglist
)
7140 enum machine_mode tmode
, mode1
;
7141 tree arg0
, arg1
, arg2
;
7145 arg0
= TREE_VALUE (arglist
);
7146 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7147 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7149 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
7150 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7151 gcc_assert (VECTOR_MODE_P (tmode
));
7153 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, 0);
7154 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, 0);
7155 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
7157 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
7158 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
7160 op0
= force_reg (tmode
, op0
);
7161 op1
= force_reg (mode1
, op1
);
7163 rs6000_expand_vector_set (op0
, op1
, elt
);
7168 /* Expand vec_ext builtin. */
7170 altivec_expand_vec_ext_builtin (tree arglist
, rtx target
)
7172 enum machine_mode tmode
, mode0
;
7177 arg0
= TREE_VALUE (arglist
);
7178 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7180 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7181 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
7183 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7184 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
7185 gcc_assert (VECTOR_MODE_P (mode0
));
7187 op0
= force_reg (mode0
, op0
);
7189 if (optimize
|| !target
|| !register_operand (target
, tmode
))
7190 target
= gen_reg_rtx (tmode
);
7192 rs6000_expand_vector_extract (target
, op0
, elt
);
7197 /* Expand the builtin in EXP and store the result in TARGET. Store
7198 true in *EXPANDEDP if we found a builtin to expand. */
7200 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7202 struct builtin_description
*d
;
7203 struct builtin_description_predicates
*dp
;
7205 enum insn_code icode
;
7206 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7207 tree arglist
= TREE_OPERAND (exp
, 1);
7210 enum machine_mode tmode
, mode0
;
7211 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7213 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7214 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
7217 error ("unresolved overload for Altivec builtin %qF", fndecl
);
7221 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
7225 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
7229 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
7237 case ALTIVEC_BUILTIN_STVX
:
7238 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, arglist
);
7239 case ALTIVEC_BUILTIN_STVEBX
:
7240 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, arglist
);
7241 case ALTIVEC_BUILTIN_STVEHX
:
7242 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, arglist
);
7243 case ALTIVEC_BUILTIN_STVEWX
:
7244 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, arglist
);
7245 case ALTIVEC_BUILTIN_STVXL
:
7246 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, arglist
);
7248 case ALTIVEC_BUILTIN_MFVSCR
:
7249 icode
= CODE_FOR_altivec_mfvscr
;
7250 tmode
= insn_data
[icode
].operand
[0].mode
;
7253 || GET_MODE (target
) != tmode
7254 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7255 target
= gen_reg_rtx (tmode
);
7257 pat
= GEN_FCN (icode
) (target
);
7263 case ALTIVEC_BUILTIN_MTVSCR
:
7264 icode
= CODE_FOR_altivec_mtvscr
;
7265 arg0
= TREE_VALUE (arglist
);
7266 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7267 mode0
= insn_data
[icode
].operand
[0].mode
;
7269 /* If we got invalid arguments bail out before generating bad rtl. */
7270 if (arg0
== error_mark_node
)
7273 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7274 op0
= copy_to_mode_reg (mode0
, op0
);
7276 pat
= GEN_FCN (icode
) (op0
);
7281 case ALTIVEC_BUILTIN_DSSALL
:
7282 emit_insn (gen_altivec_dssall ());
7285 case ALTIVEC_BUILTIN_DSS
:
7286 icode
= CODE_FOR_altivec_dss
;
7287 arg0
= TREE_VALUE (arglist
);
7289 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7290 mode0
= insn_data
[icode
].operand
[0].mode
;
7292 /* If we got invalid arguments bail out before generating bad rtl. */
7293 if (arg0
== error_mark_node
)
7296 if (TREE_CODE (arg0
) != INTEGER_CST
7297 || TREE_INT_CST_LOW (arg0
) & ~0x3)
7299 error ("argument to dss must be a 2-bit unsigned literal");
7303 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7304 op0
= copy_to_mode_reg (mode0
, op0
);
7306 emit_insn (gen_altivec_dss (op0
));
7309 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
7310 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
7311 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
7312 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
7313 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), arglist
, target
);
7315 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
7316 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
7317 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
7318 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
7319 return altivec_expand_vec_set_builtin (arglist
);
7321 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
7322 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
7323 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
7324 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
7325 return altivec_expand_vec_ext_builtin (arglist
, target
);
7332 /* Expand abs* operations. */
7333 d
= (struct builtin_description
*) bdesc_abs
;
7334 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
7335 if (d
->code
== fcode
)
7336 return altivec_expand_abs_builtin (d
->icode
, arglist
, target
);
7338 /* Expand the AltiVec predicates. */
7339 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
7340 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
7341 if (dp
->code
== fcode
)
7342 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
7345 /* LV* are funky. We initialized them differently. */
7348 case ALTIVEC_BUILTIN_LVSL
:
7349 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
7351 case ALTIVEC_BUILTIN_LVSR
:
7352 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
7354 case ALTIVEC_BUILTIN_LVEBX
:
7355 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
7357 case ALTIVEC_BUILTIN_LVEHX
:
7358 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
7360 case ALTIVEC_BUILTIN_LVEWX
:
7361 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
7363 case ALTIVEC_BUILTIN_LVXL
:
7364 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
7366 case ALTIVEC_BUILTIN_LVX
:
7367 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
7378 /* Binops that need to be initialized manually, but can be expanded
7379 automagically by rs6000_expand_binop_builtin. */
7380 static struct builtin_description bdesc_2arg_spe
[] =
7382 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
7383 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
7384 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
7385 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
7386 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
7387 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
7388 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
7389 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
7390 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
7391 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
7392 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
7393 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
7394 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
7395 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
7396 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
7397 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
7398 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
7399 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
7400 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
7401 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
7402 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
7403 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
7406 /* Expand the builtin in EXP and store the result in TARGET. Store
7407 true in *EXPANDEDP if we found a builtin to expand.
7409 This expands the SPE builtins that are not simple unary and binary
7412 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7414 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7415 tree arglist
= TREE_OPERAND (exp
, 1);
7417 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7418 enum insn_code icode
;
7419 enum machine_mode tmode
, mode0
;
7421 struct builtin_description
*d
;
7426 /* Syntax check for a 5-bit unsigned immediate. */
7429 case SPE_BUILTIN_EVSTDD
:
7430 case SPE_BUILTIN_EVSTDH
:
7431 case SPE_BUILTIN_EVSTDW
:
7432 case SPE_BUILTIN_EVSTWHE
:
7433 case SPE_BUILTIN_EVSTWHO
:
7434 case SPE_BUILTIN_EVSTWWE
:
7435 case SPE_BUILTIN_EVSTWWO
:
7436 arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7437 if (TREE_CODE (arg1
) != INTEGER_CST
7438 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7440 error ("argument 2 must be a 5-bit unsigned literal");
7448 /* The evsplat*i instructions are not quite generic. */
7451 case SPE_BUILTIN_EVSPLATFI
:
7452 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
7454 case SPE_BUILTIN_EVSPLATI
:
7455 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
7461 d
= (struct builtin_description
*) bdesc_2arg_spe
;
7462 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
7463 if (d
->code
== fcode
)
7464 return rs6000_expand_binop_builtin (d
->icode
, arglist
, target
);
7466 d
= (struct builtin_description
*) bdesc_spe_predicates
;
7467 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
7468 if (d
->code
== fcode
)
7469 return spe_expand_predicate_builtin (d
->icode
, arglist
, target
);
7471 d
= (struct builtin_description
*) bdesc_spe_evsel
;
7472 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
7473 if (d
->code
== fcode
)
7474 return spe_expand_evsel_builtin (d
->icode
, arglist
, target
);
7478 case SPE_BUILTIN_EVSTDDX
:
7479 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, arglist
);
7480 case SPE_BUILTIN_EVSTDHX
:
7481 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, arglist
);
7482 case SPE_BUILTIN_EVSTDWX
:
7483 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, arglist
);
7484 case SPE_BUILTIN_EVSTWHEX
:
7485 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, arglist
);
7486 case SPE_BUILTIN_EVSTWHOX
:
7487 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, arglist
);
7488 case SPE_BUILTIN_EVSTWWEX
:
7489 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, arglist
);
7490 case SPE_BUILTIN_EVSTWWOX
:
7491 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, arglist
);
7492 case SPE_BUILTIN_EVSTDD
:
7493 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, arglist
);
7494 case SPE_BUILTIN_EVSTDH
:
7495 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, arglist
);
7496 case SPE_BUILTIN_EVSTDW
:
7497 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, arglist
);
7498 case SPE_BUILTIN_EVSTWHE
:
7499 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, arglist
);
7500 case SPE_BUILTIN_EVSTWHO
:
7501 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, arglist
);
7502 case SPE_BUILTIN_EVSTWWE
:
7503 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, arglist
);
7504 case SPE_BUILTIN_EVSTWWO
:
7505 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, arglist
);
7506 case SPE_BUILTIN_MFSPEFSCR
:
7507 icode
= CODE_FOR_spe_mfspefscr
;
7508 tmode
= insn_data
[icode
].operand
[0].mode
;
7511 || GET_MODE (target
) != tmode
7512 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7513 target
= gen_reg_rtx (tmode
);
7515 pat
= GEN_FCN (icode
) (target
);
7520 case SPE_BUILTIN_MTSPEFSCR
:
7521 icode
= CODE_FOR_spe_mtspefscr
;
7522 arg0
= TREE_VALUE (arglist
);
7523 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7524 mode0
= insn_data
[icode
].operand
[0].mode
;
7526 if (arg0
== error_mark_node
)
7529 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7530 op0
= copy_to_mode_reg (mode0
, op0
);
7532 pat
= GEN_FCN (icode
) (op0
);
7545 spe_expand_predicate_builtin (enum insn_code icode
, tree arglist
, rtx target
)
7547 rtx pat
, scratch
, tmp
;
7548 tree form
= TREE_VALUE (arglist
);
7549 tree arg0
= TREE_VALUE (TREE_CHAIN (arglist
));
7550 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7551 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7552 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7553 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7554 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7558 if (TREE_CODE (form
) != INTEGER_CST
)
7560 error ("argument 1 of __builtin_spe_predicate must be a constant");
7564 form_int
= TREE_INT_CST_LOW (form
);
7566 gcc_assert (mode0
== mode1
);
7568 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7572 || GET_MODE (target
) != SImode
7573 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
7574 target
= gen_reg_rtx (SImode
);
7576 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7577 op0
= copy_to_mode_reg (mode0
, op0
);
7578 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7579 op1
= copy_to_mode_reg (mode1
, op1
);
7581 scratch
= gen_reg_rtx (CCmode
);
7583 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
7588 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7589 _lower_. We use one compare, but look in different bits of the
7590 CR for each variant.
7592 There are 2 elements in each SPE simd type (upper/lower). The CR
7593 bits are set as follows:
7595 BIT0 | BIT 1 | BIT 2 | BIT 3
7596 U | L | (U | L) | (U & L)
7598 So, for an "all" relationship, BIT 3 would be set.
7599 For an "any" relationship, BIT 2 would be set. Etc.
7601 Following traditional nomenclature, these bits map to:
7603 BIT0 | BIT 1 | BIT 2 | BIT 3
7606 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
7611 /* All variant. OV bit. */
7613 /* We need to get to the OV bit, which is the ORDERED bit. We
7614 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
7615 that's ugly and will make validate_condition_mode die.
7616 So let's just use another pattern. */
7617 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
7619 /* Any variant. EQ bit. */
7623 /* Upper variant. LT bit. */
7627 /* Lower variant. GT bit. */
7632 error ("argument 1 of __builtin_spe_predicate is out of range");
7636 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
7637 emit_move_insn (target
, tmp
);
7642 /* The evsel builtins look like this:
7644 e = __builtin_spe_evsel_OP (a, b, c, d);
7648 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
7649 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
7653 spe_expand_evsel_builtin (enum insn_code icode
, tree arglist
, rtx target
)
7656 tree arg0
= TREE_VALUE (arglist
);
7657 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7658 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7659 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
7660 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7661 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7662 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
7663 rtx op3
= expand_expr (arg3
, NULL_RTX
, VOIDmode
, 0);
7664 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7665 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7667 gcc_assert (mode0
== mode1
);
7669 if (arg0
== error_mark_node
|| arg1
== error_mark_node
7670 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
7674 || GET_MODE (target
) != mode0
7675 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
7676 target
= gen_reg_rtx (mode0
);
7678 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7679 op0
= copy_to_mode_reg (mode0
, op0
);
7680 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
7681 op1
= copy_to_mode_reg (mode0
, op1
);
7682 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
7683 op2
= copy_to_mode_reg (mode0
, op2
);
7684 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
7685 op3
= copy_to_mode_reg (mode0
, op3
);
7687 /* Generate the compare. */
7688 scratch
= gen_reg_rtx (CCmode
);
7689 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
7694 if (mode0
== V2SImode
)
7695 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
7697 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
7702 /* Expand an expression EXP that calls a built-in function,
7703 with result going to TARGET if that's convenient
7704 (and in mode MODE if that's convenient).
7705 SUBTARGET may be used as the target for computing one of EXP's operands.
7706 IGNORE is nonzero if the value is to be ignored. */
7709 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
7710 enum machine_mode mode ATTRIBUTE_UNUSED
,
7711 int ignore ATTRIBUTE_UNUSED
)
7713 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7714 tree arglist
= TREE_OPERAND (exp
, 1);
7715 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7716 struct builtin_description
*d
;
7721 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
7722 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
7724 int icode
= (int) CODE_FOR_altivec_lvsr
;
7725 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7726 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
7730 gcc_assert (TARGET_ALTIVEC
);
7732 arg
= TREE_VALUE (arglist
);
7733 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
7734 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
7735 addr
= memory_address (mode
, op
);
7736 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
7740 /* For the load case need to negate the address. */
7741 op
= gen_reg_rtx (GET_MODE (addr
));
7742 emit_insn (gen_rtx_SET (VOIDmode
, op
,
7743 gen_rtx_NEG (GET_MODE (addr
), addr
)));
7745 op
= gen_rtx_MEM (mode
, op
);
7748 || GET_MODE (target
) != tmode
7749 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7750 target
= gen_reg_rtx (tmode
);
7752 /*pat = gen_altivec_lvsr (target, op);*/
7753 pat
= GEN_FCN (icode
) (target
, op
);
7763 ret
= altivec_expand_builtin (exp
, target
, &success
);
7770 ret
= spe_expand_builtin (exp
, target
, &success
);
7776 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
);
7778 /* Handle simple unary operations. */
7779 d
= (struct builtin_description
*) bdesc_1arg
;
7780 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
7781 if (d
->code
== fcode
)
7782 return rs6000_expand_unop_builtin (d
->icode
, arglist
, target
);
7784 /* Handle simple binary operations. */
7785 d
= (struct builtin_description
*) bdesc_2arg
;
7786 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
7787 if (d
->code
== fcode
)
7788 return rs6000_expand_binop_builtin (d
->icode
, arglist
, target
);
7790 /* Handle simple ternary operations. */
7791 d
= (struct builtin_description
*) bdesc_3arg
;
7792 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
7793 if (d
->code
== fcode
)
7794 return rs6000_expand_ternop_builtin (d
->icode
, arglist
, target
);
7800 build_opaque_vector_type (tree node
, int nunits
)
7802 node
= copy_node (node
);
7803 TYPE_MAIN_VARIANT (node
) = node
;
7804 return build_vector_type (node
, nunits
);
7808 rs6000_init_builtins (void)
7810 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
7811 V2SF_type_node
= build_vector_type (float_type_node
, 2);
7812 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
7813 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
7814 V4SF_type_node
= build_vector_type (float_type_node
, 4);
7815 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
7816 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
7818 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
7819 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
7820 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
7822 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
7823 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
7824 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
7825 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
7827 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
7828 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
7829 'vector unsigned short'. */
7831 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
7832 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
7833 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
7834 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
7836 long_integer_type_internal_node
= long_integer_type_node
;
7837 long_unsigned_type_internal_node
= long_unsigned_type_node
;
7838 intQI_type_internal_node
= intQI_type_node
;
7839 uintQI_type_internal_node
= unsigned_intQI_type_node
;
7840 intHI_type_internal_node
= intHI_type_node
;
7841 uintHI_type_internal_node
= unsigned_intHI_type_node
;
7842 intSI_type_internal_node
= intSI_type_node
;
7843 uintSI_type_internal_node
= unsigned_intSI_type_node
;
7844 float_type_internal_node
= float_type_node
;
7845 void_type_internal_node
= void_type_node
;
7847 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7848 get_identifier ("__bool char"),
7849 bool_char_type_node
));
7850 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7851 get_identifier ("__bool short"),
7852 bool_short_type_node
));
7853 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7854 get_identifier ("__bool int"),
7855 bool_int_type_node
));
7856 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7857 get_identifier ("__pixel"),
7860 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
7861 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
7862 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
7863 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
7865 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7866 get_identifier ("__vector unsigned char"),
7867 unsigned_V16QI_type_node
));
7868 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7869 get_identifier ("__vector signed char"),
7871 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7872 get_identifier ("__vector __bool char"),
7873 bool_V16QI_type_node
));
7875 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7876 get_identifier ("__vector unsigned short"),
7877 unsigned_V8HI_type_node
));
7878 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7879 get_identifier ("__vector signed short"),
7881 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7882 get_identifier ("__vector __bool short"),
7883 bool_V8HI_type_node
));
7885 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7886 get_identifier ("__vector unsigned int"),
7887 unsigned_V4SI_type_node
));
7888 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7889 get_identifier ("__vector signed int"),
7891 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7892 get_identifier ("__vector __bool int"),
7893 bool_V4SI_type_node
));
7895 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7896 get_identifier ("__vector float"),
7898 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7899 get_identifier ("__vector __pixel"),
7900 pixel_V8HI_type_node
));
7903 spe_init_builtins ();
7905 altivec_init_builtins ();
7906 if (TARGET_ALTIVEC
|| TARGET_SPE
)
7907 rs6000_common_init_builtins ();
7910 /* Search through a set of builtins and enable the mask bits.
7911 DESC is an array of builtins.
7912 SIZE is the total number of builtins.
7913 START is the builtin enum at which to start.
7914 END is the builtin enum at which to end. */
7916 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
7917 enum rs6000_builtins start
,
7918 enum rs6000_builtins end
)
7922 for (i
= 0; i
< size
; ++i
)
7923 if (desc
[i
].code
== start
)
7929 for (; i
< size
; ++i
)
7931 /* Flip all the bits on. */
7932 desc
[i
].mask
= target_flags
;
7933 if (desc
[i
].code
== end
)
7939 spe_init_builtins (void)
7941 tree endlink
= void_list_node
;
7942 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
7943 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
7944 struct builtin_description
*d
;
7947 tree v2si_ftype_4_v2si
7948 = build_function_type
7949 (opaque_V2SI_type_node
,
7950 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7951 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7952 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7953 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7956 tree v2sf_ftype_4_v2sf
7957 = build_function_type
7958 (opaque_V2SF_type_node
,
7959 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7960 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7961 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7962 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7965 tree int_ftype_int_v2si_v2si
7966 = build_function_type
7968 tree_cons (NULL_TREE
, integer_type_node
,
7969 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7970 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7973 tree int_ftype_int_v2sf_v2sf
7974 = build_function_type
7976 tree_cons (NULL_TREE
, integer_type_node
,
7977 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7978 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7981 tree void_ftype_v2si_puint_int
7982 = build_function_type (void_type_node
,
7983 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7984 tree_cons (NULL_TREE
, puint_type_node
,
7985 tree_cons (NULL_TREE
,
7989 tree void_ftype_v2si_puint_char
7990 = build_function_type (void_type_node
,
7991 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7992 tree_cons (NULL_TREE
, puint_type_node
,
7993 tree_cons (NULL_TREE
,
7997 tree void_ftype_v2si_pv2si_int
7998 = build_function_type (void_type_node
,
7999 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8000 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8001 tree_cons (NULL_TREE
,
8005 tree void_ftype_v2si_pv2si_char
8006 = build_function_type (void_type_node
,
8007 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8008 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8009 tree_cons (NULL_TREE
,
8014 = build_function_type (void_type_node
,
8015 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
8018 = build_function_type (integer_type_node
, endlink
);
8020 tree v2si_ftype_pv2si_int
8021 = build_function_type (opaque_V2SI_type_node
,
8022 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8023 tree_cons (NULL_TREE
, integer_type_node
,
8026 tree v2si_ftype_puint_int
8027 = build_function_type (opaque_V2SI_type_node
,
8028 tree_cons (NULL_TREE
, puint_type_node
,
8029 tree_cons (NULL_TREE
, integer_type_node
,
8032 tree v2si_ftype_pushort_int
8033 = build_function_type (opaque_V2SI_type_node
,
8034 tree_cons (NULL_TREE
, pushort_type_node
,
8035 tree_cons (NULL_TREE
, integer_type_node
,
8038 tree v2si_ftype_signed_char
8039 = build_function_type (opaque_V2SI_type_node
,
8040 tree_cons (NULL_TREE
, signed_char_type_node
,
8043 /* The initialization of the simple binary and unary builtins is
8044 done in rs6000_common_init_builtins, but we have to enable the
8045 mask bits here manually because we have run out of `target_flags'
8046 bits. We really need to redesign this mask business. */
8048 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
8049 ARRAY_SIZE (bdesc_2arg
),
8052 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
8053 ARRAY_SIZE (bdesc_1arg
),
8055 SPE_BUILTIN_EVSUBFUSIAAW
);
8056 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
8057 ARRAY_SIZE (bdesc_spe_predicates
),
8058 SPE_BUILTIN_EVCMPEQ
,
8059 SPE_BUILTIN_EVFSTSTLT
);
8060 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
8061 ARRAY_SIZE (bdesc_spe_evsel
),
8062 SPE_BUILTIN_EVSEL_CMPGTS
,
8063 SPE_BUILTIN_EVSEL_FSTSTEQ
);
8065 (*lang_hooks
.decls
.pushdecl
)
8066 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
8067 opaque_V2SI_type_node
));
8069 /* Initialize irregular SPE builtins. */
8071 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
8072 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
8073 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
8074 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
8075 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
8076 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
8077 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
8078 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
8079 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
8080 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
8081 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
8082 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
8083 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
8084 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
8085 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
8086 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
8087 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
8088 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
8091 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
8092 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
8093 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
8094 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
8095 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
8096 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
8097 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
8098 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
8099 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
8100 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
8101 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
8102 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
8103 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
8104 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
8105 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
8106 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
8107 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
8108 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
8109 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
8110 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
8111 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
8112 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
8115 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8116 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
8120 switch (insn_data
[d
->icode
].operand
[1].mode
)
8123 type
= int_ftype_int_v2si_v2si
;
8126 type
= int_ftype_int_v2sf_v2sf
;
8132 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8135 /* Evsel predicates. */
8136 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8137 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
8141 switch (insn_data
[d
->icode
].operand
[1].mode
)
8144 type
= v2si_ftype_4_v2si
;
8147 type
= v2sf_ftype_4_v2sf
;
8153 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8158 altivec_init_builtins (void)
8160 struct builtin_description
*d
;
8161 struct builtin_description_predicates
*dp
;
8165 tree pfloat_type_node
= build_pointer_type (float_type_node
);
8166 tree pint_type_node
= build_pointer_type (integer_type_node
);
8167 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
8168 tree pchar_type_node
= build_pointer_type (char_type_node
);
8170 tree pvoid_type_node
= build_pointer_type (void_type_node
);
8172 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
8173 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
8174 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
8175 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
8177 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
8179 tree int_ftype_opaque
8180 = build_function_type_list (integer_type_node
,
8181 opaque_V4SI_type_node
, NULL_TREE
);
8183 tree opaque_ftype_opaque_int
8184 = build_function_type_list (opaque_V4SI_type_node
,
8185 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
8186 tree opaque_ftype_opaque_opaque_int
8187 = build_function_type_list (opaque_V4SI_type_node
,
8188 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
8189 integer_type_node
, NULL_TREE
);
8190 tree int_ftype_int_opaque_opaque
8191 = build_function_type_list (integer_type_node
,
8192 integer_type_node
, opaque_V4SI_type_node
,
8193 opaque_V4SI_type_node
, NULL_TREE
);
8194 tree int_ftype_int_v4si_v4si
8195 = build_function_type_list (integer_type_node
,
8196 integer_type_node
, V4SI_type_node
,
8197 V4SI_type_node
, NULL_TREE
);
8198 tree v4sf_ftype_pcfloat
8199 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
8200 tree void_ftype_pfloat_v4sf
8201 = build_function_type_list (void_type_node
,
8202 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
8203 tree v4si_ftype_pcint
8204 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
8205 tree void_ftype_pint_v4si
8206 = build_function_type_list (void_type_node
,
8207 pint_type_node
, V4SI_type_node
, NULL_TREE
);
8208 tree v8hi_ftype_pcshort
8209 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
8210 tree void_ftype_pshort_v8hi
8211 = build_function_type_list (void_type_node
,
8212 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
8213 tree v16qi_ftype_pcchar
8214 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
8215 tree void_ftype_pchar_v16qi
8216 = build_function_type_list (void_type_node
,
8217 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
8218 tree void_ftype_v4si
8219 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
8220 tree v8hi_ftype_void
8221 = build_function_type (V8HI_type_node
, void_list_node
);
8222 tree void_ftype_void
8223 = build_function_type (void_type_node
, void_list_node
);
8225 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
8227 tree opaque_ftype_long_pcvoid
8228 = build_function_type_list (opaque_V4SI_type_node
,
8229 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8230 tree v16qi_ftype_long_pcvoid
8231 = build_function_type_list (V16QI_type_node
,
8232 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8233 tree v8hi_ftype_long_pcvoid
8234 = build_function_type_list (V8HI_type_node
,
8235 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8236 tree v4si_ftype_long_pcvoid
8237 = build_function_type_list (V4SI_type_node
,
8238 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8240 tree void_ftype_opaque_long_pvoid
8241 = build_function_type_list (void_type_node
,
8242 opaque_V4SI_type_node
, long_integer_type_node
,
8243 pvoid_type_node
, NULL_TREE
);
8244 tree void_ftype_v4si_long_pvoid
8245 = build_function_type_list (void_type_node
,
8246 V4SI_type_node
, long_integer_type_node
,
8247 pvoid_type_node
, NULL_TREE
);
8248 tree void_ftype_v16qi_long_pvoid
8249 = build_function_type_list (void_type_node
,
8250 V16QI_type_node
, long_integer_type_node
,
8251 pvoid_type_node
, NULL_TREE
);
8252 tree void_ftype_v8hi_long_pvoid
8253 = build_function_type_list (void_type_node
,
8254 V8HI_type_node
, long_integer_type_node
,
8255 pvoid_type_node
, NULL_TREE
);
8256 tree int_ftype_int_v8hi_v8hi
8257 = build_function_type_list (integer_type_node
,
8258 integer_type_node
, V8HI_type_node
,
8259 V8HI_type_node
, NULL_TREE
);
8260 tree int_ftype_int_v16qi_v16qi
8261 = build_function_type_list (integer_type_node
,
8262 integer_type_node
, V16QI_type_node
,
8263 V16QI_type_node
, NULL_TREE
);
8264 tree int_ftype_int_v4sf_v4sf
8265 = build_function_type_list (integer_type_node
,
8266 integer_type_node
, V4SF_type_node
,
8267 V4SF_type_node
, NULL_TREE
);
8268 tree v4si_ftype_v4si
8269 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8270 tree v8hi_ftype_v8hi
8271 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8272 tree v16qi_ftype_v16qi
8273 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8274 tree v4sf_ftype_v4sf
8275 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8276 tree void_ftype_pcvoid_int_int
8277 = build_function_type_list (void_type_node
,
8278 pcvoid_type_node
, integer_type_node
,
8279 integer_type_node
, NULL_TREE
);
8281 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
8282 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
8283 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
8284 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
8285 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
8286 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
8287 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
8288 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
8289 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
8290 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
8291 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
8292 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
8293 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
8294 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
8295 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
8296 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
8297 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
8298 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
8299 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
8300 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
8301 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
8302 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
8303 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
8304 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
8305 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
8306 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
8307 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
8308 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
8309 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
8310 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
8311 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
8312 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
8313 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
8314 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
8315 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
8316 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
8317 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
8318 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
8319 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
8320 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
8321 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
8322 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
8323 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
8324 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
8325 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
8326 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
8328 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
8330 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
8331 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
8332 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
8333 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
8334 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
8335 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
8336 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
8337 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
8338 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
8339 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
8341 /* Add the DST variants. */
8342 d
= (struct builtin_description
*) bdesc_dst
;
8343 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8344 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
8346 /* Initialize the predicates. */
8347 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
8348 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8350 enum machine_mode mode1
;
8352 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8353 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8358 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
8363 type
= int_ftype_int_opaque_opaque
;
8366 type
= int_ftype_int_v4si_v4si
;
8369 type
= int_ftype_int_v8hi_v8hi
;
8372 type
= int_ftype_int_v16qi_v16qi
;
8375 type
= int_ftype_int_v4sf_v4sf
;
8381 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
8384 /* Initialize the abs* operators. */
8385 d
= (struct builtin_description
*) bdesc_abs
;
8386 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8388 enum machine_mode mode0
;
8391 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8396 type
= v4si_ftype_v4si
;
8399 type
= v8hi_ftype_v8hi
;
8402 type
= v16qi_ftype_v16qi
;
8405 type
= v4sf_ftype_v4sf
;
8411 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8418 /* Initialize target builtin that implements
8419 targetm.vectorize.builtin_mask_for_load. */
8421 decl
= lang_hooks
.builtin_function ("__builtin_altivec_mask_for_load",
8422 v16qi_ftype_long_pcvoid
,
8423 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
8425 tree_cons (get_identifier ("const"),
8426 NULL_TREE
, NULL_TREE
));
8427 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8428 altivec_builtin_mask_for_load
= decl
;
8431 /* Access to the vec_init patterns. */
8432 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
8433 integer_type_node
, integer_type_node
,
8434 integer_type_node
, NULL_TREE
);
8435 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
8436 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
8438 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
8439 short_integer_type_node
,
8440 short_integer_type_node
,
8441 short_integer_type_node
,
8442 short_integer_type_node
,
8443 short_integer_type_node
,
8444 short_integer_type_node
,
8445 short_integer_type_node
, NULL_TREE
);
8446 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
8447 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
8449 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
8450 char_type_node
, char_type_node
,
8451 char_type_node
, char_type_node
,
8452 char_type_node
, char_type_node
,
8453 char_type_node
, char_type_node
,
8454 char_type_node
, char_type_node
,
8455 char_type_node
, char_type_node
,
8456 char_type_node
, char_type_node
,
8457 char_type_node
, NULL_TREE
);
8458 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
8459 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
8461 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
8462 float_type_node
, float_type_node
,
8463 float_type_node
, NULL_TREE
);
8464 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
8465 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
8467 /* Access to the vec_set patterns. */
8468 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
8470 integer_type_node
, NULL_TREE
);
8471 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
8472 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
8474 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
8476 integer_type_node
, NULL_TREE
);
8477 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
8478 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
8480 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
8482 integer_type_node
, NULL_TREE
);
8483 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
8484 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
8486 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
8488 integer_type_node
, NULL_TREE
);
8489 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
8490 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
8492 /* Access to the vec_extract patterns. */
8493 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
8494 integer_type_node
, NULL_TREE
);
8495 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
8496 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
8498 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
8499 integer_type_node
, NULL_TREE
);
8500 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
8501 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
8503 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
8504 integer_type_node
, NULL_TREE
);
8505 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
8506 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
8508 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
8509 integer_type_node
, NULL_TREE
);
8510 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
8511 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
8515 rs6000_common_init_builtins (void)
8517 struct builtin_description
*d
;
8520 tree v4sf_ftype_v4sf_v4sf_v16qi
8521 = build_function_type_list (V4SF_type_node
,
8522 V4SF_type_node
, V4SF_type_node
,
8523 V16QI_type_node
, NULL_TREE
);
8524 tree v4si_ftype_v4si_v4si_v16qi
8525 = build_function_type_list (V4SI_type_node
,
8526 V4SI_type_node
, V4SI_type_node
,
8527 V16QI_type_node
, NULL_TREE
);
8528 tree v8hi_ftype_v8hi_v8hi_v16qi
8529 = build_function_type_list (V8HI_type_node
,
8530 V8HI_type_node
, V8HI_type_node
,
8531 V16QI_type_node
, NULL_TREE
);
8532 tree v16qi_ftype_v16qi_v16qi_v16qi
8533 = build_function_type_list (V16QI_type_node
,
8534 V16QI_type_node
, V16QI_type_node
,
8535 V16QI_type_node
, NULL_TREE
);
8537 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
8539 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
8540 tree v16qi_ftype_int
8541 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
8542 tree v8hi_ftype_v16qi
8543 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
8544 tree v4sf_ftype_v4sf
8545 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8547 tree v2si_ftype_v2si_v2si
8548 = build_function_type_list (opaque_V2SI_type_node
,
8549 opaque_V2SI_type_node
,
8550 opaque_V2SI_type_node
, NULL_TREE
);
8552 tree v2sf_ftype_v2sf_v2sf
8553 = build_function_type_list (opaque_V2SF_type_node
,
8554 opaque_V2SF_type_node
,
8555 opaque_V2SF_type_node
, NULL_TREE
);
8557 tree v2si_ftype_int_int
8558 = build_function_type_list (opaque_V2SI_type_node
,
8559 integer_type_node
, integer_type_node
,
8562 tree opaque_ftype_opaque
8563 = build_function_type_list (opaque_V4SI_type_node
,
8564 opaque_V4SI_type_node
, NULL_TREE
);
8566 tree v2si_ftype_v2si
8567 = build_function_type_list (opaque_V2SI_type_node
,
8568 opaque_V2SI_type_node
, NULL_TREE
);
8570 tree v2sf_ftype_v2sf
8571 = build_function_type_list (opaque_V2SF_type_node
,
8572 opaque_V2SF_type_node
, NULL_TREE
);
8574 tree v2sf_ftype_v2si
8575 = build_function_type_list (opaque_V2SF_type_node
,
8576 opaque_V2SI_type_node
, NULL_TREE
);
8578 tree v2si_ftype_v2sf
8579 = build_function_type_list (opaque_V2SI_type_node
,
8580 opaque_V2SF_type_node
, NULL_TREE
);
8582 tree v2si_ftype_v2si_char
8583 = build_function_type_list (opaque_V2SI_type_node
,
8584 opaque_V2SI_type_node
,
8585 char_type_node
, NULL_TREE
);
8587 tree v2si_ftype_int_char
8588 = build_function_type_list (opaque_V2SI_type_node
,
8589 integer_type_node
, char_type_node
, NULL_TREE
);
8591 tree v2si_ftype_char
8592 = build_function_type_list (opaque_V2SI_type_node
,
8593 char_type_node
, NULL_TREE
);
8595 tree int_ftype_int_int
8596 = build_function_type_list (integer_type_node
,
8597 integer_type_node
, integer_type_node
,
8600 tree opaque_ftype_opaque_opaque
8601 = build_function_type_list (opaque_V4SI_type_node
,
8602 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
8603 tree v4si_ftype_v4si_v4si
8604 = build_function_type_list (V4SI_type_node
,
8605 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8606 tree v4sf_ftype_v4si_int
8607 = build_function_type_list (V4SF_type_node
,
8608 V4SI_type_node
, integer_type_node
, NULL_TREE
);
8609 tree v4si_ftype_v4sf_int
8610 = build_function_type_list (V4SI_type_node
,
8611 V4SF_type_node
, integer_type_node
, NULL_TREE
);
8612 tree v4si_ftype_v4si_int
8613 = build_function_type_list (V4SI_type_node
,
8614 V4SI_type_node
, integer_type_node
, NULL_TREE
);
8615 tree v8hi_ftype_v8hi_int
8616 = build_function_type_list (V8HI_type_node
,
8617 V8HI_type_node
, integer_type_node
, NULL_TREE
);
8618 tree v16qi_ftype_v16qi_int
8619 = build_function_type_list (V16QI_type_node
,
8620 V16QI_type_node
, integer_type_node
, NULL_TREE
);
8621 tree v16qi_ftype_v16qi_v16qi_int
8622 = build_function_type_list (V16QI_type_node
,
8623 V16QI_type_node
, V16QI_type_node
,
8624 integer_type_node
, NULL_TREE
);
8625 tree v8hi_ftype_v8hi_v8hi_int
8626 = build_function_type_list (V8HI_type_node
,
8627 V8HI_type_node
, V8HI_type_node
,
8628 integer_type_node
, NULL_TREE
);
8629 tree v4si_ftype_v4si_v4si_int
8630 = build_function_type_list (V4SI_type_node
,
8631 V4SI_type_node
, V4SI_type_node
,
8632 integer_type_node
, NULL_TREE
);
8633 tree v4sf_ftype_v4sf_v4sf_int
8634 = build_function_type_list (V4SF_type_node
,
8635 V4SF_type_node
, V4SF_type_node
,
8636 integer_type_node
, NULL_TREE
);
8637 tree v4sf_ftype_v4sf_v4sf
8638 = build_function_type_list (V4SF_type_node
,
8639 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8640 tree opaque_ftype_opaque_opaque_opaque
8641 = build_function_type_list (opaque_V4SI_type_node
,
8642 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
8643 opaque_V4SI_type_node
, NULL_TREE
);
8644 tree v4sf_ftype_v4sf_v4sf_v4si
8645 = build_function_type_list (V4SF_type_node
,
8646 V4SF_type_node
, V4SF_type_node
,
8647 V4SI_type_node
, NULL_TREE
);
8648 tree v4sf_ftype_v4sf_v4sf_v4sf
8649 = build_function_type_list (V4SF_type_node
,
8650 V4SF_type_node
, V4SF_type_node
,
8651 V4SF_type_node
, NULL_TREE
);
8652 tree v4si_ftype_v4si_v4si_v4si
8653 = build_function_type_list (V4SI_type_node
,
8654 V4SI_type_node
, V4SI_type_node
,
8655 V4SI_type_node
, NULL_TREE
);
8656 tree v8hi_ftype_v8hi_v8hi
8657 = build_function_type_list (V8HI_type_node
,
8658 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8659 tree v8hi_ftype_v8hi_v8hi_v8hi
8660 = build_function_type_list (V8HI_type_node
,
8661 V8HI_type_node
, V8HI_type_node
,
8662 V8HI_type_node
, NULL_TREE
);
8663 tree v4si_ftype_v8hi_v8hi_v4si
8664 = build_function_type_list (V4SI_type_node
,
8665 V8HI_type_node
, V8HI_type_node
,
8666 V4SI_type_node
, NULL_TREE
);
8667 tree v4si_ftype_v16qi_v16qi_v4si
8668 = build_function_type_list (V4SI_type_node
,
8669 V16QI_type_node
, V16QI_type_node
,
8670 V4SI_type_node
, NULL_TREE
);
8671 tree v16qi_ftype_v16qi_v16qi
8672 = build_function_type_list (V16QI_type_node
,
8673 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8674 tree v4si_ftype_v4sf_v4sf
8675 = build_function_type_list (V4SI_type_node
,
8676 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8677 tree v8hi_ftype_v16qi_v16qi
8678 = build_function_type_list (V8HI_type_node
,
8679 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8680 tree v4si_ftype_v8hi_v8hi
8681 = build_function_type_list (V4SI_type_node
,
8682 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8683 tree v8hi_ftype_v4si_v4si
8684 = build_function_type_list (V8HI_type_node
,
8685 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8686 tree v16qi_ftype_v8hi_v8hi
8687 = build_function_type_list (V16QI_type_node
,
8688 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8689 tree v4si_ftype_v16qi_v4si
8690 = build_function_type_list (V4SI_type_node
,
8691 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
8692 tree v4si_ftype_v16qi_v16qi
8693 = build_function_type_list (V4SI_type_node
,
8694 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8695 tree v4si_ftype_v8hi_v4si
8696 = build_function_type_list (V4SI_type_node
,
8697 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
8698 tree v4si_ftype_v8hi
8699 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
8700 tree int_ftype_v4si_v4si
8701 = build_function_type_list (integer_type_node
,
8702 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8703 tree int_ftype_v4sf_v4sf
8704 = build_function_type_list (integer_type_node
,
8705 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8706 tree int_ftype_v16qi_v16qi
8707 = build_function_type_list (integer_type_node
,
8708 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8709 tree int_ftype_v8hi_v8hi
8710 = build_function_type_list (integer_type_node
,
8711 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8713 /* Add the simple ternary operators. */
8714 d
= (struct builtin_description
*) bdesc_3arg
;
8715 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
8717 enum machine_mode mode0
, mode1
, mode2
, mode3
;
8719 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8720 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8731 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8734 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8735 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8736 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8737 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
8740 /* When all four are of the same mode. */
8741 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
8746 type
= opaque_ftype_opaque_opaque_opaque
;
8749 type
= v4si_ftype_v4si_v4si_v4si
;
8752 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
8755 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
8758 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
8764 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
8769 type
= v4si_ftype_v4si_v4si_v16qi
;
8772 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
8775 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
8778 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
8784 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
8785 && mode3
== V4SImode
)
8786 type
= v4si_ftype_v16qi_v16qi_v4si
;
8787 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
8788 && mode3
== V4SImode
)
8789 type
= v4si_ftype_v8hi_v8hi_v4si
;
8790 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
8791 && mode3
== V4SImode
)
8792 type
= v4sf_ftype_v4sf_v4sf_v4si
;
8794 /* vchar, vchar, vchar, 4 bit literal. */
8795 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
8797 type
= v16qi_ftype_v16qi_v16qi_int
;
8799 /* vshort, vshort, vshort, 4 bit literal. */
8800 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
8802 type
= v8hi_ftype_v8hi_v8hi_int
;
8804 /* vint, vint, vint, 4 bit literal. */
8805 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
8807 type
= v4si_ftype_v4si_v4si_int
;
8809 /* vfloat, vfloat, vfloat, 4 bit literal. */
8810 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
8812 type
= v4sf_ftype_v4sf_v4sf_int
;
8817 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8820 /* Add the simple binary operators. */
8821 d
= (struct builtin_description
*) bdesc_2arg
;
8822 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
8824 enum machine_mode mode0
, mode1
, mode2
;
8826 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8827 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8837 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8840 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8841 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8842 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8845 /* When all three operands are of the same mode. */
8846 if (mode0
== mode1
&& mode1
== mode2
)
8851 type
= opaque_ftype_opaque_opaque
;
8854 type
= v4sf_ftype_v4sf_v4sf
;
8857 type
= v4si_ftype_v4si_v4si
;
8860 type
= v16qi_ftype_v16qi_v16qi
;
8863 type
= v8hi_ftype_v8hi_v8hi
;
8866 type
= v2si_ftype_v2si_v2si
;
8869 type
= v2sf_ftype_v2sf_v2sf
;
8872 type
= int_ftype_int_int
;
8879 /* A few other combos we really don't want to do manually. */
8881 /* vint, vfloat, vfloat. */
8882 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
8883 type
= v4si_ftype_v4sf_v4sf
;
8885 /* vshort, vchar, vchar. */
8886 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
8887 type
= v8hi_ftype_v16qi_v16qi
;
8889 /* vint, vshort, vshort. */
8890 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
8891 type
= v4si_ftype_v8hi_v8hi
;
8893 /* vshort, vint, vint. */
8894 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
8895 type
= v8hi_ftype_v4si_v4si
;
8897 /* vchar, vshort, vshort. */
8898 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
8899 type
= v16qi_ftype_v8hi_v8hi
;
8901 /* vint, vchar, vint. */
8902 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
8903 type
= v4si_ftype_v16qi_v4si
;
8905 /* vint, vchar, vchar. */
8906 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
8907 type
= v4si_ftype_v16qi_v16qi
;
8909 /* vint, vshort, vint. */
8910 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
8911 type
= v4si_ftype_v8hi_v4si
;
8913 /* vint, vint, 5 bit literal. */
8914 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
8915 type
= v4si_ftype_v4si_int
;
8917 /* vshort, vshort, 5 bit literal. */
8918 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
8919 type
= v8hi_ftype_v8hi_int
;
8921 /* vchar, vchar, 5 bit literal. */
8922 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
8923 type
= v16qi_ftype_v16qi_int
;
8925 /* vfloat, vint, 5 bit literal. */
8926 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
8927 type
= v4sf_ftype_v4si_int
;
8929 /* vint, vfloat, 5 bit literal. */
8930 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
8931 type
= v4si_ftype_v4sf_int
;
8933 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
8934 type
= v2si_ftype_int_int
;
8936 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
8937 type
= v2si_ftype_v2si_char
;
8939 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
8940 type
= v2si_ftype_int_char
;
8945 gcc_assert (mode0
== SImode
);
8949 type
= int_ftype_v4si_v4si
;
8952 type
= int_ftype_v4sf_v4sf
;
8955 type
= int_ftype_v16qi_v16qi
;
8958 type
= int_ftype_v8hi_v8hi
;
8965 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8968 /* Add the simple unary operators. */
8969 d
= (struct builtin_description
*) bdesc_1arg
;
8970 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
8972 enum machine_mode mode0
, mode1
;
8974 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8975 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8984 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8987 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8988 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8991 if (mode0
== V4SImode
&& mode1
== QImode
)
8992 type
= v4si_ftype_int
;
8993 else if (mode0
== V8HImode
&& mode1
== QImode
)
8994 type
= v8hi_ftype_int
;
8995 else if (mode0
== V16QImode
&& mode1
== QImode
)
8996 type
= v16qi_ftype_int
;
8997 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
8998 type
= opaque_ftype_opaque
;
8999 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
9000 type
= v4sf_ftype_v4sf
;
9001 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
9002 type
= v8hi_ftype_v16qi
;
9003 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
9004 type
= v4si_ftype_v8hi
;
9005 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
9006 type
= v2si_ftype_v2si
;
9007 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
9008 type
= v2sf_ftype_v2sf
;
9009 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
9010 type
= v2sf_ftype_v2si
;
9011 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
9012 type
= v2si_ftype_v2sf
;
9013 else if (mode0
== V2SImode
&& mode1
== QImode
)
9014 type
= v2si_ftype_char
;
9018 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9023 rs6000_init_libfuncs (void)
9025 if (!TARGET_HARD_FLOAT
)
9028 if (DEFAULT_ABI
!= ABI_V4
)
9030 if (TARGET_XCOFF
&& ! TARGET_POWER2
&& ! TARGET_POWERPC
)
9032 /* AIX library routines for float->int conversion. */
9033 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
9034 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
9035 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
9036 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
9039 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9040 if (!TARGET_XL_COMPAT
)
9042 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
9043 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
9044 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
9045 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
9049 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
9050 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
9051 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
9052 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
9057 /* 32-bit SVR4 quad floating point routines. */
9059 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
9060 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
9061 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
9062 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
9063 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
9064 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
9065 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
9067 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
9068 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
9069 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
9070 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
9071 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
9072 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
9074 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
9075 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
9076 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
9077 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
9078 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
9079 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
9080 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
9085 /* Expand a block clear operation, and return 1 if successful. Return 0
9086 if we should let the compiler generate normal code.
9088 operands[0] is the destination
9089 operands[1] is the length
9090 operands[3] is the alignment */
9093 expand_block_clear (rtx operands
[])
9095 rtx orig_dest
= operands
[0];
9096 rtx bytes_rtx
= operands
[1];
9097 rtx align_rtx
= operands
[3];
9098 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9099 HOST_WIDE_INT align
;
9100 HOST_WIDE_INT bytes
;
9105 /* If this is not a fixed size move, just call memcpy */
9109 /* This must be a fixed size alignment */
9110 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9111 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9113 /* Anything to clear? */
9114 bytes
= INTVAL (bytes_rtx
);
9118 /* Use the builtin memset after a point, to avoid huge code bloat.
9119 When optimize_size, avoid any significant code bloat; calling
9120 memset is about 4 instructions, so allow for one instruction to
9121 load zero and three to do clearing. */
9122 if (TARGET_ALTIVEC
&& align
>= 128)
9124 else if (TARGET_POWERPC64
&& align
>= 32)
9129 if (optimize_size
&& bytes
> 3 * clear_step
)
9131 if (! optimize_size
&& bytes
> 8 * clear_step
)
9134 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
9136 enum machine_mode mode
= BLKmode
;
9139 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
9144 else if (bytes
>= 8 && TARGET_POWERPC64
9145 /* 64-bit loads and stores require word-aligned
9147 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9152 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9153 { /* move 4 bytes */
9157 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9158 { /* move 2 bytes */
9162 else /* move 1 byte at a time */
9168 dest
= adjust_address (orig_dest
, mode
, offset
);
9170 emit_move_insn (dest
, CONST0_RTX (mode
));
9177 /* Expand a block move operation, and return 1 if successful. Return 0
9178 if we should let the compiler generate normal code.
9180 operands[0] is the destination
9181 operands[1] is the source
9182 operands[2] is the length
9183 operands[3] is the alignment */
9185 #define MAX_MOVE_REG 4
9188 expand_block_move (rtx operands
[])
9190 rtx orig_dest
= operands
[0];
9191 rtx orig_src
= operands
[1];
9192 rtx bytes_rtx
= operands
[2];
9193 rtx align_rtx
= operands
[3];
9194 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9199 rtx stores
[MAX_MOVE_REG
];
9202 /* If this is not a fixed size move, just call memcpy */
9206 /* This must be a fixed size alignment */
9207 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9208 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9210 /* Anything to move? */
9211 bytes
= INTVAL (bytes_rtx
);
9215 /* store_one_arg depends on expand_block_move to handle at least the size of
9216 reg_parm_stack_space. */
9217 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
9220 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
9223 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
9224 rtx (*mov
) (rtx
, rtx
);
9226 enum machine_mode mode
= BLKmode
;
9229 /* Altivec first, since it will be faster than a string move
9230 when it applies, and usually not significantly larger. */
9231 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
9235 gen_func
.mov
= gen_movv4si
;
9237 else if (TARGET_STRING
9238 && bytes
> 24 /* move up to 32 bytes at a time */
9246 && ! fixed_regs
[12])
9248 move_bytes
= (bytes
> 32) ? 32 : bytes
;
9249 gen_func
.movmemsi
= gen_movmemsi_8reg
;
9251 else if (TARGET_STRING
9252 && bytes
> 16 /* move up to 24 bytes at a time */
9258 && ! fixed_regs
[10])
9260 move_bytes
= (bytes
> 24) ? 24 : bytes
;
9261 gen_func
.movmemsi
= gen_movmemsi_6reg
;
9263 else if (TARGET_STRING
9264 && bytes
> 8 /* move up to 16 bytes at a time */
9270 move_bytes
= (bytes
> 16) ? 16 : bytes
;
9271 gen_func
.movmemsi
= gen_movmemsi_4reg
;
9273 else if (bytes
>= 8 && TARGET_POWERPC64
9274 /* 64-bit loads and stores require word-aligned
9276 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9280 gen_func
.mov
= gen_movdi
;
9282 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
9283 { /* move up to 8 bytes at a time */
9284 move_bytes
= (bytes
> 8) ? 8 : bytes
;
9285 gen_func
.movmemsi
= gen_movmemsi_2reg
;
9287 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9288 { /* move 4 bytes */
9291 gen_func
.mov
= gen_movsi
;
9293 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9294 { /* move 2 bytes */
9297 gen_func
.mov
= gen_movhi
;
9299 else if (TARGET_STRING
&& bytes
> 1)
9300 { /* move up to 4 bytes at a time */
9301 move_bytes
= (bytes
> 4) ? 4 : bytes
;
9302 gen_func
.movmemsi
= gen_movmemsi_1reg
;
9304 else /* move 1 byte at a time */
9308 gen_func
.mov
= gen_movqi
;
9311 src
= adjust_address (orig_src
, mode
, offset
);
9312 dest
= adjust_address (orig_dest
, mode
, offset
);
9314 if (mode
!= BLKmode
)
9316 rtx tmp_reg
= gen_reg_rtx (mode
);
9318 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
9319 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
9322 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
9325 for (i
= 0; i
< num_reg
; i
++)
9326 emit_insn (stores
[i
]);
9330 if (mode
== BLKmode
)
9332 /* Move the address into scratch registers. The movmemsi
9333 patterns require zero offset. */
9334 if (!REG_P (XEXP (src
, 0)))
9336 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
9337 src
= replace_equiv_address (src
, src_reg
);
9339 set_mem_size (src
, GEN_INT (move_bytes
));
9341 if (!REG_P (XEXP (dest
, 0)))
9343 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
9344 dest
= replace_equiv_address (dest
, dest_reg
);
9346 set_mem_size (dest
, GEN_INT (move_bytes
));
9348 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
9349 GEN_INT (move_bytes
& 31),
9358 /* Return a string to perform a load_multiple operation.
9359 operands[0] is the vector.
9360 operands[1] is the source address.
9361 operands[2] is the first destination register. */
9364 rs6000_output_load_multiple (rtx operands
[3])
9366 /* We have to handle the case where the pseudo used to contain the address
9367 is assigned to one of the output registers. */
9369 int words
= XVECLEN (operands
[0], 0);
9372 if (XVECLEN (operands
[0], 0) == 1)
9373 return "{l|lwz} %2,0(%1)";
9375 for (i
= 0; i
< words
; i
++)
9376 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
9377 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
9381 xop
[0] = GEN_INT (4 * (words
-1));
9382 xop
[1] = operands
[1];
9383 xop
[2] = operands
[2];
9384 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
9389 xop
[0] = GEN_INT (4 * (words
-1));
9390 xop
[1] = operands
[1];
9391 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
9392 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
);
9397 for (j
= 0; j
< words
; j
++)
9400 xop
[0] = GEN_INT (j
* 4);
9401 xop
[1] = operands
[1];
9402 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
9403 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
9405 xop
[0] = GEN_INT (i
* 4);
9406 xop
[1] = operands
[1];
9407 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
9412 return "{lsi|lswi} %2,%1,%N0";
9416 /* A validation routine: say whether CODE, a condition code, and MODE
9417 match. The other alternatives either don't make sense or should
9418 never be generated. */
9421 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
9423 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
9424 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
9425 && GET_MODE_CLASS (mode
) == MODE_CC
);
9427 /* These don't make sense. */
9428 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
9429 || mode
!= CCUNSmode
);
9431 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
9432 || mode
== CCUNSmode
);
9434 gcc_assert (mode
== CCFPmode
9435 || (code
!= ORDERED
&& code
!= UNORDERED
9436 && code
!= UNEQ
&& code
!= LTGT
9437 && code
!= UNGT
&& code
!= UNLT
9438 && code
!= UNGE
&& code
!= UNLE
));
9440 /* These should never be generated except for
9441 flag_finite_math_only. */
9442 gcc_assert (mode
!= CCFPmode
9443 || flag_finite_math_only
9444 || (code
!= LE
&& code
!= GE
9445 && code
!= UNEQ
&& code
!= LTGT
9446 && code
!= UNGT
&& code
!= UNLT
));
9448 /* These are invalid; the information is not there. */
9449 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
9453 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9454 mask required to convert the result of a rotate insn into a shift
9455 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9458 includes_lshift_p (rtx shiftop
, rtx andop
)
9460 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
9462 shift_mask
<<= INTVAL (shiftop
);
9464 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
9467 /* Similar, but for right shift. */
9470 includes_rshift_p (rtx shiftop
, rtx andop
)
9472 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
9474 shift_mask
>>= INTVAL (shiftop
);
9476 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
9479 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9480 to perform a left shift. It must have exactly SHIFTOP least
9481 significant 0's, then one or more 1's, then zero or more 0's. */
9484 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
9486 if (GET_CODE (andop
) == CONST_INT
)
9488 HOST_WIDE_INT c
, lsb
, shift_mask
;
9491 if (c
== 0 || c
== ~0)
9495 shift_mask
<<= INTVAL (shiftop
);
9497 /* Find the least significant one bit. */
9500 /* It must coincide with the LSB of the shift mask. */
9501 if (-lsb
!= shift_mask
)
9504 /* Invert to look for the next transition (if any). */
9507 /* Remove the low group of ones (originally low group of zeros). */
9510 /* Again find the lsb, and check we have all 1's above. */
9514 else if (GET_CODE (andop
) == CONST_DOUBLE
9515 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
9517 HOST_WIDE_INT low
, high
, lsb
;
9518 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
9520 low
= CONST_DOUBLE_LOW (andop
);
9521 if (HOST_BITS_PER_WIDE_INT
< 64)
9522 high
= CONST_DOUBLE_HIGH (andop
);
9524 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
9525 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
9528 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
9530 shift_mask_high
= ~0;
9531 if (INTVAL (shiftop
) > 32)
9532 shift_mask_high
<<= INTVAL (shiftop
) - 32;
9536 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
9543 return high
== -lsb
;
9546 shift_mask_low
= ~0;
9547 shift_mask_low
<<= INTVAL (shiftop
);
9551 if (-lsb
!= shift_mask_low
)
9554 if (HOST_BITS_PER_WIDE_INT
< 64)
9559 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
9562 return high
== -lsb
;
9566 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
9572 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9573 to perform a left shift. It must have SHIFTOP or more least
9574 significant 0's, with the remainder of the word 1's. */
9577 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
9579 if (GET_CODE (andop
) == CONST_INT
)
9581 HOST_WIDE_INT c
, lsb
, shift_mask
;
9584 shift_mask
<<= INTVAL (shiftop
);
9587 /* Find the least significant one bit. */
9590 /* It must be covered by the shift mask.
9591 This test also rejects c == 0. */
9592 if ((lsb
& shift_mask
) == 0)
9595 /* Check we have all 1's above the transition, and reject all 1's. */
9596 return c
== -lsb
&& lsb
!= 1;
9598 else if (GET_CODE (andop
) == CONST_DOUBLE
9599 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
9601 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
9603 low
= CONST_DOUBLE_LOW (andop
);
9605 if (HOST_BITS_PER_WIDE_INT
< 64)
9607 HOST_WIDE_INT high
, shift_mask_high
;
9609 high
= CONST_DOUBLE_HIGH (andop
);
9613 shift_mask_high
= ~0;
9614 if (INTVAL (shiftop
) > 32)
9615 shift_mask_high
<<= INTVAL (shiftop
) - 32;
9619 if ((lsb
& shift_mask_high
) == 0)
9622 return high
== -lsb
;
9628 shift_mask_low
= ~0;
9629 shift_mask_low
<<= INTVAL (shiftop
);
9633 if ((lsb
& shift_mask_low
) == 0)
9636 return low
== -lsb
&& lsb
!= 1;
9642 /* Return 1 if operands will generate a valid arguments to rlwimi
9643 instruction for insert with right shift in 64-bit mode. The mask may
9644 not start on the first bit or stop on the last bit because wrap-around
9645 effects of instruction do not correspond to semantics of RTL insn. */
9648 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
9650 if (INTVAL (startop
) < 64
9651 && INTVAL (startop
) > 32
9652 && (INTVAL (sizeop
) + INTVAL (startop
) < 64)
9653 && (INTVAL (sizeop
) + INTVAL (startop
) > 33)
9654 && (INTVAL (sizeop
) + INTVAL (startop
) + INTVAL (shiftop
) < 96)
9655 && (INTVAL (sizeop
) + INTVAL (startop
) + INTVAL (shiftop
) >= 64)
9656 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
9662 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
9663 for lfq and stfq insns iff the registers are hard registers. */
9666 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
9668 /* We might have been passed a SUBREG. */
9669 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
9672 /* We might have been passed non floating point registers. */
9673 if (!FP_REGNO_P (REGNO (reg1
))
9674 || !FP_REGNO_P (REGNO (reg2
)))
9677 return (REGNO (reg1
) == REGNO (reg2
) - 1);
9680 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
9681 addr1 and addr2 must be in consecutive memory locations
9682 (addr2 == addr1 + 8). */
9685 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
9688 unsigned int reg1
, reg2
;
9689 int offset1
, offset2
;
9691 /* The mems cannot be volatile. */
9692 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
9695 addr1
= XEXP (mem1
, 0);
9696 addr2
= XEXP (mem2
, 0);
9698 /* Extract an offset (if used) from the first addr. */
9699 if (GET_CODE (addr1
) == PLUS
)
9701 /* If not a REG, return zero. */
9702 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
9706 reg1
= REGNO (XEXP (addr1
, 0));
9707 /* The offset must be constant! */
9708 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
9710 offset1
= INTVAL (XEXP (addr1
, 1));
9713 else if (GET_CODE (addr1
) != REG
)
9717 reg1
= REGNO (addr1
);
9718 /* This was a simple (mem (reg)) expression. Offset is 0. */
9722 /* And now for the second addr. */
9723 if (GET_CODE (addr2
) == PLUS
)
9725 /* If not a REG, return zero. */
9726 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
9730 reg2
= REGNO (XEXP (addr2
, 0));
9731 /* The offset must be constant. */
9732 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
9734 offset2
= INTVAL (XEXP (addr2
, 1));
9737 else if (GET_CODE (addr2
) != REG
)
9741 reg2
= REGNO (addr2
);
9742 /* This was a simple (mem (reg)) expression. Offset is 0. */
9746 /* Both of these must have the same base register. */
9750 /* The offset for the second addr must be 8 more than the first addr. */
9751 if (offset2
!= offset1
+ 8)
9754 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
9759 /* Return the register class of a scratch register needed to copy IN into
9760 or out of a register in CLASS in MODE. If it can be done directly,
9761 NO_REGS is returned. */
9764 rs6000_secondary_reload_class (enum reg_class
class,
9765 enum machine_mode mode ATTRIBUTE_UNUSED
,
9770 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
9772 && MACHOPIC_INDIRECT
9776 /* We cannot copy a symbolic operand directly into anything
9777 other than BASE_REGS for TARGET_ELF. So indicate that a
9778 register from BASE_REGS is needed as an intermediate
9781 On Darwin, pic addresses require a load from memory, which
9782 needs a base register. */
9783 if (class != BASE_REGS
9784 && (GET_CODE (in
) == SYMBOL_REF
9785 || GET_CODE (in
) == HIGH
9786 || GET_CODE (in
) == LABEL_REF
9787 || GET_CODE (in
) == CONST
))
9791 if (GET_CODE (in
) == REG
)
9794 if (regno
>= FIRST_PSEUDO_REGISTER
)
9796 regno
= true_regnum (in
);
9797 if (regno
>= FIRST_PSEUDO_REGISTER
)
9801 else if (GET_CODE (in
) == SUBREG
)
9803 regno
= true_regnum (in
);
9804 if (regno
>= FIRST_PSEUDO_REGISTER
)
9810 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
9812 if (class == GENERAL_REGS
|| class == BASE_REGS
9813 || (regno
>= 0 && INT_REGNO_P (regno
)))
9816 /* Constants, memory, and FP registers can go into FP registers. */
9817 if ((regno
== -1 || FP_REGNO_P (regno
))
9818 && (class == FLOAT_REGS
|| class == NON_SPECIAL_REGS
))
9821 /* Memory, and AltiVec registers can go into AltiVec registers. */
9822 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
9823 && class == ALTIVEC_REGS
)
9826 /* We can copy among the CR registers. */
9827 if ((class == CR_REGS
|| class == CR0_REGS
)
9828 && regno
>= 0 && CR_REGNO_P (regno
))
9831 /* Otherwise, we need GENERAL_REGS. */
9832 return GENERAL_REGS
;
9835 /* Given a comparison operation, return the bit number in CCR to test. We
9836 know this is a valid comparison.
9838 SCC_P is 1 if this is for an scc. That means that %D will have been
9839 used instead of %C, so the bits will be in different places.
9841 Return -1 if OP isn't a valid comparison for some reason. */
9844 ccr_bit (rtx op
, int scc_p
)
9846 enum rtx_code code
= GET_CODE (op
);
9847 enum machine_mode cc_mode
;
9852 if (!COMPARISON_P (op
))
9857 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
9859 cc_mode
= GET_MODE (reg
);
9860 cc_regnum
= REGNO (reg
);
9861 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
9863 validate_condition_mode (code
, cc_mode
);
9865 /* When generating a sCOND operation, only positive conditions are
9868 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
9869 || code
== GTU
|| code
== LTU
);
9874 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
9876 return base_bit
+ 2;
9877 case GT
: case GTU
: case UNLE
:
9878 return base_bit
+ 1;
9879 case LT
: case LTU
: case UNGE
:
9881 case ORDERED
: case UNORDERED
:
9882 return base_bit
+ 3;
9885 /* If scc, we will have done a cror to put the bit in the
9886 unordered position. So test that bit. For integer, this is ! LT
9887 unless this is an scc insn. */
9888 return scc_p
? base_bit
+ 3 : base_bit
;
9891 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
9898 /* Return the GOT register. */
9901 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
9903 /* The second flow pass currently (June 1999) can't update
9904 regs_ever_live without disturbing other parts of the compiler, so
9905 update it here to make the prolog/epilogue code happy. */
9906 if (no_new_pseudos
&& ! regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
])
9907 regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
9909 current_function_uses_pic_offset_table
= 1;
9911 return pic_offset_table_rtx
;
9914 /* Function to init struct machine_function.
9915 This will be called, via a pointer variable,
9916 from push_function_context. */
9918 static struct machine_function
*
9919 rs6000_init_machine_status (void)
9921 return ggc_alloc_cleared (sizeof (machine_function
));
9924 /* These macros test for integers and extract the low-order bits. */
9926 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
9927 && GET_MODE (X) == VOIDmode)
9929 #define INT_LOWPART(X) \
9930 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
9936 unsigned long val
= INT_LOWPART (op
);
9938 /* If the high bit is zero, the value is the first 1 bit we find
9940 if ((val
& 0x80000000) == 0)
9942 gcc_assert (val
& 0xffffffff);
9945 while (((val
<<= 1) & 0x80000000) == 0)
9950 /* If the high bit is set and the low bit is not, or the mask is all
9951 1's, the value is zero. */
9952 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
9955 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
9958 while (((val
>>= 1) & 1) != 0)
9968 unsigned long val
= INT_LOWPART (op
);
9970 /* If the low bit is zero, the value is the first 1 bit we find from
9974 gcc_assert (val
& 0xffffffff);
9977 while (((val
>>= 1) & 1) == 0)
9983 /* If the low bit is set and the high bit is not, or the mask is all
9984 1's, the value is 31. */
9985 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
9988 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
9991 while (((val
<<= 1) & 0x80000000) != 0)
9997 /* Locate some local-dynamic symbol still in use by this function
9998 so that we can print its name in some tls_ld pattern. */
10000 static const char *
10001 rs6000_get_some_local_dynamic_name (void)
10005 if (cfun
->machine
->some_ld_name
)
10006 return cfun
->machine
->some_ld_name
;
10008 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10010 && for_each_rtx (&PATTERN (insn
),
10011 rs6000_get_some_local_dynamic_name_1
, 0))
10012 return cfun
->machine
->some_ld_name
;
10014 gcc_unreachable ();
10017 /* Helper function for rs6000_get_some_local_dynamic_name. */
10020 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
10024 if (GET_CODE (x
) == SYMBOL_REF
)
10026 const char *str
= XSTR (x
, 0);
10027 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
10029 cfun
->machine
->some_ld_name
= str
;
10037 /* Write out a function code label. */
10040 rs6000_output_function_entry (FILE *file
, const char *fname
)
10042 if (fname
[0] != '.')
10044 switch (DEFAULT_ABI
)
10047 gcc_unreachable ();
10053 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
10062 RS6000_OUTPUT_BASENAME (file
, fname
);
10064 assemble_name (file
, fname
);
10067 /* Print an operand. Recognize special options, documented below. */
10070 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10071 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10073 #define SMALL_DATA_RELOC "sda21"
10074 #define SMALL_DATA_REG 0
10078 print_operand (FILE *file
, rtx x
, int code
)
10082 unsigned HOST_WIDE_INT uval
;
10087 /* Write out an instruction after the call which may be replaced
10088 with glue code by the loader. This depends on the AIX version. */
10089 asm_fprintf (file
, RS6000_CALL_GLUE
);
10092 /* %a is output_address. */
10095 /* If X is a constant integer whose low-order 5 bits are zero,
10096 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10097 in the AIX assembler where "sri" with a zero shift count
10098 writes a trash instruction. */
10099 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
10106 /* If constant, low-order 16 bits of constant, unsigned.
10107 Otherwise, write normally. */
10109 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
10111 print_operand (file
, x
, 0);
10115 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10116 for 64-bit mask direction. */
10117 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
10120 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10124 /* X is a CR register. Print the number of the GT bit of the CR. */
10125 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10126 output_operand_lossage ("invalid %%E value");
10128 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
10132 /* Like 'J' but get to the EQ bit. */
10133 gcc_assert (GET_CODE (x
) == REG
);
10135 /* Bit 1 is EQ bit. */
10136 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 2;
10138 fprintf (file
, "%d", i
);
10142 /* X is a CR register. Print the number of the EQ bit of the CR */
10143 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10144 output_operand_lossage ("invalid %%E value");
10146 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
10150 /* X is a CR register. Print the shift count needed to move it
10151 to the high-order four bits. */
10152 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10153 output_operand_lossage ("invalid %%f value");
10155 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
10159 /* Similar, but print the count for the rotate in the opposite
10161 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10162 output_operand_lossage ("invalid %%F value");
10164 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
10168 /* X is a constant integer. If it is negative, print "m",
10169 otherwise print "z". This is to make an aze or ame insn. */
10170 if (GET_CODE (x
) != CONST_INT
)
10171 output_operand_lossage ("invalid %%G value");
10172 else if (INTVAL (x
) >= 0)
10179 /* If constant, output low-order five bits. Otherwise, write
10182 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
10184 print_operand (file
, x
, 0);
10188 /* If constant, output low-order six bits. Otherwise, write
10191 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
10193 print_operand (file
, x
, 0);
10197 /* Print `i' if this is a constant, else nothing. */
10203 /* Write the bit number in CCR for jump. */
10204 i
= ccr_bit (x
, 0);
10206 output_operand_lossage ("invalid %%j code");
10208 fprintf (file
, "%d", i
);
10212 /* Similar, but add one for shift count in rlinm for scc and pass
10213 scc flag to `ccr_bit'. */
10214 i
= ccr_bit (x
, 1);
10216 output_operand_lossage ("invalid %%J code");
10218 /* If we want bit 31, write a shift count of zero, not 32. */
10219 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10223 /* X must be a constant. Write the 1's complement of the
10226 output_operand_lossage ("invalid %%k value");
10228 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
10232 /* X must be a symbolic constant on ELF. Write an
10233 expression suitable for an 'addi' that adds in the low 16
10234 bits of the MEM. */
10235 if (GET_CODE (x
) != CONST
)
10237 print_operand_address (file
, x
);
10238 fputs ("@l", file
);
10242 if (GET_CODE (XEXP (x
, 0)) != PLUS
10243 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
10244 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
10245 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
10246 output_operand_lossage ("invalid %%K value");
10247 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
10248 fputs ("@l", file
);
10249 /* For GNU as, there must be a non-alphanumeric character
10250 between 'l' and the number. The '-' is added by
10251 print_operand() already. */
10252 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
10254 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
10258 /* %l is output_asm_label. */
10261 /* Write second word of DImode or DFmode reference. Works on register
10262 or non-indexed memory only. */
10263 if (GET_CODE (x
) == REG
)
10264 fputs (reg_names
[REGNO (x
) + 1], file
);
10265 else if (GET_CODE (x
) == MEM
)
10267 /* Handle possible auto-increment. Since it is pre-increment and
10268 we have already done it, we can just use an offset of word. */
10269 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10270 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10271 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
10274 output_address (XEXP (adjust_address_nv (x
, SImode
,
10278 if (small_data_operand (x
, GET_MODE (x
)))
10279 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10280 reg_names
[SMALL_DATA_REG
]);
10285 /* MB value for a mask operand. */
10286 if (! mask_operand (x
, SImode
))
10287 output_operand_lossage ("invalid %%m value");
10289 fprintf (file
, "%d", extract_MB (x
));
10293 /* ME value for a mask operand. */
10294 if (! mask_operand (x
, SImode
))
10295 output_operand_lossage ("invalid %%M value");
10297 fprintf (file
, "%d", extract_ME (x
));
10300 /* %n outputs the negative of its operand. */
10303 /* Write the number of elements in the vector times 4. */
10304 if (GET_CODE (x
) != PARALLEL
)
10305 output_operand_lossage ("invalid %%N value");
10307 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
10311 /* Similar, but subtract 1 first. */
10312 if (GET_CODE (x
) != PARALLEL
)
10313 output_operand_lossage ("invalid %%O value");
10315 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
10319 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10321 || INT_LOWPART (x
) < 0
10322 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
10323 output_operand_lossage ("invalid %%p value");
10325 fprintf (file
, "%d", i
);
10329 /* The operand must be an indirect memory reference. The result
10330 is the register name. */
10331 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
10332 || REGNO (XEXP (x
, 0)) >= 32)
10333 output_operand_lossage ("invalid %%P value");
10335 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
10339 /* This outputs the logical code corresponding to a boolean
10340 expression. The expression may have one or both operands
10341 negated (if one, only the first one). For condition register
10342 logical operations, it will also treat the negated
10343 CR codes as NOTs, but not handle NOTs of them. */
10345 const char *const *t
= 0;
10347 enum rtx_code code
= GET_CODE (x
);
10348 static const char * const tbl
[3][3] = {
10349 { "and", "andc", "nor" },
10350 { "or", "orc", "nand" },
10351 { "xor", "eqv", "xor" } };
10355 else if (code
== IOR
)
10357 else if (code
== XOR
)
10360 output_operand_lossage ("invalid %%q value");
10362 if (GET_CODE (XEXP (x
, 0)) != NOT
)
10366 if (GET_CODE (XEXP (x
, 1)) == NOT
)
10384 /* X is a CR register. Print the mask for `mtcrf'. */
10385 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10386 output_operand_lossage ("invalid %%R value");
10388 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
10392 /* Low 5 bits of 32 - value */
10394 output_operand_lossage ("invalid %%s value");
10396 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
10400 /* PowerPC64 mask position. All 0's is excluded.
10401 CONST_INT 32-bit mask is considered sign-extended so any
10402 transition must occur within the CONST_INT, not on the boundary. */
10403 if (! mask64_operand (x
, DImode
))
10404 output_operand_lossage ("invalid %%S value");
10406 uval
= INT_LOWPART (x
);
10408 if (uval
& 1) /* Clear Left */
10410 #if HOST_BITS_PER_WIDE_INT > 64
10411 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10415 else /* Clear Right */
10418 #if HOST_BITS_PER_WIDE_INT > 64
10419 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10425 gcc_assert (i
>= 0);
10426 fprintf (file
, "%d", i
);
10430 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10431 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
10433 /* Bit 3 is OV bit. */
10434 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
10436 /* If we want bit 31, write a shift count of zero, not 32. */
10437 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10441 /* Print the symbolic name of a branch target register. */
10442 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LINK_REGISTER_REGNUM
10443 && REGNO (x
) != COUNT_REGISTER_REGNUM
))
10444 output_operand_lossage ("invalid %%T value");
10445 else if (REGNO (x
) == LINK_REGISTER_REGNUM
)
10446 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
10448 fputs ("ctr", file
);
10452 /* High-order 16 bits of constant for use in unsigned operand. */
10454 output_operand_lossage ("invalid %%u value");
10456 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
10457 (INT_LOWPART (x
) >> 16) & 0xffff);
10461 /* High-order 16 bits of constant for use in signed operand. */
10463 output_operand_lossage ("invalid %%v value");
10465 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
10466 (INT_LOWPART (x
) >> 16) & 0xffff);
10470 /* Print `u' if this has an auto-increment or auto-decrement. */
10471 if (GET_CODE (x
) == MEM
10472 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
10473 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
))
10478 /* Print the trap code for this operand. */
10479 switch (GET_CODE (x
))
10482 fputs ("eq", file
); /* 4 */
10485 fputs ("ne", file
); /* 24 */
10488 fputs ("lt", file
); /* 16 */
10491 fputs ("le", file
); /* 20 */
10494 fputs ("gt", file
); /* 8 */
10497 fputs ("ge", file
); /* 12 */
10500 fputs ("llt", file
); /* 2 */
10503 fputs ("lle", file
); /* 6 */
10506 fputs ("lgt", file
); /* 1 */
10509 fputs ("lge", file
); /* 5 */
10512 gcc_unreachable ();
10517 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10520 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
10521 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
10523 print_operand (file
, x
, 0);
10527 /* MB value for a PowerPC64 rldic operand. */
10528 val
= (GET_CODE (x
) == CONST_INT
10529 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
10534 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
10535 if ((val
<<= 1) < 0)
10538 #if HOST_BITS_PER_WIDE_INT == 32
10539 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
10540 i
+= 32; /* zero-extend high-part was all 0's */
10541 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
10543 val
= CONST_DOUBLE_LOW (x
);
10549 for ( ; i
< 64; i
++)
10550 if ((val
<<= 1) < 0)
10555 fprintf (file
, "%d", i
+ 1);
10559 if (GET_CODE (x
) == MEM
10560 && legitimate_indexed_address_p (XEXP (x
, 0), 0))
10565 /* Like 'L', for third word of TImode */
10566 if (GET_CODE (x
) == REG
)
10567 fputs (reg_names
[REGNO (x
) + 2], file
);
10568 else if (GET_CODE (x
) == MEM
)
10570 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10571 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10572 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
10574 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
10575 if (small_data_operand (x
, GET_MODE (x
)))
10576 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10577 reg_names
[SMALL_DATA_REG
]);
10582 /* X is a SYMBOL_REF. Write out the name preceded by a
10583 period and without any trailing data in brackets. Used for function
10584 names. If we are configured for System V (or the embedded ABI) on
10585 the PowerPC, do not emit the period, since those systems do not use
10586 TOCs and the like. */
10587 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
10589 /* Mark the decl as referenced so that cgraph will output the
10591 if (SYMBOL_REF_DECL (x
))
10592 mark_decl_referenced (SYMBOL_REF_DECL (x
));
10594 /* For macho, check to see if we need a stub. */
10597 const char *name
= XSTR (x
, 0);
10599 if (MACHOPIC_INDIRECT
10600 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
10601 name
= machopic_indirection_name (x
, /*stub_p=*/true);
10603 assemble_name (file
, name
);
10605 else if (!DOT_SYMBOLS
)
10606 assemble_name (file
, XSTR (x
, 0));
10608 rs6000_output_function_entry (file
, XSTR (x
, 0));
10612 /* Like 'L', for last word of TImode. */
10613 if (GET_CODE (x
) == REG
)
10614 fputs (reg_names
[REGNO (x
) + 3], file
);
10615 else if (GET_CODE (x
) == MEM
)
10617 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10618 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10619 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
10621 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
10622 if (small_data_operand (x
, GET_MODE (x
)))
10623 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10624 reg_names
[SMALL_DATA_REG
]);
10628 /* Print AltiVec or SPE memory operand. */
10633 gcc_assert (GET_CODE (x
) == MEM
);
10639 /* Handle [reg]. */
10640 if (GET_CODE (tmp
) == REG
)
10642 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
10645 /* Handle [reg+UIMM]. */
10646 else if (GET_CODE (tmp
) == PLUS
&&
10647 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
10651 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
10653 x
= INTVAL (XEXP (tmp
, 1));
10654 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
10658 /* Fall through. Must be [reg+reg]. */
10661 && GET_CODE (tmp
) == AND
10662 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
10663 && INTVAL (XEXP (tmp
, 1)) == -16)
10664 tmp
= XEXP (tmp
, 0);
10665 if (GET_CODE (tmp
) == REG
)
10666 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
10669 gcc_assert (GET_CODE (tmp
) == PLUS
10670 && GET_CODE (XEXP (tmp
, 1)) == REG
);
10672 if (REGNO (XEXP (tmp
, 0)) == 0)
10673 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
10674 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
10676 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
10677 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
10683 if (GET_CODE (x
) == REG
)
10684 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
10685 else if (GET_CODE (x
) == MEM
)
10687 /* We need to handle PRE_INC and PRE_DEC here, since we need to
10688 know the width from the mode. */
10689 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
10690 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
10691 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
10692 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10693 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
10694 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
10696 output_address (XEXP (x
, 0));
10699 output_addr_const (file
, x
);
10703 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
10707 output_operand_lossage ("invalid %%xn code");
10711 /* Print the address of an operand. */
10714 print_operand_address (FILE *file
, rtx x
)
10716 if (GET_CODE (x
) == REG
)
10717 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
10718 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
10719 || GET_CODE (x
) == LABEL_REF
)
10721 output_addr_const (file
, x
);
10722 if (small_data_operand (x
, GET_MODE (x
)))
10723 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10724 reg_names
[SMALL_DATA_REG
]);
10726 gcc_assert (!TARGET_TOC
);
10728 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
10730 if (REGNO (XEXP (x
, 0)) == 0)
10731 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
10732 reg_names
[ REGNO (XEXP (x
, 0)) ]);
10734 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
10735 reg_names
[ REGNO (XEXP (x
, 1)) ]);
10737 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
10738 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
10739 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
10741 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
10742 && CONSTANT_P (XEXP (x
, 1)))
10744 output_addr_const (file
, XEXP (x
, 1));
10745 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
10749 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
10750 && CONSTANT_P (XEXP (x
, 1)))
10752 fprintf (file
, "lo16(");
10753 output_addr_const (file
, XEXP (x
, 1));
10754 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
10757 else if (legitimate_constant_pool_address_p (x
))
10759 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
10761 rtx contains_minus
= XEXP (x
, 1);
10765 /* Find the (minus (sym) (toc)) buried in X, and temporarily
10766 turn it into (sym) for output_addr_const. */
10767 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
10768 contains_minus
= XEXP (contains_minus
, 0);
10770 minus
= XEXP (contains_minus
, 0);
10771 symref
= XEXP (minus
, 0);
10772 XEXP (contains_minus
, 0) = symref
;
10777 name
= XSTR (symref
, 0);
10778 newname
= alloca (strlen (name
) + sizeof ("@toc"));
10779 strcpy (newname
, name
);
10780 strcat (newname
, "@toc");
10781 XSTR (symref
, 0) = newname
;
10783 output_addr_const (file
, XEXP (x
, 1));
10785 XSTR (symref
, 0) = name
;
10786 XEXP (contains_minus
, 0) = minus
;
10789 output_addr_const (file
, XEXP (x
, 1));
10791 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
10794 gcc_unreachable ();
10797 /* Target hook for assembling integer objects. The PowerPC version has
10798 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
10799 is defined. It also needs to handle DI-mode objects on 64-bit
10803 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
10805 #ifdef RELOCATABLE_NEEDS_FIXUP
10806 /* Special handling for SI values. */
10807 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
10809 extern int in_toc_section (void);
10810 static int recurse
= 0;
10812 /* For -mrelocatable, we mark all addresses that need to be fixed up
10813 in the .fixup section. */
10814 if (TARGET_RELOCATABLE
10815 && !in_toc_section ()
10816 && !in_text_section ()
10817 && !in_unlikely_text_section ()
10819 && GET_CODE (x
) != CONST_INT
10820 && GET_CODE (x
) != CONST_DOUBLE
10826 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
10828 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
10829 fprintf (asm_out_file
, "\t.long\t(");
10830 output_addr_const (asm_out_file
, x
);
10831 fprintf (asm_out_file
, ")@fixup\n");
10832 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
10833 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
10834 fprintf (asm_out_file
, "\t.long\t");
10835 assemble_name (asm_out_file
, buf
);
10836 fprintf (asm_out_file
, "\n\t.previous\n");
10840 /* Remove initial .'s to turn a -mcall-aixdesc function
10841 address into the address of the descriptor, not the function
10843 else if (GET_CODE (x
) == SYMBOL_REF
10844 && XSTR (x
, 0)[0] == '.'
10845 && DEFAULT_ABI
== ABI_AIX
)
10847 const char *name
= XSTR (x
, 0);
10848 while (*name
== '.')
10851 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
10855 #endif /* RELOCATABLE_NEEDS_FIXUP */
10856 return default_assemble_integer (x
, size
, aligned_p
);
10859 #ifdef HAVE_GAS_HIDDEN
10860 /* Emit an assembler directive to set symbol visibility for DECL to
10861 VISIBILITY_TYPE. */
10864 rs6000_assemble_visibility (tree decl
, int vis
)
10866 /* Functions need to have their entry point symbol visibility set as
10867 well as their descriptor symbol visibility. */
10868 if (DEFAULT_ABI
== ABI_AIX
10870 && TREE_CODE (decl
) == FUNCTION_DECL
)
10872 static const char * const visibility_types
[] = {
10873 NULL
, "internal", "hidden", "protected"
10876 const char *name
, *type
;
10878 name
= ((* targetm
.strip_name_encoding
)
10879 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
10880 type
= visibility_types
[vis
];
10882 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
10883 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
10886 default_assemble_visibility (decl
, vis
);
10891 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
10893 /* Reversal of FP compares takes care -- an ordered compare
10894 becomes an unordered compare and vice versa. */
10895 if (mode
== CCFPmode
10896 && (!flag_finite_math_only
10897 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
10898 || code
== UNEQ
|| code
== LTGT
))
10899 return reverse_condition_maybe_unordered (code
);
10901 return reverse_condition (code
);
10904 /* Generate a compare for CODE. Return a brand-new rtx that
10905 represents the result of the compare. */
10908 rs6000_generate_compare (enum rtx_code code
)
10910 enum machine_mode comp_mode
;
10911 rtx compare_result
;
10913 if (rs6000_compare_fp_p
)
10914 comp_mode
= CCFPmode
;
10915 else if (code
== GTU
|| code
== LTU
10916 || code
== GEU
|| code
== LEU
)
10917 comp_mode
= CCUNSmode
;
10918 else if ((code
== EQ
|| code
== NE
)
10919 && GET_CODE (rs6000_compare_op0
) == SUBREG
10920 && GET_CODE (rs6000_compare_op1
) == SUBREG
10921 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
10922 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
10923 /* These are unsigned values, perhaps there will be a later
10924 ordering compare that can be shared with this one.
10925 Unfortunately we cannot detect the signedness of the operands
10926 for non-subregs. */
10927 comp_mode
= CCUNSmode
;
10929 comp_mode
= CCmode
;
10931 /* First, the compare. */
10932 compare_result
= gen_reg_rtx (comp_mode
);
10934 /* SPE FP compare instructions on the GPRs. Yuck! */
10935 if ((TARGET_E500
&& !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
10936 && rs6000_compare_fp_p
)
10938 rtx cmp
, or_result
, compare_result2
;
10939 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
10941 if (op_mode
== VOIDmode
)
10942 op_mode
= GET_MODE (rs6000_compare_op1
);
10944 /* Note: The E500 comparison instructions set the GT bit (x +
10945 1), on success. This explains the mess. */
10949 case EQ
: case UNEQ
: case NE
: case LTGT
:
10953 cmp
= flag_unsafe_math_optimizations
10954 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
10955 rs6000_compare_op1
)
10956 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
10957 rs6000_compare_op1
);
10961 cmp
= flag_unsafe_math_optimizations
10962 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
10963 rs6000_compare_op1
)
10964 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
10965 rs6000_compare_op1
);
10969 gcc_unreachable ();
10973 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
10977 cmp
= flag_unsafe_math_optimizations
10978 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
10979 rs6000_compare_op1
)
10980 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
10981 rs6000_compare_op1
);
10985 cmp
= flag_unsafe_math_optimizations
10986 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
10987 rs6000_compare_op1
)
10988 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
10989 rs6000_compare_op1
);
10993 gcc_unreachable ();
10997 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
11001 cmp
= flag_unsafe_math_optimizations
11002 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
11003 rs6000_compare_op1
)
11004 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
11005 rs6000_compare_op1
);
11009 cmp
= flag_unsafe_math_optimizations
11010 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
11011 rs6000_compare_op1
)
11012 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
11013 rs6000_compare_op1
);
11017 gcc_unreachable ();
11021 gcc_unreachable ();
11024 /* Synthesize LE and GE from LT/GT || EQ. */
11025 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
11031 case LE
: code
= LT
; break;
11032 case GE
: code
= GT
; break;
11033 case LEU
: code
= LT
; break;
11034 case GEU
: code
= GT
; break;
11035 default: gcc_unreachable ();
11038 compare_result2
= gen_reg_rtx (CCFPmode
);
11044 cmp
= flag_unsafe_math_optimizations
11045 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11046 rs6000_compare_op1
)
11047 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11048 rs6000_compare_op1
);
11052 cmp
= flag_unsafe_math_optimizations
11053 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11054 rs6000_compare_op1
)
11055 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11056 rs6000_compare_op1
);
11060 gcc_unreachable ();
11064 /* OR them together. */
11065 or_result
= gen_reg_rtx (CCFPmode
);
11066 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
11068 compare_result
= or_result
;
11073 if (code
== NE
|| code
== LTGT
)
11083 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11084 CLOBBERs to match cmptf_internal2 pattern. */
11085 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
11086 && GET_MODE (rs6000_compare_op0
) == TFmode
11087 && (DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_DARWIN
)
11088 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
11089 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
11091 gen_rtx_SET (VOIDmode
,
11093 gen_rtx_COMPARE (comp_mode
,
11094 rs6000_compare_op0
,
11095 rs6000_compare_op1
)),
11096 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11097 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11098 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11099 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11100 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11101 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11102 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11103 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
11104 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
11105 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
11107 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
11108 comp_mode
= CCEQmode
;
11109 compare_result
= gen_reg_rtx (CCEQmode
);
11111 emit_insn (gen_stack_protect_testdi (compare_result
,
11112 rs6000_compare_op0
, op1
));
11114 emit_insn (gen_stack_protect_testsi (compare_result
,
11115 rs6000_compare_op0
, op1
));
11118 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
11119 gen_rtx_COMPARE (comp_mode
,
11120 rs6000_compare_op0
,
11121 rs6000_compare_op1
)));
11124 /* Some kinds of FP comparisons need an OR operation;
11125 under flag_finite_math_only we don't bother. */
11126 if (rs6000_compare_fp_p
11127 && !flag_finite_math_only
11128 && !(TARGET_HARD_FLOAT
&& TARGET_E500
&& !TARGET_FPRS
)
11129 && (code
== LE
|| code
== GE
11130 || code
== UNEQ
|| code
== LTGT
11131 || code
== UNGT
|| code
== UNLT
))
11133 enum rtx_code or1
, or2
;
11134 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
11135 rtx or_result
= gen_reg_rtx (CCEQmode
);
11139 case LE
: or1
= LT
; or2
= EQ
; break;
11140 case GE
: or1
= GT
; or2
= EQ
; break;
11141 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
11142 case LTGT
: or1
= LT
; or2
= GT
; break;
11143 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
11144 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
11145 default: gcc_unreachable ();
11147 validate_condition_mode (or1
, comp_mode
);
11148 validate_condition_mode (or2
, comp_mode
);
11149 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
11150 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
11151 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
11152 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
11154 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
11156 compare_result
= or_result
;
11160 validate_condition_mode (code
, GET_MODE (compare_result
));
11162 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
11166 /* Emit the RTL for an sCOND pattern. */
11169 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
11172 enum machine_mode op_mode
;
11173 enum rtx_code cond_code
;
11175 condition_rtx
= rs6000_generate_compare (code
);
11176 cond_code
= GET_CODE (condition_rtx
);
11178 if (TARGET_E500
&& rs6000_compare_fp_p
11179 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
11183 PUT_MODE (condition_rtx
, SImode
);
11184 t
= XEXP (condition_rtx
, 0);
11186 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
11188 if (cond_code
== NE
)
11189 emit_insn (gen_e500_flip_gt_bit (t
, t
));
11191 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
11195 if (cond_code
== NE
11196 || cond_code
== GE
|| cond_code
== LE
11197 || cond_code
== GEU
|| cond_code
== LEU
11198 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
11200 rtx not_result
= gen_reg_rtx (CCEQmode
);
11201 rtx not_op
, rev_cond_rtx
;
11202 enum machine_mode cc_mode
;
11204 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
11206 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
11207 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
11208 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
11209 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
11210 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
11213 op_mode
= GET_MODE (rs6000_compare_op0
);
11214 if (op_mode
== VOIDmode
)
11215 op_mode
= GET_MODE (rs6000_compare_op1
);
11217 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
11219 PUT_MODE (condition_rtx
, DImode
);
11220 convert_move (result
, condition_rtx
, 0);
11224 PUT_MODE (condition_rtx
, SImode
);
11225 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
11229 /* Emit a branch of kind CODE to location LOC. */
11232 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
11234 rtx condition_rtx
, loc_ref
;
11236 condition_rtx
= rs6000_generate_compare (code
);
11237 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
11238 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
11239 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
11240 loc_ref
, pc_rtx
)));
11243 /* Return the string to output a conditional branch to LABEL, which is
11244 the operand number of the label, or -1 if the branch is really a
11245 conditional return.
11247 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11248 condition code register and its mode specifies what kind of
11249 comparison we made.
11251 REVERSED is nonzero if we should reverse the sense of the comparison.
11253 INSN is the insn. */
11256 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
11258 static char string
[64];
11259 enum rtx_code code
= GET_CODE (op
);
11260 rtx cc_reg
= XEXP (op
, 0);
11261 enum machine_mode mode
= GET_MODE (cc_reg
);
11262 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
11263 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
11264 int really_reversed
= reversed
^ need_longbranch
;
11270 validate_condition_mode (code
, mode
);
11272 /* Work out which way this really branches. We could use
11273 reverse_condition_maybe_unordered here always but this
11274 makes the resulting assembler clearer. */
11275 if (really_reversed
)
11277 /* Reversal of FP compares takes care -- an ordered compare
11278 becomes an unordered compare and vice versa. */
11279 if (mode
== CCFPmode
)
11280 code
= reverse_condition_maybe_unordered (code
);
11282 code
= reverse_condition (code
);
11285 if ((TARGET_E500
&& !TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
11287 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11292 /* Opposite of GT. */
11301 gcc_unreachable ();
11307 /* Not all of these are actually distinct opcodes, but
11308 we distinguish them for clarity of the resulting assembler. */
11309 case NE
: case LTGT
:
11310 ccode
= "ne"; break;
11311 case EQ
: case UNEQ
:
11312 ccode
= "eq"; break;
11314 ccode
= "ge"; break;
11315 case GT
: case GTU
: case UNGT
:
11316 ccode
= "gt"; break;
11318 ccode
= "le"; break;
11319 case LT
: case LTU
: case UNLT
:
11320 ccode
= "lt"; break;
11321 case UNORDERED
: ccode
= "un"; break;
11322 case ORDERED
: ccode
= "nu"; break;
11323 case UNGE
: ccode
= "nl"; break;
11324 case UNLE
: ccode
= "ng"; break;
11326 gcc_unreachable ();
11329 /* Maybe we have a guess as to how likely the branch is.
11330 The old mnemonics don't have a way to specify this information. */
11332 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
11333 if (note
!= NULL_RTX
)
11335 /* PROB is the difference from 50%. */
11336 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
11338 /* Only hint for highly probable/improbable branches on newer
11339 cpus as static prediction overrides processor dynamic
11340 prediction. For older cpus we may as well always hint, but
11341 assume not taken for branches that are very close to 50% as a
11342 mispredicted taken branch is more expensive than a
11343 mispredicted not-taken branch. */
11344 if (rs6000_always_hint
11345 || abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48)
11347 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
11348 && ((prob
> 0) ^ need_longbranch
))
11356 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
11358 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
11360 /* We need to escape any '%' characters in the reg_names string.
11361 Assume they'd only be the first character.... */
11362 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
11364 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
11368 /* If the branch distance was too far, we may have to use an
11369 unconditional branch to go the distance. */
11370 if (need_longbranch
)
11371 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
11373 s
+= sprintf (s
, ",%s", label
);
11379 /* Return the string to flip the GT bit on a CR. */
11381 output_e500_flip_gt_bit (rtx dst
, rtx src
)
11383 static char string
[64];
11386 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
11387 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
11390 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
11391 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
11393 sprintf (string
, "crnot %d,%d", a
, b
);
11397 /* Return insn index for the vector compare instruction for given CODE,
11398 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11402 get_vec_cmp_insn (enum rtx_code code
,
11403 enum machine_mode dest_mode
,
11404 enum machine_mode op_mode
)
11406 if (!TARGET_ALTIVEC
)
11407 return INSN_NOT_AVAILABLE
;
11412 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11413 return UNSPEC_VCMPEQUB
;
11414 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11415 return UNSPEC_VCMPEQUH
;
11416 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11417 return UNSPEC_VCMPEQUW
;
11418 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11419 return UNSPEC_VCMPEQFP
;
11422 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11423 return UNSPEC_VCMPGEFP
;
11425 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11426 return UNSPEC_VCMPGTSB
;
11427 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11428 return UNSPEC_VCMPGTSH
;
11429 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11430 return UNSPEC_VCMPGTSW
;
11431 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11432 return UNSPEC_VCMPGTFP
;
11435 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11436 return UNSPEC_VCMPGTUB
;
11437 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11438 return UNSPEC_VCMPGTUH
;
11439 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11440 return UNSPEC_VCMPGTUW
;
11445 return INSN_NOT_AVAILABLE
;
11448 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11449 DMODE is expected destination mode. This is a recursive function. */
11452 rs6000_emit_vector_compare (enum rtx_code rcode
,
11454 enum machine_mode dmode
)
11458 enum machine_mode dest_mode
;
11459 enum machine_mode op_mode
= GET_MODE (op1
);
11461 gcc_assert (TARGET_ALTIVEC
);
11462 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
11464 /* Floating point vector compare instructions uses destination V4SImode.
11465 Move destination to appropriate mode later. */
11466 if (dmode
== V4SFmode
)
11467 dest_mode
= V4SImode
;
11471 mask
= gen_reg_rtx (dest_mode
);
11472 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
11474 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
11476 bool swap_operands
= false;
11477 bool try_again
= false;
11482 swap_operands
= true;
11487 swap_operands
= true;
11491 /* Treat A != B as ~(A==B). */
11493 enum insn_code nor_code
;
11494 rtx eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
11497 nor_code
= one_cmpl_optab
->handlers
[(int)dest_mode
].insn_code
;
11498 gcc_assert (nor_code
!= CODE_FOR_nothing
);
11499 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
11501 if (dmode
!= dest_mode
)
11503 rtx temp
= gen_reg_rtx (dest_mode
);
11504 convert_move (temp
, mask
, 0);
11514 /* Try GT/GTU/LT/LTU OR EQ */
11517 enum insn_code ior_code
;
11518 enum rtx_code new_code
;
11539 gcc_unreachable ();
11542 c_rtx
= rs6000_emit_vector_compare (new_code
,
11543 op0
, op1
, dest_mode
);
11544 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
11547 ior_code
= ior_optab
->handlers
[(int)dest_mode
].insn_code
;
11548 gcc_assert (ior_code
!= CODE_FOR_nothing
);
11549 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
11550 if (dmode
!= dest_mode
)
11552 rtx temp
= gen_reg_rtx (dest_mode
);
11553 convert_move (temp
, mask
, 0);
11560 gcc_unreachable ();
11565 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
11566 /* You only get two chances. */
11567 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
11579 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
11580 gen_rtx_UNSPEC (dest_mode
,
11581 gen_rtvec (2, op0
, op1
),
11583 if (dmode
!= dest_mode
)
11585 rtx temp
= gen_reg_rtx (dest_mode
);
11586 convert_move (temp
, mask
, 0);
11592 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
11593 valid insn doesn exist for given mode. */
11596 get_vsel_insn (enum machine_mode mode
)
11601 return UNSPEC_VSEL4SI
;
11604 return UNSPEC_VSEL4SF
;
11607 return UNSPEC_VSEL8HI
;
11610 return UNSPEC_VSEL16QI
;
11613 return INSN_NOT_AVAILABLE
;
11616 return INSN_NOT_AVAILABLE
;
11619 /* Emit vector select insn where DEST is destination using
11620 operands OP1, OP2 and MASK. */
11623 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
11626 enum machine_mode dest_mode
= GET_MODE (dest
);
11627 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
11629 temp
= gen_reg_rtx (dest_mode
);
11631 /* For each vector element, select op1 when mask is 1 otherwise
11633 t
= gen_rtx_SET (VOIDmode
, temp
,
11634 gen_rtx_UNSPEC (dest_mode
,
11635 gen_rtvec (3, op2
, op1
, mask
),
11638 emit_move_insn (dest
, temp
);
11642 /* Emit vector conditional expression.
11643 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
11644 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
11647 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
11648 rtx cond
, rtx cc_op0
, rtx cc_op1
)
11650 enum machine_mode dest_mode
= GET_MODE (dest
);
11651 enum rtx_code rcode
= GET_CODE (cond
);
11654 if (!TARGET_ALTIVEC
)
11657 /* Get the vector mask for the given relational operations. */
11658 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
11660 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
11665 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
11666 operands of the last comparison is nonzero/true, FALSE_COND if it
11667 is zero/false. Return 0 if the hardware has no such operation. */
11670 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
11672 enum rtx_code code
= GET_CODE (op
);
11673 rtx op0
= rs6000_compare_op0
;
11674 rtx op1
= rs6000_compare_op1
;
11675 REAL_VALUE_TYPE c1
;
11676 enum machine_mode compare_mode
= GET_MODE (op0
);
11677 enum machine_mode result_mode
= GET_MODE (dest
);
11679 bool is_against_zero
;
11681 /* These modes should always match. */
11682 if (GET_MODE (op1
) != compare_mode
11683 /* In the isel case however, we can use a compare immediate, so
11684 op1 may be a small constant. */
11685 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
11687 if (GET_MODE (true_cond
) != result_mode
)
11689 if (GET_MODE (false_cond
) != result_mode
)
11692 /* First, work out if the hardware can do this at all, or
11693 if it's too slow.... */
11694 if (! rs6000_compare_fp_p
)
11697 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
11700 else if (TARGET_E500
&& TARGET_HARD_FLOAT
&& !TARGET_FPRS
11701 && SCALAR_FLOAT_MODE_P (compare_mode
))
11704 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
11706 /* A floating-point subtract might overflow, underflow, or produce
11707 an inexact result, thus changing the floating-point flags, so it
11708 can't be generated if we care about that. It's safe if one side
11709 of the construct is zero, since then no subtract will be
11711 if (SCALAR_FLOAT_MODE_P (compare_mode
)
11712 && flag_trapping_math
&& ! is_against_zero
)
11715 /* Eliminate half of the comparisons by switching operands, this
11716 makes the remaining code simpler. */
11717 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
11718 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
11720 code
= reverse_condition_maybe_unordered (code
);
11722 true_cond
= false_cond
;
11726 /* UNEQ and LTGT take four instructions for a comparison with zero,
11727 it'll probably be faster to use a branch here too. */
11728 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
11731 if (GET_CODE (op1
) == CONST_DOUBLE
)
11732 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
11734 /* We're going to try to implement comparisons by performing
11735 a subtract, then comparing against zero. Unfortunately,
11736 Inf - Inf is NaN which is not zero, and so if we don't
11737 know that the operand is finite and the comparison
11738 would treat EQ different to UNORDERED, we can't do it. */
11739 if (HONOR_INFINITIES (compare_mode
)
11740 && code
!= GT
&& code
!= UNGE
11741 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
11742 /* Constructs of the form (a OP b ? a : b) are safe. */
11743 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
11744 || (! rtx_equal_p (op0
, true_cond
)
11745 && ! rtx_equal_p (op1
, true_cond
))))
11748 /* At this point we know we can use fsel. */
11750 /* Reduce the comparison to a comparison against zero. */
11751 if (! is_against_zero
)
11753 temp
= gen_reg_rtx (compare_mode
);
11754 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11755 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
11757 op1
= CONST0_RTX (compare_mode
);
11760 /* If we don't care about NaNs we can reduce some of the comparisons
11761 down to faster ones. */
11762 if (! HONOR_NANS (compare_mode
))
11768 true_cond
= false_cond
;
11781 /* Now, reduce everything down to a GE. */
11788 temp
= gen_reg_rtx (compare_mode
);
11789 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11794 temp
= gen_reg_rtx (compare_mode
);
11795 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
11800 temp
= gen_reg_rtx (compare_mode
);
11801 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11802 gen_rtx_NEG (compare_mode
,
11803 gen_rtx_ABS (compare_mode
, op0
))));
11808 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
11809 temp
= gen_reg_rtx (result_mode
);
11810 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11811 gen_rtx_IF_THEN_ELSE (result_mode
,
11812 gen_rtx_GE (VOIDmode
,
11814 true_cond
, false_cond
)));
11815 false_cond
= true_cond
;
11818 temp
= gen_reg_rtx (compare_mode
);
11819 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11824 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
11825 temp
= gen_reg_rtx (result_mode
);
11826 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11827 gen_rtx_IF_THEN_ELSE (result_mode
,
11828 gen_rtx_GE (VOIDmode
,
11830 true_cond
, false_cond
)));
11831 true_cond
= false_cond
;
11834 temp
= gen_reg_rtx (compare_mode
);
11835 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11840 gcc_unreachable ();
11843 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
11844 gen_rtx_IF_THEN_ELSE (result_mode
,
11845 gen_rtx_GE (VOIDmode
,
11847 true_cond
, false_cond
)));
11851 /* Same as above, but for ints (isel). */
11854 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
11856 rtx condition_rtx
, cr
;
11858 /* All isel implementations thus far are 32-bits. */
11859 if (GET_MODE (rs6000_compare_op0
) != SImode
)
11862 /* We still have to do the compare, because isel doesn't do a
11863 compare, it just looks at the CRx bits set by a previous compare
11865 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
11866 cr
= XEXP (condition_rtx
, 0);
11868 if (GET_MODE (cr
) == CCmode
)
11869 emit_insn (gen_isel_signed (dest
, condition_rtx
,
11870 true_cond
, false_cond
, cr
));
11872 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
11873 true_cond
, false_cond
, cr
));
11879 output_isel (rtx
*operands
)
11881 enum rtx_code code
;
11883 code
= GET_CODE (operands
[1]);
11884 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
11886 PUT_CODE (operands
[1], reverse_condition (code
));
11887 return "isel %0,%3,%2,%j1";
11890 return "isel %0,%2,%3,%j1";
11894 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
11896 enum machine_mode mode
= GET_MODE (op0
);
11900 if (code
== SMAX
|| code
== SMIN
)
11905 if (code
== SMAX
|| code
== UMAX
)
11906 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
11907 op0
, op1
, mode
, 0);
11909 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
11910 op1
, op0
, mode
, 0);
11911 gcc_assert (target
);
11912 if (target
!= dest
)
11913 emit_move_insn (dest
, target
);
11916 /* Emit instructions to perform a load-reserved/store-conditional operation.
11917 The operation performed is an atomic
11918 (set M (CODE:MODE M OP))
11919 If not NULL, BEFORE is atomically set to M before the operation, and
11920 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
11921 If SYNC_P then a memory barrier is emitted before the operation.
11922 Either OP or M may be wrapped in a NOT operation. */
11925 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
11926 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
11929 enum machine_mode used_mode
;
11930 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
11933 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
11934 rtx shift
= NULL_RTX
;
11937 emit_insn (gen_memory_barrier ());
11939 if (GET_CODE (m
) == NOT
)
11940 used_m
= XEXP (m
, 0);
11944 /* If this is smaller than SImode, we'll have to use SImode with
11946 if (mode
== QImode
|| mode
== HImode
)
11950 if (MEM_ALIGN (used_m
) >= 32)
11953 if (BYTES_BIG_ENDIAN
)
11954 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
11956 shift
= GEN_INT (ishift
);
11960 rtx addrSI
, aligned_addr
;
11961 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
11963 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
,
11964 XEXP (used_m
, 0)));
11965 shift
= gen_reg_rtx (SImode
);
11967 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
11968 GEN_INT (shift_mask
)));
11969 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
11971 aligned_addr
= expand_binop (Pmode
, and_optab
,
11973 GEN_INT (-4), NULL_RTX
,
11974 1, OPTAB_LIB_WIDEN
);
11975 used_m
= change_address (used_m
, SImode
, aligned_addr
);
11976 set_mem_align (used_m
, 32);
11977 /* It's safe to keep the old alias set of USED_M, because
11978 the operation is atomic and only affects the original
11980 if (GET_CODE (m
) == NOT
)
11981 m
= gen_rtx_NOT (SImode
, used_m
);
11986 if (GET_CODE (op
) == NOT
)
11988 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
11989 oldop
= gen_rtx_NOT (SImode
, oldop
);
11992 oldop
= lowpart_subreg (SImode
, op
, mode
);
11998 newop
= expand_binop (SImode
, and_optab
,
11999 oldop
, GEN_INT (imask
), NULL_RTX
,
12000 1, OPTAB_LIB_WIDEN
);
12001 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12005 newop
= expand_binop (SImode
, ior_optab
,
12006 oldop
, GEN_INT (~imask
), NULL_RTX
,
12007 1, OPTAB_LIB_WIDEN
);
12008 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
12016 newop
= expand_binop (SImode
, and_optab
,
12017 oldop
, GEN_INT (imask
), NULL_RTX
,
12018 1, OPTAB_LIB_WIDEN
);
12019 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12021 mask
= gen_reg_rtx (SImode
);
12022 emit_move_insn (mask
, GEN_INT (imask
));
12023 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12026 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
12028 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
12029 newop
= gen_rtx_AND (SImode
, newop
, mask
);
12030 newop
= gen_rtx_IOR (SImode
, newop
,
12031 gen_rtx_AND (SImode
,
12032 gen_rtx_NOT (SImode
, mask
),
12038 gcc_unreachable ();
12041 if (GET_CODE (m
) == NOT
)
12045 mask
= gen_reg_rtx (SImode
);
12046 emit_move_insn (mask
, GEN_INT (imask
));
12047 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12049 xorm
= gen_rtx_XOR (SImode
, used_m
, mask
);
12050 /* Depending on the value of 'op', the XOR or the operation might
12051 be able to be simplified away. */
12052 newop
= simplify_gen_binary (code
, SImode
, xorm
, newop
);
12055 used_mode
= SImode
;
12056 before
= gen_reg_rtx (used_mode
);
12057 after
= gen_reg_rtx (used_mode
);
12062 before
= before_param
;
12063 after
= after_param
;
12065 if (before
== NULL_RTX
)
12066 before
= gen_reg_rtx (used_mode
);
12067 if (after
== NULL_RTX
)
12068 after
= gen_reg_rtx (used_mode
);
12071 if ((code
== PLUS
|| code
== MINUS
|| GET_CODE (m
) == NOT
)
12072 && used_mode
!= mode
)
12073 the_op
= op
; /* Computed above. */
12074 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
12075 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
12077 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
12079 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
12080 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
12081 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
12082 gen_rtx_UNSPEC (used_mode
,
12083 gen_rtvec (1, the_op
),
12085 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
12087 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
12088 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
12089 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
12091 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
12092 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
12094 /* Shift and mask the return values properly. */
12095 if (used_mode
!= mode
&& before_param
)
12097 emit_insn (gen_lshrsi3 (before
, before
, shift
));
12098 convert_move (before_param
, before
, 1);
12101 if (used_mode
!= mode
&& after_param
)
12103 emit_insn (gen_lshrsi3 (after
, after
, shift
));
12104 convert_move (after_param
, after
, 1);
12107 /* The previous sequence will end with a branch that's dependent on
12108 the conditional store, so placing an isync will ensure that no
12109 other instructions (especially, no load or store instructions)
12110 can start before the atomic operation completes. */
12112 emit_insn (gen_isync ());
12115 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12116 COND is true. Mark the jump as unlikely to be taken. */
12119 emit_unlikely_jump (rtx cond
, rtx label
)
12121 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
12124 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
12125 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
12126 REG_NOTES (x
) = gen_rtx_EXPR_LIST (REG_BR_PROB
, very_unlikely
, NULL_RTX
);
12129 /* A subroutine of the atomic operation splitters. Emit a load-locked
12130 instruction in MODE. */
12133 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
12135 rtx (*fn
) (rtx
, rtx
) = NULL
;
12136 if (mode
== SImode
)
12137 fn
= gen_load_locked_si
;
12138 else if (mode
== DImode
)
12139 fn
= gen_load_locked_di
;
12140 emit_insn (fn (reg
, mem
));
12143 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12144 instruction in MODE. */
12147 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
12149 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
12150 if (mode
== SImode
)
12151 fn
= gen_store_conditional_si
;
12152 else if (mode
== DImode
)
12153 fn
= gen_store_conditional_di
;
12155 /* Emit sync before stwcx. to address PPC405 Erratum. */
12156 if (PPC405_ERRATUM77
)
12157 emit_insn (gen_memory_barrier ());
12159 emit_insn (fn (res
, mem
, val
));
12162 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12163 to perform. MEM is the memory on which to operate. VAL is the second
12164 operand of the binary operator. BEFORE and AFTER are optional locations to
12165 return the value of MEM either before of after the operation. SCRATCH is
12166 a scratch register. */
12169 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
12170 rtx before
, rtx after
, rtx scratch
)
12172 enum machine_mode mode
= GET_MODE (mem
);
12173 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12175 emit_insn (gen_memory_barrier ());
12177 label
= gen_label_rtx ();
12178 emit_label (label
);
12179 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
12181 if (before
== NULL_RTX
)
12183 emit_load_locked (mode
, before
, mem
);
12186 x
= gen_rtx_AND (mode
, gen_rtx_NOT (mode
, before
), val
);
12187 else if (code
== AND
)
12188 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
12190 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
12192 if (after
!= NULL_RTX
)
12193 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
12194 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
12196 emit_store_conditional (mode
, cond
, mem
, scratch
);
12198 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12199 emit_unlikely_jump (x
, label
);
12201 emit_insn (gen_isync ());
12204 /* Expand an atomic compare and swap operation. MEM is the memory on which
12205 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12206 value to be stored. SCRATCH is a scratch GPR. */
12209 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
12212 enum machine_mode mode
= GET_MODE (mem
);
12213 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12215 emit_insn (gen_memory_barrier ());
12217 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12218 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12219 emit_label (XEXP (label1
, 0));
12221 emit_load_locked (mode
, retval
, mem
);
12223 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
12224 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
12226 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12227 emit_unlikely_jump (x
, label2
);
12229 emit_move_insn (scratch
, newval
);
12230 emit_store_conditional (mode
, cond
, mem
, scratch
);
12232 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12233 emit_unlikely_jump (x
, label1
);
12235 emit_insn (gen_isync ());
12236 emit_label (XEXP (label2
, 0));
12239 /* Expand an atomic test and set operation. MEM is the memory on which
12240 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12243 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
12245 enum machine_mode mode
= GET_MODE (mem
);
12246 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12248 emit_insn (gen_memory_barrier ());
12250 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12251 emit_label (XEXP (label
, 0));
12253 emit_load_locked (mode
, retval
, mem
);
12254 emit_move_insn (scratch
, val
);
12255 emit_store_conditional (mode
, cond
, mem
, scratch
);
12257 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12258 emit_unlikely_jump (x
, label
);
12260 emit_insn (gen_isync ());
12263 /* Emit instructions to move SRC to DST. Called by splitters for
12264 multi-register moves. It will emit at most one instruction for
12265 each register that is accessed; that is, it won't emit li/lis pairs
12266 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12270 rs6000_split_multireg_move (rtx dst
, rtx src
)
12272 /* The register number of the first register being moved. */
12274 /* The mode that is to be moved. */
12275 enum machine_mode mode
;
12276 /* The mode that the move is being done in, and its size. */
12277 enum machine_mode reg_mode
;
12279 /* The number of registers that will be moved. */
12282 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
12283 mode
= GET_MODE (dst
);
12284 nregs
= hard_regno_nregs
[reg
][mode
];
12285 if (FP_REGNO_P (reg
))
12287 else if (ALTIVEC_REGNO_P (reg
))
12288 reg_mode
= V16QImode
;
12290 reg_mode
= word_mode
;
12291 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
12293 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
12295 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
12297 /* Move register range backwards, if we might have destructive
12300 for (i
= nregs
- 1; i
>= 0; i
--)
12301 emit_insn (gen_rtx_SET (VOIDmode
,
12302 simplify_gen_subreg (reg_mode
, dst
, mode
,
12303 i
* reg_mode_size
),
12304 simplify_gen_subreg (reg_mode
, src
, mode
,
12305 i
* reg_mode_size
)));
12311 bool used_update
= false;
12313 if (MEM_P (src
) && INT_REGNO_P (reg
))
12317 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
12318 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
12321 breg
= XEXP (XEXP (src
, 0), 0);
12322 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
12323 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
12324 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
12325 emit_insn (TARGET_32BIT
12326 ? gen_addsi3 (breg
, breg
, delta_rtx
)
12327 : gen_adddi3 (breg
, breg
, delta_rtx
));
12328 src
= replace_equiv_address (src
, breg
);
12330 else if (! offsettable_memref_p (src
))
12333 basereg
= gen_rtx_REG (Pmode
, reg
);
12334 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
12335 src
= replace_equiv_address (src
, basereg
);
12338 breg
= XEXP (src
, 0);
12339 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
12340 breg
= XEXP (breg
, 0);
12342 /* If the base register we are using to address memory is
12343 also a destination reg, then change that register last. */
12345 && REGNO (breg
) >= REGNO (dst
)
12346 && REGNO (breg
) < REGNO (dst
) + nregs
)
12347 j
= REGNO (breg
) - REGNO (dst
);
12350 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
12354 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
12355 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
12358 breg
= XEXP (XEXP (dst
, 0), 0);
12359 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
12360 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
12361 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
12363 /* We have to update the breg before doing the store.
12364 Use store with update, if available. */
12368 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
12369 emit_insn (TARGET_32BIT
12370 ? (TARGET_POWERPC64
12371 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
12372 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
12373 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
12374 used_update
= true;
12377 emit_insn (TARGET_32BIT
12378 ? gen_addsi3 (breg
, breg
, delta_rtx
)
12379 : gen_adddi3 (breg
, breg
, delta_rtx
));
12380 dst
= replace_equiv_address (dst
, breg
);
12383 gcc_assert (offsettable_memref_p (dst
));
12386 for (i
= 0; i
< nregs
; i
++)
12388 /* Calculate index to next subword. */
12393 /* If compiler already emitted move of first word by
12394 store with update, no need to do anything. */
12395 if (j
== 0 && used_update
)
12398 emit_insn (gen_rtx_SET (VOIDmode
,
12399 simplify_gen_subreg (reg_mode
, dst
, mode
,
12400 j
* reg_mode_size
),
12401 simplify_gen_subreg (reg_mode
, src
, mode
,
12402 j
* reg_mode_size
)));
12408 /* This page contains routines that are used to determine what the
12409 function prologue and epilogue code will do and write them out. */
12411 /* Return the first fixed-point register that is required to be
12412 saved. 32 if none. */
12415 first_reg_to_save (void)
12419 /* Find lowest numbered live register. */
12420 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
12421 if (regs_ever_live
[first_reg
]
12422 && (! call_used_regs
[first_reg
]
12423 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
12424 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
12425 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
12426 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
12431 && current_function_uses_pic_offset_table
12432 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
12433 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
12439 /* Similar, for FP regs. */
12442 first_fp_reg_to_save (void)
12446 /* Find lowest numbered live register. */
12447 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
12448 if (regs_ever_live
[first_reg
])
12454 /* Similar, for AltiVec regs. */
12457 first_altivec_reg_to_save (void)
12461 /* Stack frame remains as is unless we are in AltiVec ABI. */
12462 if (! TARGET_ALTIVEC_ABI
)
12463 return LAST_ALTIVEC_REGNO
+ 1;
12465 /* Find lowest numbered live register. */
12466 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
12467 if (regs_ever_live
[i
])
12473 /* Return a 32-bit mask of the AltiVec registers we need to set in
12474 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
12475 the 32-bit word is 0. */
12477 static unsigned int
12478 compute_vrsave_mask (void)
12480 unsigned int i
, mask
= 0;
12482 /* First, find out if we use _any_ altivec registers. */
12483 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
12484 if (regs_ever_live
[i
])
12485 mask
|= ALTIVEC_REG_BIT (i
);
12490 /* Next, remove the argument registers from the set. These must
12491 be in the VRSAVE mask set by the caller, so we don't need to add
12492 them in again. More importantly, the mask we compute here is
12493 used to generate CLOBBERs in the set_vrsave insn, and we do not
12494 wish the argument registers to die. */
12495 for (i
= cfun
->args_info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
12496 mask
&= ~ALTIVEC_REG_BIT (i
);
12498 /* Similarly, remove the return value from the set. */
12501 diddle_return_value (is_altivec_return_reg
, &yes
);
12503 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
12509 /* For a very restricted set of circumstances, we can cut down the
12510 size of prologues/epilogues by calling our own save/restore-the-world
12514 compute_save_world_info (rs6000_stack_t
*info_ptr
)
12516 info_ptr
->world_save_p
= 1;
12517 info_ptr
->world_save_p
12518 = (WORLD_SAVE_P (info_ptr
)
12519 && DEFAULT_ABI
== ABI_DARWIN
12520 && ! (current_function_calls_setjmp
&& flag_exceptions
)
12521 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
12522 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
12523 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
12524 && info_ptr
->cr_save_p
);
12526 /* This will not work in conjunction with sibcalls. Make sure there
12527 are none. (This check is expensive, but seldom executed.) */
12528 if (WORLD_SAVE_P (info_ptr
))
12531 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
12532 if ( GET_CODE (insn
) == CALL_INSN
12533 && SIBLING_CALL_P (insn
))
12535 info_ptr
->world_save_p
= 0;
12540 if (WORLD_SAVE_P (info_ptr
))
12542 /* Even if we're not touching VRsave, make sure there's room on the
12543 stack for it, if it looks like we're calling SAVE_WORLD, which
12544 will attempt to save it. */
12545 info_ptr
->vrsave_size
= 4;
12547 /* "Save" the VRsave register too if we're saving the world. */
12548 if (info_ptr
->vrsave_mask
== 0)
12549 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
12551 /* Because the Darwin register save/restore routines only handle
12552 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
12554 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
12555 && (info_ptr
->first_altivec_reg_save
12556 >= FIRST_SAVED_ALTIVEC_REGNO
));
12563 is_altivec_return_reg (rtx reg
, void *xyes
)
12565 bool *yes
= (bool *) xyes
;
12566 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
12571 /* Calculate the stack information for the current function. This is
12572 complicated by having two separate calling sequences, the AIX calling
12573 sequence and the V.4 calling sequence.
12575 AIX (and Darwin/Mac OS X) stack frames look like:
12577 SP----> +---------------------------------------+
12578 | back chain to caller | 0 0
12579 +---------------------------------------+
12580 | saved CR | 4 8 (8-11)
12581 +---------------------------------------+
12583 +---------------------------------------+
12584 | reserved for compilers | 12 24
12585 +---------------------------------------+
12586 | reserved for binders | 16 32
12587 +---------------------------------------+
12588 | saved TOC pointer | 20 40
12589 +---------------------------------------+
12590 | Parameter save area (P) | 24 48
12591 +---------------------------------------+
12592 | Alloca space (A) | 24+P etc.
12593 +---------------------------------------+
12594 | Local variable space (L) | 24+P+A
12595 +---------------------------------------+
12596 | Float/int conversion temporary (X) | 24+P+A+L
12597 +---------------------------------------+
12598 | Save area for AltiVec registers (W) | 24+P+A+L+X
12599 +---------------------------------------+
12600 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
12601 +---------------------------------------+
12602 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
12603 +---------------------------------------+
12604 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
12605 +---------------------------------------+
12606 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
12607 +---------------------------------------+
12608 old SP->| back chain to caller's caller |
12609 +---------------------------------------+
12611 The required alignment for AIX configurations is two words (i.e., 8
12615 V.4 stack frames look like:
12617 SP----> +---------------------------------------+
12618 | back chain to caller | 0
12619 +---------------------------------------+
12620 | caller's saved LR | 4
12621 +---------------------------------------+
12622 | Parameter save area (P) | 8
12623 +---------------------------------------+
12624 | Alloca space (A) | 8+P
12625 +---------------------------------------+
12626 | Varargs save area (V) | 8+P+A
12627 +---------------------------------------+
12628 | Local variable space (L) | 8+P+A+V
12629 +---------------------------------------+
12630 | Float/int conversion temporary (X) | 8+P+A+V+L
12631 +---------------------------------------+
12632 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
12633 +---------------------------------------+
12634 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
12635 +---------------------------------------+
12636 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
12637 +---------------------------------------+
12638 | SPE: area for 64-bit GP registers |
12639 +---------------------------------------+
12640 | SPE alignment padding |
12641 +---------------------------------------+
12642 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
12643 +---------------------------------------+
12644 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
12645 +---------------------------------------+
12646 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
12647 +---------------------------------------+
12648 old SP->| back chain to caller's caller |
12649 +---------------------------------------+
12651 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
12652 given. (But note below and in sysv4.h that we require only 8 and
12653 may round up the size of our stack frame anyways. The historical
12654 reason is early versions of powerpc-linux which didn't properly
12655 align the stack at program startup. A happy side-effect is that
12656 -mno-eabi libraries can be used with -meabi programs.)
12658 The EABI configuration defaults to the V.4 layout. However,
12659 the stack alignment requirements may differ. If -mno-eabi is not
12660 given, the required stack alignment is 8 bytes; if -mno-eabi is
12661 given, the required alignment is 16 bytes. (But see V.4 comment
12664 #ifndef ABI_STACK_BOUNDARY
12665 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
12668 static rs6000_stack_t
*
12669 rs6000_stack_info (void)
12671 static rs6000_stack_t info
, zero_info
;
12672 rs6000_stack_t
*info_ptr
= &info
;
12673 int reg_size
= TARGET_32BIT
? 4 : 8;
12676 HOST_WIDE_INT non_fixed_size
;
12678 /* Zero all fields portably. */
12683 /* Cache value so we don't rescan instruction chain over and over. */
12684 if (cfun
->machine
->insn_chain_scanned_p
== 0)
12685 cfun
->machine
->insn_chain_scanned_p
12686 = spe_func_has_64bit_regs_p () + 1;
12687 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
12690 /* Select which calling sequence. */
12691 info_ptr
->abi
= DEFAULT_ABI
;
12693 /* Calculate which registers need to be saved & save area size. */
12694 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
12695 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
12696 even if it currently looks like we won't. */
12697 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
12698 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
12699 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
12700 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
12701 info_ptr
->gp_size
= reg_size
* (32 - RS6000_PIC_OFFSET_TABLE_REGNUM
);
12703 info_ptr
->gp_size
= reg_size
* (32 - info_ptr
->first_gp_reg_save
);
12705 /* For the SPE, we have an additional upper 32-bits on each GPR.
12706 Ideally we should save the entire 64-bits only when the upper
12707 half is used in SIMD instructions. Since we only record
12708 registers live (not the size they are used in), this proves
12709 difficult because we'd have to traverse the instruction chain at
12710 the right time, taking reload into account. This is a real pain,
12711 so we opt to save the GPRs in 64-bits always if but one register
12712 gets used in 64-bits. Otherwise, all the registers in the frame
12713 get saved in 32-bits.
12715 So... since when we save all GPRs (except the SP) in 64-bits, the
12716 traditional GP save area will be empty. */
12717 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12718 info_ptr
->gp_size
= 0;
12720 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
12721 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
12723 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
12724 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
12725 - info_ptr
->first_altivec_reg_save
);
12727 /* Does this function call anything? */
12728 info_ptr
->calls_p
= (! current_function_is_leaf
12729 || cfun
->machine
->ra_needs_full_frame
);
12731 /* Determine if we need to save the link register. */
12732 if (rs6000_ra_ever_killed ()
12733 || (DEFAULT_ABI
== ABI_AIX
12734 && current_function_profile
12735 && !TARGET_PROFILE_KERNEL
)
12736 #ifdef TARGET_RELOCATABLE
12737 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
12739 || (info_ptr
->first_fp_reg_save
!= 64
12740 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
12741 || info_ptr
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
12742 || (DEFAULT_ABI
== ABI_V4
&& current_function_calls_alloca
)
12743 || info_ptr
->calls_p
)
12745 info_ptr
->lr_save_p
= 1;
12746 regs_ever_live
[LINK_REGISTER_REGNUM
] = 1;
12749 /* Determine if we need to save the condition code registers. */
12750 if (regs_ever_live
[CR2_REGNO
]
12751 || regs_ever_live
[CR3_REGNO
]
12752 || regs_ever_live
[CR4_REGNO
])
12754 info_ptr
->cr_save_p
= 1;
12755 if (DEFAULT_ABI
== ABI_V4
)
12756 info_ptr
->cr_size
= reg_size
;
12759 /* If the current function calls __builtin_eh_return, then we need
12760 to allocate stack space for registers that will hold data for
12761 the exception handler. */
12762 if (current_function_calls_eh_return
)
12765 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
12768 /* SPE saves EH registers in 64-bits. */
12769 ehrd_size
= i
* (TARGET_SPE_ABI
12770 && info_ptr
->spe_64bit_regs_used
!= 0
12771 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
12776 /* Determine various sizes. */
12777 info_ptr
->reg_size
= reg_size
;
12778 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
12779 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
12780 info_ptr
->parm_size
= RS6000_ALIGN (current_function_outgoing_args_size
,
12781 TARGET_ALTIVEC
? 16 : 8);
12782 if (FRAME_GROWS_DOWNWARD
)
12783 info_ptr
->vars_size
12784 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
12785 + info_ptr
->parm_size
,
12786 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
12787 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
12788 + info_ptr
->parm_size
);
12790 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12791 info_ptr
->spe_gp_size
= 8 * (32 - info_ptr
->first_gp_reg_save
);
12793 info_ptr
->spe_gp_size
= 0;
12795 if (TARGET_ALTIVEC_ABI
)
12796 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
12798 info_ptr
->vrsave_mask
= 0;
12800 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
12801 info_ptr
->vrsave_size
= 4;
12803 info_ptr
->vrsave_size
= 0;
12805 compute_save_world_info (info_ptr
);
12807 /* Calculate the offsets. */
12808 switch (DEFAULT_ABI
)
12812 gcc_unreachable ();
12816 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
12817 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
12819 if (TARGET_ALTIVEC_ABI
)
12821 info_ptr
->vrsave_save_offset
12822 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
12824 /* Align stack so vector save area is on a quadword boundary. */
12825 if (info_ptr
->altivec_size
!= 0)
12826 info_ptr
->altivec_padding_size
12827 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
12829 info_ptr
->altivec_padding_size
= 0;
12831 info_ptr
->altivec_save_offset
12832 = info_ptr
->vrsave_save_offset
12833 - info_ptr
->altivec_padding_size
12834 - info_ptr
->altivec_size
;
12836 /* Adjust for AltiVec case. */
12837 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
12840 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
12841 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
12842 info_ptr
->lr_save_offset
= 2*reg_size
;
12846 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
12847 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
12848 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
12850 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12852 /* Align stack so SPE GPR save area is aligned on a
12853 double-word boundary. */
12854 if (info_ptr
->spe_gp_size
!= 0)
12855 info_ptr
->spe_padding_size
12856 = 8 - (-info_ptr
->cr_save_offset
% 8);
12858 info_ptr
->spe_padding_size
= 0;
12860 info_ptr
->spe_gp_save_offset
12861 = info_ptr
->cr_save_offset
12862 - info_ptr
->spe_padding_size
12863 - info_ptr
->spe_gp_size
;
12865 /* Adjust for SPE case. */
12866 info_ptr
->toc_save_offset
12867 = info_ptr
->spe_gp_save_offset
- info_ptr
->toc_size
;
12869 else if (TARGET_ALTIVEC_ABI
)
12871 info_ptr
->vrsave_save_offset
12872 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
12874 /* Align stack so vector save area is on a quadword boundary. */
12875 if (info_ptr
->altivec_size
!= 0)
12876 info_ptr
->altivec_padding_size
12877 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
12879 info_ptr
->altivec_padding_size
= 0;
12881 info_ptr
->altivec_save_offset
12882 = info_ptr
->vrsave_save_offset
12883 - info_ptr
->altivec_padding_size
12884 - info_ptr
->altivec_size
;
12886 /* Adjust for AltiVec case. */
12887 info_ptr
->toc_save_offset
12888 = info_ptr
->altivec_save_offset
- info_ptr
->toc_size
;
12891 info_ptr
->toc_save_offset
= info_ptr
->cr_save_offset
- info_ptr
->toc_size
;
12892 info_ptr
->ehrd_offset
= info_ptr
->toc_save_offset
- ehrd_size
;
12893 info_ptr
->lr_save_offset
= reg_size
;
12897 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
12898 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
12899 + info_ptr
->gp_size
12900 + info_ptr
->altivec_size
12901 + info_ptr
->altivec_padding_size
12902 + info_ptr
->spe_gp_size
12903 + info_ptr
->spe_padding_size
12905 + info_ptr
->cr_size
12906 + info_ptr
->lr_size
12907 + info_ptr
->vrsave_size
12908 + info_ptr
->toc_size
,
12911 non_fixed_size
= (info_ptr
->vars_size
12912 + info_ptr
->parm_size
12913 + info_ptr
->save_size
);
12915 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
12916 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
12918 /* Determine if we need to allocate any stack frame:
12920 For AIX we need to push the stack if a frame pointer is needed
12921 (because the stack might be dynamically adjusted), if we are
12922 debugging, if we make calls, or if the sum of fp_save, gp_save,
12923 and local variables are more than the space needed to save all
12924 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
12925 + 18*8 = 288 (GPR13 reserved).
12927 For V.4 we don't have the stack cushion that AIX uses, but assume
12928 that the debugger can handle stackless frames. */
12930 if (info_ptr
->calls_p
)
12931 info_ptr
->push_p
= 1;
12933 else if (DEFAULT_ABI
== ABI_V4
)
12934 info_ptr
->push_p
= non_fixed_size
!= 0;
12936 else if (frame_pointer_needed
)
12937 info_ptr
->push_p
= 1;
12939 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
12940 info_ptr
->push_p
= 1;
12943 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
12945 /* Zero offsets if we're not saving those registers. */
12946 if (info_ptr
->fp_size
== 0)
12947 info_ptr
->fp_save_offset
= 0;
12949 if (info_ptr
->gp_size
== 0)
12950 info_ptr
->gp_save_offset
= 0;
12952 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
12953 info_ptr
->altivec_save_offset
= 0;
12955 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
12956 info_ptr
->vrsave_save_offset
= 0;
12958 if (! TARGET_SPE_ABI
12959 || info_ptr
->spe_64bit_regs_used
== 0
12960 || info_ptr
->spe_gp_size
== 0)
12961 info_ptr
->spe_gp_save_offset
= 0;
12963 if (! info_ptr
->lr_save_p
)
12964 info_ptr
->lr_save_offset
= 0;
12966 if (! info_ptr
->cr_save_p
)
12967 info_ptr
->cr_save_offset
= 0;
12969 if (! info_ptr
->toc_save_p
)
12970 info_ptr
->toc_save_offset
= 0;
12975 /* Return true if the current function uses any GPRs in 64-bit SIMD
12979 spe_func_has_64bit_regs_p (void)
12983 /* Functions that save and restore all the call-saved registers will
12984 need to save/restore the registers in 64-bits. */
12985 if (current_function_calls_eh_return
12986 || current_function_calls_setjmp
12987 || current_function_has_nonlocal_goto
)
12990 insns
= get_insns ();
12992 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
12998 /* FIXME: This should be implemented with attributes...
13000 (set_attr "spe64" "true")....then,
13001 if (get_spe64(insn)) return true;
13003 It's the only reliable way to do the stuff below. */
13005 i
= PATTERN (insn
);
13006 if (GET_CODE (i
) == SET
)
13008 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
13010 if (SPE_VECTOR_MODE (mode
))
13012 if (TARGET_E500_DOUBLE
&& mode
== DFmode
)
13022 debug_stack_info (rs6000_stack_t
*info
)
13024 const char *abi_string
;
13027 info
= rs6000_stack_info ();
13029 fprintf (stderr
, "\nStack information for function %s:\n",
13030 ((current_function_decl
&& DECL_NAME (current_function_decl
))
13031 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
13036 default: abi_string
= "Unknown"; break;
13037 case ABI_NONE
: abi_string
= "NONE"; break;
13038 case ABI_AIX
: abi_string
= "AIX"; break;
13039 case ABI_DARWIN
: abi_string
= "Darwin"; break;
13040 case ABI_V4
: abi_string
= "V.4"; break;
13043 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
13045 if (TARGET_ALTIVEC_ABI
)
13046 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
13048 if (TARGET_SPE_ABI
)
13049 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
13051 if (info
->first_gp_reg_save
!= 32)
13052 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
13054 if (info
->first_fp_reg_save
!= 64)
13055 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
13057 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
13058 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
13059 info
->first_altivec_reg_save
);
13061 if (info
->lr_save_p
)
13062 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
13064 if (info
->cr_save_p
)
13065 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
13067 if (info
->toc_save_p
)
13068 fprintf (stderr
, "\ttoc_save_p = %5d\n", info
->toc_save_p
);
13070 if (info
->vrsave_mask
)
13071 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
13074 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
13077 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
13079 if (info
->gp_save_offset
)
13080 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
13082 if (info
->fp_save_offset
)
13083 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
13085 if (info
->altivec_save_offset
)
13086 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
13087 info
->altivec_save_offset
);
13089 if (info
->spe_gp_save_offset
)
13090 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
13091 info
->spe_gp_save_offset
);
13093 if (info
->vrsave_save_offset
)
13094 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
13095 info
->vrsave_save_offset
);
13097 if (info
->lr_save_offset
)
13098 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
13100 if (info
->cr_save_offset
)
13101 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
13103 if (info
->toc_save_offset
)
13104 fprintf (stderr
, "\ttoc_save_offset = %5d\n", info
->toc_save_offset
);
13106 if (info
->varargs_save_offset
)
13107 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
13109 if (info
->total_size
)
13110 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13113 if (info
->vars_size
)
13114 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13117 if (info
->parm_size
)
13118 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
13120 if (info
->fixed_size
)
13121 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
13124 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
13126 if (info
->spe_gp_size
)
13127 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
13130 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
13132 if (info
->altivec_size
)
13133 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
13135 if (info
->vrsave_size
)
13136 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
13138 if (info
->altivec_padding_size
)
13139 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
13140 info
->altivec_padding_size
);
13142 if (info
->spe_padding_size
)
13143 fprintf (stderr
, "\tspe_padding_size = %5d\n",
13144 info
->spe_padding_size
);
13147 fprintf (stderr
, "\tlr_size = %5d\n", info
->lr_size
);
13150 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
13152 if (info
->toc_size
)
13153 fprintf (stderr
, "\ttoc_size = %5d\n", info
->toc_size
);
13155 if (info
->save_size
)
13156 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
13158 if (info
->reg_size
!= 4)
13159 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
13161 fprintf (stderr
, "\n");
13165 rs6000_return_addr (int count
, rtx frame
)
13167 /* Currently we don't optimize very well between prolog and body
13168 code and for PIC code the code can be actually quite bad, so
13169 don't try to be too clever here. */
13170 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
13172 cfun
->machine
->ra_needs_full_frame
= 1;
13179 plus_constant (copy_to_reg
13180 (gen_rtx_MEM (Pmode
,
13181 memory_address (Pmode
, frame
))),
13182 RETURN_ADDRESS_OFFSET
)));
13185 cfun
->machine
->ra_need_lr
= 1;
13186 return get_hard_reg_initial_val (Pmode
, LINK_REGISTER_REGNUM
);
13189 /* Say whether a function is a candidate for sibcall handling or not.
13190 We do not allow indirect calls to be optimized into sibling calls.
13191 Also, we can't do it if there are any vector parameters; there's
13192 nowhere to put the VRsave code so it works; note that functions with
13193 vector parameters are required to have a prototype, so the argument
13194 type info must be available here. (The tail recursion case can work
13195 with vector parameters, but there's no way to distinguish here.) */
13197 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
13202 if (TARGET_ALTIVEC_VRSAVE
)
13204 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
13205 type
; type
= TREE_CHAIN (type
))
13207 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
13211 if (DEFAULT_ABI
== ABI_DARWIN
13212 || (*targetm
.binds_local_p
) (decl
))
13214 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
13216 if (!lookup_attribute ("longcall", attr_list
)
13217 || lookup_attribute ("shortcall", attr_list
))
13224 /* NULL if INSN insn is valid within a low-overhead loop.
13225 Otherwise return why doloop cannot be applied.
13226 PowerPC uses the COUNT register for branch on table instructions. */
13228 static const char *
13229 rs6000_invalid_within_doloop (rtx insn
)
13232 return "Function call in the loop.";
13235 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
13236 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
13237 return "Computed branch in the loop.";
13243 rs6000_ra_ever_killed (void)
13249 if (current_function_is_thunk
)
13252 /* regs_ever_live has LR marked as used if any sibcalls are present,
13253 but this should not force saving and restoring in the
13254 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13255 clobbers LR, so that is inappropriate. */
13257 /* Also, the prologue can generate a store into LR that
13258 doesn't really count, like this:
13261 bcl to set PIC register
13265 When we're called from the epilogue, we need to avoid counting
13266 this as a store. */
13268 push_topmost_sequence ();
13269 top
= get_insns ();
13270 pop_topmost_sequence ();
13271 reg
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13273 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13277 if (FIND_REG_INC_NOTE (insn
, reg
))
13279 else if (GET_CODE (insn
) == CALL_INSN
13280 && !SIBLING_CALL_P (insn
))
13282 else if (set_of (reg
, insn
) != NULL_RTX
13283 && !prologue_epilogue_contains (insn
))
13290 /* Add a REG_MAYBE_DEAD note to the insn. */
13292 rs6000_maybe_dead (rtx insn
)
13294 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
,
13299 /* Emit instructions needed to load the TOC register.
13300 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13301 a constant pool; or for SVR4 -fpic. */
13304 rs6000_emit_load_toc_table (int fromprolog
)
13307 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
13309 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
13312 rtx lab
, tmp1
, tmp2
, got
, tempLR
;
13314 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
13315 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13317 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
13319 got
= rs6000_got_sym ();
13320 tmp1
= tmp2
= dest
;
13323 tmp1
= gen_reg_rtx (Pmode
);
13324 tmp2
= gen_reg_rtx (Pmode
);
13326 tempLR
= (fromprolog
13327 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13328 : gen_reg_rtx (Pmode
));
13329 insn
= emit_insn (gen_load_toc_v4_PIC_1 (tempLR
, lab
));
13331 rs6000_maybe_dead (insn
);
13332 insn
= emit_move_insn (tmp1
, tempLR
);
13334 rs6000_maybe_dead (insn
);
13335 insn
= emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
13337 rs6000_maybe_dead (insn
);
13338 insn
= emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
13340 rs6000_maybe_dead (insn
);
13342 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
13344 rtx tempLR
= (fromprolog
13345 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13346 : gen_reg_rtx (Pmode
));
13348 insn
= emit_insn (gen_load_toc_v4_pic_si (tempLR
));
13350 rs6000_maybe_dead (insn
);
13351 insn
= emit_move_insn (dest
, tempLR
);
13353 rs6000_maybe_dead (insn
);
13355 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
13358 rtx tempLR
= (fromprolog
13359 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13360 : gen_reg_rtx (Pmode
));
13361 rtx temp0
= (fromprolog
13362 ? gen_rtx_REG (Pmode
, 0)
13363 : gen_reg_rtx (Pmode
));
13369 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
13370 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13372 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
13373 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13375 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR
,
13377 rs6000_maybe_dead (emit_move_insn (dest
, tempLR
));
13378 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
,
13386 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
13387 emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, tocsym
));
13388 emit_move_insn (dest
, tempLR
);
13389 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
13391 insn
= emit_insn (gen_addsi3 (dest
, temp0
, dest
));
13393 rs6000_maybe_dead (insn
);
13395 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
13397 /* This is for AIX code running in non-PIC ELF32. */
13400 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
13401 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13403 insn
= emit_insn (gen_elf_high (dest
, realsym
));
13405 rs6000_maybe_dead (insn
);
13406 insn
= emit_insn (gen_elf_low (dest
, dest
, realsym
));
13408 rs6000_maybe_dead (insn
);
13412 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
13415 insn
= emit_insn (gen_load_toc_aix_si (dest
));
13417 insn
= emit_insn (gen_load_toc_aix_di (dest
));
13419 rs6000_maybe_dead (insn
);
13423 /* Emit instructions to restore the link register after determining where
13424 its value has been stored. */
13427 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
13429 rs6000_stack_t
*info
= rs6000_stack_info ();
13432 operands
[0] = source
;
13433 operands
[1] = scratch
;
13435 if (info
->lr_save_p
)
13437 rtx frame_rtx
= stack_pointer_rtx
;
13438 HOST_WIDE_INT sp_offset
= 0;
13441 if (frame_pointer_needed
13442 || current_function_calls_alloca
13443 || info
->total_size
> 32767)
13445 tmp
= gen_rtx_MEM (Pmode
, frame_rtx
);
13446 MEM_NOTRAP_P (tmp
) = 1;
13447 set_mem_alias_set (tmp
, rs6000_sr_alias_set
);
13448 emit_move_insn (operands
[1], tmp
);
13449 frame_rtx
= operands
[1];
13451 else if (info
->push_p
)
13452 sp_offset
= info
->total_size
;
13454 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
13455 tmp
= gen_rtx_MEM (Pmode
, tmp
);
13456 MEM_NOTRAP_P (tmp
) = 1;
13457 set_mem_alias_set (tmp
, rs6000_sr_alias_set
);
13458 emit_move_insn (tmp
, operands
[0]);
13461 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
), operands
[0]);
13464 static GTY(()) int set
= -1;
13467 get_TOC_alias_set (void)
13470 set
= new_alias_set ();
13474 /* This returns nonzero if the current function uses the TOC. This is
13475 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
13476 is generated by the ABI_V4 load_toc_* patterns. */
13483 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
13486 rtx pat
= PATTERN (insn
);
13489 if (GET_CODE (pat
) == PARALLEL
)
13490 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
13492 rtx sub
= XVECEXP (pat
, 0, i
);
13493 if (GET_CODE (sub
) == USE
)
13495 sub
= XEXP (sub
, 0);
13496 if (GET_CODE (sub
) == UNSPEC
13497 && XINT (sub
, 1) == UNSPEC_TOC
)
13507 create_TOC_reference (rtx symbol
)
13509 return gen_rtx_PLUS (Pmode
,
13510 gen_rtx_REG (Pmode
, TOC_REGISTER
),
13511 gen_rtx_CONST (Pmode
,
13512 gen_rtx_MINUS (Pmode
, symbol
,
13513 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
13516 /* If _Unwind_* has been called from within the same module,
13517 toc register is not guaranteed to be saved to 40(1) on function
13518 entry. Save it there in that case. */
13521 rs6000_aix_emit_builtin_unwind_init (void)
13524 rtx stack_top
= gen_reg_rtx (Pmode
);
13525 rtx opcode_addr
= gen_reg_rtx (Pmode
);
13526 rtx opcode
= gen_reg_rtx (SImode
);
13527 rtx tocompare
= gen_reg_rtx (SImode
);
13528 rtx no_toc_save_needed
= gen_label_rtx ();
13530 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
13531 emit_move_insn (stack_top
, mem
);
13533 mem
= gen_frame_mem (Pmode
,
13534 gen_rtx_PLUS (Pmode
, stack_top
,
13535 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
13536 emit_move_insn (opcode_addr
, mem
);
13537 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
13538 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
13539 : 0xE8410028, SImode
));
13541 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
13542 SImode
, NULL_RTX
, NULL_RTX
,
13543 no_toc_save_needed
);
13545 mem
= gen_frame_mem (Pmode
,
13546 gen_rtx_PLUS (Pmode
, stack_top
,
13547 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
13548 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
13549 emit_label (no_toc_save_needed
);
13552 /* This ties together stack memory (MEM with an alias set of
13553 rs6000_sr_alias_set) and the change to the stack pointer. */
13556 rs6000_emit_stack_tie (void)
13558 rtx mem
= gen_rtx_MEM (BLKmode
, gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
13560 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13561 emit_insn (gen_stack_tie (mem
));
13564 /* Emit the correct code for allocating stack space, as insns.
13565 If COPY_R12, make sure a copy of the old frame is left in r12.
13566 The generated code may use hard register 0 as a temporary. */
13569 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
13572 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
13573 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
13574 rtx todec
= gen_int_mode (-size
, Pmode
);
13576 if (INTVAL (todec
) != -size
)
13578 warning (0, "stack frame too large");
13579 emit_insn (gen_trap ());
13583 if (current_function_limit_stack
)
13585 if (REG_P (stack_limit_rtx
)
13586 && REGNO (stack_limit_rtx
) > 1
13587 && REGNO (stack_limit_rtx
) <= 31)
13589 emit_insn (TARGET_32BIT
13590 ? gen_addsi3 (tmp_reg
,
13593 : gen_adddi3 (tmp_reg
,
13597 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
13600 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
13602 && DEFAULT_ABI
== ABI_V4
)
13604 rtx toload
= gen_rtx_CONST (VOIDmode
,
13605 gen_rtx_PLUS (Pmode
,
13609 emit_insn (gen_elf_high (tmp_reg
, toload
));
13610 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
13611 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
13615 warning (0, "stack limit expression is not supported");
13618 if (copy_r12
|| ! TARGET_UPDATE
)
13619 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
13625 /* Need a note here so that try_split doesn't get confused. */
13626 if (get_last_insn () == NULL_RTX
)
13627 emit_note (NOTE_INSN_DELETED
);
13628 insn
= emit_move_insn (tmp_reg
, todec
);
13629 try_split (PATTERN (insn
), insn
, 0);
13633 insn
= emit_insn (TARGET_32BIT
13634 ? gen_movsi_update (stack_reg
, stack_reg
,
13636 : gen_movdi_di_update (stack_reg
, stack_reg
,
13637 todec
, stack_reg
));
13641 insn
= emit_insn (TARGET_32BIT
13642 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
13643 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
13644 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
13645 gen_rtx_REG (Pmode
, 12));
13648 RTX_FRAME_RELATED_P (insn
) = 1;
13650 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13651 gen_rtx_SET (VOIDmode
, stack_reg
,
13652 gen_rtx_PLUS (Pmode
, stack_reg
,
13657 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
13658 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
13659 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
13660 deduce these equivalences by itself so it wasn't necessary to hold
13661 its hand so much. */
13664 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
13665 rtx reg2
, rtx rreg
)
13669 /* copy_rtx will not make unique copies of registers, so we need to
13670 ensure we don't have unwanted sharing here. */
13672 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
13675 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
13677 real
= copy_rtx (PATTERN (insn
));
13679 if (reg2
!= NULL_RTX
)
13680 real
= replace_rtx (real
, reg2
, rreg
);
13682 real
= replace_rtx (real
, reg
,
13683 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
13684 STACK_POINTER_REGNUM
),
13687 /* We expect that 'real' is either a SET or a PARALLEL containing
13688 SETs (and possibly other stuff). In a PARALLEL, all the SETs
13689 are important so they all have to be marked RTX_FRAME_RELATED_P. */
13691 if (GET_CODE (real
) == SET
)
13695 temp
= simplify_rtx (SET_SRC (set
));
13697 SET_SRC (set
) = temp
;
13698 temp
= simplify_rtx (SET_DEST (set
));
13700 SET_DEST (set
) = temp
;
13701 if (GET_CODE (SET_DEST (set
)) == MEM
)
13703 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
13705 XEXP (SET_DEST (set
), 0) = temp
;
13712 gcc_assert (GET_CODE (real
) == PARALLEL
);
13713 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
13714 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
13716 rtx set
= XVECEXP (real
, 0, i
);
13718 temp
= simplify_rtx (SET_SRC (set
));
13720 SET_SRC (set
) = temp
;
13721 temp
= simplify_rtx (SET_DEST (set
));
13723 SET_DEST (set
) = temp
;
13724 if (GET_CODE (SET_DEST (set
)) == MEM
)
13726 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
13728 XEXP (SET_DEST (set
), 0) = temp
;
13730 RTX_FRAME_RELATED_P (set
) = 1;
13735 real
= spe_synthesize_frame_save (real
);
13737 RTX_FRAME_RELATED_P (insn
) = 1;
13738 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13743 /* Given an SPE frame note, return a PARALLEL of SETs with the
13744 original note, plus a synthetic register save. */
13747 spe_synthesize_frame_save (rtx real
)
13749 rtx synth
, offset
, reg
, real2
;
13751 if (GET_CODE (real
) != SET
13752 || GET_MODE (SET_SRC (real
)) != V2SImode
)
13755 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
13756 frame related note. The parallel contains a set of the register
13757 being saved, and another set to a synthetic register (n+1200).
13758 This is so we can differentiate between 64-bit and 32-bit saves.
13759 Words cannot describe this nastiness. */
13761 gcc_assert (GET_CODE (SET_DEST (real
)) == MEM
13762 && GET_CODE (XEXP (SET_DEST (real
), 0)) == PLUS
13763 && GET_CODE (SET_SRC (real
)) == REG
);
13766 (set (mem (plus (reg x) (const y)))
13769 (set (mem (plus (reg x) (const y+4)))
13773 real2
= copy_rtx (real
);
13774 PUT_MODE (SET_DEST (real2
), SImode
);
13775 reg
= SET_SRC (real2
);
13776 real2
= replace_rtx (real2
, reg
, gen_rtx_REG (SImode
, REGNO (reg
)));
13777 synth
= copy_rtx (real2
);
13779 if (BYTES_BIG_ENDIAN
)
13781 offset
= XEXP (XEXP (SET_DEST (real2
), 0), 1);
13782 real2
= replace_rtx (real2
, offset
, GEN_INT (INTVAL (offset
) + 4));
13785 reg
= SET_SRC (synth
);
13787 synth
= replace_rtx (synth
, reg
,
13788 gen_rtx_REG (SImode
, REGNO (reg
) + 1200));
13790 offset
= XEXP (XEXP (SET_DEST (synth
), 0), 1);
13791 synth
= replace_rtx (synth
, offset
,
13792 GEN_INT (INTVAL (offset
)
13793 + (BYTES_BIG_ENDIAN
? 0 : 4)));
13795 RTX_FRAME_RELATED_P (synth
) = 1;
13796 RTX_FRAME_RELATED_P (real2
) = 1;
13797 if (BYTES_BIG_ENDIAN
)
13798 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, synth
, real2
));
13800 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, real2
, synth
));
13805 /* Returns an insn that has a vrsave set operation with the
13806 appropriate CLOBBERs. */
13809 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
13812 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
13813 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
13816 = gen_rtx_SET (VOIDmode
,
13818 gen_rtx_UNSPEC_VOLATILE (SImode
,
13819 gen_rtvec (2, reg
, vrsave
),
13820 UNSPECV_SET_VRSAVE
));
13824 /* We need to clobber the registers in the mask so the scheduler
13825 does not move sets to VRSAVE before sets of AltiVec registers.
13827 However, if the function receives nonlocal gotos, reload will set
13828 all call saved registers live. We will end up with:
13830 (set (reg 999) (mem))
13831 (parallel [ (set (reg vrsave) (unspec blah))
13832 (clobber (reg 999))])
13834 The clobber will cause the store into reg 999 to be dead, and
13835 flow will attempt to delete an epilogue insn. In this case, we
13836 need an unspec use/set of the register. */
13838 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13839 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13841 if (!epiloguep
|| call_used_regs
[i
])
13842 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
13843 gen_rtx_REG (V4SImode
, i
));
13846 rtx reg
= gen_rtx_REG (V4SImode
, i
);
13849 = gen_rtx_SET (VOIDmode
,
13851 gen_rtx_UNSPEC (V4SImode
,
13852 gen_rtvec (1, reg
), 27));
13856 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
13858 for (i
= 0; i
< nclobs
; ++i
)
13859 XVECEXP (insn
, 0, i
) = clobs
[i
];
13864 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
13865 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
13868 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
13869 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
13871 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
13872 rtx replacea
, replaceb
;
13874 int_rtx
= GEN_INT (offset
);
13876 /* Some cases that need register indexed addressing. */
13877 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
13878 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
13880 && SPE_VECTOR_MODE (mode
)
13881 && !SPE_CONST_OFFSET_OK (offset
)))
13883 /* Whomever calls us must make sure r11 is available in the
13884 flow path of instructions in the prologue. */
13885 offset_rtx
= gen_rtx_REG (Pmode
, 11);
13886 emit_move_insn (offset_rtx
, int_rtx
);
13888 replacea
= offset_rtx
;
13889 replaceb
= int_rtx
;
13893 offset_rtx
= int_rtx
;
13894 replacea
= NULL_RTX
;
13895 replaceb
= NULL_RTX
;
13898 reg
= gen_rtx_REG (mode
, regno
);
13899 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
13900 mem
= gen_rtx_MEM (mode
, addr
);
13901 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13903 insn
= emit_move_insn (mem
, reg
);
13905 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
13908 /* Emit an offset memory reference suitable for a frame store, while
13909 converting to a valid addressing mode. */
13912 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
13914 rtx int_rtx
, offset_rtx
;
13916 int_rtx
= GEN_INT (offset
);
13918 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
13919 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
13921 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
13922 emit_move_insn (offset_rtx
, int_rtx
);
13925 offset_rtx
= int_rtx
;
13927 return gen_rtx_MEM (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
13930 /* Look for user-defined global regs. We should not save and restore these,
13931 and cannot use stmw/lmw if there are any in its range. */
13934 no_global_regs_above (int first_greg
)
13937 for (i
= 0; i
< 32 - first_greg
; i
++)
13938 if (global_regs
[first_greg
+ i
])
13943 #ifndef TARGET_FIX_AND_CONTINUE
13944 #define TARGET_FIX_AND_CONTINUE 0
13947 /* Emit function prologue as insns. */
13950 rs6000_emit_prologue (void)
13952 rs6000_stack_t
*info
= rs6000_stack_info ();
13953 enum machine_mode reg_mode
= Pmode
;
13954 int reg_size
= TARGET_32BIT
? 4 : 8;
13955 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
13956 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
13957 rtx frame_reg_rtx
= sp_reg_rtx
;
13958 rtx cr_save_rtx
= NULL_RTX
;
13960 int saving_FPRs_inline
;
13961 int using_store_multiple
;
13962 HOST_WIDE_INT sp_offset
= 0;
13964 if (TARGET_FIX_AND_CONTINUE
)
13966 /* gdb on darwin arranges to forward a function from the old
13967 address by modifying the first 5 instructions of the function
13968 to branch to the overriding function. This is necessary to
13969 permit function pointers that point to the old function to
13970 actually forward to the new function. */
13971 emit_insn (gen_nop ());
13972 emit_insn (gen_nop ());
13973 emit_insn (gen_nop ());
13974 emit_insn (gen_nop ());
13975 emit_insn (gen_nop ());
13978 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
13980 reg_mode
= V2SImode
;
13984 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
13985 && (!TARGET_SPE_ABI
13986 || info
->spe_64bit_regs_used
== 0)
13987 && info
->first_gp_reg_save
< 31
13988 && no_global_regs_above (info
->first_gp_reg_save
));
13989 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
13990 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
13991 || current_function_calls_eh_return
13992 || cfun
->machine
->ra_need_lr
);
13994 /* For V.4, update stack before we do any saving and set back pointer. */
13996 && (DEFAULT_ABI
== ABI_V4
13997 || current_function_calls_eh_return
))
13999 if (info
->total_size
< 32767)
14000 sp_offset
= info
->total_size
;
14002 frame_reg_rtx
= frame_ptr_rtx
;
14003 rs6000_emit_allocate_stack (info
->total_size
,
14004 (frame_reg_rtx
!= sp_reg_rtx
14005 && (info
->cr_save_p
14007 || info
->first_fp_reg_save
< 64
14008 || info
->first_gp_reg_save
< 32
14010 if (frame_reg_rtx
!= sp_reg_rtx
)
14011 rs6000_emit_stack_tie ();
14014 /* Handle world saves specially here. */
14015 if (WORLD_SAVE_P (info
))
14021 /* save_world expects lr in r0. */
14022 if (info
->lr_save_p
)
14024 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
14025 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14026 RTX_FRAME_RELATED_P (insn
) = 1;
14029 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14030 assumptions about the offsets of various bits of the stack
14032 gcc_assert (info
->gp_save_offset
== -220
14033 && info
->fp_save_offset
== -144
14034 && info
->lr_save_offset
== 8
14035 && info
->cr_save_offset
== 4
14038 && (!current_function_calls_eh_return
14039 || info
->ehrd_offset
== -432)
14040 && info
->vrsave_save_offset
== -224
14041 && info
->altivec_save_offset
== (-224 -16 -192));
14043 treg
= gen_rtx_REG (SImode
, 11);
14044 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
14046 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14047 in R11. It also clobbers R12, so beware! */
14049 /* Preserve CR2 for save_world prologues */
14051 sz
+= 32 - info
->first_gp_reg_save
;
14052 sz
+= 64 - info
->first_fp_reg_save
;
14053 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
14054 p
= rtvec_alloc (sz
);
14056 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
14057 gen_rtx_REG (Pmode
,
14058 LINK_REGISTER_REGNUM
));
14059 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
14060 gen_rtx_SYMBOL_REF (Pmode
,
14062 /* We do floats first so that the instruction pattern matches
14064 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14066 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14067 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14068 GEN_INT (info
->fp_save_offset
14069 + sp_offset
+ 8 * i
));
14070 rtx mem
= gen_rtx_MEM (DFmode
, addr
);
14071 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14073 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14075 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
14077 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
14078 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14079 GEN_INT (info
->altivec_save_offset
14080 + sp_offset
+ 16 * i
));
14081 rtx mem
= gen_rtx_MEM (V4SImode
, addr
);
14082 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14084 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14086 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14088 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14089 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14090 GEN_INT (info
->gp_save_offset
14091 + sp_offset
+ reg_size
* i
));
14092 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14093 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14095 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14099 /* CR register traditionally saved as CR2. */
14100 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
14101 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14102 GEN_INT (info
->cr_save_offset
14104 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14105 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14107 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14109 /* Prevent any attempt to delete the setting of r0 and treg! */
14110 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 0));
14111 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, treg
);
14112 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
, sp_reg_rtx
);
14114 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14115 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14116 NULL_RTX
, NULL_RTX
);
14118 if (current_function_calls_eh_return
)
14123 unsigned int regno
= EH_RETURN_DATA_REGNO (i
);
14124 if (regno
== INVALID_REGNUM
)
14126 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
14127 info
->ehrd_offset
+ sp_offset
14128 + reg_size
* (int) i
,
14134 /* Save AltiVec registers if needed. */
14135 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
14139 /* There should be a non inline version of this, for when we
14140 are saving lots of vector registers. */
14141 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14142 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14144 rtx areg
, savereg
, mem
;
14147 offset
= info
->altivec_save_offset
+ sp_offset
14148 + 16 * (i
- info
->first_altivec_reg_save
);
14150 savereg
= gen_rtx_REG (V4SImode
, i
);
14152 areg
= gen_rtx_REG (Pmode
, 0);
14153 emit_move_insn (areg
, GEN_INT (offset
));
14155 /* AltiVec addressing mode is [reg+reg]. */
14156 mem
= gen_rtx_MEM (V4SImode
,
14157 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
14159 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14161 insn
= emit_move_insn (mem
, savereg
);
14163 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14164 areg
, GEN_INT (offset
));
14168 /* VRSAVE is a bit vector representing which AltiVec registers
14169 are used. The OS uses this to determine which vector
14170 registers to save on a context switch. We need to save
14171 VRSAVE on the stack frame, add whatever AltiVec registers we
14172 used in this function, and do the corresponding magic in the
14175 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
14176 && info
->vrsave_mask
!= 0)
14178 rtx reg
, mem
, vrsave
;
14181 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14182 as frame_reg_rtx and r11 as the static chain pointer for
14183 nested functions. */
14184 reg
= gen_rtx_REG (SImode
, 0);
14185 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
14187 emit_insn (gen_get_vrsave_internal (reg
));
14189 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
14191 if (!WORLD_SAVE_P (info
))
14194 offset
= info
->vrsave_save_offset
+ sp_offset
;
14196 = gen_rtx_MEM (SImode
,
14197 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, GEN_INT (offset
)));
14198 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14199 insn
= emit_move_insn (mem
, reg
);
14202 /* Include the registers in the mask. */
14203 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
14205 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
14208 /* If we use the link register, get it into r0. */
14209 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
14211 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
14212 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14213 RTX_FRAME_RELATED_P (insn
) = 1;
14216 /* If we need to save CR, put it into r12. */
14217 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
14221 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
14222 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
14223 RTX_FRAME_RELATED_P (insn
) = 1;
14224 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14225 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14226 But that's OK. All we have to do is specify that _one_ condition
14227 code register is saved in this stack slot. The thrower's epilogue
14228 will then restore all the call-saved registers.
14229 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14230 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
14231 gen_rtx_REG (SImode
, CR2_REGNO
));
14232 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14237 /* Do any required saving of fpr's. If only one or two to save, do
14238 it ourselves. Otherwise, call function. */
14239 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
14242 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14243 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
14244 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
14245 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
14246 info
->first_fp_reg_save
+ i
,
14247 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
14250 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
14254 const char *alloc_rname
;
14256 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
14258 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
14259 gen_rtx_REG (Pmode
,
14260 LINK_REGISTER_REGNUM
));
14261 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
14262 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
14263 alloc_rname
= ggc_strdup (rname
);
14264 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
14265 gen_rtx_SYMBOL_REF (Pmode
,
14267 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14269 rtx addr
, reg
, mem
;
14270 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14271 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14272 GEN_INT (info
->fp_save_offset
14273 + sp_offset
+ 8*i
));
14274 mem
= gen_rtx_MEM (DFmode
, addr
);
14275 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14277 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14279 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14280 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14281 NULL_RTX
, NULL_RTX
);
14284 /* Save GPRs. This is done as a PARALLEL if we are using
14285 the store-multiple instructions. */
14286 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
14290 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14291 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14293 rtx addr
, reg
, mem
;
14294 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14295 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14296 GEN_INT (info
->gp_save_offset
14299 mem
= gen_rtx_MEM (reg_mode
, addr
);
14300 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14302 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14304 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14305 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14306 NULL_RTX
, NULL_RTX
);
14308 else if (!WORLD_SAVE_P (info
))
14311 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14312 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
14313 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
14314 || (i
+ info
->first_gp_reg_save
14315 == RS6000_PIC_OFFSET_TABLE_REGNUM
14316 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14317 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14318 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14319 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14321 rtx addr
, reg
, mem
;
14322 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14324 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14326 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14329 if (!SPE_CONST_OFFSET_OK (offset
))
14331 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14332 emit_move_insn (b
, GEN_INT (offset
));
14335 b
= GEN_INT (offset
);
14337 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
14338 mem
= gen_rtx_MEM (V2SImode
, addr
);
14339 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14340 insn
= emit_move_insn (mem
, reg
);
14342 if (GET_CODE (b
) == CONST_INT
)
14343 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14344 NULL_RTX
, NULL_RTX
);
14346 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14347 b
, GEN_INT (offset
));
14351 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14352 GEN_INT (info
->gp_save_offset
14355 mem
= gen_rtx_MEM (reg_mode
, addr
);
14356 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14358 insn
= emit_move_insn (mem
, reg
);
14359 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14360 NULL_RTX
, NULL_RTX
);
14365 /* ??? There's no need to emit actual instructions here, but it's the
14366 easiest way to get the frame unwind information emitted. */
14367 if (!WORLD_SAVE_P (info
) && current_function_calls_eh_return
)
14369 unsigned int i
, regno
;
14371 /* In AIX ABI we need to pretend we save r2 here. */
14374 rtx addr
, reg
, mem
;
14376 reg
= gen_rtx_REG (reg_mode
, 2);
14377 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14378 GEN_INT (sp_offset
+ 5 * reg_size
));
14379 mem
= gen_rtx_MEM (reg_mode
, addr
);
14380 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14382 insn
= emit_move_insn (mem
, reg
);
14383 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14384 NULL_RTX
, NULL_RTX
);
14385 PATTERN (insn
) = gen_blockage ();
14390 regno
= EH_RETURN_DATA_REGNO (i
);
14391 if (regno
== INVALID_REGNUM
)
14394 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
14395 info
->ehrd_offset
+ sp_offset
14396 + reg_size
* (int) i
,
14401 /* Save lr if we used it. */
14402 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
14404 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14405 GEN_INT (info
->lr_save_offset
+ sp_offset
));
14406 rtx reg
= gen_rtx_REG (Pmode
, 0);
14407 rtx mem
= gen_rtx_MEM (Pmode
, addr
);
14408 /* This should not be of rs6000_sr_alias_set, because of
14409 __builtin_return_address. */
14411 insn
= emit_move_insn (mem
, reg
);
14412 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14413 NULL_RTX
, NULL_RTX
);
14416 /* Save CR if we use any that must be preserved. */
14417 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
14419 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14420 GEN_INT (info
->cr_save_offset
+ sp_offset
));
14421 rtx mem
= gen_rtx_MEM (SImode
, addr
);
14422 /* See the large comment above about why CR2_REGNO is used. */
14423 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
14425 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14427 /* If r12 was used to hold the original sp, copy cr into r0 now
14429 if (REGNO (frame_reg_rtx
) == 12)
14433 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
14434 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
14435 RTX_FRAME_RELATED_P (insn
) = 1;
14436 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
14437 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14442 insn
= emit_move_insn (mem
, cr_save_rtx
);
14444 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14445 NULL_RTX
, NULL_RTX
);
14448 /* Update stack and set back pointer unless this is V.4,
14449 for which it was done previously. */
14450 if (!WORLD_SAVE_P (info
) && info
->push_p
14451 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
14452 rs6000_emit_allocate_stack (info
->total_size
, FALSE
);
14454 /* Set frame pointer, if needed. */
14455 if (frame_pointer_needed
)
14457 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
14459 RTX_FRAME_RELATED_P (insn
) = 1;
14462 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
14463 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
14464 || (DEFAULT_ABI
== ABI_V4
14465 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
14466 && regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
]))
14468 /* If emit_load_toc_table will use the link register, we need to save
14469 it. We use R12 for this purpose because emit_load_toc_table
14470 can use register 0. This allows us to use a plain 'blr' to return
14471 from the procedure more often. */
14472 int save_LR_around_toc_setup
= (TARGET_ELF
14473 && DEFAULT_ABI
!= ABI_AIX
14475 && ! info
->lr_save_p
14476 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
14477 if (save_LR_around_toc_setup
)
14479 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
14481 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
14482 rs6000_maybe_dead (insn
);
14483 RTX_FRAME_RELATED_P (insn
) = 1;
14485 rs6000_emit_load_toc_table (TRUE
);
14487 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
14488 rs6000_maybe_dead (insn
);
14489 RTX_FRAME_RELATED_P (insn
) = 1;
14492 rs6000_emit_load_toc_table (TRUE
);
14496 if (DEFAULT_ABI
== ABI_DARWIN
14497 && flag_pic
&& current_function_uses_pic_offset_table
)
14499 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
14500 rtx src
= machopic_function_base_sym ();
14502 /* Save and restore LR locally around this call (in R0). */
14503 if (!info
->lr_save_p
)
14504 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
));
14506 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr
, src
)));
14508 insn
= emit_move_insn (gen_rtx_REG (Pmode
,
14509 RS6000_PIC_OFFSET_TABLE_REGNUM
),
14511 rs6000_maybe_dead (insn
);
14513 if (!info
->lr_save_p
)
14514 rs6000_maybe_dead (emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0)));
14519 /* Write function prologue. */
14522 rs6000_output_function_prologue (FILE *file
,
14523 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
14525 rs6000_stack_t
*info
= rs6000_stack_info ();
14527 if (TARGET_DEBUG_STACK
)
14528 debug_stack_info (info
);
14530 /* Write .extern for any function we will call to save and restore
14532 if (info
->first_fp_reg_save
< 64
14533 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
14534 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
14535 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
14536 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
14537 RESTORE_FP_SUFFIX
);
14539 /* Write .extern for AIX common mode routines, if needed. */
14540 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
14542 fputs ("\t.extern __mulh\n", file
);
14543 fputs ("\t.extern __mull\n", file
);
14544 fputs ("\t.extern __divss\n", file
);
14545 fputs ("\t.extern __divus\n", file
);
14546 fputs ("\t.extern __quoss\n", file
);
14547 fputs ("\t.extern __quous\n", file
);
14548 common_mode_defined
= 1;
14551 if (! HAVE_prologue
)
14555 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
14556 the "toplevel" insn chain. */
14557 emit_note (NOTE_INSN_DELETED
);
14558 rs6000_emit_prologue ();
14559 emit_note (NOTE_INSN_DELETED
);
14561 /* Expand INSN_ADDRESSES so final() doesn't crash. */
14565 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
14567 INSN_ADDRESSES_NEW (insn
, addr
);
14572 if (TARGET_DEBUG_STACK
)
14573 debug_rtx_list (get_insns (), 100);
14574 final (get_insns (), file
, FALSE
);
14578 rs6000_pic_labelno
++;
14581 /* Emit function epilogue as insns.
14583 At present, dwarf2out_frame_debug_expr doesn't understand
14584 register restores, so we don't bother setting RTX_FRAME_RELATED_P
14585 anywhere in the epilogue. Most of the insns below would in any case
14586 need special notes to explain where r11 is in relation to the stack. */
14589 rs6000_emit_epilogue (int sibcall
)
14591 rs6000_stack_t
*info
;
14592 int restoring_FPRs_inline
;
14593 int using_load_multiple
;
14594 int using_mfcr_multiple
;
14595 int use_backchain_to_restore_sp
;
14597 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
14598 rtx frame_reg_rtx
= sp_reg_rtx
;
14599 enum machine_mode reg_mode
= Pmode
;
14600 int reg_size
= TARGET_32BIT
? 4 : 8;
14603 info
= rs6000_stack_info ();
14605 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14607 reg_mode
= V2SImode
;
14611 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
14612 && (!TARGET_SPE_ABI
14613 || info
->spe_64bit_regs_used
== 0)
14614 && info
->first_gp_reg_save
< 31
14615 && no_global_regs_above (info
->first_gp_reg_save
));
14616 restoring_FPRs_inline
= (sibcall
14617 || current_function_calls_eh_return
14618 || info
->first_fp_reg_save
== 64
14619 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
14620 use_backchain_to_restore_sp
= (frame_pointer_needed
14621 || current_function_calls_alloca
14622 || info
->total_size
> 32767);
14623 using_mfcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
14624 || rs6000_cpu
== PROCESSOR_PPC603
14625 || rs6000_cpu
== PROCESSOR_PPC750
14628 if (WORLD_SAVE_P (info
))
14632 const char *alloc_rname
;
14635 /* eh_rest_world_r10 will return to the location saved in the LR
14636 stack slot (which is not likely to be our caller.)
14637 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
14638 rest_world is similar, except any R10 parameter is ignored.
14639 The exception-handling stuff that was here in 2.95 is no
14640 longer necessary. */
14644 + 32 - info
->first_gp_reg_save
14645 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
14646 + 63 + 1 - info
->first_fp_reg_save
);
14648 strcpy (rname
, ((current_function_calls_eh_return
) ?
14649 "*eh_rest_world_r10" : "*rest_world"));
14650 alloc_rname
= ggc_strdup (rname
);
14653 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
14654 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
14655 gen_rtx_REG (Pmode
,
14656 LINK_REGISTER_REGNUM
));
14658 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
14659 /* The instruction pattern requires a clobber here;
14660 it is shared with the restVEC helper. */
14662 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
14665 /* CR register traditionally saved as CR2. */
14666 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
14667 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14668 GEN_INT (info
->cr_save_offset
));
14669 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14670 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14672 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14675 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14677 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14678 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14679 GEN_INT (info
->gp_save_offset
14681 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14682 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14684 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14686 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
14688 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
14689 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14690 GEN_INT (info
->altivec_save_offset
14692 rtx mem
= gen_rtx_MEM (V4SImode
, addr
);
14693 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14695 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14697 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
14699 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14700 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14701 GEN_INT (info
->fp_save_offset
14703 rtx mem
= gen_rtx_MEM (DFmode
, addr
);
14704 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14706 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14709 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
14711 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
14713 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
14715 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
14717 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
14718 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14723 /* If we have a frame pointer, a call to alloca, or a large stack
14724 frame, restore the old stack pointer using the backchain. Otherwise,
14725 we know what size to update it with. */
14726 if (use_backchain_to_restore_sp
)
14728 /* Under V.4, don't reset the stack pointer until after we're done
14729 loading the saved registers. */
14730 if (DEFAULT_ABI
== ABI_V4
)
14731 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
14733 emit_move_insn (frame_reg_rtx
,
14734 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
14737 else if (info
->push_p
)
14739 if (DEFAULT_ABI
== ABI_V4
14740 || current_function_calls_eh_return
)
14741 sp_offset
= info
->total_size
;
14744 emit_insn (TARGET_32BIT
14745 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
14746 GEN_INT (info
->total_size
))
14747 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
14748 GEN_INT (info
->total_size
)));
14752 /* Restore AltiVec registers if needed. */
14753 if (TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
14757 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14758 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14760 rtx addr
, areg
, mem
;
14762 areg
= gen_rtx_REG (Pmode
, 0);
14764 (areg
, GEN_INT (info
->altivec_save_offset
14766 + 16 * (i
- info
->first_altivec_reg_save
)));
14768 /* AltiVec addressing mode is [reg+reg]. */
14769 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
14770 mem
= gen_rtx_MEM (V4SImode
, addr
);
14771 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14773 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
14777 /* Restore VRSAVE if needed. */
14778 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
14779 && info
->vrsave_mask
!= 0)
14781 rtx addr
, mem
, reg
;
14783 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14784 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
14785 mem
= gen_rtx_MEM (SImode
, addr
);
14786 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14787 reg
= gen_rtx_REG (SImode
, 12);
14788 emit_move_insn (reg
, mem
);
14790 emit_insn (generate_set_vrsave (reg
, info
, 1));
14793 /* Get the old lr if we saved it. */
14794 if (info
->lr_save_p
)
14796 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
14797 info
->lr_save_offset
+ sp_offset
);
14799 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14801 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
14804 /* Get the old cr if we saved it. */
14805 if (info
->cr_save_p
)
14807 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14808 GEN_INT (info
->cr_save_offset
+ sp_offset
));
14809 rtx mem
= gen_rtx_MEM (SImode
, addr
);
14811 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14813 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
14816 /* Set LR here to try to overlap restores below. */
14817 if (info
->lr_save_p
)
14818 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
),
14819 gen_rtx_REG (Pmode
, 0));
14821 /* Load exception handler data registers, if needed. */
14822 if (current_function_calls_eh_return
)
14824 unsigned int i
, regno
;
14828 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14829 GEN_INT (sp_offset
+ 5 * reg_size
));
14830 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14832 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14834 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
14841 regno
= EH_RETURN_DATA_REGNO (i
);
14842 if (regno
== INVALID_REGNUM
)
14845 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
14846 info
->ehrd_offset
+ sp_offset
14847 + reg_size
* (int) i
);
14848 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14850 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
14854 /* Restore GPRs. This is done as a PARALLEL if we are using
14855 the load-multiple instructions. */
14856 if (using_load_multiple
)
14859 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14860 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14862 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14863 GEN_INT (info
->gp_save_offset
14866 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14868 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14871 gen_rtx_SET (VOIDmode
,
14872 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
14875 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14878 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14879 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
14880 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
14881 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14882 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14883 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14884 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14885 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14887 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14888 GEN_INT (info
->gp_save_offset
14891 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14893 /* Restore 64-bit quantities for SPE. */
14894 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14896 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14899 if (!SPE_CONST_OFFSET_OK (offset
))
14901 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14902 emit_move_insn (b
, GEN_INT (offset
));
14905 b
= GEN_INT (offset
);
14907 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
14908 mem
= gen_rtx_MEM (V2SImode
, addr
);
14911 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14913 emit_move_insn (gen_rtx_REG (reg_mode
,
14914 info
->first_gp_reg_save
+ i
), mem
);
14917 /* Restore fpr's if we need to do it without calling a function. */
14918 if (restoring_FPRs_inline
)
14919 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14920 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
14921 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
14924 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14925 GEN_INT (info
->fp_save_offset
14928 mem
= gen_rtx_MEM (DFmode
, addr
);
14929 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14931 emit_move_insn (gen_rtx_REG (DFmode
,
14932 info
->first_fp_reg_save
+ i
),
14936 /* If we saved cr, restore it here. Just those that were used. */
14937 if (info
->cr_save_p
)
14939 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
14942 if (using_mfcr_multiple
)
14944 for (i
= 0; i
< 8; i
++)
14945 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14947 gcc_assert (count
);
14950 if (using_mfcr_multiple
&& count
> 1)
14955 p
= rtvec_alloc (count
);
14958 for (i
= 0; i
< 8; i
++)
14959 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14961 rtvec r
= rtvec_alloc (2);
14962 RTVEC_ELT (r
, 0) = r12_rtx
;
14963 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
14964 RTVEC_ELT (p
, ndx
) =
14965 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
14966 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
14969 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14970 gcc_assert (ndx
== count
);
14973 for (i
= 0; i
< 8; i
++)
14974 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14976 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
14982 /* If this is V.4, unwind the stack pointer after all of the loads
14983 have been done. We need to emit a block here so that sched
14984 doesn't decide to move the sp change before the register restores
14985 (which may not have any obvious dependency on the stack). This
14986 doesn't hurt performance, because there is no scheduling that can
14987 be done after this point. */
14988 if (DEFAULT_ABI
== ABI_V4
14989 || current_function_calls_eh_return
)
14991 if (frame_reg_rtx
!= sp_reg_rtx
)
14992 rs6000_emit_stack_tie ();
14994 if (use_backchain_to_restore_sp
)
14996 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
14998 else if (sp_offset
!= 0)
15000 emit_insn (TARGET_32BIT
15001 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
15002 GEN_INT (sp_offset
))
15003 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
15004 GEN_INT (sp_offset
)));
15008 if (current_function_calls_eh_return
)
15010 rtx sa
= EH_RETURN_STACKADJ_RTX
;
15011 emit_insn (TARGET_32BIT
15012 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
15013 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
15019 if (! restoring_FPRs_inline
)
15020 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
15022 p
= rtvec_alloc (2);
15024 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
15025 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
15026 gen_rtx_REG (Pmode
,
15027 LINK_REGISTER_REGNUM
));
15029 /* If we have to restore more than two FP registers, branch to the
15030 restore function. It will return to our caller. */
15031 if (! restoring_FPRs_inline
)
15035 const char *alloc_rname
;
15037 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
15038 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
15039 alloc_rname
= ggc_strdup (rname
);
15040 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
15041 gen_rtx_SYMBOL_REF (Pmode
,
15044 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15047 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
15048 GEN_INT (info
->fp_save_offset
+ 8*i
));
15049 mem
= gen_rtx_MEM (DFmode
, addr
);
15050 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
15052 RTVEC_ELT (p
, i
+3) =
15053 gen_rtx_SET (VOIDmode
,
15054 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
15059 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15063 /* Write function epilogue. */
15066 rs6000_output_function_epilogue (FILE *file
,
15067 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
15069 rs6000_stack_t
*info
= rs6000_stack_info ();
15071 if (! HAVE_epilogue
)
15073 rtx insn
= get_last_insn ();
15074 /* If the last insn was a BARRIER, we don't have to write anything except
15075 the trace table. */
15076 if (GET_CODE (insn
) == NOTE
)
15077 insn
= prev_nonnote_insn (insn
);
15078 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
15080 /* This is slightly ugly, but at least we don't have two
15081 copies of the epilogue-emitting code. */
15084 /* A NOTE_INSN_DELETED is supposed to be at the start
15085 and end of the "toplevel" insn chain. */
15086 emit_note (NOTE_INSN_DELETED
);
15087 rs6000_emit_epilogue (FALSE
);
15088 emit_note (NOTE_INSN_DELETED
);
15090 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15094 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
15096 INSN_ADDRESSES_NEW (insn
, addr
);
15101 if (TARGET_DEBUG_STACK
)
15102 debug_rtx_list (get_insns (), 100);
15103 final (get_insns (), file
, FALSE
);
15109 macho_branch_islands ();
15110 /* Mach-O doesn't support labels at the end of objects, so if
15111 it looks like we might want one, insert a NOP. */
15113 rtx insn
= get_last_insn ();
15116 && NOTE_LINE_NUMBER (insn
) != NOTE_INSN_DELETED_LABEL
)
15117 insn
= PREV_INSN (insn
);
15121 && NOTE_LINE_NUMBER (insn
) == NOTE_INSN_DELETED_LABEL
)))
15122 fputs ("\tnop\n", file
);
15126 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15129 We don't output a traceback table if -finhibit-size-directive was
15130 used. The documentation for -finhibit-size-directive reads
15131 ``don't output a @code{.size} assembler directive, or anything
15132 else that would cause trouble if the function is split in the
15133 middle, and the two halves are placed at locations far apart in
15134 memory.'' The traceback table has this property, since it
15135 includes the offset from the start of the function to the
15136 traceback table itself.
15138 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15139 different traceback table. */
15140 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
15141 && rs6000_traceback
!= traceback_none
)
15143 const char *fname
= NULL
;
15144 const char *language_string
= lang_hooks
.name
;
15145 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
15147 int optional_tbtab
;
15149 if (rs6000_traceback
== traceback_full
)
15150 optional_tbtab
= 1;
15151 else if (rs6000_traceback
== traceback_part
)
15152 optional_tbtab
= 0;
15154 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
15156 if (optional_tbtab
)
15158 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
15159 while (*fname
== '.') /* V.4 encodes . in the name */
15162 /* Need label immediately before tbtab, so we can compute
15163 its offset from the function start. */
15164 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15165 ASM_OUTPUT_LABEL (file
, fname
);
15168 /* The .tbtab pseudo-op can only be used for the first eight
15169 expressions, since it can't handle the possibly variable
15170 length fields that follow. However, if you omit the optional
15171 fields, the assembler outputs zeros for all optional fields
15172 anyways, giving each variable length field is minimum length
15173 (as defined in sys/debug.h). Thus we can not use the .tbtab
15174 pseudo-op at all. */
15176 /* An all-zero word flags the start of the tbtab, for debuggers
15177 that have to find it by searching forward from the entry
15178 point or from the current pc. */
15179 fputs ("\t.long 0\n", file
);
15181 /* Tbtab format type. Use format type 0. */
15182 fputs ("\t.byte 0,", file
);
15184 /* Language type. Unfortunately, there does not seem to be any
15185 official way to discover the language being compiled, so we
15186 use language_string.
15187 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15188 Java is 13. Objective-C is 14. */
15189 if (! strcmp (language_string
, "GNU C"))
15191 else if (! strcmp (language_string
, "GNU F77")
15192 || ! strcmp (language_string
, "GNU F95"))
15194 else if (! strcmp (language_string
, "GNU Pascal"))
15196 else if (! strcmp (language_string
, "GNU Ada"))
15198 else if (! strcmp (language_string
, "GNU C++"))
15200 else if (! strcmp (language_string
, "GNU Java"))
15202 else if (! strcmp (language_string
, "GNU Objective-C"))
15205 gcc_unreachable ();
15206 fprintf (file
, "%d,", i
);
15208 /* 8 single bit fields: global linkage (not set for C extern linkage,
15209 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15210 from start of procedure stored in tbtab, internal function, function
15211 has controlled storage, function has no toc, function uses fp,
15212 function logs/aborts fp operations. */
15213 /* Assume that fp operations are used if any fp reg must be saved. */
15214 fprintf (file
, "%d,",
15215 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
15217 /* 6 bitfields: function is interrupt handler, name present in
15218 proc table, function calls alloca, on condition directives
15219 (controls stack walks, 3 bits), saves condition reg, saves
15221 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15222 set up as a frame pointer, even when there is no alloca call. */
15223 fprintf (file
, "%d,",
15224 ((optional_tbtab
<< 6)
15225 | ((optional_tbtab
& frame_pointer_needed
) << 5)
15226 | (info
->cr_save_p
<< 1)
15227 | (info
->lr_save_p
)));
15229 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15231 fprintf (file
, "%d,",
15232 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
15234 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15235 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
15237 if (optional_tbtab
)
15239 /* Compute the parameter info from the function decl argument
15242 int next_parm_info_bit
= 31;
15244 for (decl
= DECL_ARGUMENTS (current_function_decl
);
15245 decl
; decl
= TREE_CHAIN (decl
))
15247 rtx parameter
= DECL_INCOMING_RTL (decl
);
15248 enum machine_mode mode
= GET_MODE (parameter
);
15250 if (GET_CODE (parameter
) == REG
)
15252 if (SCALAR_FLOAT_MODE_P (mode
))
15270 gcc_unreachable ();
15273 /* If only one bit will fit, don't or in this entry. */
15274 if (next_parm_info_bit
> 0)
15275 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
15276 next_parm_info_bit
-= 2;
15280 fixed_parms
+= ((GET_MODE_SIZE (mode
)
15281 + (UNITS_PER_WORD
- 1))
15283 next_parm_info_bit
-= 1;
15289 /* Number of fixed point parameters. */
15290 /* This is actually the number of words of fixed point parameters; thus
15291 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15292 fprintf (file
, "%d,", fixed_parms
);
15294 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15296 /* This is actually the number of fp registers that hold parameters;
15297 and thus the maximum value is 13. */
15298 /* Set parameters on stack bit if parameters are not in their original
15299 registers, regardless of whether they are on the stack? Xlc
15300 seems to set the bit when not optimizing. */
15301 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
15303 if (! optional_tbtab
)
15306 /* Optional fields follow. Some are variable length. */
15308 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15309 11 double float. */
15310 /* There is an entry for each parameter in a register, in the order that
15311 they occur in the parameter list. Any intervening arguments on the
15312 stack are ignored. If the list overflows a long (max possible length
15313 34 bits) then completely leave off all elements that don't fit. */
15314 /* Only emit this long if there was at least one parameter. */
15315 if (fixed_parms
|| float_parms
)
15316 fprintf (file
, "\t.long %d\n", parm_info
);
15318 /* Offset from start of code to tb table. */
15319 fputs ("\t.long ", file
);
15320 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15322 RS6000_OUTPUT_BASENAME (file
, fname
);
15324 assemble_name (file
, fname
);
15326 rs6000_output_function_entry (file
, fname
);
15329 /* Interrupt handler mask. */
15330 /* Omit this long, since we never set the interrupt handler bit
15333 /* Number of CTL (controlled storage) anchors. */
15334 /* Omit this long, since the has_ctl bit is never set above. */
15336 /* Displacement into stack of each CTL anchor. */
15337 /* Omit this list of longs, because there are no CTL anchors. */
15339 /* Length of function name. */
15342 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
15344 /* Function name. */
15345 assemble_string (fname
, strlen (fname
));
15347 /* Register for alloca automatic storage; this is always reg 31.
15348 Only emit this if the alloca bit was set above. */
15349 if (frame_pointer_needed
)
15350 fputs ("\t.byte 31\n", file
);
15352 fputs ("\t.align 2\n", file
);
15356 /* A C compound statement that outputs the assembler code for a thunk
15357 function, used to implement C++ virtual function calls with
15358 multiple inheritance. The thunk acts as a wrapper around a virtual
15359 function, adjusting the implicit object parameter before handing
15360 control off to the real function.
15362 First, emit code to add the integer DELTA to the location that
15363 contains the incoming first argument. Assume that this argument
15364 contains a pointer, and is the one used to pass the `this' pointer
15365 in C++. This is the incoming argument *before* the function
15366 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15367 values of all other incoming arguments.
15369 After the addition, emit code to jump to FUNCTION, which is a
15370 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15371 not touch the return address. Hence returning from FUNCTION will
15372 return to whoever called the current `thunk'.
15374 The effect must be as if FUNCTION had been called directly with the
15375 adjusted first argument. This macro is responsible for emitting
15376 all of the code for a thunk function; output_function_prologue()
15377 and output_function_epilogue() are not invoked.
15379 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15380 been extracted from it.) It might possibly be useful on some
15381 targets, but probably not.
15383 If you do not define this macro, the target-independent code in the
15384 C++ frontend will generate a less efficient heavyweight thunk that
15385 calls FUNCTION instead of jumping to it. The generic approach does
15386 not support varargs. */
15389 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
15390 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
15393 rtx
this, insn
, funexp
;
15395 reload_completed
= 1;
15396 epilogue_completed
= 1;
15397 no_new_pseudos
= 1;
15398 reset_block_changes ();
15400 /* Mark the end of the (empty) prologue. */
15401 emit_note (NOTE_INSN_PROLOGUE_END
);
15403 /* Find the "this" pointer. If the function returns a structure,
15404 the structure return pointer is in r3. */
15405 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
15406 this = gen_rtx_REG (Pmode
, 4);
15408 this = gen_rtx_REG (Pmode
, 3);
15410 /* Apply the constant offset, if required. */
15413 rtx delta_rtx
= GEN_INT (delta
);
15414 emit_insn (TARGET_32BIT
15415 ? gen_addsi3 (this, this, delta_rtx
)
15416 : gen_adddi3 (this, this, delta_rtx
));
15419 /* Apply the offset from the vtable, if required. */
15422 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
15423 rtx tmp
= gen_rtx_REG (Pmode
, 12);
15425 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
15426 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
15428 emit_insn (TARGET_32BIT
15429 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
15430 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
15431 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
15435 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
15437 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
15439 emit_insn (TARGET_32BIT
15440 ? gen_addsi3 (this, this, tmp
)
15441 : gen_adddi3 (this, this, tmp
));
15444 /* Generate a tail call to the target function. */
15445 if (!TREE_USED (function
))
15447 assemble_external (function
);
15448 TREE_USED (function
) = 1;
15450 funexp
= XEXP (DECL_RTL (function
), 0);
15451 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
15454 if (MACHOPIC_INDIRECT
)
15455 funexp
= machopic_indirect_call_target (funexp
);
15458 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15459 generate sibcall RTL explicitly. */
15460 insn
= emit_call_insn (
15461 gen_rtx_PARALLEL (VOIDmode
,
15463 gen_rtx_CALL (VOIDmode
,
15464 funexp
, const0_rtx
),
15465 gen_rtx_USE (VOIDmode
, const0_rtx
),
15466 gen_rtx_USE (VOIDmode
,
15467 gen_rtx_REG (SImode
,
15468 LINK_REGISTER_REGNUM
)),
15469 gen_rtx_RETURN (VOIDmode
))));
15470 SIBLING_CALL_P (insn
) = 1;
15473 /* Run just enough of rest_of_compilation to get the insns emitted.
15474 There's not really enough bulk here to make other passes such as
15475 instruction scheduling worth while. Note that use_thunk calls
15476 assemble_start_function and assemble_end_function. */
15477 insn
= get_insns ();
15478 insn_locators_initialize ();
15479 shorten_branches (insn
);
15480 final_start_function (insn
, file
, 1);
15481 final (insn
, file
, 1);
15482 final_end_function ();
15484 reload_completed
= 0;
15485 epilogue_completed
= 0;
15486 no_new_pseudos
= 0;
15489 /* A quick summary of the various types of 'constant-pool tables'
15492 Target Flags Name One table per
15493 AIX (none) AIX TOC object file
15494 AIX -mfull-toc AIX TOC object file
15495 AIX -mminimal-toc AIX minimal TOC translation unit
15496 SVR4/EABI (none) SVR4 SDATA object file
15497 SVR4/EABI -fpic SVR4 pic object file
15498 SVR4/EABI -fPIC SVR4 PIC translation unit
15499 SVR4/EABI -mrelocatable EABI TOC function
15500 SVR4/EABI -maix AIX TOC object file
15501 SVR4/EABI -maix -mminimal-toc
15502 AIX minimal TOC translation unit
15504 Name Reg. Set by entries contains:
15505 made by addrs? fp? sum?
15507 AIX TOC 2 crt0 as Y option option
15508 AIX minimal TOC 30 prolog gcc Y Y option
15509 SVR4 SDATA 13 crt0 gcc N Y N
15510 SVR4 pic 30 prolog ld Y not yet N
15511 SVR4 PIC 30 prolog gcc Y option option
15512 EABI TOC 30 prolog gcc Y option option
15516 /* Hash functions for the hash table. */
15519 rs6000_hash_constant (rtx k
)
15521 enum rtx_code code
= GET_CODE (k
);
15522 enum machine_mode mode
= GET_MODE (k
);
15523 unsigned result
= (code
<< 3) ^ mode
;
15524 const char *format
;
15527 format
= GET_RTX_FORMAT (code
);
15528 flen
= strlen (format
);
15534 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
15537 if (mode
!= VOIDmode
)
15538 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
15550 for (; fidx
< flen
; fidx
++)
15551 switch (format
[fidx
])
15556 const char *str
= XSTR (k
, fidx
);
15557 len
= strlen (str
);
15558 result
= result
* 613 + len
;
15559 for (i
= 0; i
< len
; i
++)
15560 result
= result
* 613 + (unsigned) str
[i
];
15565 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
15569 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
15572 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
15573 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
15577 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
15578 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
15585 gcc_unreachable ();
15592 toc_hash_function (const void *hash_entry
)
15594 const struct toc_hash_struct
*thc
=
15595 (const struct toc_hash_struct
*) hash_entry
;
15596 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
15599 /* Compare H1 and H2 for equivalence. */
15602 toc_hash_eq (const void *h1
, const void *h2
)
15604 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
15605 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
15607 if (((const struct toc_hash_struct
*) h1
)->key_mode
15608 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
15611 return rtx_equal_p (r1
, r2
);
15614 /* These are the names given by the C++ front-end to vtables, and
15615 vtable-like objects. Ideally, this logic should not be here;
15616 instead, there should be some programmatic way of inquiring as
15617 to whether or not an object is a vtable. */
15619 #define VTABLE_NAME_P(NAME) \
15620 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
15621 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
15622 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
15623 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
15624 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
15627 rs6000_output_symbol_ref (FILE *file
, rtx x
)
15629 /* Currently C++ toc references to vtables can be emitted before it
15630 is decided whether the vtable is public or private. If this is
15631 the case, then the linker will eventually complain that there is
15632 a reference to an unknown section. Thus, for vtables only,
15633 we emit the TOC reference to reference the symbol and not the
15635 const char *name
= XSTR (x
, 0);
15637 if (VTABLE_NAME_P (name
))
15639 RS6000_OUTPUT_BASENAME (file
, name
);
15642 assemble_name (file
, name
);
15645 /* Output a TOC entry. We derive the entry name from what is being
15649 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
15652 const char *name
= buf
;
15653 const char *real_name
;
15655 HOST_WIDE_INT offset
= 0;
15657 gcc_assert (!TARGET_NO_TOC
);
15659 /* When the linker won't eliminate them, don't output duplicate
15660 TOC entries (this happens on AIX if there is any kind of TOC,
15661 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
15663 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
15665 struct toc_hash_struct
*h
;
15668 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
15669 time because GGC is not initialized at that point. */
15670 if (toc_hash_table
== NULL
)
15671 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
15672 toc_hash_eq
, NULL
);
15674 h
= ggc_alloc (sizeof (*h
));
15676 h
->key_mode
= mode
;
15677 h
->labelno
= labelno
;
15679 found
= htab_find_slot (toc_hash_table
, h
, 1);
15680 if (*found
== NULL
)
15682 else /* This is indeed a duplicate.
15683 Set this label equal to that label. */
15685 fputs ("\t.set ", file
);
15686 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
15687 fprintf (file
, "%d,", labelno
);
15688 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
15689 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
15695 /* If we're going to put a double constant in the TOC, make sure it's
15696 aligned properly when strict alignment is on. */
15697 if (GET_CODE (x
) == CONST_DOUBLE
15698 && STRICT_ALIGNMENT
15699 && GET_MODE_BITSIZE (mode
) >= 64
15700 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
15701 ASM_OUTPUT_ALIGN (file
, 3);
15704 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
15706 /* Handle FP constants specially. Note that if we have a minimal
15707 TOC, things we put here aren't actually in the TOC, so we can allow
15709 if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == TFmode
)
15711 REAL_VALUE_TYPE rv
;
15714 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
15715 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
15719 if (TARGET_MINIMAL_TOC
)
15720 fputs (DOUBLE_INT_ASM_OP
, file
);
15722 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15723 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15724 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15725 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
15726 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15727 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15732 if (TARGET_MINIMAL_TOC
)
15733 fputs ("\t.long ", file
);
15735 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15736 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15737 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15738 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
15739 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15740 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15744 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == DFmode
)
15746 REAL_VALUE_TYPE rv
;
15749 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
15750 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
15754 if (TARGET_MINIMAL_TOC
)
15755 fputs (DOUBLE_INT_ASM_OP
, file
);
15757 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
15758 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15759 fprintf (file
, "0x%lx%08lx\n",
15760 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15765 if (TARGET_MINIMAL_TOC
)
15766 fputs ("\t.long ", file
);
15768 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
15769 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15770 fprintf (file
, "0x%lx,0x%lx\n",
15771 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15775 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == SFmode
)
15777 REAL_VALUE_TYPE rv
;
15780 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
15781 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
15785 if (TARGET_MINIMAL_TOC
)
15786 fputs (DOUBLE_INT_ASM_OP
, file
);
15788 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
15789 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
15794 if (TARGET_MINIMAL_TOC
)
15795 fputs ("\t.long ", file
);
15797 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
15798 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
15802 else if (GET_MODE (x
) == VOIDmode
15803 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
15805 unsigned HOST_WIDE_INT low
;
15806 HOST_WIDE_INT high
;
15808 if (GET_CODE (x
) == CONST_DOUBLE
)
15810 low
= CONST_DOUBLE_LOW (x
);
15811 high
= CONST_DOUBLE_HIGH (x
);
15814 #if HOST_BITS_PER_WIDE_INT == 32
15817 high
= (low
& 0x80000000) ? ~0 : 0;
15821 low
= INTVAL (x
) & 0xffffffff;
15822 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
15826 /* TOC entries are always Pmode-sized, but since this
15827 is a bigendian machine then if we're putting smaller
15828 integer constants in the TOC we have to pad them.
15829 (This is still a win over putting the constants in
15830 a separate constant pool, because then we'd have
15831 to have both a TOC entry _and_ the actual constant.)
15833 For a 32-bit target, CONST_INT values are loaded and shifted
15834 entirely within `low' and can be stored in one TOC entry. */
15836 /* It would be easy to make this work, but it doesn't now. */
15837 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
15839 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
15841 #if HOST_BITS_PER_WIDE_INT == 32
15842 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
15843 POINTER_SIZE
, &low
, &high
, 0);
15846 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
15847 high
= (HOST_WIDE_INT
) low
>> 32;
15854 if (TARGET_MINIMAL_TOC
)
15855 fputs (DOUBLE_INT_ASM_OP
, file
);
15857 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15858 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15859 fprintf (file
, "0x%lx%08lx\n",
15860 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15865 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
15867 if (TARGET_MINIMAL_TOC
)
15868 fputs ("\t.long ", file
);
15870 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15871 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15872 fprintf (file
, "0x%lx,0x%lx\n",
15873 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15877 if (TARGET_MINIMAL_TOC
)
15878 fputs ("\t.long ", file
);
15880 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
15881 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
15887 if (GET_CODE (x
) == CONST
)
15889 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
15891 base
= XEXP (XEXP (x
, 0), 0);
15892 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
15895 switch (GET_CODE (base
))
15898 name
= XSTR (base
, 0);
15902 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
15903 CODE_LABEL_NUMBER (XEXP (base
, 0)));
15907 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
15911 gcc_unreachable ();
15914 real_name
= (*targetm
.strip_name_encoding
) (name
);
15915 if (TARGET_MINIMAL_TOC
)
15916 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
15919 fprintf (file
, "\t.tc %s", real_name
);
15922 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
15924 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
15926 fputs ("[TC],", file
);
15929 /* Currently C++ toc references to vtables can be emitted before it
15930 is decided whether the vtable is public or private. If this is
15931 the case, then the linker will eventually complain that there is
15932 a TOC reference to an unknown section. Thus, for vtables only,
15933 we emit the TOC reference to reference the symbol and not the
15935 if (VTABLE_NAME_P (name
))
15937 RS6000_OUTPUT_BASENAME (file
, name
);
15939 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
15940 else if (offset
> 0)
15941 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
15944 output_addr_const (file
, x
);
15948 /* Output an assembler pseudo-op to write an ASCII string of N characters
15949 starting at P to FILE.
15951 On the RS/6000, we have to do this using the .byte operation and
15952 write out special characters outside the quoted string.
15953 Also, the assembler is broken; very long strings are truncated,
15954 so we must artificially break them up early. */
15957 output_ascii (FILE *file
, const char *p
, int n
)
15960 int i
, count_string
;
15961 const char *for_string
= "\t.byte \"";
15962 const char *for_decimal
= "\t.byte ";
15963 const char *to_close
= NULL
;
15966 for (i
= 0; i
< n
; i
++)
15969 if (c
>= ' ' && c
< 0177)
15972 fputs (for_string
, file
);
15975 /* Write two quotes to get one. */
15983 for_decimal
= "\"\n\t.byte ";
15987 if (count_string
>= 512)
15989 fputs (to_close
, file
);
15991 for_string
= "\t.byte \"";
15992 for_decimal
= "\t.byte ";
16000 fputs (for_decimal
, file
);
16001 fprintf (file
, "%d", c
);
16003 for_string
= "\n\t.byte \"";
16004 for_decimal
= ", ";
16010 /* Now close the string if we have written one. Then end the line. */
16012 fputs (to_close
, file
);
16015 /* Generate a unique section name for FILENAME for a section type
16016 represented by SECTION_DESC. Output goes into BUF.
16018 SECTION_DESC can be any string, as long as it is different for each
16019 possible section type.
16021 We name the section in the same manner as xlc. The name begins with an
16022 underscore followed by the filename (after stripping any leading directory
16023 names) with the last period replaced by the string SECTION_DESC. If
16024 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16028 rs6000_gen_section_name (char **buf
, const char *filename
,
16029 const char *section_desc
)
16031 const char *q
, *after_last_slash
, *last_period
= 0;
16035 after_last_slash
= filename
;
16036 for (q
= filename
; *q
; q
++)
16039 after_last_slash
= q
+ 1;
16040 else if (*q
== '.')
16044 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
16045 *buf
= (char *) xmalloc (len
);
16050 for (q
= after_last_slash
; *q
; q
++)
16052 if (q
== last_period
)
16054 strcpy (p
, section_desc
);
16055 p
+= strlen (section_desc
);
16059 else if (ISALNUM (*q
))
16063 if (last_period
== 0)
16064 strcpy (p
, section_desc
);
16069 /* Emit profile function. */
16072 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
16074 /* Non-standard profiling for kernels, which just saves LR then calls
16075 _mcount without worrying about arg saves. The idea is to change
16076 the function prologue as little as possible as it isn't easy to
16077 account for arg save/restore code added just for _mcount. */
16078 if (TARGET_PROFILE_KERNEL
)
16081 if (DEFAULT_ABI
== ABI_AIX
)
16083 #ifndef NO_PROFILE_COUNTERS
16084 # define NO_PROFILE_COUNTERS 0
16086 if (NO_PROFILE_COUNTERS
)
16087 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
16091 const char *label_name
;
16094 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16095 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
16096 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
16098 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
16102 else if (DEFAULT_ABI
== ABI_DARWIN
)
16104 const char *mcount_name
= RS6000_MCOUNT
;
16105 int caller_addr_regno
= LINK_REGISTER_REGNUM
;
16107 /* Be conservative and always set this, at least for now. */
16108 current_function_uses_pic_offset_table
= 1;
16111 /* For PIC code, set up a stub and collect the caller's address
16112 from r0, which is where the prologue puts it. */
16113 if (MACHOPIC_INDIRECT
16114 && current_function_uses_pic_offset_table
)
16115 caller_addr_regno
= 0;
16117 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
16119 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
16123 /* Write function profiler code. */
16126 output_function_profiler (FILE *file
, int labelno
)
16130 switch (DEFAULT_ABI
)
16133 gcc_unreachable ();
16138 warning (0, "no profiling of 64-bit code for this ABI");
16141 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16142 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16143 if (NO_PROFILE_COUNTERS
)
16145 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16146 reg_names
[0], reg_names
[1]);
16148 else if (TARGET_SECURE_PLT
&& flag_pic
)
16150 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16151 reg_names
[0], reg_names
[1]);
16152 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16153 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
16154 reg_names
[12], reg_names
[12]);
16155 assemble_name (file
, buf
);
16156 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
16157 assemble_name (file
, buf
);
16158 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
16160 else if (flag_pic
== 1)
16162 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
16163 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16164 reg_names
[0], reg_names
[1]);
16165 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16166 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
16167 assemble_name (file
, buf
);
16168 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
16170 else if (flag_pic
> 1)
16172 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16173 reg_names
[0], reg_names
[1]);
16174 /* Now, we need to get the address of the label. */
16175 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
16176 assemble_name (file
, buf
);
16177 fputs ("-.\n1:", file
);
16178 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
16179 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
16180 reg_names
[0], reg_names
[11]);
16181 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
16182 reg_names
[0], reg_names
[0], reg_names
[11]);
16186 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
16187 assemble_name (file
, buf
);
16188 fputs ("@ha\n", file
);
16189 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16190 reg_names
[0], reg_names
[1]);
16191 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
16192 assemble_name (file
, buf
);
16193 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
16196 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16197 fprintf (file
, "\tbl %s%s\n",
16198 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
16203 if (!TARGET_PROFILE_KERNEL
)
16205 /* Don't do anything, done in output_profile_hook (). */
16209 gcc_assert (!TARGET_32BIT
);
16211 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16212 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
16214 if (cfun
->static_chain_decl
!= NULL
)
16216 asm_fprintf (file
, "\tstd %s,24(%s)\n",
16217 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16218 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16219 asm_fprintf (file
, "\tld %s,24(%s)\n",
16220 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16223 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16230 /* Power4 load update and store update instructions are cracked into a
16231 load or store and an integer insn which are executed in the same cycle.
16232 Branches have their own dispatch slot which does not count against the
16233 GCC issue rate, but it changes the program flow so there are no other
16234 instructions to issue in this cycle. */
16237 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
16238 int verbose ATTRIBUTE_UNUSED
,
16239 rtx insn
, int more
)
16241 if (GET_CODE (PATTERN (insn
)) == USE
16242 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16245 if (rs6000_sched_groups
)
16247 if (is_microcoded_insn (insn
))
16249 else if (is_cracked_insn (insn
))
16250 return more
> 2 ? more
- 2 : 0;
16256 /* Adjust the cost of a scheduling dependency. Return the new cost of
16257 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16260 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
16262 if (! recog_memoized (insn
))
16265 if (REG_NOTE_KIND (link
) != 0)
16268 if (REG_NOTE_KIND (link
) == 0)
16270 /* Data dependency; DEP_INSN writes a register that INSN reads
16271 some cycles later. */
16273 /* Separate a load from a narrower, dependent store. */
16274 if (rs6000_sched_groups
16275 && GET_CODE (PATTERN (insn
)) == SET
16276 && GET_CODE (PATTERN (dep_insn
)) == SET
16277 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
16278 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
16279 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
16280 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
16283 switch (get_attr_type (insn
))
16286 /* Tell the first scheduling pass about the latency between
16287 a mtctr and bctr (and mtlr and br/blr). The first
16288 scheduling pass will not know about this latency since
16289 the mtctr instruction, which has the latency associated
16290 to it, will be generated by reload. */
16291 return TARGET_POWER
? 5 : 4;
16293 /* Leave some extra cycles between a compare and its
16294 dependent branch, to inhibit expensive mispredicts. */
16295 if ((rs6000_cpu_attr
== CPU_PPC603
16296 || rs6000_cpu_attr
== CPU_PPC604
16297 || rs6000_cpu_attr
== CPU_PPC604E
16298 || rs6000_cpu_attr
== CPU_PPC620
16299 || rs6000_cpu_attr
== CPU_PPC630
16300 || rs6000_cpu_attr
== CPU_PPC750
16301 || rs6000_cpu_attr
== CPU_PPC7400
16302 || rs6000_cpu_attr
== CPU_PPC7450
16303 || rs6000_cpu_attr
== CPU_POWER4
16304 || rs6000_cpu_attr
== CPU_POWER5
)
16305 && recog_memoized (dep_insn
)
16306 && (INSN_CODE (dep_insn
) >= 0)
16307 && (get_attr_type (dep_insn
) == TYPE_CMP
16308 || get_attr_type (dep_insn
) == TYPE_COMPARE
16309 || get_attr_type (dep_insn
) == TYPE_DELAYED_COMPARE
16310 || get_attr_type (dep_insn
) == TYPE_IMUL_COMPARE
16311 || get_attr_type (dep_insn
) == TYPE_LMUL_COMPARE
16312 || get_attr_type (dep_insn
) == TYPE_FPCOMPARE
16313 || get_attr_type (dep_insn
) == TYPE_CR_LOGICAL
16314 || get_attr_type (dep_insn
) == TYPE_DELAYED_CR
))
16319 /* Fall out to return default cost. */
16325 /* The function returns a true if INSN is microcoded.
16326 Return false otherwise. */
16329 is_microcoded_insn (rtx insn
)
16331 if (!insn
|| !INSN_P (insn
)
16332 || GET_CODE (PATTERN (insn
)) == USE
16333 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16336 if (rs6000_sched_groups
)
16338 enum attr_type type
= get_attr_type (insn
);
16339 if (type
== TYPE_LOAD_EXT_U
16340 || type
== TYPE_LOAD_EXT_UX
16341 || type
== TYPE_LOAD_UX
16342 || type
== TYPE_STORE_UX
16343 || type
== TYPE_MFCR
)
16350 /* The function returns a nonzero value if INSN can be scheduled only
16351 as the first insn in a dispatch group ("dispatch-slot restricted").
16352 In this case, the returned value indicates how many dispatch slots
16353 the insn occupies (at the beginning of the group).
16354 Return 0 otherwise. */
16357 is_dispatch_slot_restricted (rtx insn
)
16359 enum attr_type type
;
16361 if (!rs6000_sched_groups
)
16365 || insn
== NULL_RTX
16366 || GET_CODE (insn
) == NOTE
16367 || GET_CODE (PATTERN (insn
)) == USE
16368 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16371 type
= get_attr_type (insn
);
16378 case TYPE_DELAYED_CR
:
16379 case TYPE_CR_LOGICAL
:
16392 if (rs6000_cpu
== PROCESSOR_POWER5
16393 && is_cracked_insn (insn
))
16399 /* The function returns true if INSN is cracked into 2 instructions
16400 by the processor (and therefore occupies 2 issue slots). */
16403 is_cracked_insn (rtx insn
)
16405 if (!insn
|| !INSN_P (insn
)
16406 || GET_CODE (PATTERN (insn
)) == USE
16407 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16410 if (rs6000_sched_groups
)
16412 enum attr_type type
= get_attr_type (insn
);
16413 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
16414 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
16415 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
16416 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
16417 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
16418 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
16419 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
16420 || type
== TYPE_INSERT_WORD
)
16427 /* The function returns true if INSN can be issued only from
16428 the branch slot. */
16431 is_branch_slot_insn (rtx insn
)
16433 if (!insn
|| !INSN_P (insn
)
16434 || GET_CODE (PATTERN (insn
)) == USE
16435 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16438 if (rs6000_sched_groups
)
16440 enum attr_type type
= get_attr_type (insn
);
16441 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
16449 /* A C statement (sans semicolon) to update the integer scheduling
16450 priority INSN_PRIORITY (INSN). Increase the priority to execute the
16451 INSN earlier, reduce the priority to execute INSN later. Do not
16452 define this macro if you do not need to adjust the scheduling
16453 priorities of insns. */
16456 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
16458 /* On machines (like the 750) which have asymmetric integer units,
16459 where one integer unit can do multiply and divides and the other
16460 can't, reduce the priority of multiply/divide so it is scheduled
16461 before other integer operations. */
16464 if (! INSN_P (insn
))
16467 if (GET_CODE (PATTERN (insn
)) == USE
)
16470 switch (rs6000_cpu_attr
) {
16472 switch (get_attr_type (insn
))
16479 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
16480 priority
, priority
);
16481 if (priority
>= 0 && priority
< 0x01000000)
16488 if (is_dispatch_slot_restricted (insn
)
16489 && reload_completed
16490 && current_sched_info
->sched_max_insns_priority
16491 && rs6000_sched_restricted_insns_priority
)
16494 /* Prioritize insns that can be dispatched only in the first
16496 if (rs6000_sched_restricted_insns_priority
== 1)
16497 /* Attach highest priority to insn. This means that in
16498 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
16499 precede 'priority' (critical path) considerations. */
16500 return current_sched_info
->sched_max_insns_priority
;
16501 else if (rs6000_sched_restricted_insns_priority
== 2)
16502 /* Increase priority of insn by a minimal amount. This means that in
16503 haifa-sched.c:ready_sort(), only 'priority' (critical path)
16504 considerations precede dispatch-slot restriction considerations. */
16505 return (priority
+ 1);
16511 /* Return how many instructions the machine can issue per cycle. */
16514 rs6000_issue_rate (void)
16516 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
16517 if (!reload_completed
)
16520 switch (rs6000_cpu_attr
) {
16521 case CPU_RIOS1
: /* ? */
16523 case CPU_PPC601
: /* ? */
16546 /* Return how many instructions to look ahead for better insn
16550 rs6000_use_sched_lookahead (void)
16552 if (rs6000_cpu_attr
== CPU_PPC8540
)
16557 /* Determine is PAT refers to memory. */
16560 is_mem_ref (rtx pat
)
16566 if (GET_CODE (pat
) == MEM
)
16569 /* Recursively process the pattern. */
16570 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
16572 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
16575 ret
|= is_mem_ref (XEXP (pat
, i
));
16576 else if (fmt
[i
] == 'E')
16577 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
16578 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
16584 /* Determine if PAT is a PATTERN of a load insn. */
16587 is_load_insn1 (rtx pat
)
16589 if (!pat
|| pat
== NULL_RTX
)
16592 if (GET_CODE (pat
) == SET
)
16593 return is_mem_ref (SET_SRC (pat
));
16595 if (GET_CODE (pat
) == PARALLEL
)
16599 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
16600 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
16607 /* Determine if INSN loads from memory. */
16610 is_load_insn (rtx insn
)
16612 if (!insn
|| !INSN_P (insn
))
16615 if (GET_CODE (insn
) == CALL_INSN
)
16618 return is_load_insn1 (PATTERN (insn
));
16621 /* Determine if PAT is a PATTERN of a store insn. */
16624 is_store_insn1 (rtx pat
)
16626 if (!pat
|| pat
== NULL_RTX
)
16629 if (GET_CODE (pat
) == SET
)
16630 return is_mem_ref (SET_DEST (pat
));
16632 if (GET_CODE (pat
) == PARALLEL
)
16636 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
16637 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
16644 /* Determine if INSN stores to memory. */
16647 is_store_insn (rtx insn
)
16649 if (!insn
|| !INSN_P (insn
))
16652 return is_store_insn1 (PATTERN (insn
));
16655 /* Returns whether the dependence between INSN and NEXT is considered
16656 costly by the given target. */
16659 rs6000_is_costly_dependence (rtx insn
, rtx next
, rtx link
, int cost
,
16662 /* If the flag is not enabled - no dependence is considered costly;
16663 allow all dependent insns in the same group.
16664 This is the most aggressive option. */
16665 if (rs6000_sched_costly_dep
== no_dep_costly
)
16668 /* If the flag is set to 1 - a dependence is always considered costly;
16669 do not allow dependent instructions in the same group.
16670 This is the most conservative option. */
16671 if (rs6000_sched_costly_dep
== all_deps_costly
)
16674 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
16675 && is_load_insn (next
)
16676 && is_store_insn (insn
))
16677 /* Prevent load after store in the same group. */
16680 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
16681 && is_load_insn (next
)
16682 && is_store_insn (insn
)
16683 && (!link
|| (int) REG_NOTE_KIND (link
) == 0))
16684 /* Prevent load after store in the same group if it is a true
16688 /* The flag is set to X; dependences with latency >= X are considered costly,
16689 and will not be scheduled in the same group. */
16690 if (rs6000_sched_costly_dep
<= max_dep_latency
16691 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
16697 /* Return the next insn after INSN that is found before TAIL is reached,
16698 skipping any "non-active" insns - insns that will not actually occupy
16699 an issue slot. Return NULL_RTX if such an insn is not found. */
16702 get_next_active_insn (rtx insn
, rtx tail
)
16704 if (insn
== NULL_RTX
|| insn
== tail
)
16709 insn
= NEXT_INSN (insn
);
16710 if (insn
== NULL_RTX
|| insn
== tail
)
16715 || (NONJUMP_INSN_P (insn
)
16716 && GET_CODE (PATTERN (insn
)) != USE
16717 && GET_CODE (PATTERN (insn
)) != CLOBBER
16718 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
16724 /* Return whether the presence of INSN causes a dispatch group termination
16725 of group WHICH_GROUP.
16727 If WHICH_GROUP == current_group, this function will return true if INSN
16728 causes the termination of the current group (i.e, the dispatch group to
16729 which INSN belongs). This means that INSN will be the last insn in the
16730 group it belongs to.
16732 If WHICH_GROUP == previous_group, this function will return true if INSN
16733 causes the termination of the previous group (i.e, the dispatch group that
16734 precedes the group to which INSN belongs). This means that INSN will be
16735 the first insn in the group it belongs to). */
16738 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
16740 enum attr_type type
;
16745 type
= get_attr_type (insn
);
16747 if (is_microcoded_insn (insn
))
16750 if (which_group
== current_group
)
16752 if (is_branch_slot_insn (insn
))
16756 else if (which_group
== previous_group
)
16758 if (is_dispatch_slot_restricted (insn
))
16766 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
16767 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
16770 is_costly_group (rtx
*group_insns
, rtx next_insn
)
16775 int issue_rate
= rs6000_issue_rate ();
16777 for (i
= 0; i
< issue_rate
; i
++)
16779 rtx insn
= group_insns
[i
];
16782 for (link
= INSN_DEPEND (insn
); link
!= 0; link
= XEXP (link
, 1))
16784 rtx next
= XEXP (link
, 0);
16785 if (next
== next_insn
)
16787 cost
= insn_cost (insn
, link
, next_insn
);
16788 if (rs6000_is_costly_dependence (insn
, next_insn
, link
, cost
, 0))
16797 /* Utility of the function redefine_groups.
16798 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
16799 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
16800 to keep it "far" (in a separate group) from GROUP_INSNS, following
16801 one of the following schemes, depending on the value of the flag
16802 -minsert_sched_nops = X:
16803 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
16804 in order to force NEXT_INSN into a separate group.
16805 (2) X < sched_finish_regroup_exact: insert exactly X nops.
16806 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
16807 insertion (has a group just ended, how many vacant issue slots remain in the
16808 last group, and how many dispatch groups were encountered so far). */
16811 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
16812 rtx next_insn
, bool *group_end
, int can_issue_more
,
16817 int issue_rate
= rs6000_issue_rate ();
16818 bool end
= *group_end
;
16821 if (next_insn
== NULL_RTX
)
16822 return can_issue_more
;
16824 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
16825 return can_issue_more
;
16827 force
= is_costly_group (group_insns
, next_insn
);
16829 return can_issue_more
;
16831 if (sched_verbose
> 6)
16832 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
16833 *group_count
,can_issue_more
);
16835 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
16838 can_issue_more
= 0;
16840 /* Since only a branch can be issued in the last issue_slot, it is
16841 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
16842 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
16843 in this case the last nop will start a new group and the branch
16844 will be forced to the new group. */
16845 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
16848 while (can_issue_more
> 0)
16851 emit_insn_before (nop
, next_insn
);
16859 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
16861 int n_nops
= rs6000_sched_insert_nops
;
16863 /* Nops can't be issued from the branch slot, so the effective
16864 issue_rate for nops is 'issue_rate - 1'. */
16865 if (can_issue_more
== 0)
16866 can_issue_more
= issue_rate
;
16868 if (can_issue_more
== 0)
16870 can_issue_more
= issue_rate
- 1;
16873 for (i
= 0; i
< issue_rate
; i
++)
16875 group_insns
[i
] = 0;
16882 emit_insn_before (nop
, next_insn
);
16883 if (can_issue_more
== issue_rate
- 1) /* new group begins */
16886 if (can_issue_more
== 0)
16888 can_issue_more
= issue_rate
- 1;
16891 for (i
= 0; i
< issue_rate
; i
++)
16893 group_insns
[i
] = 0;
16899 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
16902 /* Is next_insn going to start a new group? */
16905 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
16906 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
16907 || (can_issue_more
< issue_rate
&&
16908 insn_terminates_group_p (next_insn
, previous_group
)));
16909 if (*group_end
&& end
)
16912 if (sched_verbose
> 6)
16913 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
16914 *group_count
, can_issue_more
);
16915 return can_issue_more
;
16918 return can_issue_more
;
16921 /* This function tries to synch the dispatch groups that the compiler "sees"
16922 with the dispatch groups that the processor dispatcher is expected to
16923 form in practice. It tries to achieve this synchronization by forcing the
16924 estimated processor grouping on the compiler (as opposed to the function
16925 'pad_goups' which tries to force the scheduler's grouping on the processor).
16927 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
16928 examines the (estimated) dispatch groups that will be formed by the processor
16929 dispatcher. It marks these group boundaries to reflect the estimated
16930 processor grouping, overriding the grouping that the scheduler had marked.
16931 Depending on the value of the flag '-minsert-sched-nops' this function can
16932 force certain insns into separate groups or force a certain distance between
16933 them by inserting nops, for example, if there exists a "costly dependence"
16936 The function estimates the group boundaries that the processor will form as
16937 follows: It keeps track of how many vacant issue slots are available after
16938 each insn. A subsequent insn will start a new group if one of the following
16940 - no more vacant issue slots remain in the current dispatch group.
16941 - only the last issue slot, which is the branch slot, is vacant, but the next
16942 insn is not a branch.
16943 - only the last 2 or less issue slots, including the branch slot, are vacant,
16944 which means that a cracked insn (which occupies two issue slots) can't be
16945 issued in this group.
16946 - less than 'issue_rate' slots are vacant, and the next insn always needs to
16947 start a new group. */
16950 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
16952 rtx insn
, next_insn
;
16954 int can_issue_more
;
16957 int group_count
= 0;
16961 issue_rate
= rs6000_issue_rate ();
16962 group_insns
= alloca (issue_rate
* sizeof (rtx
));
16963 for (i
= 0; i
< issue_rate
; i
++)
16965 group_insns
[i
] = 0;
16967 can_issue_more
= issue_rate
;
16969 insn
= get_next_active_insn (prev_head_insn
, tail
);
16972 while (insn
!= NULL_RTX
)
16974 slot
= (issue_rate
- can_issue_more
);
16975 group_insns
[slot
] = insn
;
16977 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
16978 if (insn_terminates_group_p (insn
, current_group
))
16979 can_issue_more
= 0;
16981 next_insn
= get_next_active_insn (insn
, tail
);
16982 if (next_insn
== NULL_RTX
)
16983 return group_count
+ 1;
16985 /* Is next_insn going to start a new group? */
16987 = (can_issue_more
== 0
16988 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
16989 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
16990 || (can_issue_more
< issue_rate
&&
16991 insn_terminates_group_p (next_insn
, previous_group
)));
16993 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
16994 next_insn
, &group_end
, can_issue_more
,
17000 can_issue_more
= 0;
17001 for (i
= 0; i
< issue_rate
; i
++)
17003 group_insns
[i
] = 0;
17007 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
17008 PUT_MODE (next_insn
, VOIDmode
);
17009 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
17010 PUT_MODE (next_insn
, TImode
);
17013 if (can_issue_more
== 0)
17014 can_issue_more
= issue_rate
;
17017 return group_count
;
17020 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
17021 dispatch group boundaries that the scheduler had marked. Pad with nops
17022 any dispatch groups which have vacant issue slots, in order to force the
17023 scheduler's grouping on the processor dispatcher. The function
17024 returns the number of dispatch groups found. */
17027 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
17029 rtx insn
, next_insn
;
17032 int can_issue_more
;
17034 int group_count
= 0;
17036 /* Initialize issue_rate. */
17037 issue_rate
= rs6000_issue_rate ();
17038 can_issue_more
= issue_rate
;
17040 insn
= get_next_active_insn (prev_head_insn
, tail
);
17041 next_insn
= get_next_active_insn (insn
, tail
);
17043 while (insn
!= NULL_RTX
)
17046 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
17048 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
17050 if (next_insn
== NULL_RTX
)
17055 /* If the scheduler had marked group termination at this location
17056 (between insn and next_indn), and neither insn nor next_insn will
17057 force group termination, pad the group with nops to force group
17060 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
17061 && !insn_terminates_group_p (insn
, current_group
)
17062 && !insn_terminates_group_p (next_insn
, previous_group
))
17064 if (!is_branch_slot_insn (next_insn
))
17067 while (can_issue_more
)
17070 emit_insn_before (nop
, next_insn
);
17075 can_issue_more
= issue_rate
;
17080 next_insn
= get_next_active_insn (insn
, tail
);
17083 return group_count
;
17086 /* The following function is called at the end of scheduling BB.
17087 After reload, it inserts nops at insn group bundling. */
17090 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
17095 fprintf (dump
, "=== Finishing schedule.\n");
17097 if (reload_completed
&& rs6000_sched_groups
)
17099 if (rs6000_sched_insert_nops
== sched_finish_none
)
17102 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
17103 n_groups
= pad_groups (dump
, sched_verbose
,
17104 current_sched_info
->prev_head
,
17105 current_sched_info
->next_tail
);
17107 n_groups
= redefine_groups (dump
, sched_verbose
,
17108 current_sched_info
->prev_head
,
17109 current_sched_info
->next_tail
);
17111 if (sched_verbose
>= 6)
17113 fprintf (dump
, "ngroups = %d\n", n_groups
);
17114 print_rtl (dump
, current_sched_info
->prev_head
);
17115 fprintf (dump
, "Done finish_sched\n");
17120 /* Length in units of the trampoline for entering a nested function. */
17123 rs6000_trampoline_size (void)
17127 switch (DEFAULT_ABI
)
17130 gcc_unreachable ();
17133 ret
= (TARGET_32BIT
) ? 12 : 24;
17138 ret
= (TARGET_32BIT
) ? 40 : 48;
17145 /* Emit RTL insns to initialize the variable parts of a trampoline.
17146 FNADDR is an RTX for the address of the function's pure code.
17147 CXT is an RTX for the static chain value for the function. */
17150 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
17152 enum machine_mode pmode
= Pmode
;
17153 int regsize
= (TARGET_32BIT
) ? 4 : 8;
17154 rtx ctx_reg
= force_reg (pmode
, cxt
);
17156 switch (DEFAULT_ABI
)
17159 gcc_unreachable ();
17161 /* Macros to shorten the code expansions below. */
17162 #define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
17163 #define MEM_PLUS(addr,offset) \
17164 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
17166 /* Under AIX, just build the 3 word function descriptor */
17169 rtx fn_reg
= gen_reg_rtx (pmode
);
17170 rtx toc_reg
= gen_reg_rtx (pmode
);
17171 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
17172 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
17173 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
17174 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
17175 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
17179 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
17182 emit_library_call (gen_rtx_SYMBOL_REF (SImode
, "__trampoline_setup"),
17183 FALSE
, VOIDmode
, 4,
17185 GEN_INT (rs6000_trampoline_size ()), SImode
,
17195 /* Table of valid machine attributes. */
17197 const struct attribute_spec rs6000_attribute_table
[] =
17199 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
17200 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
17201 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
17202 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
17203 #ifdef SUBTARGET_ATTRIBUTE_TABLE
17204 SUBTARGET_ATTRIBUTE_TABLE
,
17206 { NULL
, 0, 0, false, false, false, NULL
}
17209 /* Handle the "altivec" attribute. The attribute may have
17210 arguments as follows:
17212 __attribute__((altivec(vector__)))
17213 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
17214 __attribute__((altivec(bool__))) (always followed by 'unsigned')
17216 and may appear more than once (e.g., 'vector bool char') in a
17217 given declaration. */
17220 rs6000_handle_altivec_attribute (tree
*node
,
17221 tree name ATTRIBUTE_UNUSED
,
17223 int flags ATTRIBUTE_UNUSED
,
17224 bool *no_add_attrs
)
17226 tree type
= *node
, result
= NULL_TREE
;
17227 enum machine_mode mode
;
17230 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
17231 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
17232 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
17235 while (POINTER_TYPE_P (type
)
17236 || TREE_CODE (type
) == FUNCTION_TYPE
17237 || TREE_CODE (type
) == METHOD_TYPE
17238 || TREE_CODE (type
) == ARRAY_TYPE
)
17239 type
= TREE_TYPE (type
);
17241 mode
= TYPE_MODE (type
);
17243 /* Check for invalid AltiVec type qualifiers. */
17244 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
17247 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
17248 else if (rs6000_warn_altivec_long
)
17249 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
17251 else if (type
== long_long_unsigned_type_node
17252 || type
== long_long_integer_type_node
)
17253 error ("use of %<long long%> in AltiVec types is invalid");
17254 else if (type
== double_type_node
)
17255 error ("use of %<double%> in AltiVec types is invalid");
17256 else if (type
== long_double_type_node
)
17257 error ("use of %<long double%> in AltiVec types is invalid");
17258 else if (type
== boolean_type_node
)
17259 error ("use of boolean types in AltiVec types is invalid");
17260 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
17261 error ("use of %<complex%> in AltiVec types is invalid");
17263 switch (altivec_type
)
17266 unsigned_p
= TYPE_UNSIGNED (type
);
17270 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
17273 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
17276 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
17278 case SFmode
: result
= V4SF_type_node
; break;
17279 /* If the user says 'vector int bool', we may be handed the 'bool'
17280 attribute _before_ the 'vector' attribute, and so select the
17281 proper type in the 'b' case below. */
17282 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
17290 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
17291 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
17292 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
17299 case V8HImode
: result
= pixel_V8HI_type_node
;
17305 if (result
&& result
!= type
&& TYPE_READONLY (type
))
17306 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
17308 *no_add_attrs
= true; /* No need to hang on to the attribute. */
17311 *node
= reconstruct_complex_type (*node
, result
);
17316 /* AltiVec defines four built-in scalar types that serve as vector
17317 elements; we must teach the compiler how to mangle them. */
17319 static const char *
17320 rs6000_mangle_fundamental_type (tree type
)
17322 if (type
== bool_char_type_node
) return "U6__boolc";
17323 if (type
== bool_short_type_node
) return "U6__bools";
17324 if (type
== pixel_type_node
) return "u7__pixel";
17325 if (type
== bool_int_type_node
) return "U6__booli";
17327 /* For all other types, use normal C++ mangling. */
17331 /* Handle a "longcall" or "shortcall" attribute; arguments as in
17332 struct attribute_spec.handler. */
17335 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
17336 tree args ATTRIBUTE_UNUSED
,
17337 int flags ATTRIBUTE_UNUSED
,
17338 bool *no_add_attrs
)
17340 if (TREE_CODE (*node
) != FUNCTION_TYPE
17341 && TREE_CODE (*node
) != FIELD_DECL
17342 && TREE_CODE (*node
) != TYPE_DECL
)
17344 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
17345 IDENTIFIER_POINTER (name
));
17346 *no_add_attrs
= true;
17352 /* Set longcall attributes on all functions declared when
17353 rs6000_default_long_calls is true. */
17355 rs6000_set_default_type_attributes (tree type
)
17357 if (rs6000_default_long_calls
17358 && (TREE_CODE (type
) == FUNCTION_TYPE
17359 || TREE_CODE (type
) == METHOD_TYPE
))
17360 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
17362 TYPE_ATTRIBUTES (type
));
17365 /* Return a reference suitable for calling a function with the
17366 longcall attribute. */
17369 rs6000_longcall_ref (rtx call_ref
)
17371 const char *call_name
;
17374 if (GET_CODE (call_ref
) != SYMBOL_REF
)
17377 /* System V adds '.' to the internal name, so skip them. */
17378 call_name
= XSTR (call_ref
, 0);
17379 if (*call_name
== '.')
17381 while (*call_name
== '.')
17384 node
= get_identifier (call_name
);
17385 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
17388 return force_reg (Pmode
, call_ref
);
17391 #ifdef USING_ELFOS_H
17393 /* A C statement or statements to switch to the appropriate section
17394 for output of RTX in mode MODE. You can assume that RTX is some
17395 kind of constant in RTL. The argument MODE is redundant except in
17396 the case of a `const_int' rtx. Select the section by calling
17397 `text_section' or one of the alternatives for other sections.
17399 Do not define this macro if you put all constants in the read-only
17403 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
17404 unsigned HOST_WIDE_INT align
)
17406 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
17409 default_elf_select_rtx_section (mode
, x
, align
);
17412 /* A C statement or statements to switch to the appropriate
17413 section for output of DECL. DECL is either a `VAR_DECL' node
17414 or a constant of some sort. RELOC indicates whether forming
17415 the initial value of DECL requires link-time relocations. */
17418 rs6000_elf_select_section (tree decl
, int reloc
,
17419 unsigned HOST_WIDE_INT align
)
17421 /* Pretend that we're always building for a shared library when
17422 ABI_AIX, because otherwise we end up with dynamic relocations
17423 in read-only sections. This happens for function pointers,
17424 references to vtables in typeinfo, and probably other cases. */
17425 default_elf_select_section_1 (decl
, reloc
, align
,
17426 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
17429 /* A C statement to build up a unique section name, expressed as a
17430 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
17431 RELOC indicates whether the initial value of EXP requires
17432 link-time relocations. If you do not define this macro, GCC will use
17433 the symbol name prefixed by `.' as the section name. Note - this
17434 macro can now be called for uninitialized data items as well as
17435 initialized data and functions. */
17438 rs6000_elf_unique_section (tree decl
, int reloc
)
17440 /* As above, pretend that we're always building for a shared library
17441 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
17442 default_unique_section_1 (decl
, reloc
,
17443 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
17446 /* For a SYMBOL_REF, set generic flags and then perform some
17447 target-specific processing.
17449 When the AIX ABI is requested on a non-AIX system, replace the
17450 function name with the real name (with a leading .) rather than the
17451 function descriptor name. This saves a lot of overriding code to
17452 read the prefixes. */
17455 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
17457 default_encode_section_info (decl
, rtl
, first
);
17460 && TREE_CODE (decl
) == FUNCTION_DECL
17462 && DEFAULT_ABI
== ABI_AIX
)
17464 rtx sym_ref
= XEXP (rtl
, 0);
17465 size_t len
= strlen (XSTR (sym_ref
, 0));
17466 char *str
= alloca (len
+ 2);
17468 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
17469 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
17474 rs6000_elf_in_small_data_p (tree decl
)
17476 if (rs6000_sdata
== SDATA_NONE
)
17479 /* We want to merge strings, so we never consider them small data. */
17480 if (TREE_CODE (decl
) == STRING_CST
)
17483 /* Functions are never in the small data area. */
17484 if (TREE_CODE (decl
) == FUNCTION_DECL
)
17487 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
17489 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
17490 if (strcmp (section
, ".sdata") == 0
17491 || strcmp (section
, ".sdata2") == 0
17492 || strcmp (section
, ".sbss") == 0
17493 || strcmp (section
, ".sbss2") == 0
17494 || strcmp (section
, ".PPC.EMB.sdata0") == 0
17495 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
17500 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
17503 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
17504 /* If it's not public, and we're not going to reference it there,
17505 there's no need to put it in the small data section. */
17506 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
17513 #endif /* USING_ELFOS_H */
17516 /* Return a REG that occurs in ADDR with coefficient 1.
17517 ADDR can be effectively incremented by incrementing REG.
17519 r0 is special and we must not select it as an address
17520 register by this routine since our caller will try to
17521 increment the returned register via an "la" instruction. */
17524 find_addr_reg (rtx addr
)
17526 while (GET_CODE (addr
) == PLUS
)
17528 if (GET_CODE (XEXP (addr
, 0)) == REG
17529 && REGNO (XEXP (addr
, 0)) != 0)
17530 addr
= XEXP (addr
, 0);
17531 else if (GET_CODE (XEXP (addr
, 1)) == REG
17532 && REGNO (XEXP (addr
, 1)) != 0)
17533 addr
= XEXP (addr
, 1);
17534 else if (CONSTANT_P (XEXP (addr
, 0)))
17535 addr
= XEXP (addr
, 1);
17536 else if (CONSTANT_P (XEXP (addr
, 1)))
17537 addr
= XEXP (addr
, 0);
17539 gcc_unreachable ();
17541 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
17546 rs6000_fatal_bad_address (rtx op
)
17548 fatal_insn ("bad address", op
);
17553 static tree branch_island_list
= 0;
17555 /* Remember to generate a branch island for far calls to the given
17559 add_compiler_branch_island (tree label_name
, tree function_name
,
17562 tree branch_island
= build_tree_list (function_name
, label_name
);
17563 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
17564 TREE_CHAIN (branch_island
) = branch_island_list
;
17565 branch_island_list
= branch_island
;
17568 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
17569 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
17570 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
17571 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
17573 /* Generate far-jump branch islands for everything on the
17574 branch_island_list. Invoked immediately after the last instruction
17575 of the epilogue has been emitted; the branch-islands must be
17576 appended to, and contiguous with, the function body. Mach-O stubs
17577 are generated in machopic_output_stub(). */
17580 macho_branch_islands (void)
17583 tree branch_island
;
17585 for (branch_island
= branch_island_list
;
17587 branch_island
= TREE_CHAIN (branch_island
))
17589 const char *label
=
17590 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
17592 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
17593 char name_buf
[512];
17594 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
17595 if (name
[0] == '*' || name
[0] == '&')
17596 strcpy (name_buf
, name
+1);
17600 strcpy (name_buf
+1, name
);
17602 strcpy (tmp_buf
, "\n");
17603 strcat (tmp_buf
, label
);
17604 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17605 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
17606 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
17607 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17610 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
17611 strcat (tmp_buf
, label
);
17612 strcat (tmp_buf
, "_pic\n");
17613 strcat (tmp_buf
, label
);
17614 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
17616 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
17617 strcat (tmp_buf
, name_buf
);
17618 strcat (tmp_buf
, " - ");
17619 strcat (tmp_buf
, label
);
17620 strcat (tmp_buf
, "_pic)\n");
17622 strcat (tmp_buf
, "\tmtlr r0\n");
17624 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
17625 strcat (tmp_buf
, name_buf
);
17626 strcat (tmp_buf
, " - ");
17627 strcat (tmp_buf
, label
);
17628 strcat (tmp_buf
, "_pic)\n");
17630 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
17634 strcat (tmp_buf
, ":\nlis r12,hi16(");
17635 strcat (tmp_buf
, name_buf
);
17636 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
17637 strcat (tmp_buf
, name_buf
);
17638 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
17640 output_asm_insn (tmp_buf
, 0);
17641 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17642 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
17643 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
17644 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17647 branch_island_list
= 0;
17650 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
17651 already there or not. */
17654 no_previous_def (tree function_name
)
17656 tree branch_island
;
17657 for (branch_island
= branch_island_list
;
17659 branch_island
= TREE_CHAIN (branch_island
))
17660 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
17665 /* GET_PREV_LABEL gets the label name from the previous definition of
17669 get_prev_label (tree function_name
)
17671 tree branch_island
;
17672 for (branch_island
= branch_island_list
;
17674 branch_island
= TREE_CHAIN (branch_island
))
17675 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
17676 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
17680 /* INSN is either a function call or a millicode call. It may have an
17681 unconditional jump in its delay slot.
17683 CALL_DEST is the routine we are calling. */
17686 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
17687 int cookie_operand_number
)
17689 static char buf
[256];
17690 if (GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
17691 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
17694 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
17696 if (no_previous_def (funname
))
17698 int line_number
= 0;
17699 rtx label_rtx
= gen_label_rtx ();
17700 char *label_buf
, temp_buf
[256];
17701 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
17702 CODE_LABEL_NUMBER (label_rtx
));
17703 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
17704 labelname
= get_identifier (label_buf
);
17705 for (; insn
&& GET_CODE (insn
) != NOTE
; insn
= PREV_INSN (insn
));
17707 line_number
= NOTE_LINE_NUMBER (insn
);
17708 add_compiler_branch_island (labelname
, funname
, line_number
);
17711 labelname
= get_prev_label (funname
);
17713 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
17714 instruction will reach 'foo', otherwise link as 'bl L42'".
17715 "L42" should be a 'branch island', that will do a far jump to
17716 'foo'. Branch islands are generated in
17717 macho_branch_islands(). */
17718 sprintf (buf
, "jbsr %%z%d,%.246s",
17719 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
17722 sprintf (buf
, "bl %%z%d", dest_operand_number
);
17726 /* Generate PIC and indirect symbol stubs. */
17729 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
17731 unsigned int length
;
17732 char *symbol_name
, *lazy_ptr_name
;
17733 char *local_label_0
;
17734 static int label
= 0;
17736 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
17737 symb
= (*targetm
.strip_name_encoding
) (symb
);
17740 length
= strlen (symb
);
17741 symbol_name
= alloca (length
+ 32);
17742 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
17744 lazy_ptr_name
= alloca (length
+ 32);
17745 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
17748 machopic_picsymbol_stub1_section ();
17750 machopic_symbol_stub1_section ();
17754 fprintf (file
, "\t.align 5\n");
17756 fprintf (file
, "%s:\n", stub
);
17757 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17760 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
17761 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
17763 fprintf (file
, "\tmflr r0\n");
17764 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
17765 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
17766 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
17767 lazy_ptr_name
, local_label_0
);
17768 fprintf (file
, "\tmtlr r0\n");
17769 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
17770 (TARGET_64BIT
? "ldu" : "lwzu"),
17771 lazy_ptr_name
, local_label_0
);
17772 fprintf (file
, "\tmtctr r12\n");
17773 fprintf (file
, "\tbctr\n");
17777 fprintf (file
, "\t.align 4\n");
17779 fprintf (file
, "%s:\n", stub
);
17780 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17782 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
17783 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
17784 (TARGET_64BIT
? "ldu" : "lwzu"),
17786 fprintf (file
, "\tmtctr r12\n");
17787 fprintf (file
, "\tbctr\n");
17790 machopic_lazy_symbol_ptr_section ();
17791 fprintf (file
, "%s:\n", lazy_ptr_name
);
17792 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17793 fprintf (file
, "%sdyld_stub_binding_helper\n",
17794 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
17797 /* Legitimize PIC addresses. If the address is already
17798 position-independent, we return ORIG. Newly generated
17799 position-independent addresses go into a reg. This is REG if non
17800 zero, otherwise we allocate register(s) as necessary. */
17802 #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x8000) < 0x10000)
17805 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
17810 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
17811 reg
= gen_reg_rtx (Pmode
);
17813 if (GET_CODE (orig
) == CONST
)
17817 if (GET_CODE (XEXP (orig
, 0)) == PLUS
17818 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
17821 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
17823 /* Use a different reg for the intermediate value, as
17824 it will be marked UNCHANGING. */
17825 reg_temp
= no_new_pseudos
? reg
: gen_reg_rtx (Pmode
);
17826 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
17829 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
17832 if (GET_CODE (offset
) == CONST_INT
)
17834 if (SMALL_INT (offset
))
17835 return plus_constant (base
, INTVAL (offset
));
17836 else if (! reload_in_progress
&& ! reload_completed
)
17837 offset
= force_reg (Pmode
, offset
);
17840 rtx mem
= force_const_mem (Pmode
, orig
);
17841 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
17844 return gen_rtx_PLUS (Pmode
, base
, offset
);
17847 /* Fall back on generic machopic code. */
17848 return machopic_legitimize_pic_address (orig
, mode
, reg
);
17851 /* This is just a placeholder to make linking work without having to
17852 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
17853 ever needed for Darwin (not too likely!) this would have to get a
17854 real definition. */
17861 /* Output a .machine directive for the Darwin assembler, and call
17862 the generic start_file routine. */
17865 rs6000_darwin_file_start (void)
17867 static const struct
17873 { "ppc64", "ppc64", MASK_64BIT
},
17874 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
17875 { "power4", "ppc970", 0 },
17876 { "G5", "ppc970", 0 },
17877 { "7450", "ppc7450", 0 },
17878 { "7400", "ppc7400", MASK_ALTIVEC
},
17879 { "G4", "ppc7400", 0 },
17880 { "750", "ppc750", 0 },
17881 { "740", "ppc750", 0 },
17882 { "G3", "ppc750", 0 },
17883 { "604e", "ppc604e", 0 },
17884 { "604", "ppc604", 0 },
17885 { "603e", "ppc603", 0 },
17886 { "603", "ppc603", 0 },
17887 { "601", "ppc601", 0 },
17888 { NULL
, "ppc", 0 } };
17889 const char *cpu_id
= "";
17892 rs6000_file_start ();
17894 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
17895 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
17896 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
17897 && rs6000_select
[i
].string
[0] != '\0')
17898 cpu_id
= rs6000_select
[i
].string
;
17900 /* Look through the mapping array. Pick the first name that either
17901 matches the argument, has a bit set in IF_SET that is also set
17902 in the target flags, or has a NULL name. */
17905 while (mapping
[i
].arg
!= NULL
17906 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
17907 && (mapping
[i
].if_set
& target_flags
) == 0)
17910 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
17913 #endif /* TARGET_MACHO */
17916 static unsigned int
17917 rs6000_elf_section_type_flags (tree decl
, const char *name
, int reloc
)
17919 return default_section_type_flags_1 (decl
, name
, reloc
,
17920 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
17923 /* Record an element in the table of global constructors. SYMBOL is
17924 a SYMBOL_REF of the function to be called; PRIORITY is a number
17925 between 0 and MAX_INIT_PRIORITY.
17927 This differs from default_named_section_asm_out_constructor in
17928 that we have special handling for -mrelocatable. */
17931 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
17933 const char *section
= ".ctors";
17936 if (priority
!= DEFAULT_INIT_PRIORITY
)
17938 sprintf (buf
, ".ctors.%.5u",
17939 /* Invert the numbering so the linker puts us in the proper
17940 order; constructors are run from right to left, and the
17941 linker sorts in increasing order. */
17942 MAX_INIT_PRIORITY
- priority
);
17946 named_section_flags (section
, SECTION_WRITE
);
17947 assemble_align (POINTER_SIZE
);
17949 if (TARGET_RELOCATABLE
)
17951 fputs ("\t.long (", asm_out_file
);
17952 output_addr_const (asm_out_file
, symbol
);
17953 fputs (")@fixup\n", asm_out_file
);
17956 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
17960 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
17962 const char *section
= ".dtors";
17965 if (priority
!= DEFAULT_INIT_PRIORITY
)
17967 sprintf (buf
, ".dtors.%.5u",
17968 /* Invert the numbering so the linker puts us in the proper
17969 order; constructors are run from right to left, and the
17970 linker sorts in increasing order. */
17971 MAX_INIT_PRIORITY
- priority
);
17975 named_section_flags (section
, SECTION_WRITE
);
17976 assemble_align (POINTER_SIZE
);
17978 if (TARGET_RELOCATABLE
)
17980 fputs ("\t.long (", asm_out_file
);
17981 output_addr_const (asm_out_file
, symbol
);
17982 fputs (")@fixup\n", asm_out_file
);
17985 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
17989 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
17993 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
17994 ASM_OUTPUT_LABEL (file
, name
);
17995 fputs (DOUBLE_INT_ASM_OP
, file
);
17996 rs6000_output_function_entry (file
, name
);
17997 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
18000 fputs ("\t.size\t", file
);
18001 assemble_name (file
, name
);
18002 fputs (",24\n\t.type\t.", file
);
18003 assemble_name (file
, name
);
18004 fputs (",@function\n", file
);
18005 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
18007 fputs ("\t.globl\t.", file
);
18008 assemble_name (file
, name
);
18013 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
18014 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
18015 rs6000_output_function_entry (file
, name
);
18016 fputs (":\n", file
);
18020 if (TARGET_RELOCATABLE
18021 && !TARGET_SECURE_PLT
18022 && (get_pool_size () != 0 || current_function_profile
)
18027 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
18029 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
18030 fprintf (file
, "\t.long ");
18031 assemble_name (file
, buf
);
18033 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
18034 assemble_name (file
, buf
);
18038 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
18039 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
18041 if (DEFAULT_ABI
== ABI_AIX
)
18043 const char *desc_name
, *orig_name
;
18045 orig_name
= (*targetm
.strip_name_encoding
) (name
);
18046 desc_name
= orig_name
;
18047 while (*desc_name
== '.')
18050 if (TREE_PUBLIC (decl
))
18051 fprintf (file
, "\t.globl %s\n", desc_name
);
18053 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18054 fprintf (file
, "%s:\n", desc_name
);
18055 fprintf (file
, "\t.long %s\n", orig_name
);
18056 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
18057 if (DEFAULT_ABI
== ABI_AIX
)
18058 fputs ("\t.long 0\n", file
);
18059 fprintf (file
, "\t.previous\n");
18061 ASM_OUTPUT_LABEL (file
, name
);
18065 rs6000_elf_end_indicate_exec_stack (void)
18068 file_end_indicate_exec_stack ();
18074 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
18076 fputs (GLOBAL_ASM_OP
, stream
);
18077 RS6000_OUTPUT_BASENAME (stream
, name
);
18078 putc ('\n', stream
);
18082 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
18083 tree decl ATTRIBUTE_UNUSED
)
18086 static const char * const suffix
[3] = { "PR", "RO", "RW" };
18088 if (flags
& SECTION_CODE
)
18090 else if (flags
& SECTION_WRITE
)
18095 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
18096 (flags
& SECTION_CODE
) ? "." : "",
18097 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
18101 rs6000_xcoff_select_section (tree decl
, int reloc
,
18102 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
18104 if (decl_readonly_section_1 (decl
, reloc
, 1))
18106 if (TREE_PUBLIC (decl
))
18107 read_only_data_section ();
18109 read_only_private_data_section ();
18113 if (TREE_PUBLIC (decl
))
18116 private_data_section ();
18121 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
18125 /* Use select_section for private and uninitialized data. */
18126 if (!TREE_PUBLIC (decl
)
18127 || DECL_COMMON (decl
)
18128 || DECL_INITIAL (decl
) == NULL_TREE
18129 || DECL_INITIAL (decl
) == error_mark_node
18130 || (flag_zero_initialized_in_bss
18131 && initializer_zerop (DECL_INITIAL (decl
))))
18134 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
18135 name
= (*targetm
.strip_name_encoding
) (name
);
18136 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
18139 /* Select section for constant in constant pool.
18141 On RS/6000, all constants are in the private read-only data area.
18142 However, if this is being placed in the TOC it must be output as a
18146 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
18147 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
18149 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
18152 read_only_private_data_section ();
18155 /* Remove any trailing [DS] or the like from the symbol name. */
18157 static const char *
18158 rs6000_xcoff_strip_name_encoding (const char *name
)
18163 len
= strlen (name
);
18164 if (name
[len
- 1] == ']')
18165 return ggc_alloc_string (name
, len
- 4);
18170 /* Section attributes. AIX is always PIC. */
18172 static unsigned int
18173 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
18175 unsigned int align
;
18176 unsigned int flags
= default_section_type_flags_1 (decl
, name
, reloc
, 1);
18178 /* Align to at least UNIT size. */
18179 if (flags
& SECTION_CODE
)
18180 align
= MIN_UNITS_PER_WORD
;
18182 /* Increase alignment of large objects if not already stricter. */
18183 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
18184 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
18185 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
18187 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
18190 /* Output at beginning of assembler file.
18192 Initialize the section names for the RS/6000 at this point.
18194 Specify filename, including full path, to assembler.
18196 We want to go into the TOC section so at least one .toc will be emitted.
18197 Also, in order to output proper .bs/.es pairs, we need at least one static
18198 [RW] section emitted.
18200 Finally, declare mcount when profiling to make the assembler happy. */
18203 rs6000_xcoff_file_start (void)
18205 rs6000_gen_section_name (&xcoff_bss_section_name
,
18206 main_input_filename
, ".bss_");
18207 rs6000_gen_section_name (&xcoff_private_data_section_name
,
18208 main_input_filename
, ".rw_");
18209 rs6000_gen_section_name (&xcoff_read_only_section_name
,
18210 main_input_filename
, ".ro_");
18212 fputs ("\t.file\t", asm_out_file
);
18213 output_quoted_string (asm_out_file
, main_input_filename
);
18214 fputc ('\n', asm_out_file
);
18215 if (write_symbols
!= NO_DEBUG
)
18216 private_data_section ();
18219 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
18220 rs6000_file_start ();
18223 /* Output at end of assembler file.
18224 On the RS/6000, referencing data should automatically pull in text. */
18227 rs6000_xcoff_file_end (void)
18230 fputs ("_section_.text:\n", asm_out_file
);
18232 fputs (TARGET_32BIT
18233 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
18236 #endif /* TARGET_XCOFF */
18238 /* Compute a (partial) cost for rtx X. Return true if the complete
18239 cost has been computed, and false if subexpressions should be
18240 scanned. In either case, *TOTAL contains the cost result. */
18243 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
18245 enum machine_mode mode
= GET_MODE (x
);
18249 /* On the RS/6000, if it is valid in the insn, it is free. */
18251 if (((outer_code
== SET
18252 || outer_code
== PLUS
18253 || outer_code
== MINUS
)
18254 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
18255 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')))
18256 || (outer_code
== AND
18257 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18258 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
18259 mode
== SImode
? 'L' : 'J'))
18260 || mask_operand (x
, mode
)
18262 && mask64_operand (x
, DImode
))))
18263 || ((outer_code
== IOR
|| outer_code
== XOR
)
18264 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18265 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
18266 mode
== SImode
? 'L' : 'J'))))
18267 || outer_code
== ASHIFT
18268 || outer_code
== ASHIFTRT
18269 || outer_code
== LSHIFTRT
18270 || outer_code
== ROTATE
18271 || outer_code
== ROTATERT
18272 || outer_code
== ZERO_EXTRACT
18273 || (outer_code
== MULT
18274 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
18275 || ((outer_code
== DIV
|| outer_code
== UDIV
18276 || outer_code
== MOD
|| outer_code
== UMOD
)
18277 && exact_log2 (INTVAL (x
)) >= 0)
18278 || (outer_code
== COMPARE
18279 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
18280 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')))
18281 || (outer_code
== EQ
18282 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
18283 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18284 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
18285 mode
== SImode
? 'L' : 'J'))))
18286 || (outer_code
== GTU
18287 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
18288 || (outer_code
== LTU
18289 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'P')))
18294 else if ((outer_code
== PLUS
18295 && reg_or_add_cint_operand (x
, VOIDmode
))
18296 || (outer_code
== MINUS
18297 && reg_or_sub_cint_operand (x
, VOIDmode
))
18298 || ((outer_code
== SET
18299 || outer_code
== IOR
18300 || outer_code
== XOR
)
18302 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
18304 *total
= COSTS_N_INSNS (1);
18311 && ((outer_code
== AND
18312 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18313 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')
18314 || mask_operand (x
, DImode
)
18315 || mask64_operand (x
, DImode
)))
18316 || ((outer_code
== IOR
|| outer_code
== XOR
)
18317 && CONST_DOUBLE_HIGH (x
) == 0
18318 && (CONST_DOUBLE_LOW (x
)
18319 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)))
18324 else if (mode
== DImode
18325 && (outer_code
== SET
18326 || outer_code
== IOR
18327 || outer_code
== XOR
)
18328 && CONST_DOUBLE_HIGH (x
) == 0)
18330 *total
= COSTS_N_INSNS (1);
18339 /* When optimizing for size, MEM should be slightly more expensive
18340 than generating address, e.g., (plus (reg) (const)).
18341 L1 cache latency is about two instructions. */
18342 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
18350 if (mode
== DFmode
)
18352 if (GET_CODE (XEXP (x
, 0)) == MULT
)
18354 /* FNMA accounted in outer NEG. */
18355 if (outer_code
== NEG
)
18356 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
18358 *total
= rs6000_cost
->dmul
;
18361 *total
= rs6000_cost
->fp
;
18363 else if (mode
== SFmode
)
18365 /* FNMA accounted in outer NEG. */
18366 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
18369 *total
= rs6000_cost
->fp
;
18372 *total
= COSTS_N_INSNS (1);
18376 if (mode
== DFmode
)
18378 if (GET_CODE (XEXP (x
, 0)) == MULT
)
18380 /* FNMA accounted in outer NEG. */
18381 if (outer_code
== NEG
)
18384 *total
= rs6000_cost
->dmul
;
18387 *total
= rs6000_cost
->fp
;
18389 else if (mode
== SFmode
)
18391 /* FNMA accounted in outer NEG. */
18392 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
18395 *total
= rs6000_cost
->fp
;
18398 *total
= COSTS_N_INSNS (1);
18402 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
18403 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x
, 1)), 'I'))
18405 if (INTVAL (XEXP (x
, 1)) >= -256
18406 && INTVAL (XEXP (x
, 1)) <= 255)
18407 *total
= rs6000_cost
->mulsi_const9
;
18409 *total
= rs6000_cost
->mulsi_const
;
18411 /* FMA accounted in outer PLUS/MINUS. */
18412 else if ((mode
== DFmode
|| mode
== SFmode
)
18413 && (outer_code
== PLUS
|| outer_code
== MINUS
))
18415 else if (mode
== DFmode
)
18416 *total
= rs6000_cost
->dmul
;
18417 else if (mode
== SFmode
)
18418 *total
= rs6000_cost
->fp
;
18419 else if (mode
== DImode
)
18420 *total
= rs6000_cost
->muldi
;
18422 *total
= rs6000_cost
->mulsi
;
18427 if (FLOAT_MODE_P (mode
))
18429 *total
= mode
== DFmode
? rs6000_cost
->ddiv
18430 : rs6000_cost
->sdiv
;
18437 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
18438 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
18440 if (code
== DIV
|| code
== MOD
)
18442 *total
= COSTS_N_INSNS (2);
18445 *total
= COSTS_N_INSNS (1);
18449 if (GET_MODE (XEXP (x
, 1)) == DImode
)
18450 *total
= rs6000_cost
->divdi
;
18452 *total
= rs6000_cost
->divsi
;
18454 /* Add in shift and subtract for MOD. */
18455 if (code
== MOD
|| code
== UMOD
)
18456 *total
+= COSTS_N_INSNS (2);
18460 *total
= COSTS_N_INSNS (4);
18464 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
18475 *total
= COSTS_N_INSNS (1);
18483 /* Handle mul_highpart. */
18484 if (outer_code
== TRUNCATE
18485 && GET_CODE (XEXP (x
, 0)) == MULT
)
18487 if (mode
== DImode
)
18488 *total
= rs6000_cost
->muldi
;
18490 *total
= rs6000_cost
->mulsi
;
18493 else if (outer_code
== AND
)
18496 *total
= COSTS_N_INSNS (1);
18501 if (GET_CODE (XEXP (x
, 0)) == MEM
)
18504 *total
= COSTS_N_INSNS (1);
18510 if (!FLOAT_MODE_P (mode
))
18512 *total
= COSTS_N_INSNS (1);
18518 case UNSIGNED_FLOAT
:
18521 case FLOAT_TRUNCATE
:
18522 *total
= rs6000_cost
->fp
;
18526 if (mode
== DFmode
)
18529 *total
= rs6000_cost
->fp
;
18533 switch (XINT (x
, 1))
18536 *total
= rs6000_cost
->fp
;
18548 *total
= COSTS_N_INSNS (1);
18551 else if (FLOAT_MODE_P (mode
)
18552 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
18554 *total
= rs6000_cost
->fp
;
18562 /* Carry bit requires mode == Pmode.
18563 NEG or PLUS already counted so only add one. */
18565 && (outer_code
== NEG
|| outer_code
== PLUS
))
18567 *total
= COSTS_N_INSNS (1);
18570 if (outer_code
== SET
)
18572 if (XEXP (x
, 1) == const0_rtx
)
18574 *total
= COSTS_N_INSNS (2);
18577 else if (mode
== Pmode
)
18579 *total
= COSTS_N_INSNS (3);
18588 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
18590 *total
= COSTS_N_INSNS (2);
18594 if (outer_code
== COMPARE
)
18608 /* A C expression returning the cost of moving data from a register of class
18609 CLASS1 to one of CLASS2. */
18612 rs6000_register_move_cost (enum machine_mode mode
,
18613 enum reg_class from
, enum reg_class to
)
18615 /* Moves from/to GENERAL_REGS. */
18616 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
18617 || reg_classes_intersect_p (from
, GENERAL_REGS
))
18619 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
18622 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
18623 return (rs6000_memory_move_cost (mode
, from
, 0)
18624 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
18626 /* It's more expensive to move CR_REGS than CR0_REGS because of the
18628 else if (from
== CR_REGS
)
18632 /* A move will cost one instruction per GPR moved. */
18633 return 2 * hard_regno_nregs
[0][mode
];
18636 /* Moving between two similar registers is just one instruction. */
18637 else if (reg_classes_intersect_p (to
, from
))
18638 return mode
== TFmode
? 4 : 2;
18640 /* Everything else has to go through GENERAL_REGS. */
18642 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
18643 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
18646 /* A C expressions returning the cost of moving data of MODE from a register to
18650 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
18651 int in ATTRIBUTE_UNUSED
)
18653 if (reg_classes_intersect_p (class, GENERAL_REGS
))
18654 return 4 * hard_regno_nregs
[0][mode
];
18655 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
18656 return 4 * hard_regno_nregs
[32][mode
];
18657 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
18658 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
18660 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
18663 /* Newton-Raphson approximation of single-precision floating point divide n/d.
18664 Assumes no trapping math and finite arguments. */
18667 rs6000_emit_swdivsf (rtx res
, rtx n
, rtx d
)
18669 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
18671 x0
= gen_reg_rtx (SFmode
);
18672 e0
= gen_reg_rtx (SFmode
);
18673 e1
= gen_reg_rtx (SFmode
);
18674 y1
= gen_reg_rtx (SFmode
);
18675 u0
= gen_reg_rtx (SFmode
);
18676 v0
= gen_reg_rtx (SFmode
);
18677 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
18679 /* x0 = 1./d estimate */
18680 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
18681 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
18683 /* e0 = 1. - d * x0 */
18684 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
18685 gen_rtx_MINUS (SFmode
, one
,
18686 gen_rtx_MULT (SFmode
, d
, x0
))));
18687 /* e1 = e0 + e0 * e0 */
18688 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
18689 gen_rtx_PLUS (SFmode
,
18690 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
18691 /* y1 = x0 + e1 * x0 */
18692 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
18693 gen_rtx_PLUS (SFmode
,
18694 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
18696 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
18697 gen_rtx_MULT (SFmode
, n
, y1
)));
18698 /* v0 = n - d * u0 */
18699 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
18700 gen_rtx_MINUS (SFmode
, n
,
18701 gen_rtx_MULT (SFmode
, d
, u0
))));
18702 /* res = u0 + v0 * y1 */
18703 emit_insn (gen_rtx_SET (VOIDmode
, res
,
18704 gen_rtx_PLUS (SFmode
,
18705 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
18708 /* Newton-Raphson approximation of double-precision floating point divide n/d.
18709 Assumes no trapping math and finite arguments. */
18712 rs6000_emit_swdivdf (rtx res
, rtx n
, rtx d
)
18714 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
18716 x0
= gen_reg_rtx (DFmode
);
18717 e0
= gen_reg_rtx (DFmode
);
18718 e1
= gen_reg_rtx (DFmode
);
18719 e2
= gen_reg_rtx (DFmode
);
18720 y1
= gen_reg_rtx (DFmode
);
18721 y2
= gen_reg_rtx (DFmode
);
18722 y3
= gen_reg_rtx (DFmode
);
18723 u0
= gen_reg_rtx (DFmode
);
18724 v0
= gen_reg_rtx (DFmode
);
18725 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
18727 /* x0 = 1./d estimate */
18728 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
18729 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
18731 /* e0 = 1. - d * x0 */
18732 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
18733 gen_rtx_MINUS (DFmode
, one
,
18734 gen_rtx_MULT (SFmode
, d
, x0
))));
18735 /* y1 = x0 + e0 * x0 */
18736 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
18737 gen_rtx_PLUS (DFmode
,
18738 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
18740 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
18741 gen_rtx_MULT (DFmode
, e0
, e0
)));
18742 /* y2 = y1 + e1 * y1 */
18743 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
18744 gen_rtx_PLUS (DFmode
,
18745 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
18747 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
18748 gen_rtx_MULT (DFmode
, e1
, e1
)));
18749 /* y3 = y2 + e2 * y2 */
18750 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
18751 gen_rtx_PLUS (DFmode
,
18752 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
18754 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
18755 gen_rtx_MULT (DFmode
, n
, y3
)));
18756 /* v0 = n - d * u0 */
18757 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
18758 gen_rtx_MINUS (DFmode
, n
,
18759 gen_rtx_MULT (DFmode
, d
, u0
))));
18760 /* res = u0 + v0 * y3 */
18761 emit_insn (gen_rtx_SET (VOIDmode
, res
,
18762 gen_rtx_PLUS (DFmode
,
18763 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
18766 /* Return an RTX representing where to find the function value of a
18767 function returning MODE. */
18769 rs6000_complex_function_value (enum machine_mode mode
)
18771 unsigned int regno
;
18773 enum machine_mode inner
= GET_MODE_INNER (mode
);
18774 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
18776 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
18777 regno
= FP_ARG_RETURN
;
18780 regno
= GP_ARG_RETURN
;
18782 /* 32-bit is OK since it'll go in r3/r4. */
18783 if (TARGET_32BIT
&& inner_bytes
>= 4)
18784 return gen_rtx_REG (mode
, regno
);
18787 if (inner_bytes
>= 8)
18788 return gen_rtx_REG (mode
, regno
);
18790 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
18792 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
18793 GEN_INT (inner_bytes
));
18794 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
18797 /* Define how to find the value returned by a function.
18798 VALTYPE is the data type of the value (as a tree).
18799 If the precise function being called is known, FUNC is its FUNCTION_DECL;
18800 otherwise, FUNC is 0.
18802 On the SPE, both FPs and vectors are returned in r3.
18804 On RS/6000 an integer value is in r3 and a floating-point value is in
18805 fp1, unless -msoft-float. */
18808 rs6000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
18810 enum machine_mode mode
;
18811 unsigned int regno
;
18813 /* Special handling for structs in darwin64. */
18814 if (rs6000_darwin64_abi
18815 && TYPE_MODE (valtype
) == BLKmode
18816 && TREE_CODE (valtype
) == RECORD_TYPE
18817 && int_size_in_bytes (valtype
) > 0)
18819 CUMULATIVE_ARGS valcum
;
18823 valcum
.fregno
= FP_ARG_MIN_REG
;
18824 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
18825 /* Do a trial code generation as if this were going to be passed as
18826 an argument; if any part goes in memory, we return NULL. */
18827 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
18830 /* Otherwise fall through to standard ABI rules. */
18833 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
18835 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
18836 return gen_rtx_PARALLEL (DImode
,
18838 gen_rtx_EXPR_LIST (VOIDmode
,
18839 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
18841 gen_rtx_EXPR_LIST (VOIDmode
,
18842 gen_rtx_REG (SImode
,
18843 GP_ARG_RETURN
+ 1),
18846 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
18848 return gen_rtx_PARALLEL (DCmode
,
18850 gen_rtx_EXPR_LIST (VOIDmode
,
18851 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
18853 gen_rtx_EXPR_LIST (VOIDmode
,
18854 gen_rtx_REG (SImode
,
18855 GP_ARG_RETURN
+ 1),
18857 gen_rtx_EXPR_LIST (VOIDmode
,
18858 gen_rtx_REG (SImode
,
18859 GP_ARG_RETURN
+ 2),
18861 gen_rtx_EXPR_LIST (VOIDmode
,
18862 gen_rtx_REG (SImode
,
18863 GP_ARG_RETURN
+ 3),
18866 if ((INTEGRAL_TYPE_P (valtype
)
18867 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
18868 || POINTER_TYPE_P (valtype
))
18869 mode
= TARGET_32BIT
? SImode
: DImode
;
18871 mode
= TYPE_MODE (valtype
);
18873 if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
18874 regno
= FP_ARG_RETURN
;
18875 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
18876 && targetm
.calls
.split_complex_arg
)
18877 return rs6000_complex_function_value (mode
);
18878 else if (TREE_CODE (valtype
) == VECTOR_TYPE
18879 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
18880 && ALTIVEC_VECTOR_MODE (mode
))
18881 regno
= ALTIVEC_ARG_RETURN
;
18882 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
18883 && (mode
== DFmode
|| mode
== DCmode
))
18884 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
18886 regno
= GP_ARG_RETURN
;
18888 return gen_rtx_REG (mode
, regno
);
18891 /* Define how to find the value returned by a library function
18892 assuming the value has mode MODE. */
18894 rs6000_libcall_value (enum machine_mode mode
)
18896 unsigned int regno
;
18898 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
18900 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
18901 return gen_rtx_PARALLEL (DImode
,
18903 gen_rtx_EXPR_LIST (VOIDmode
,
18904 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
18906 gen_rtx_EXPR_LIST (VOIDmode
,
18907 gen_rtx_REG (SImode
,
18908 GP_ARG_RETURN
+ 1),
18912 if (SCALAR_FLOAT_MODE_P (mode
)
18913 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
18914 regno
= FP_ARG_RETURN
;
18915 else if (ALTIVEC_VECTOR_MODE (mode
)
18916 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
18917 regno
= ALTIVEC_ARG_RETURN
;
18918 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
18919 return rs6000_complex_function_value (mode
);
18920 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
18921 && (mode
== DFmode
|| mode
== DCmode
))
18922 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
18924 regno
= GP_ARG_RETURN
;
18926 return gen_rtx_REG (mode
, regno
);
18929 /* Define the offset between two registers, FROM to be eliminated and its
18930 replacement TO, at the start of a routine. */
18932 rs6000_initial_elimination_offset (int from
, int to
)
18934 rs6000_stack_t
*info
= rs6000_stack_info ();
18935 HOST_WIDE_INT offset
;
18937 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
18938 offset
= info
->push_p
? 0 : -info
->total_size
;
18939 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
18941 offset
= info
->push_p
? 0 : -info
->total_size
;
18942 if (FRAME_GROWS_DOWNWARD
)
18943 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
18945 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
18946 offset
= FRAME_GROWS_DOWNWARD
18947 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
18949 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
18950 offset
= info
->total_size
;
18951 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
18952 offset
= info
->push_p
? info
->total_size
: 0;
18953 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
18956 gcc_unreachable ();
18961 /* Return true if TYPE is a SPE or AltiVec opaque type. */
18964 rs6000_is_opaque_type (tree type
)
18966 return (type
== opaque_V2SI_type_node
18967 || type
== opaque_V2SF_type_node
18968 || type
== opaque_p_V2SI_type_node
18969 || type
== opaque_V4SI_type_node
);
18973 rs6000_dwarf_register_span (rtx reg
)
18978 && (SPE_VECTOR_MODE (GET_MODE (reg
))
18979 || (TARGET_E500_DOUBLE
&& GET_MODE (reg
) == DFmode
)))
18984 regno
= REGNO (reg
);
18986 /* The duality of the SPE register size wreaks all kinds of havoc.
18987 This is a way of distinguishing r0 in 32-bits from r0 in
18990 gen_rtx_PARALLEL (VOIDmode
,
18993 gen_rtx_REG (SImode
, regno
+ 1200),
18994 gen_rtx_REG (SImode
, regno
))
18996 gen_rtx_REG (SImode
, regno
),
18997 gen_rtx_REG (SImode
, regno
+ 1200)));
19000 /* Map internal gcc register numbers to DWARF2 register numbers. */
19003 rs6000_dbx_register_number (unsigned int regno
)
19005 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
19007 if (regno
== MQ_REGNO
)
19009 if (regno
== LINK_REGISTER_REGNUM
)
19011 if (regno
== COUNT_REGISTER_REGNUM
)
19013 if (CR_REGNO_P (regno
))
19014 return regno
- CR0_REGNO
+ 86;
19015 if (regno
== XER_REGNO
)
19017 if (ALTIVEC_REGNO_P (regno
))
19018 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
19019 if (regno
== VRSAVE_REGNO
)
19021 if (regno
== VSCR_REGNO
)
19023 if (regno
== SPE_ACC_REGNO
)
19025 if (regno
== SPEFSCR_REGNO
)
19027 /* SPE high reg number. We get these values of regno from
19028 rs6000_dwarf_register_span. */
19029 gcc_assert (regno
>= 1200 && regno
< 1232);
19033 /* target hook eh_return_filter_mode */
19034 static enum machine_mode
19035 rs6000_eh_return_filter_mode (void)
19037 return TARGET_32BIT
? SImode
: word_mode
;
19040 /* Target hook for vector_mode_supported_p. */
19042 rs6000_vector_mode_supported_p (enum machine_mode mode
)
19045 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
19048 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
19055 /* Target hook for invalid_arg_for_unprototyped_fn. */
19056 static const char *
19057 invalid_arg_for_unprototyped_fn (tree typelist
, tree funcdecl
, tree val
)
19059 return (!rs6000_darwin64_abi
19061 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
19062 && (funcdecl
== NULL_TREE
19063 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
19064 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
19065 ? N_("AltiVec argument passed to unprototyped function")
19069 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
19070 setup by using __stack_chk_fail_local hidden function instead of
19071 calling __stack_chk_fail directly. Otherwise it is better to call
19072 __stack_chk_fail directly. */
19075 rs6000_stack_protect_fail (void)
19077 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
19078 ? default_hidden_stack_protect_fail ()
19079 : default_external_stack_protect_fail ();
19082 #include "gt-rs6000.h"