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, 59 Temple Place - Suite 330, Boston,
21 MA 02111-1307, 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"
58 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
61 #include "gstab.h" /* for N_SLINE */
64 #ifndef TARGET_NO_PROTOTYPE
65 #define TARGET_NO_PROTOTYPE 0
68 #define min(A,B) ((A) < (B) ? (A) : (B))
69 #define max(A,B) ((A) > (B) ? (A) : (B))
71 /* Structure used to define the rs6000 stack */
72 typedef struct rs6000_stack
{
73 int first_gp_reg_save
; /* first callee saved GP register used */
74 int first_fp_reg_save
; /* first callee saved FP register used */
75 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
76 int lr_save_p
; /* true if the link reg needs to be saved */
77 int cr_save_p
; /* true if the CR reg needs to be saved */
78 unsigned int vrsave_mask
; /* mask of vec registers to save */
79 int toc_save_p
; /* true if the TOC needs to be saved */
80 int push_p
; /* true if we need to allocate stack space */
81 int calls_p
; /* true if the function makes any calls */
82 int world_save_p
; /* true if we're saving *everything*:
83 r13-r31, cr, f14-f31, vrsave, v20-v31 */
84 enum rs6000_abi abi
; /* which ABI to use */
85 int gp_save_offset
; /* offset to save GP regs from initial SP */
86 int fp_save_offset
; /* offset to save FP regs from initial SP */
87 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
88 int lr_save_offset
; /* offset to save LR from initial SP */
89 int cr_save_offset
; /* offset to save CR from initial SP */
90 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
91 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
92 int toc_save_offset
; /* offset to save the TOC pointer */
93 int varargs_save_offset
; /* offset to save the varargs registers */
94 int ehrd_offset
; /* offset to EH return data */
95 int reg_size
; /* register size (4 or 8) */
96 int varargs_size
; /* size to hold V.4 args passed in regs */
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 /* Target cpu type */
118 enum processor_type rs6000_cpu
;
119 struct rs6000_cpu_select rs6000_select
[3] =
121 /* switch name, tune arch */
122 { (const char *)0, "--with-cpu=", 1, 1 },
123 { (const char *)0, "-mcpu=", 1, 1 },
124 { (const char *)0, "-mtune=", 1, 0 },
127 /* Always emit branch hint bits. */
128 static GTY(()) bool rs6000_always_hint
;
130 /* Schedule instructions for group formation. */
131 static GTY(()) bool rs6000_sched_groups
;
133 /* Support for -msched-costly-dep option. */
134 const char *rs6000_sched_costly_dep_str
;
135 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
137 /* Support for -minsert-sched-nops option. */
138 const char *rs6000_sched_insert_nops_str
;
139 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
141 /* Support targetm.vectorize.builtin_mask_for_load. */
142 static GTY(()) tree altivec_builtin_mask_for_load
;
144 /* Size of long double */
145 int rs6000_long_double_type_size
;
147 /* Whether -mabi=altivec has appeared */
148 int rs6000_altivec_abi
;
150 /* Nonzero if we want SPE ABI extensions. */
153 /* Nonzero if floating point operations are done in the GPRs. */
154 int rs6000_float_gprs
= 0;
156 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
157 int rs6000_darwin64_abi
;
159 /* Set to nonzero once AIX common-mode calls have been defined. */
160 static GTY(()) int common_mode_defined
;
162 /* Save information from a "cmpxx" operation until the branch or scc is
164 rtx rs6000_compare_op0
, rs6000_compare_op1
;
165 int rs6000_compare_fp_p
;
167 /* Label number of label created for -mrelocatable, to call to so we can
168 get the address of the GOT section */
169 int rs6000_pic_labelno
;
172 /* Which abi to adhere to */
173 const char *rs6000_abi_name
;
175 /* Semantics of the small data area */
176 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
178 /* Which small data model to use */
179 const char *rs6000_sdata_name
= (char *)0;
181 /* Counter for labels which are to be placed in .fixup. */
182 int fixuplabelno
= 0;
185 /* Bit size of immediate TLS offsets and string from which it is decoded. */
186 int rs6000_tls_size
= 32;
187 const char *rs6000_tls_size_string
;
189 /* ABI enumeration available for subtarget to use. */
190 enum rs6000_abi rs6000_current_abi
;
192 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
196 const char *rs6000_debug_name
;
197 int rs6000_debug_stack
; /* debug stack applications */
198 int rs6000_debug_arg
; /* debug argument handling */
200 /* Value is TRUE if register/mode pair is acceptable. */
201 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
203 /* Built in types. */
205 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
206 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
208 const char *rs6000_traceback_name
;
210 traceback_default
= 0,
216 /* Flag to say the TOC is initialized */
218 char toc_label_name
[10];
220 /* Alias set for saves and restores from the rs6000 stack. */
221 static GTY(()) int rs6000_sr_alias_set
;
223 /* Control alignment for fields within structures. */
224 /* String from -malign-XXXXX. */
225 int rs6000_alignment_flags
;
227 /* True for any options that were explicitly set. */
229 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
230 bool alignment
; /* True if -malign- was used. */
231 bool abi
; /* True if -mabi= was used. */
232 bool spe
; /* True if -mspe= was used. */
233 bool float_gprs
; /* True if -mfloat-gprs= was used. */
234 bool isel
; /* True if -misel was used. */
235 bool long_double
; /* True if -mlong-double- was used. */
236 } rs6000_explicit_options
;
238 struct builtin_description
240 /* mask is not const because we're going to alter it below. This
241 nonsense will go away when we rewrite the -march infrastructure
242 to give us more target flag bits. */
244 const enum insn_code icode
;
245 const char *const name
;
246 const enum rs6000_builtins code
;
249 /* Target cpu costs. */
251 struct processor_costs
{
252 const int mulsi
; /* cost of SImode multiplication. */
253 const int mulsi_const
; /* cost of SImode multiplication by constant. */
254 const int mulsi_const9
; /* cost of SImode mult by short constant. */
255 const int muldi
; /* cost of DImode multiplication. */
256 const int divsi
; /* cost of SImode division. */
257 const int divdi
; /* cost of DImode division. */
258 const int fp
; /* cost of simple SFmode and DFmode insns. */
259 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
260 const int sdiv
; /* cost of SFmode division (fdivs). */
261 const int ddiv
; /* cost of DFmode division (fdiv). */
264 const struct processor_costs
*rs6000_cost
;
266 /* Processor costs (relative to an add) */
268 /* Instruction size costs on 32bit processors. */
270 struct processor_costs size32_cost
= {
271 COSTS_N_INSNS (1), /* mulsi */
272 COSTS_N_INSNS (1), /* mulsi_const */
273 COSTS_N_INSNS (1), /* mulsi_const9 */
274 COSTS_N_INSNS (1), /* muldi */
275 COSTS_N_INSNS (1), /* divsi */
276 COSTS_N_INSNS (1), /* divdi */
277 COSTS_N_INSNS (1), /* fp */
278 COSTS_N_INSNS (1), /* dmul */
279 COSTS_N_INSNS (1), /* sdiv */
280 COSTS_N_INSNS (1), /* ddiv */
283 /* Instruction size costs on 64bit processors. */
285 struct processor_costs size64_cost
= {
286 COSTS_N_INSNS (1), /* mulsi */
287 COSTS_N_INSNS (1), /* mulsi_const */
288 COSTS_N_INSNS (1), /* mulsi_const9 */
289 COSTS_N_INSNS (1), /* muldi */
290 COSTS_N_INSNS (1), /* divsi */
291 COSTS_N_INSNS (1), /* divdi */
292 COSTS_N_INSNS (1), /* fp */
293 COSTS_N_INSNS (1), /* dmul */
294 COSTS_N_INSNS (1), /* sdiv */
295 COSTS_N_INSNS (1), /* ddiv */
298 /* Instruction costs on RIOS1 processors. */
300 struct processor_costs rios1_cost
= {
301 COSTS_N_INSNS (5), /* mulsi */
302 COSTS_N_INSNS (4), /* mulsi_const */
303 COSTS_N_INSNS (3), /* mulsi_const9 */
304 COSTS_N_INSNS (5), /* muldi */
305 COSTS_N_INSNS (19), /* divsi */
306 COSTS_N_INSNS (19), /* divdi */
307 COSTS_N_INSNS (2), /* fp */
308 COSTS_N_INSNS (2), /* dmul */
309 COSTS_N_INSNS (19), /* sdiv */
310 COSTS_N_INSNS (19), /* ddiv */
313 /* Instruction costs on RIOS2 processors. */
315 struct processor_costs rios2_cost
= {
316 COSTS_N_INSNS (2), /* mulsi */
317 COSTS_N_INSNS (2), /* mulsi_const */
318 COSTS_N_INSNS (2), /* mulsi_const9 */
319 COSTS_N_INSNS (2), /* muldi */
320 COSTS_N_INSNS (13), /* divsi */
321 COSTS_N_INSNS (13), /* divdi */
322 COSTS_N_INSNS (2), /* fp */
323 COSTS_N_INSNS (2), /* dmul */
324 COSTS_N_INSNS (17), /* sdiv */
325 COSTS_N_INSNS (17), /* ddiv */
328 /* Instruction costs on RS64A processors. */
330 struct processor_costs rs64a_cost
= {
331 COSTS_N_INSNS (20), /* mulsi */
332 COSTS_N_INSNS (12), /* mulsi_const */
333 COSTS_N_INSNS (8), /* mulsi_const9 */
334 COSTS_N_INSNS (34), /* muldi */
335 COSTS_N_INSNS (65), /* divsi */
336 COSTS_N_INSNS (67), /* divdi */
337 COSTS_N_INSNS (4), /* fp */
338 COSTS_N_INSNS (4), /* dmul */
339 COSTS_N_INSNS (31), /* sdiv */
340 COSTS_N_INSNS (31), /* ddiv */
343 /* Instruction costs on MPCCORE processors. */
345 struct processor_costs mpccore_cost
= {
346 COSTS_N_INSNS (2), /* mulsi */
347 COSTS_N_INSNS (2), /* mulsi_const */
348 COSTS_N_INSNS (2), /* mulsi_const9 */
349 COSTS_N_INSNS (2), /* muldi */
350 COSTS_N_INSNS (6), /* divsi */
351 COSTS_N_INSNS (6), /* divdi */
352 COSTS_N_INSNS (4), /* fp */
353 COSTS_N_INSNS (5), /* dmul */
354 COSTS_N_INSNS (10), /* sdiv */
355 COSTS_N_INSNS (17), /* ddiv */
358 /* Instruction costs on PPC403 processors. */
360 struct processor_costs ppc403_cost
= {
361 COSTS_N_INSNS (4), /* mulsi */
362 COSTS_N_INSNS (4), /* mulsi_const */
363 COSTS_N_INSNS (4), /* mulsi_const9 */
364 COSTS_N_INSNS (4), /* muldi */
365 COSTS_N_INSNS (33), /* divsi */
366 COSTS_N_INSNS (33), /* divdi */
367 COSTS_N_INSNS (11), /* fp */
368 COSTS_N_INSNS (11), /* dmul */
369 COSTS_N_INSNS (11), /* sdiv */
370 COSTS_N_INSNS (11), /* ddiv */
373 /* Instruction costs on PPC405 processors. */
375 struct processor_costs ppc405_cost
= {
376 COSTS_N_INSNS (5), /* mulsi */
377 COSTS_N_INSNS (4), /* mulsi_const */
378 COSTS_N_INSNS (3), /* mulsi_const9 */
379 COSTS_N_INSNS (5), /* muldi */
380 COSTS_N_INSNS (35), /* divsi */
381 COSTS_N_INSNS (35), /* divdi */
382 COSTS_N_INSNS (11), /* fp */
383 COSTS_N_INSNS (11), /* dmul */
384 COSTS_N_INSNS (11), /* sdiv */
385 COSTS_N_INSNS (11), /* ddiv */
388 /* Instruction costs on PPC440 processors. */
390 struct processor_costs ppc440_cost
= {
391 COSTS_N_INSNS (3), /* mulsi */
392 COSTS_N_INSNS (2), /* mulsi_const */
393 COSTS_N_INSNS (2), /* mulsi_const9 */
394 COSTS_N_INSNS (3), /* muldi */
395 COSTS_N_INSNS (34), /* divsi */
396 COSTS_N_INSNS (34), /* divdi */
397 COSTS_N_INSNS (5), /* fp */
398 COSTS_N_INSNS (5), /* dmul */
399 COSTS_N_INSNS (19), /* sdiv */
400 COSTS_N_INSNS (33), /* ddiv */
403 /* Instruction costs on PPC601 processors. */
405 struct processor_costs ppc601_cost
= {
406 COSTS_N_INSNS (5), /* mulsi */
407 COSTS_N_INSNS (5), /* mulsi_const */
408 COSTS_N_INSNS (5), /* mulsi_const9 */
409 COSTS_N_INSNS (5), /* muldi */
410 COSTS_N_INSNS (36), /* divsi */
411 COSTS_N_INSNS (36), /* divdi */
412 COSTS_N_INSNS (4), /* fp */
413 COSTS_N_INSNS (5), /* dmul */
414 COSTS_N_INSNS (17), /* sdiv */
415 COSTS_N_INSNS (31), /* ddiv */
418 /* Instruction costs on PPC603 processors. */
420 struct processor_costs ppc603_cost
= {
421 COSTS_N_INSNS (5), /* mulsi */
422 COSTS_N_INSNS (3), /* mulsi_const */
423 COSTS_N_INSNS (2), /* mulsi_const9 */
424 COSTS_N_INSNS (5), /* muldi */
425 COSTS_N_INSNS (37), /* divsi */
426 COSTS_N_INSNS (37), /* divdi */
427 COSTS_N_INSNS (3), /* fp */
428 COSTS_N_INSNS (4), /* dmul */
429 COSTS_N_INSNS (18), /* sdiv */
430 COSTS_N_INSNS (33), /* ddiv */
433 /* Instruction costs on PPC604 processors. */
435 struct processor_costs ppc604_cost
= {
436 COSTS_N_INSNS (4), /* mulsi */
437 COSTS_N_INSNS (4), /* mulsi_const */
438 COSTS_N_INSNS (4), /* mulsi_const9 */
439 COSTS_N_INSNS (4), /* muldi */
440 COSTS_N_INSNS (20), /* divsi */
441 COSTS_N_INSNS (20), /* divdi */
442 COSTS_N_INSNS (3), /* fp */
443 COSTS_N_INSNS (3), /* dmul */
444 COSTS_N_INSNS (18), /* sdiv */
445 COSTS_N_INSNS (32), /* ddiv */
448 /* Instruction costs on PPC604e processors. */
450 struct processor_costs ppc604e_cost
= {
451 COSTS_N_INSNS (2), /* mulsi */
452 COSTS_N_INSNS (2), /* mulsi_const */
453 COSTS_N_INSNS (2), /* mulsi_const9 */
454 COSTS_N_INSNS (2), /* muldi */
455 COSTS_N_INSNS (20), /* divsi */
456 COSTS_N_INSNS (20), /* divdi */
457 COSTS_N_INSNS (3), /* fp */
458 COSTS_N_INSNS (3), /* dmul */
459 COSTS_N_INSNS (18), /* sdiv */
460 COSTS_N_INSNS (32), /* ddiv */
463 /* Instruction costs on PPC620 processors. */
465 struct processor_costs ppc620_cost
= {
466 COSTS_N_INSNS (5), /* mulsi */
467 COSTS_N_INSNS (4), /* mulsi_const */
468 COSTS_N_INSNS (3), /* mulsi_const9 */
469 COSTS_N_INSNS (7), /* muldi */
470 COSTS_N_INSNS (21), /* divsi */
471 COSTS_N_INSNS (37), /* divdi */
472 COSTS_N_INSNS (3), /* fp */
473 COSTS_N_INSNS (3), /* dmul */
474 COSTS_N_INSNS (18), /* sdiv */
475 COSTS_N_INSNS (32), /* ddiv */
478 /* Instruction costs on PPC630 processors. */
480 struct processor_costs ppc630_cost
= {
481 COSTS_N_INSNS (5), /* mulsi */
482 COSTS_N_INSNS (4), /* mulsi_const */
483 COSTS_N_INSNS (3), /* mulsi_const9 */
484 COSTS_N_INSNS (7), /* muldi */
485 COSTS_N_INSNS (21), /* divsi */
486 COSTS_N_INSNS (37), /* divdi */
487 COSTS_N_INSNS (3), /* fp */
488 COSTS_N_INSNS (3), /* dmul */
489 COSTS_N_INSNS (17), /* sdiv */
490 COSTS_N_INSNS (21), /* ddiv */
493 /* Instruction costs on PPC750 and PPC7400 processors. */
495 struct processor_costs ppc750_cost
= {
496 COSTS_N_INSNS (5), /* mulsi */
497 COSTS_N_INSNS (3), /* mulsi_const */
498 COSTS_N_INSNS (2), /* mulsi_const9 */
499 COSTS_N_INSNS (5), /* muldi */
500 COSTS_N_INSNS (17), /* divsi */
501 COSTS_N_INSNS (17), /* divdi */
502 COSTS_N_INSNS (3), /* fp */
503 COSTS_N_INSNS (3), /* dmul */
504 COSTS_N_INSNS (17), /* sdiv */
505 COSTS_N_INSNS (31), /* ddiv */
508 /* Instruction costs on PPC7450 processors. */
510 struct processor_costs ppc7450_cost
= {
511 COSTS_N_INSNS (4), /* mulsi */
512 COSTS_N_INSNS (3), /* mulsi_const */
513 COSTS_N_INSNS (3), /* mulsi_const9 */
514 COSTS_N_INSNS (4), /* muldi */
515 COSTS_N_INSNS (23), /* divsi */
516 COSTS_N_INSNS (23), /* divdi */
517 COSTS_N_INSNS (5), /* fp */
518 COSTS_N_INSNS (5), /* dmul */
519 COSTS_N_INSNS (21), /* sdiv */
520 COSTS_N_INSNS (35), /* ddiv */
523 /* Instruction costs on PPC8540 processors. */
525 struct processor_costs ppc8540_cost
= {
526 COSTS_N_INSNS (4), /* mulsi */
527 COSTS_N_INSNS (4), /* mulsi_const */
528 COSTS_N_INSNS (4), /* mulsi_const9 */
529 COSTS_N_INSNS (4), /* muldi */
530 COSTS_N_INSNS (19), /* divsi */
531 COSTS_N_INSNS (19), /* divdi */
532 COSTS_N_INSNS (4), /* fp */
533 COSTS_N_INSNS (4), /* dmul */
534 COSTS_N_INSNS (29), /* sdiv */
535 COSTS_N_INSNS (29), /* ddiv */
538 /* Instruction costs on POWER4 and POWER5 processors. */
540 struct processor_costs power4_cost
= {
541 COSTS_N_INSNS (3), /* mulsi */
542 COSTS_N_INSNS (2), /* mulsi_const */
543 COSTS_N_INSNS (2), /* mulsi_const9 */
544 COSTS_N_INSNS (4), /* muldi */
545 COSTS_N_INSNS (18), /* divsi */
546 COSTS_N_INSNS (34), /* divdi */
547 COSTS_N_INSNS (3), /* fp */
548 COSTS_N_INSNS (3), /* dmul */
549 COSTS_N_INSNS (17), /* sdiv */
550 COSTS_N_INSNS (17), /* ddiv */
554 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
555 static rtx
rs6000_generate_compare (enum rtx_code
);
556 static void rs6000_maybe_dead (rtx
);
557 static void rs6000_emit_stack_tie (void);
558 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
559 static rtx
spe_synthesize_frame_save (rtx
);
560 static bool spe_func_has_64bit_regs_p (void);
561 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
563 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
564 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int);
565 static unsigned rs6000_hash_constant (rtx
);
566 static unsigned toc_hash_function (const void *);
567 static int toc_hash_eq (const void *, const void *);
568 static int constant_pool_expr_1 (rtx
, int *, int *);
569 static bool constant_pool_expr_p (rtx
);
570 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
571 static bool legitimate_indexed_address_p (rtx
, int);
572 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
573 static struct machine_function
* rs6000_init_machine_status (void);
574 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
575 #ifdef HAVE_GAS_HIDDEN
576 static void rs6000_assemble_visibility (tree
, int);
578 static int rs6000_ra_ever_killed (void);
579 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
580 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
581 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
582 static const char *rs6000_mangle_fundamental_type (tree
);
583 extern const struct attribute_spec rs6000_attribute_table
[];
584 static void rs6000_set_default_type_attributes (tree
);
585 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
586 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
587 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
589 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
590 static bool rs6000_return_in_memory (tree
, tree
);
591 static void rs6000_file_start (void);
593 static unsigned int rs6000_elf_section_type_flags (tree
, const char *, int);
594 static void rs6000_elf_asm_out_constructor (rtx
, int);
595 static void rs6000_elf_asm_out_destructor (rtx
, int);
596 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
597 static void rs6000_elf_select_section (tree
, int, unsigned HOST_WIDE_INT
);
598 static void rs6000_elf_unique_section (tree
, int);
599 static void rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
600 unsigned HOST_WIDE_INT
);
601 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
603 static bool rs6000_elf_in_small_data_p (tree
);
606 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
607 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
608 static void rs6000_xcoff_select_section (tree
, int, unsigned HOST_WIDE_INT
);
609 static void rs6000_xcoff_unique_section (tree
, int);
610 static void rs6000_xcoff_select_rtx_section (enum machine_mode
, rtx
,
611 unsigned HOST_WIDE_INT
);
612 static const char * rs6000_xcoff_strip_name_encoding (const char *);
613 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
614 static void rs6000_xcoff_file_start (void);
615 static void rs6000_xcoff_file_end (void);
618 static bool rs6000_binds_local_p (tree
);
620 static int rs6000_variable_issue (FILE *, int, rtx
, int);
621 static bool rs6000_rtx_costs (rtx
, int, int, int *);
622 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
623 static bool is_microcoded_insn (rtx
);
624 static int is_dispatch_slot_restricted (rtx
);
625 static bool is_cracked_insn (rtx
);
626 static bool is_branch_slot_insn (rtx
);
627 static int rs6000_adjust_priority (rtx
, int);
628 static int rs6000_issue_rate (void);
629 static bool rs6000_is_costly_dependence (rtx
, rtx
, rtx
, int, int);
630 static rtx
get_next_active_insn (rtx
, rtx
);
631 static bool insn_terminates_group_p (rtx
, enum group_termination
);
632 static bool is_costly_group (rtx
*, rtx
);
633 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
634 static int redefine_groups (FILE *, int, rtx
, rtx
);
635 static int pad_groups (FILE *, int, rtx
, rtx
);
636 static void rs6000_sched_finish (FILE *, int);
637 static int rs6000_use_sched_lookahead (void);
638 static tree
rs6000_builtin_mask_for_load (void);
640 static void def_builtin (int, const char *, tree
, int);
641 static void rs6000_init_builtins (void);
642 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
643 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
644 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
645 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
646 static void altivec_init_builtins (void);
647 static void rs6000_common_init_builtins (void);
648 static void rs6000_init_libfuncs (void);
650 static void enable_mask_for_builtins (struct builtin_description
*, int,
651 enum rs6000_builtins
,
652 enum rs6000_builtins
);
653 static tree
build_opaque_vector_type (tree
, int);
654 static void spe_init_builtins (void);
655 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
656 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
657 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
658 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
659 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
660 static rs6000_stack_t
*rs6000_stack_info (void);
661 static void debug_stack_info (rs6000_stack_t
*);
663 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
664 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
665 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
666 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
667 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
668 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
669 const char *, tree
, rtx
);
670 static rtx
altivec_expand_lv_builtin (enum insn_code
, tree
, rtx
);
671 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
672 static bool rs6000_handle_option (size_t, const char *, int);
673 static void rs6000_parse_tls_size_option (void);
674 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
675 static int first_altivec_reg_to_save (void);
676 static unsigned int compute_vrsave_mask (void);
677 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
678 static void is_altivec_return_reg (rtx
, void *);
679 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
680 int easy_vector_constant (rtx
, enum machine_mode
);
681 static bool rs6000_is_opaque_type (tree
);
682 static rtx
rs6000_dwarf_register_span (rtx
);
683 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
684 static rtx
rs6000_tls_get_addr (void);
685 static rtx
rs6000_got_sym (void);
686 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
687 static const char *rs6000_get_some_local_dynamic_name (void);
688 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
689 static rtx
rs6000_complex_function_value (enum machine_mode
);
690 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
691 enum machine_mode
, tree
);
692 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
694 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
695 tree
, HOST_WIDE_INT
);
696 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
699 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
702 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, tree
, int, bool);
703 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
704 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
705 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
706 enum machine_mode
, tree
,
708 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
710 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
712 static const char *invalid_arg_for_unprototyped_fn (tree
, tree
, tree
);
714 static void macho_branch_islands (void);
715 static void add_compiler_branch_island (tree
, tree
, int);
716 static int no_previous_def (tree function_name
);
717 static tree
get_prev_label (tree function_name
);
718 static void rs6000_darwin_file_start (void);
721 static tree
rs6000_build_builtin_va_list (void);
722 static tree
rs6000_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
723 static bool rs6000_must_pass_in_stack (enum machine_mode
, tree
);
724 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
725 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
727 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
729 static int get_vsel_insn (enum machine_mode
);
730 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
733 const int INSN_NOT_AVAILABLE
= -1;
734 static enum machine_mode
rs6000_eh_return_filter_mode (void);
736 /* Hash table stuff for keeping track of TOC entries. */
738 struct toc_hash_struct
GTY(())
740 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
741 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
743 enum machine_mode key_mode
;
747 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
749 /* Default register names. */
750 char rs6000_reg_names
[][8] =
752 "0", "1", "2", "3", "4", "5", "6", "7",
753 "8", "9", "10", "11", "12", "13", "14", "15",
754 "16", "17", "18", "19", "20", "21", "22", "23",
755 "24", "25", "26", "27", "28", "29", "30", "31",
756 "0", "1", "2", "3", "4", "5", "6", "7",
757 "8", "9", "10", "11", "12", "13", "14", "15",
758 "16", "17", "18", "19", "20", "21", "22", "23",
759 "24", "25", "26", "27", "28", "29", "30", "31",
760 "mq", "lr", "ctr","ap",
761 "0", "1", "2", "3", "4", "5", "6", "7",
763 /* AltiVec registers. */
764 "0", "1", "2", "3", "4", "5", "6", "7",
765 "8", "9", "10", "11", "12", "13", "14", "15",
766 "16", "17", "18", "19", "20", "21", "22", "23",
767 "24", "25", "26", "27", "28", "29", "30", "31",
773 #ifdef TARGET_REGNAMES
774 static const char alt_reg_names
[][8] =
776 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
777 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
778 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
779 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
780 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
781 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
782 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
783 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
784 "mq", "lr", "ctr", "ap",
785 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
787 /* AltiVec registers. */
788 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
789 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
790 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
791 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
798 #ifndef MASK_STRICT_ALIGN
799 #define MASK_STRICT_ALIGN 0
801 #ifndef TARGET_PROFILE_KERNEL
802 #define TARGET_PROFILE_KERNEL 0
805 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
806 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
808 /* Initialize the GCC target structure. */
809 #undef TARGET_ATTRIBUTE_TABLE
810 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
811 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
812 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
814 #undef TARGET_ASM_ALIGNED_DI_OP
815 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
817 /* Default unaligned ops are only provided for ELF. Find the ops needed
818 for non-ELF systems. */
819 #ifndef OBJECT_FORMAT_ELF
821 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
823 #undef TARGET_ASM_UNALIGNED_HI_OP
824 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
825 #undef TARGET_ASM_UNALIGNED_SI_OP
826 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
827 #undef TARGET_ASM_UNALIGNED_DI_OP
828 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
831 #undef TARGET_ASM_UNALIGNED_HI_OP
832 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
833 #undef TARGET_ASM_UNALIGNED_SI_OP
834 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
835 #undef TARGET_ASM_UNALIGNED_DI_OP
836 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
837 #undef TARGET_ASM_ALIGNED_DI_OP
838 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
842 /* This hook deals with fixups for relocatable code and DI-mode objects
844 #undef TARGET_ASM_INTEGER
845 #define TARGET_ASM_INTEGER rs6000_assemble_integer
847 #ifdef HAVE_GAS_HIDDEN
848 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
849 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
852 #undef TARGET_HAVE_TLS
853 #define TARGET_HAVE_TLS HAVE_AS_TLS
855 #undef TARGET_CANNOT_FORCE_CONST_MEM
856 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
858 #undef TARGET_ASM_FUNCTION_PROLOGUE
859 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
860 #undef TARGET_ASM_FUNCTION_EPILOGUE
861 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
863 #undef TARGET_SCHED_VARIABLE_ISSUE
864 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
866 #undef TARGET_SCHED_ISSUE_RATE
867 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
868 #undef TARGET_SCHED_ADJUST_COST
869 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
870 #undef TARGET_SCHED_ADJUST_PRIORITY
871 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
872 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
873 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
874 #undef TARGET_SCHED_FINISH
875 #define TARGET_SCHED_FINISH rs6000_sched_finish
877 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
878 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
880 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
881 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
883 #undef TARGET_INIT_BUILTINS
884 #define TARGET_INIT_BUILTINS rs6000_init_builtins
886 #undef TARGET_EXPAND_BUILTIN
887 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
889 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
890 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
892 #undef TARGET_INIT_LIBFUNCS
893 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
896 #undef TARGET_BINDS_LOCAL_P
897 #define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
900 #undef TARGET_ASM_OUTPUT_MI_THUNK
901 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
903 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
904 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
906 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
907 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
909 #undef TARGET_RTX_COSTS
910 #define TARGET_RTX_COSTS rs6000_rtx_costs
911 #undef TARGET_ADDRESS_COST
912 #define TARGET_ADDRESS_COST hook_int_rtx_0
914 #undef TARGET_VECTOR_OPAQUE_P
915 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
917 #undef TARGET_DWARF_REGISTER_SPAN
918 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
920 /* On rs6000, function arguments are promoted, as are function return
922 #undef TARGET_PROMOTE_FUNCTION_ARGS
923 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
924 #undef TARGET_PROMOTE_FUNCTION_RETURN
925 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
927 #undef TARGET_RETURN_IN_MEMORY
928 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
930 #undef TARGET_SETUP_INCOMING_VARARGS
931 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
933 /* Always strict argument naming on rs6000. */
934 #undef TARGET_STRICT_ARGUMENT_NAMING
935 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
936 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
937 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
938 #undef TARGET_SPLIT_COMPLEX_ARG
939 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
940 #undef TARGET_MUST_PASS_IN_STACK
941 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
942 #undef TARGET_PASS_BY_REFERENCE
943 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
944 #undef TARGET_ARG_PARTIAL_BYTES
945 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
947 #undef TARGET_BUILD_BUILTIN_VA_LIST
948 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
950 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
951 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
953 #undef TARGET_EH_RETURN_FILTER_MODE
954 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
956 #undef TARGET_VECTOR_MODE_SUPPORTED_P
957 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
959 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
960 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
962 #undef TARGET_HANDLE_OPTION
963 #define TARGET_HANDLE_OPTION rs6000_handle_option
965 #undef TARGET_DEFAULT_TARGET_FLAGS
966 #define TARGET_DEFAULT_TARGET_FLAGS \
967 (TARGET_DEFAULT | MASK_SCHED_PROLOG)
969 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
970 The PowerPC architecture requires only weak consistency among
971 processors--that is, memory accesses between processors need not be
972 sequentially consistent and memory accesses among processors can occur
973 in any order. The ability to order memory accesses weakly provides
974 opportunities for more efficient use of the system bus. Unless a
975 dependency exists, the 604e allows read operations to precede store
977 #undef TARGET_RELAXED_ORDERING
978 #define TARGET_RELAXED_ORDERING true
980 struct gcc_target targetm
= TARGET_INITIALIZER
;
983 /* Value is 1 if hard register REGNO can hold a value of machine-mode
986 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
988 /* The GPRs can hold any mode, but values bigger than one register
989 cannot go past R31. */
990 if (INT_REGNO_P (regno
))
991 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
993 /* The float registers can only hold floating modes and DImode. */
994 if (FP_REGNO_P (regno
))
996 (GET_MODE_CLASS (mode
) == MODE_FLOAT
997 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
998 || (GET_MODE_CLASS (mode
) == MODE_INT
999 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
);
1001 /* The CR register can only hold CC modes. */
1002 if (CR_REGNO_P (regno
))
1003 return GET_MODE_CLASS (mode
) == MODE_CC
;
1005 if (XER_REGNO_P (regno
))
1006 return mode
== PSImode
;
1008 /* AltiVec only in AldyVec registers. */
1009 if (ALTIVEC_REGNO_P (regno
))
1010 return ALTIVEC_VECTOR_MODE (mode
);
1012 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1013 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1016 /* We cannot put TImode anywhere except general register and it must be
1017 able to fit within the register set. */
1019 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1022 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1024 rs6000_init_hard_regno_mode_ok (void)
1028 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1029 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1030 if (rs6000_hard_regno_mode_ok (r
, m
))
1031 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1034 /* If not otherwise specified by a target, make 'long double' equivalent to
1037 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1038 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1041 /* Override command line options. Mostly we process the processor
1042 type and sometimes adjust other TARGET_ options. */
1045 rs6000_override_options (const char *default_cpu
)
1048 struct rs6000_cpu_select
*ptr
;
1051 /* Simplifications for entries below. */
1054 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1055 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1058 /* This table occasionally claims that a processor does not support
1059 a particular feature even though it does, but the feature is slower
1060 than the alternative. Thus, it shouldn't be relied on as a
1061 complete description of the processor's support.
1063 Please keep this list in order, and don't forget to update the
1064 documentation in invoke.texi when adding a new processor or
1068 const char *const name
; /* Canonical processor name. */
1069 const enum processor_type processor
; /* Processor type enum value. */
1070 const int target_enable
; /* Target flags to enable. */
1071 } const processor_target_table
[]
1072 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1073 {"403", PROCESSOR_PPC403
,
1074 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1075 {"405", PROCESSOR_PPC405
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1076 {"405fp", PROCESSOR_PPC405
, POWERPC_BASE_MASK
},
1077 {"440", PROCESSOR_PPC440
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1078 {"440fp", PROCESSOR_PPC440
, POWERPC_BASE_MASK
},
1079 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1080 {"601", PROCESSOR_PPC601
,
1081 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1082 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1083 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1084 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1085 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1086 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1087 {"620", PROCESSOR_PPC620
,
1088 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1089 {"630", PROCESSOR_PPC630
,
1090 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1091 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1092 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1093 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1094 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1095 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1096 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1097 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1098 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1099 /* 8548 has a dummy entry for now. */
1100 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1101 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1102 {"970", PROCESSOR_POWER4
,
1103 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1104 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1105 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1106 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1107 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1108 {"G5", PROCESSOR_POWER4
,
1109 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1110 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1111 {"power2", PROCESSOR_POWER
,
1112 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1113 {"power3", PROCESSOR_PPC630
,
1114 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1115 {"power4", PROCESSOR_POWER4
,
1116 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1117 {"power5", PROCESSOR_POWER5
,
1118 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1119 | MASK_MFCRF
| MASK_POPCNTB
},
1120 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1121 {"powerpc64", PROCESSOR_POWERPC64
,
1122 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1123 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1124 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1125 {"rios2", PROCESSOR_RIOS2
,
1126 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1127 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1128 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1129 {"rs64", PROCESSOR_RS64A
,
1130 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1133 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1135 /* Some OSs don't support saving the high part of 64-bit registers on
1136 context switch. Other OSs don't support saving Altivec registers.
1137 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1138 settings; if the user wants either, the user must explicitly specify
1139 them and we won't interfere with the user's specification. */
1142 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1143 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
1144 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1148 rs6000_init_hard_regno_mode_ok ();
1150 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1151 #ifdef OS_MISSING_POWERPC64
1152 if (OS_MISSING_POWERPC64
)
1153 set_masks
&= ~MASK_POWERPC64
;
1155 #ifdef OS_MISSING_ALTIVEC
1156 if (OS_MISSING_ALTIVEC
)
1157 set_masks
&= ~MASK_ALTIVEC
;
1160 /* Don't override by the processor default if given explicitly. */
1161 set_masks
&= ~target_flags_explicit
;
1163 /* Identify the processor type. */
1164 rs6000_select
[0].string
= default_cpu
;
1165 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1167 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1169 ptr
= &rs6000_select
[i
];
1170 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1172 for (j
= 0; j
< ptt_size
; j
++)
1173 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1175 if (ptr
->set_tune_p
)
1176 rs6000_cpu
= processor_target_table
[j
].processor
;
1178 if (ptr
->set_arch_p
)
1180 target_flags
&= ~set_masks
;
1181 target_flags
|= (processor_target_table
[j
].target_enable
1188 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1195 /* If we are optimizing big endian systems for space, use the load/store
1196 multiple and string instructions. */
1197 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1198 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1200 /* Don't allow -mmultiple or -mstring on little endian systems
1201 unless the cpu is a 750, because the hardware doesn't support the
1202 instructions used in little endian mode, and causes an alignment
1203 trap. The 750 does not cause an alignment trap (except when the
1204 target is unaligned). */
1206 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1208 if (TARGET_MULTIPLE
)
1210 target_flags
&= ~MASK_MULTIPLE
;
1211 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1212 warning (0, "-mmultiple is not supported on little endian systems");
1217 target_flags
&= ~MASK_STRING
;
1218 if ((target_flags_explicit
& MASK_STRING
) != 0)
1219 warning (0, "-mstring is not supported on little endian systems");
1223 /* Set debug flags */
1224 if (rs6000_debug_name
)
1226 if (! strcmp (rs6000_debug_name
, "all"))
1227 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1228 else if (! strcmp (rs6000_debug_name
, "stack"))
1229 rs6000_debug_stack
= 1;
1230 else if (! strcmp (rs6000_debug_name
, "arg"))
1231 rs6000_debug_arg
= 1;
1233 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1236 if (rs6000_traceback_name
)
1238 if (! strncmp (rs6000_traceback_name
, "full", 4))
1239 rs6000_traceback
= traceback_full
;
1240 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1241 rs6000_traceback
= traceback_part
;
1242 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1243 rs6000_traceback
= traceback_none
;
1245 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1246 rs6000_traceback_name
);
1249 if (!rs6000_explicit_options
.long_double
)
1250 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1252 /* Set Altivec ABI as default for powerpc64 linux. */
1253 if (TARGET_ELF
&& TARGET_64BIT
)
1255 rs6000_altivec_abi
= 1;
1256 TARGET_ALTIVEC_VRSAVE
= 1;
1259 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1260 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1262 rs6000_darwin64_abi
= 1;
1264 darwin_one_byte_bool
= 1;
1266 /* Default to natural alignment, for better performance. */
1267 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1270 /* Handle -mtls-size option. */
1271 rs6000_parse_tls_size_option ();
1273 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1274 SUBTARGET_OVERRIDE_OPTIONS
;
1276 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1277 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1279 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1280 SUB3TARGET_OVERRIDE_OPTIONS
;
1286 error ("AltiVec and E500 instructions cannot coexist");
1288 /* The e500 does not have string instructions, and we set
1289 MASK_STRING above when optimizing for size. */
1290 if ((target_flags
& MASK_STRING
) != 0)
1291 target_flags
= target_flags
& ~MASK_STRING
;
1293 else if (rs6000_select
[1].string
!= NULL
)
1295 /* For the powerpc-eabispe configuration, we set all these by
1296 default, so let's unset them if we manually set another
1297 CPU that is not the E500. */
1298 if (!rs6000_explicit_options
.abi
)
1300 if (!rs6000_explicit_options
.spe
)
1302 if (!rs6000_explicit_options
.float_gprs
)
1303 rs6000_float_gprs
= 0;
1304 if (!rs6000_explicit_options
.isel
)
1306 if (!rs6000_explicit_options
.long_double
)
1307 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1310 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1311 && rs6000_cpu
!= PROCESSOR_POWER5
);
1312 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1313 || rs6000_cpu
== PROCESSOR_POWER5
);
1315 rs6000_sched_restricted_insns_priority
1316 = (rs6000_sched_groups
? 1 : 0);
1318 /* Handle -msched-costly-dep option. */
1319 rs6000_sched_costly_dep
1320 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1322 if (rs6000_sched_costly_dep_str
)
1324 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1325 rs6000_sched_costly_dep
= no_dep_costly
;
1326 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1327 rs6000_sched_costly_dep
= all_deps_costly
;
1328 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1329 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1330 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1331 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1333 rs6000_sched_costly_dep
= atoi (rs6000_sched_costly_dep_str
);
1336 /* Handle -minsert-sched-nops option. */
1337 rs6000_sched_insert_nops
1338 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1340 if (rs6000_sched_insert_nops_str
)
1342 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1343 rs6000_sched_insert_nops
= sched_finish_none
;
1344 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1345 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1346 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1347 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1349 rs6000_sched_insert_nops
= atoi (rs6000_sched_insert_nops_str
);
1352 #ifdef TARGET_REGNAMES
1353 /* If the user desires alternate register names, copy in the
1354 alternate names now. */
1355 if (TARGET_REGNAMES
)
1356 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1359 /* Set aix_struct_return last, after the ABI is determined.
1360 If -maix-struct-return or -msvr4-struct-return was explicitly
1361 used, don't override with the ABI default. */
1362 if (!rs6000_explicit_options
.aix_struct_ret
)
1363 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1365 if (TARGET_LONG_DOUBLE_128
1366 && (DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_DARWIN
))
1367 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1369 /* Allocate an alias set for register saves & restores from stack. */
1370 rs6000_sr_alias_set
= new_alias_set ();
1373 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1375 /* We can only guarantee the availability of DI pseudo-ops when
1376 assembling for 64-bit targets. */
1379 targetm
.asm_out
.aligned_op
.di
= NULL
;
1380 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1383 /* Set branch target alignment, if not optimizing for size. */
1386 if (rs6000_sched_groups
)
1388 if (align_functions
<= 0)
1389 align_functions
= 16;
1390 if (align_jumps
<= 0)
1392 if (align_loops
<= 0)
1395 if (align_jumps_max_skip
<= 0)
1396 align_jumps_max_skip
= 15;
1397 if (align_loops_max_skip
<= 0)
1398 align_loops_max_skip
= 15;
1401 /* Arrange to save and restore machine status around nested functions. */
1402 init_machine_status
= rs6000_init_machine_status
;
1404 /* We should always be splitting complex arguments, but we can't break
1405 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1406 if (DEFAULT_ABI
!= ABI_AIX
)
1407 targetm
.calls
.split_complex_arg
= NULL
;
1409 /* Initialize rs6000_cost with the appropriate target costs. */
1411 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1415 case PROCESSOR_RIOS1
:
1416 rs6000_cost
= &rios1_cost
;
1419 case PROCESSOR_RIOS2
:
1420 rs6000_cost
= &rios2_cost
;
1423 case PROCESSOR_RS64A
:
1424 rs6000_cost
= &rs64a_cost
;
1427 case PROCESSOR_MPCCORE
:
1428 rs6000_cost
= &mpccore_cost
;
1431 case PROCESSOR_PPC403
:
1432 rs6000_cost
= &ppc403_cost
;
1435 case PROCESSOR_PPC405
:
1436 rs6000_cost
= &ppc405_cost
;
1439 case PROCESSOR_PPC440
:
1440 rs6000_cost
= &ppc440_cost
;
1443 case PROCESSOR_PPC601
:
1444 rs6000_cost
= &ppc601_cost
;
1447 case PROCESSOR_PPC603
:
1448 rs6000_cost
= &ppc603_cost
;
1451 case PROCESSOR_PPC604
:
1452 rs6000_cost
= &ppc604_cost
;
1455 case PROCESSOR_PPC604e
:
1456 rs6000_cost
= &ppc604e_cost
;
1459 case PROCESSOR_PPC620
:
1460 rs6000_cost
= &ppc620_cost
;
1463 case PROCESSOR_PPC630
:
1464 rs6000_cost
= &ppc630_cost
;
1467 case PROCESSOR_PPC750
:
1468 case PROCESSOR_PPC7400
:
1469 rs6000_cost
= &ppc750_cost
;
1472 case PROCESSOR_PPC7450
:
1473 rs6000_cost
= &ppc7450_cost
;
1476 case PROCESSOR_PPC8540
:
1477 rs6000_cost
= &ppc8540_cost
;
1480 case PROCESSOR_POWER4
:
1481 case PROCESSOR_POWER5
:
1482 rs6000_cost
= &power4_cost
;
1490 /* Implement targetm.vectorize.builtin_mask_for_load. */
1492 rs6000_builtin_mask_for_load (void)
1495 return altivec_builtin_mask_for_load
;
1500 /* Handle generic options of the form -mfoo=yes/no.
1501 NAME is the option name.
1502 VALUE is the option value.
1503 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1504 whether the option value is 'yes' or 'no' respectively. */
1506 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
1510 else if (!strcmp (value
, "yes"))
1512 else if (!strcmp (value
, "no"))
1515 error ("unknown -m%s= option specified: '%s'", name
, value
);
1518 /* Validate and record the size specified with the -mtls-size option. */
1521 rs6000_parse_tls_size_option (void)
1523 if (rs6000_tls_size_string
== 0)
1525 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
1526 rs6000_tls_size
= 16;
1527 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
1528 rs6000_tls_size
= 32;
1529 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
1530 rs6000_tls_size
= 64;
1532 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
1536 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1540 /* Implement TARGET_HANDLE_OPTION. */
1543 rs6000_handle_option (size_t code
, const char *arg
, int value
)
1548 target_flags
&= ~(MASK_POWER
| MASK_POWER2
1549 | MASK_MULTIPLE
| MASK_STRING
);
1550 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
1551 | MASK_MULTIPLE
| MASK_STRING
);
1553 case OPT_mno_powerpc
:
1554 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
1555 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1556 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
1557 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1560 target_flags
&= ~(MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
1561 | MASK_NO_SUM_IN_TOC
);
1562 target_flags_explicit
|= (MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
1563 | MASK_NO_SUM_IN_TOC
);
1564 #ifdef TARGET_USES_SYSV4_OPT
1565 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1566 just the same as -mminimal-toc. */
1567 target_flags
|= MASK_MINIMAL_TOC
;
1568 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1572 #ifdef TARGET_USES_SYSV4_OPT
1574 /* Make -mtoc behave like -mminimal-toc. */
1575 target_flags
|= MASK_MINIMAL_TOC
;
1576 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1580 #ifdef TARGET_USES_AIX64_OPT
1585 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
| MASK_PPC_GFXOPT
;
1586 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
1590 #ifdef TARGET_USES_AIX64_OPT
1595 target_flags
&= ~MASK_POWERPC64
;
1596 target_flags_explicit
|= MASK_POWERPC64
;
1599 case OPT_minsert_sched_nops_
:
1600 rs6000_sched_insert_nops_str
= arg
;
1603 case OPT_mminimal_toc
:
1606 target_flags
&= ~(MASK_NO_FP_IN_TOC
| MASK_NO_SUM_IN_TOC
);
1607 target_flags_explicit
|= (MASK_NO_FP_IN_TOC
| MASK_NO_SUM_IN_TOC
);
1614 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
1615 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
1622 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1623 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1627 case OPT_mpowerpc_gpopt
:
1628 case OPT_mpowerpc_gfxopt
:
1631 target_flags
|= MASK_POWERPC
;
1632 target_flags_explicit
|= MASK_POWERPC
;
1636 case OPT_maix_struct_return
:
1637 case OPT_msvr4_struct_return
:
1638 rs6000_explicit_options
.aix_struct_ret
= true;
1642 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
1646 rs6000_explicit_options
.isel
= true;
1647 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
1651 rs6000_explicit_options
.spe
= true;
1652 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
1653 /* No SPE means 64-bit long doubles, even if an E500. */
1655 rs6000_long_double_type_size
= 64;
1659 rs6000_debug_name
= arg
;
1662 #ifdef TARGET_USES_SYSV4_OPT
1664 rs6000_abi_name
= arg
;
1668 rs6000_sdata_name
= arg
;
1671 case OPT_mtls_size_
:
1672 rs6000_tls_size_string
= arg
;
1675 case OPT_mrelocatable
:
1678 target_flags
|= MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
;
1679 target_flags_explicit
|= MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
;
1683 case OPT_mrelocatable_lib
:
1686 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
1687 | MASK_NO_FP_IN_TOC
;
1688 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
1689 | MASK_NO_FP_IN_TOC
;
1693 target_flags
&= ~MASK_RELOCATABLE
;
1694 target_flags_explicit
|= MASK_RELOCATABLE
;
1700 rs6000_explicit_options
.abi
= true;
1701 if (!strcmp (arg
, "altivec"))
1703 rs6000_altivec_abi
= 1;
1706 else if (! strcmp (arg
, "no-altivec"))
1707 rs6000_altivec_abi
= 0;
1708 else if (! strcmp (arg
, "spe"))
1711 rs6000_altivec_abi
= 0;
1712 if (!TARGET_SPE_ABI
)
1713 error ("not configured for ABI: '%s'", arg
);
1715 else if (! strcmp (arg
, "no-spe"))
1718 /* These are here for testing during development only, do not
1719 document in the manual please. */
1720 else if (! strcmp (arg
, "d64"))
1722 rs6000_darwin64_abi
= 1;
1723 warning (0, "Using darwin64 ABI");
1725 else if (! strcmp (arg
, "d32"))
1727 rs6000_darwin64_abi
= 0;
1728 warning (0, "Using old darwin ABI");
1733 error ("unknown ABI specified: '%s'", arg
);
1739 rs6000_select
[1].string
= arg
;
1743 rs6000_select
[2].string
= arg
;
1746 case OPT_mtraceback_
:
1747 rs6000_traceback_name
= arg
;
1750 case OPT_mfloat_gprs_
:
1751 rs6000_explicit_options
.float_gprs
= true;
1752 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
1753 rs6000_float_gprs
= 1;
1754 else if (! strcmp (arg
, "double"))
1755 rs6000_float_gprs
= 2;
1756 else if (! strcmp (arg
, "no"))
1757 rs6000_float_gprs
= 0;
1760 error ("invalid option for -mfloat-gprs: '%s'", arg
);
1765 case OPT_mlong_double_
:
1766 rs6000_explicit_options
.long_double
= true;
1767 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1768 if (value
!= 64 && value
!= 128)
1770 error ("Unknown switch -mlong-double-%s", arg
);
1771 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1775 rs6000_long_double_type_size
= value
;
1778 case OPT_msched_costly_dep_
:
1779 rs6000_sched_costly_dep_str
= arg
;
1783 rs6000_explicit_options
.alignment
= true;
1784 if (! strcmp (arg
, "power"))
1786 /* On 64-bit Darwin, power alignment is ABI-incompatible with
1787 some C library functions, so warn about it. The flag may be
1788 useful for performance studies from time to time though, so
1789 don't disable it entirely. */
1790 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1791 warning (0, "-malign-power is not supported for 64-bit Darwin;"
1792 " it is incompatible with the installed C and C++ libraries");
1793 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
1795 else if (! strcmp (arg
, "natural"))
1796 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1799 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
1807 /* Do anything needed at the start of the asm file. */
1810 rs6000_file_start (void)
1814 const char *start
= buffer
;
1815 struct rs6000_cpu_select
*ptr
;
1816 const char *default_cpu
= TARGET_CPU_DEFAULT
;
1817 FILE *file
= asm_out_file
;
1819 default_file_start ();
1821 #ifdef TARGET_BI_ARCH
1822 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
1826 if (flag_verbose_asm
)
1828 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
1829 rs6000_select
[0].string
= default_cpu
;
1831 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1833 ptr
= &rs6000_select
[i
];
1834 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1836 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
1841 #ifdef USING_ELFOS_H
1842 switch (rs6000_sdata
)
1844 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
1845 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
1846 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
1847 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
1850 if (rs6000_sdata
&& g_switch_value
)
1852 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
1862 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
1870 /* Return nonzero if this function is known to have a null epilogue. */
1873 direct_return (void)
1875 if (reload_completed
)
1877 rs6000_stack_t
*info
= rs6000_stack_info ();
1879 if (info
->first_gp_reg_save
== 32
1880 && info
->first_fp_reg_save
== 64
1881 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
1882 && ! info
->lr_save_p
1883 && ! info
->cr_save_p
1884 && info
->vrsave_mask
== 0
1892 /* Return the number of instructions it takes to form a constant in an
1893 integer register. */
1896 num_insns_constant_wide (HOST_WIDE_INT value
)
1898 /* signed constant loadable with {cal|addi} */
1899 if (CONST_OK_FOR_LETTER_P (value
, 'I'))
1902 /* constant loadable with {cau|addis} */
1903 else if (CONST_OK_FOR_LETTER_P (value
, 'L'))
1906 #if HOST_BITS_PER_WIDE_INT == 64
1907 else if (TARGET_POWERPC64
)
1909 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1910 HOST_WIDE_INT high
= value
>> 31;
1912 if (high
== 0 || high
== -1)
1918 return num_insns_constant_wide (high
) + 1;
1920 return (num_insns_constant_wide (high
)
1921 + num_insns_constant_wide (low
) + 1);
1930 num_insns_constant (rtx op
, enum machine_mode mode
)
1932 HOST_WIDE_INT low
, high
;
1934 switch (GET_CODE (op
))
1937 #if HOST_BITS_PER_WIDE_INT == 64
1938 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
1939 && mask64_operand (op
, mode
))
1943 return num_insns_constant_wide (INTVAL (op
));
1951 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
1952 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
1953 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
1956 if (mode
== VOIDmode
|| mode
== DImode
)
1958 high
= CONST_DOUBLE_HIGH (op
);
1959 low
= CONST_DOUBLE_LOW (op
);
1966 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
1967 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
1968 high
= l
[WORDS_BIG_ENDIAN
== 0];
1969 low
= l
[WORDS_BIG_ENDIAN
!= 0];
1973 return (num_insns_constant_wide (low
)
1974 + num_insns_constant_wide (high
));
1977 if ((high
== 0 && low
>= 0)
1978 || (high
== -1 && low
< 0))
1979 return num_insns_constant_wide (low
);
1981 else if (mask64_operand (op
, mode
))
1985 return num_insns_constant_wide (high
) + 1;
1988 return (num_insns_constant_wide (high
)
1989 + num_insns_constant_wide (low
) + 1);
1997 /* Returns the constant for the splat instruction, if exists. */
2000 easy_vector_splat_const (int cst
, enum machine_mode mode
)
2005 if (EASY_VECTOR_15 (cst
)
2006 || EASY_VECTOR_15_ADD_SELF (cst
))
2008 if ((cst
& 0xffff) != ((cst
>> 16) & 0xffff))
2014 if (EASY_VECTOR_15 (cst
)
2015 || EASY_VECTOR_15_ADD_SELF (cst
))
2017 if ((cst
& 0xff) != ((cst
>> 8) & 0xff))
2023 if (EASY_VECTOR_15 (cst
)
2024 || EASY_VECTOR_15_ADD_SELF (cst
))
2032 /* Return nonzero if all elements of a vector have the same value. */
2035 easy_vector_same (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
)
2039 units
= CONST_VECTOR_NUNITS (op
);
2041 cst
= INTVAL (CONST_VECTOR_ELT (op
, 0));
2042 for (i
= 1; i
< units
; ++i
)
2043 if (INTVAL (CONST_VECTOR_ELT (op
, i
)) != cst
)
2045 if (i
== units
&& easy_vector_splat_const (cst
, mode
))
2050 /* Generate easy_vector_constant out of a easy_vector_constant_add_self. */
2053 gen_easy_vector_constant_add_self (rtx op
)
2057 units
= GET_MODE_NUNITS (GET_MODE (op
));
2058 v
= rtvec_alloc (units
);
2060 for (i
= 0; i
< units
; i
++)
2062 GEN_INT (INTVAL (CONST_VECTOR_ELT (op
, i
)) >> 1);
2063 return gen_rtx_raw_CONST_VECTOR (GET_MODE (op
), v
);
2067 output_vec_const_move (rtx
*operands
)
2070 enum machine_mode mode
;
2076 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2077 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2078 mode
= GET_MODE (dest
);
2082 if (zero_constant (vec
, mode
))
2083 return "vxor %0,%0,%0";
2085 gcc_assert (easy_vector_constant (vec
, mode
));
2087 operands
[1] = GEN_INT (cst
);
2091 if (EASY_VECTOR_15 (cst
))
2093 operands
[1] = GEN_INT (cst
);
2094 return "vspltisw %0,%1";
2096 else if (EASY_VECTOR_15_ADD_SELF (cst
))
2102 if (EASY_VECTOR_15 (cst
))
2104 operands
[1] = GEN_INT (cst
);
2105 return "vspltish %0,%1";
2107 else if (EASY_VECTOR_15_ADD_SELF (cst
))
2113 if (EASY_VECTOR_15 (cst
))
2115 operands
[1] = GEN_INT (cst
);
2116 return "vspltisb %0,%1";
2118 else if (EASY_VECTOR_15_ADD_SELF (cst
))
2126 gcc_assert (TARGET_SPE
);
2128 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2129 pattern of V1DI, V4HI, and V2SF.
2131 FIXME: We should probably return # and add post reload
2132 splitters for these, but this way is so easy ;-). */
2133 operands
[1] = GEN_INT (cst
);
2134 operands
[2] = GEN_INT (cst2
);
2136 return "li %0,%1\n\tevmergelo %0,%0,%0";
2138 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2142 mask64_1or2_operand (rtx op
, enum machine_mode mode ATTRIBUTE_UNUSED
,
2145 if (GET_CODE (op
) == CONST_INT
)
2147 HOST_WIDE_INT c
, lsb
;
2152 /* Disallow all zeros. */
2156 /* We can use a single rlwinm insn if no upper bits of C are set
2157 AND there are zero, one or two transitions in the _whole_ of
2159 one_ok
= !(c
& ~(HOST_WIDE_INT
)0xffffffff);
2161 /* We don't change the number of transitions by inverting,
2162 so make sure we start with the LS bit zero. */
2166 /* Find the first transition. */
2169 /* Invert to look for a second transition. */
2172 /* Erase first transition. */
2175 /* Find the second transition. */
2178 /* Invert to look for a third transition. */
2181 /* Erase second transition. */
2184 if (one_ok
&& !(allow_one
|| c
))
2187 /* Find the third transition (if any). */
2190 /* Match if all the bits above are 1's (or c is zero). */
2196 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2197 implement ANDing by the mask IN. */
2199 build_mask64_2_operands (rtx in
, rtx
*out
)
2201 #if HOST_BITS_PER_WIDE_INT >= 64
2202 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
2205 gcc_assert (GET_CODE (in
) == CONST_INT
);
2210 /* Assume c initially something like 0x00fff000000fffff. The idea
2211 is to rotate the word so that the middle ^^^^^^ group of zeros
2212 is at the MS end and can be cleared with an rldicl mask. We then
2213 rotate back and clear off the MS ^^ group of zeros with a
2215 c
= ~c
; /* c == 0xff000ffffff00000 */
2216 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
2217 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
2218 c
= ~c
; /* c == 0x00fff000000fffff */
2219 c
&= -lsb
; /* c == 0x00fff00000000000 */
2220 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2221 c
= ~c
; /* c == 0xff000fffffffffff */
2222 c
&= -lsb
; /* c == 0xff00000000000000 */
2224 while ((lsb
>>= 1) != 0)
2225 shift
++; /* shift == 44 on exit from loop */
2226 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
2227 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
2228 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
2232 /* Assume c initially something like 0xff000f0000000000. The idea
2233 is to rotate the word so that the ^^^ middle group of zeros
2234 is at the LS end and can be cleared with an rldicr mask. We then
2235 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2237 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
2238 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
2239 c
= ~c
; /* c == 0x00fff0ffffffffff */
2240 c
&= -lsb
; /* c == 0x00fff00000000000 */
2241 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2242 c
= ~c
; /* c == 0xff000fffffffffff */
2243 c
&= -lsb
; /* c == 0xff00000000000000 */
2245 while ((lsb
>>= 1) != 0)
2246 shift
++; /* shift == 44 on exit from loop */
2247 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
2248 m1
>>= shift
; /* m1 == 0x0000000000000fff */
2249 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
2252 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2253 masks will be all 1's. We are guaranteed more than one transition. */
2254 out
[0] = GEN_INT (64 - shift
);
2255 out
[1] = GEN_INT (m1
);
2256 out
[2] = GEN_INT (shift
);
2257 out
[3] = GEN_INT (m2
);
2265 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2268 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
2270 /* Reject (subreg:SI (reg:DF)). */
2271 if (GET_CODE (op
) == SUBREG
2273 && REG_P (SUBREG_REG (op
))
2274 && GET_MODE (SUBREG_REG (op
)) == DFmode
)
2277 /* Reject (subreg:DF (reg:DI)). */
2278 if (GET_CODE (op
) == SUBREG
2280 && REG_P (SUBREG_REG (op
))
2281 && GET_MODE (SUBREG_REG (op
)) == DImode
)
2287 /* Darwin, AIX increases natural record alignment to doubleword if the first
2288 field is an FP double while the FP fields remain word aligned. */
2291 rs6000_special_round_type_align (tree type
, int computed
, int specified
)
2293 tree field
= TYPE_FIELDS (type
);
2295 /* Skip all non field decls */
2296 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
2297 field
= TREE_CHAIN (field
);
2299 if (field
== NULL
|| field
== type
|| DECL_MODE (field
) != DFmode
)
2300 return MAX (computed
, specified
);
2302 return MAX (MAX (computed
, specified
), 64);
2305 /* Return 1 for an operand in small memory on V.4/eabi. */
2308 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
2309 enum machine_mode mode ATTRIBUTE_UNUSED
)
2314 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
2317 if (DEFAULT_ABI
!= ABI_V4
)
2320 if (GET_CODE (op
) == SYMBOL_REF
)
2323 else if (GET_CODE (op
) != CONST
2324 || GET_CODE (XEXP (op
, 0)) != PLUS
2325 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
2326 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
2331 rtx sum
= XEXP (op
, 0);
2332 HOST_WIDE_INT summand
;
2334 /* We have to be careful here, because it is the referenced address
2335 that must be 32k from _SDA_BASE_, not just the symbol. */
2336 summand
= INTVAL (XEXP (sum
, 1));
2337 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
2340 sym_ref
= XEXP (sum
, 0);
2343 return SYMBOL_REF_SMALL_P (sym_ref
);
2349 /* Return true if either operand is a general purpose register. */
2352 gpr_or_gpr_p (rtx op0
, rtx op1
)
2354 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
2355 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
2359 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2362 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
2364 switch (GET_CODE (op
))
2367 if (RS6000_SYMBOL_REF_TLS_P (op
))
2369 else if (CONSTANT_POOL_ADDRESS_P (op
))
2371 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
2379 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
2388 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
2389 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
2391 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
2400 constant_pool_expr_p (rtx op
)
2404 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
2408 toc_relative_expr_p (rtx op
)
2412 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
2416 legitimate_constant_pool_address_p (rtx x
)
2419 && GET_CODE (x
) == PLUS
2420 && GET_CODE (XEXP (x
, 0)) == REG
2421 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
2422 && constant_pool_expr_p (XEXP (x
, 1)));
2426 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
2428 return (DEFAULT_ABI
== ABI_V4
2429 && !flag_pic
&& !TARGET_TOC
2430 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
2431 && small_data_operand (x
, mode
));
2434 /* SPE offset addressing is limited to 5-bits worth of double words. */
2435 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2438 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
2440 unsigned HOST_WIDE_INT offset
, extra
;
2442 if (GET_CODE (x
) != PLUS
)
2444 if (GET_CODE (XEXP (x
, 0)) != REG
)
2446 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
2448 if (legitimate_constant_pool_address_p (x
))
2450 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
2453 offset
= INTVAL (XEXP (x
, 1));
2461 /* AltiVec vector modes. Only reg+reg addressing is valid here,
2462 which leaves the only valid constant offset of zero, which by
2463 canonicalization rules is also invalid. */
2470 /* SPE vector modes. */
2471 return SPE_CONST_OFFSET_OK (offset
);
2474 if (TARGET_E500_DOUBLE
)
2475 return SPE_CONST_OFFSET_OK (offset
);
2478 /* On e500v2, we may have:
2480 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2482 Which gets addressed with evldd instructions. */
2483 if (TARGET_E500_DOUBLE
)
2484 return SPE_CONST_OFFSET_OK (offset
);
2486 if (mode
== DFmode
|| !TARGET_POWERPC64
)
2488 else if (offset
& 3)
2494 if (mode
== TFmode
|| !TARGET_POWERPC64
)
2496 else if (offset
& 3)
2507 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
2511 legitimate_indexed_address_p (rtx x
, int strict
)
2515 if (GET_CODE (x
) != PLUS
)
2521 if (!REG_P (op0
) || !REG_P (op1
))
2524 return ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
2525 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
2526 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
2527 && INT_REG_OK_FOR_INDEX_P (op0
, strict
)));
2531 legitimate_indirect_address_p (rtx x
, int strict
)
2533 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
2537 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
2539 if (!TARGET_MACHO
|| !flag_pic
2540 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
2544 if (GET_CODE (x
) != LO_SUM
)
2546 if (GET_CODE (XEXP (x
, 0)) != REG
)
2548 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
2552 return CONSTANT_P (x
);
2556 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
2558 if (GET_CODE (x
) != LO_SUM
)
2560 if (GET_CODE (XEXP (x
, 0)) != REG
)
2562 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
2564 /* Restrict addressing for DI because of our SUBREG hackery. */
2565 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DImode
))
2569 if (TARGET_ELF
|| TARGET_MACHO
)
2571 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
2575 if (GET_MODE_NUNITS (mode
) != 1)
2577 if (GET_MODE_BITSIZE (mode
) > 64
2578 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
2579 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& mode
== DFmode
)))
2582 return CONSTANT_P (x
);
2589 /* Try machine-dependent ways of modifying an illegitimate address
2590 to be legitimate. If we find one, return the new, valid address.
2591 This is used from only one place: `memory_address' in explow.c.
2593 OLDX is the address as it was before break_out_memory_refs was
2594 called. In some cases it is useful to look at this to decide what
2597 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
2599 It is always safe for this function to do nothing. It exists to
2600 recognize opportunities to optimize the output.
2602 On RS/6000, first check for the sum of a register with a constant
2603 integer that is out of range. If so, generate code to add the
2604 constant with the low-order 16 bits masked to the register and force
2605 this result into another register (this can be done with `cau').
2606 Then generate an address of REG+(CONST&0xffff), allowing for the
2607 possibility of bit 16 being a one.
2609 Then check for the sum of a register and something not constant, try to
2610 load the other things into a register and return the sum. */
2613 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
2614 enum machine_mode mode
)
2616 if (GET_CODE (x
) == SYMBOL_REF
)
2618 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
2620 return rs6000_legitimize_tls_address (x
, model
);
2623 if (GET_CODE (x
) == PLUS
2624 && GET_CODE (XEXP (x
, 0)) == REG
2625 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2626 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000)
2628 HOST_WIDE_INT high_int
, low_int
;
2630 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2631 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
2632 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
2633 GEN_INT (high_int
)), 0);
2634 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
2636 else if (GET_CODE (x
) == PLUS
2637 && GET_CODE (XEXP (x
, 0)) == REG
2638 && GET_CODE (XEXP (x
, 1)) != CONST_INT
2639 && GET_MODE_NUNITS (mode
) == 1
2640 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2642 || (((mode
!= DImode
&& mode
!= DFmode
) || TARGET_E500_DOUBLE
)
2644 && (TARGET_POWERPC64
|| mode
!= DImode
)
2647 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
2648 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
2650 else if (ALTIVEC_VECTOR_MODE (mode
))
2654 /* Make sure both operands are registers. */
2655 if (GET_CODE (x
) == PLUS
)
2656 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
2657 force_reg (Pmode
, XEXP (x
, 1)));
2659 reg
= force_reg (Pmode
, x
);
2662 else if (SPE_VECTOR_MODE (mode
)
2663 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
2664 || mode
== DImode
)))
2668 /* We accept [reg + reg] and [reg + OFFSET]. */
2670 if (GET_CODE (x
) == PLUS
)
2672 rtx op1
= XEXP (x
, 0);
2673 rtx op2
= XEXP (x
, 1);
2675 op1
= force_reg (Pmode
, op1
);
2677 if (GET_CODE (op2
) != REG
2678 && (GET_CODE (op2
) != CONST_INT
2679 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))))
2680 op2
= force_reg (Pmode
, op2
);
2682 return gen_rtx_PLUS (Pmode
, op1
, op2
);
2685 return force_reg (Pmode
, x
);
2691 && GET_CODE (x
) != CONST_INT
2692 && GET_CODE (x
) != CONST_DOUBLE
2694 && GET_MODE_NUNITS (mode
) == 1
2695 && (GET_MODE_BITSIZE (mode
) <= 32
2696 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) && mode
== DFmode
)))
2698 rtx reg
= gen_reg_rtx (Pmode
);
2699 emit_insn (gen_elf_high (reg
, x
));
2700 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
2702 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
2705 && ! MACHO_DYNAMIC_NO_PIC_P
2707 && GET_CODE (x
) != CONST_INT
2708 && GET_CODE (x
) != CONST_DOUBLE
2710 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) || mode
!= DFmode
)
2714 rtx reg
= gen_reg_rtx (Pmode
);
2715 emit_insn (gen_macho_high (reg
, x
));
2716 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
2719 && constant_pool_expr_p (x
)
2720 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
2722 return create_TOC_reference (x
);
2728 /* This is called from dwarf2out.c via ASM_OUTPUT_DWARF_DTPREL.
2729 We need to emit DTP-relative relocations. */
2732 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
2737 fputs ("\t.long\t", file
);
2740 fputs (DOUBLE_INT_ASM_OP
, file
);
2745 output_addr_const (file
, x
);
2746 fputs ("@dtprel+0x8000", file
);
2749 /* Construct the SYMBOL_REF for the tls_get_addr function. */
2751 static GTY(()) rtx rs6000_tls_symbol
;
2753 rs6000_tls_get_addr (void)
2755 if (!rs6000_tls_symbol
)
2756 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
2758 return rs6000_tls_symbol
;
2761 /* Construct the SYMBOL_REF for TLS GOT references. */
2763 static GTY(()) rtx rs6000_got_symbol
;
2765 rs6000_got_sym (void)
2767 if (!rs6000_got_symbol
)
2769 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
2770 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
2771 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
2774 return rs6000_got_symbol
;
2777 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
2778 this (thread-local) address. */
2781 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
2785 dest
= gen_reg_rtx (Pmode
);
2786 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
2792 tlsreg
= gen_rtx_REG (Pmode
, 13);
2793 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
2797 tlsreg
= gen_rtx_REG (Pmode
, 2);
2798 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
2802 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
2806 tmp
= gen_reg_rtx (Pmode
);
2809 tlsreg
= gen_rtx_REG (Pmode
, 13);
2810 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
2814 tlsreg
= gen_rtx_REG (Pmode
, 2);
2815 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
2819 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
2821 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
2826 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
2829 got
= gen_rtx_REG (Pmode
, TOC_REGISTER
);
2833 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
2836 rtx gsym
= rs6000_got_sym ();
2837 got
= gen_reg_rtx (Pmode
);
2839 rs6000_emit_move (got
, gsym
, Pmode
);
2842 rtx tempLR
, tmp3
, mem
;
2845 tempLR
= gen_reg_rtx (Pmode
);
2846 tmp1
= gen_reg_rtx (Pmode
);
2847 tmp2
= gen_reg_rtx (Pmode
);
2848 tmp3
= gen_reg_rtx (Pmode
);
2849 mem
= gen_const_mem (Pmode
, tmp1
);
2851 first
= emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, gsym
));
2852 emit_move_insn (tmp1
, tempLR
);
2853 emit_move_insn (tmp2
, mem
);
2854 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
2855 last
= emit_move_insn (got
, tmp3
);
2856 REG_NOTES (last
) = gen_rtx_EXPR_LIST (REG_EQUAL
, gsym
,
2858 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2860 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
,
2866 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
2868 r3
= gen_rtx_REG (Pmode
, 3);
2870 insn
= gen_tls_gd_64 (r3
, got
, addr
);
2872 insn
= gen_tls_gd_32 (r3
, got
, addr
);
2875 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
2876 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
2877 insn
= emit_call_insn (insn
);
2878 CONST_OR_PURE_CALL_P (insn
) = 1;
2879 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
2880 insn
= get_insns ();
2882 emit_libcall_block (insn
, dest
, r3
, addr
);
2884 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
2886 r3
= gen_rtx_REG (Pmode
, 3);
2888 insn
= gen_tls_ld_64 (r3
, got
);
2890 insn
= gen_tls_ld_32 (r3
, got
);
2893 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
2894 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
2895 insn
= emit_call_insn (insn
);
2896 CONST_OR_PURE_CALL_P (insn
) = 1;
2897 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
2898 insn
= get_insns ();
2900 tmp1
= gen_reg_rtx (Pmode
);
2901 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
2903 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
2904 if (rs6000_tls_size
== 16)
2907 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
2909 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
2911 else if (rs6000_tls_size
== 32)
2913 tmp2
= gen_reg_rtx (Pmode
);
2915 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
2917 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
2920 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
2922 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
2926 tmp2
= gen_reg_rtx (Pmode
);
2928 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
2930 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
2932 insn
= gen_rtx_SET (Pmode
, dest
,
2933 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
2939 /* IE, or 64 bit offset LE. */
2940 tmp2
= gen_reg_rtx (Pmode
);
2942 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
2944 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
2947 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
2949 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
2957 /* Return 1 if X contains a thread-local symbol. */
2960 rs6000_tls_referenced_p (rtx x
)
2962 if (! TARGET_HAVE_TLS
)
2965 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
2968 /* Return 1 if *X is a thread-local symbol. This is the same as
2969 rs6000_tls_symbol_ref except for the type of the unused argument. */
2972 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
2974 return RS6000_SYMBOL_REF_TLS_P (*x
);
2977 /* The convention appears to be to define this wherever it is used.
2978 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2979 is now used here. */
2980 #ifndef REG_MODE_OK_FOR_BASE_P
2981 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2984 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2985 replace the input X, or the original X if no replacement is called for.
2986 The output parameter *WIN is 1 if the calling macro should goto WIN,
2989 For RS/6000, we wish to handle large displacements off a base
2990 register by splitting the addend across an addiu/addis and the mem insn.
2991 This cuts number of extra insns needed from 3 to 1.
2993 On Darwin, we use this to generate code for floating point constants.
2994 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2995 The Darwin code is inside #if TARGET_MACHO because only then is
2996 machopic_function_base_name() defined. */
2998 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
2999 int opnum
, int type
,
3000 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
3002 /* We must recognize output that we have already generated ourselves. */
3003 if (GET_CODE (x
) == PLUS
3004 && GET_CODE (XEXP (x
, 0)) == PLUS
3005 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3006 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3007 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3009 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3010 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3011 opnum
, (enum reload_type
)type
);
3017 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
3018 && GET_CODE (x
) == LO_SUM
3019 && GET_CODE (XEXP (x
, 0)) == PLUS
3020 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
3021 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
3022 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
3023 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
3024 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
3025 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
3026 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
3028 /* Result of previous invocation of this function on Darwin
3029 floating point constant. */
3030 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3031 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3032 opnum
, (enum reload_type
)type
);
3038 /* Force ld/std non-word aligned offset into base register by wrapping
3040 if (GET_CODE (x
) == PLUS
3041 && GET_CODE (XEXP (x
, 0)) == REG
3042 && REGNO (XEXP (x
, 0)) < 32
3043 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3044 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3045 && (INTVAL (XEXP (x
, 1)) & 3) != 0
3046 && !ALTIVEC_VECTOR_MODE (mode
)
3047 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
3048 && TARGET_POWERPC64
)
3050 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
3051 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3052 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3053 opnum
, (enum reload_type
) type
);
3058 if (GET_CODE (x
) == PLUS
3059 && GET_CODE (XEXP (x
, 0)) == REG
3060 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
3061 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3062 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3063 && !SPE_VECTOR_MODE (mode
)
3064 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
3066 && !ALTIVEC_VECTOR_MODE (mode
))
3068 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
3069 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
3071 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3073 /* Check for 32-bit overflow. */
3074 if (high
+ low
!= val
)
3080 /* Reload the high part into a base reg; leave the low part
3081 in the mem directly. */
3083 x
= gen_rtx_PLUS (GET_MODE (x
),
3084 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
3088 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3089 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3090 opnum
, (enum reload_type
)type
);
3096 if (GET_CODE (x
) == SYMBOL_REF
3097 && DEFAULT_ABI
== ABI_DARWIN
3098 && !ALTIVEC_VECTOR_MODE (mode
)
3099 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
3100 /* Don't do this for TFmode, since the result isn't offsettable.
3101 The same goes for DImode without 64-bit gprs. */
3103 && (mode
!= DImode
|| TARGET_POWERPC64
))
3107 rtx offset
= gen_rtx_CONST (Pmode
,
3108 gen_rtx_MINUS (Pmode
, x
,
3109 machopic_function_base_sym ()));
3110 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3111 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
3112 gen_rtx_HIGH (Pmode
, offset
)), offset
);
3115 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3116 gen_rtx_HIGH (Pmode
, x
), x
);
3118 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3119 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3120 opnum
, (enum reload_type
)type
);
3127 && constant_pool_expr_p (x
)
3128 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
3130 (x
) = create_TOC_reference (x
);
3138 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3139 that is a valid memory address for an instruction.
3140 The MODE argument is the machine mode for the MEM expression
3141 that wants to use this address.
3143 On the RS/6000, there are four valid address: a SYMBOL_REF that
3144 refers to a constant pool entry of an address (or the sum of it
3145 plus a constant), a short (16-bit signed) constant plus a register,
3146 the sum of two registers, or a register indirect, possibly with an
3147 auto-increment. For DFmode and DImode with a constant plus register,
3148 we must ensure that both words are addressable or PowerPC64 with offset
3151 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3152 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3153 adjacent memory cells are accessed by adding word-sized offsets
3154 during assembly output. */
3156 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
3158 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3160 && ALTIVEC_VECTOR_MODE (mode
)
3161 && GET_CODE (x
) == AND
3162 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3163 && INTVAL (XEXP (x
, 1)) == -16)
3166 if (RS6000_SYMBOL_REF_TLS_P (x
))
3168 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
3170 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
3171 && !ALTIVEC_VECTOR_MODE (mode
)
3172 && !SPE_VECTOR_MODE (mode
)
3173 /* Restrict addressing for DI because of our SUBREG hackery. */
3174 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DImode
))
3176 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
3178 if (legitimate_small_data_p (mode
, x
))
3180 if (legitimate_constant_pool_address_p (x
))
3182 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3184 && GET_CODE (x
) == PLUS
3185 && GET_CODE (XEXP (x
, 0)) == REG
3186 && (XEXP (x
, 0) == virtual_stack_vars_rtx
3187 || XEXP (x
, 0) == arg_pointer_rtx
)
3188 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3190 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
3194 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3196 || ((mode
!= DFmode
|| TARGET_E500_DOUBLE
) && mode
!= TFmode
))
3197 && (TARGET_POWERPC64
|| mode
!= DImode
)
3198 && legitimate_indexed_address_p (x
, reg_ok_strict
))
3200 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
3205 /* Go to LABEL if ADDR (a legitimate address expression)
3206 has an effect that depends on the machine mode it is used for.
3208 On the RS/6000 this is true of all integral offsets (since AltiVec
3209 modes don't allow them) or is a pre-increment or decrement.
3211 ??? Except that due to conceptual problems in offsettable_address_p
3212 we can't really report the problems of integral offsets. So leave
3213 this assuming that the adjustable offset must be valid for the
3214 sub-words of a TFmode operand, which is what we had before. */
3217 rs6000_mode_dependent_address (rtx addr
)
3219 switch (GET_CODE (addr
))
3222 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
3224 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
3225 return val
+ 12 + 0x8000 >= 0x10000;
3234 return TARGET_UPDATE
;
3243 /* Return number of consecutive hard regs needed starting at reg REGNO
3244 to hold something of mode MODE.
3245 This is ordinarily the length in words of a value of mode MODE
3246 but can be less for certain modes in special long registers.
3248 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3249 scalar instructions. The upper 32 bits are only available to the
3252 POWER and PowerPC GPRs hold 32 bits worth;
3253 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3256 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
3258 if (FP_REGNO_P (regno
))
3259 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
3261 if (TARGET_E500_DOUBLE
&& mode
== DFmode
)
3264 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
3265 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
3267 if (ALTIVEC_REGNO_P (regno
))
3269 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
3271 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3274 /* Change register usage conditional on target flags. */
3276 rs6000_conditional_register_usage (void)
3280 /* Set MQ register fixed (already call_used) if not POWER
3281 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3286 /* 64-bit AIX reserves GPR13 for thread-private data. */
3288 fixed_regs
[13] = call_used_regs
[13]
3289 = call_really_used_regs
[13] = 1;
3291 /* Conditionally disable FPRs. */
3292 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
3293 for (i
= 32; i
< 64; i
++)
3294 fixed_regs
[i
] = call_used_regs
[i
]
3295 = call_really_used_regs
[i
] = 1;
3297 if (DEFAULT_ABI
== ABI_V4
3298 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3300 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3302 if (DEFAULT_ABI
== ABI_V4
3303 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3305 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3306 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3307 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3309 if (DEFAULT_ABI
== ABI_DARWIN
3310 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
3311 global_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3312 = fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3313 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3314 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3316 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
3317 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3318 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3321 global_regs
[VSCR_REGNO
] = 1;
3325 global_regs
[SPEFSCR_REGNO
] = 1;
3326 fixed_regs
[FIXED_SCRATCH
]
3327 = call_used_regs
[FIXED_SCRATCH
]
3328 = call_really_used_regs
[FIXED_SCRATCH
] = 1;
3331 if (! TARGET_ALTIVEC
)
3333 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
3334 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3335 call_really_used_regs
[VRSAVE_REGNO
] = 1;
3338 if (TARGET_ALTIVEC_ABI
)
3339 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
3340 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3343 /* Try to output insns to set TARGET equal to the constant C if it can
3344 be done in less than N insns. Do all computations in MODE.
3345 Returns the place where the output has been placed if it can be
3346 done and the insns have been emitted. If it would take more than N
3347 insns, zero is returned and no insns and emitted. */
3350 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
3351 rtx source
, int n ATTRIBUTE_UNUSED
)
3353 rtx result
, insn
, set
;
3354 HOST_WIDE_INT c0
, c1
;
3361 dest
= gen_reg_rtx (mode
);
3362 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
3366 result
= no_new_pseudos
? dest
: gen_reg_rtx (SImode
);
3368 emit_insn (gen_rtx_SET (VOIDmode
, result
,
3369 GEN_INT (INTVAL (source
)
3370 & (~ (HOST_WIDE_INT
) 0xffff))));
3371 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
3372 gen_rtx_IOR (SImode
, result
,
3373 GEN_INT (INTVAL (source
) & 0xffff))));
3378 switch (GET_CODE (source
))
3381 c0
= INTVAL (source
);
3386 #if HOST_BITS_PER_WIDE_INT >= 64
3387 c0
= CONST_DOUBLE_LOW (source
);
3390 c0
= CONST_DOUBLE_LOW (source
);
3391 c1
= CONST_DOUBLE_HIGH (source
);
3399 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
3406 insn
= get_last_insn ();
3407 set
= single_set (insn
);
3408 if (! CONSTANT_P (SET_SRC (set
)))
3409 set_unique_reg_note (insn
, REG_EQUAL
, source
);
3414 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3415 fall back to a straight forward decomposition. We do this to avoid
3416 exponential run times encountered when looking for longer sequences
3417 with rs6000_emit_set_const. */
3419 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
3421 if (!TARGET_POWERPC64
)
3423 rtx operand1
, operand2
;
3425 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
3427 operand2
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
!= 0,
3429 emit_move_insn (operand1
, GEN_INT (c1
));
3430 emit_move_insn (operand2
, GEN_INT (c2
));
3434 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
3437 ud2
= (c1
& 0xffff0000) >> 16;
3438 #if HOST_BITS_PER_WIDE_INT >= 64
3442 ud4
= (c2
& 0xffff0000) >> 16;
3444 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
3445 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
3448 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
3450 emit_move_insn (dest
, GEN_INT (ud1
));
3453 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
3454 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
3457 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
3460 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
3462 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3464 else if ((ud4
== 0xffff && (ud3
& 0x8000))
3465 || (ud4
== 0 && ! (ud3
& 0x8000)))
3468 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
3471 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
3474 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud2
)));
3475 emit_move_insn (dest
, gen_rtx_ASHIFT (DImode
, dest
, GEN_INT (16)));
3477 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3482 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
3485 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
3488 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud3
)));
3490 emit_move_insn (dest
, gen_rtx_ASHIFT (DImode
, dest
, GEN_INT (32)));
3492 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
,
3493 GEN_INT (ud2
<< 16)));
3495 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3501 /* Helper for the following. Get rid of [r+r] memory refs
3502 in cases where it won't work (TImode, TFmode). */
3505 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
3507 if (GET_CODE (operands
[0]) == MEM
3508 && GET_CODE (XEXP (operands
[0], 0)) != REG
3509 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
3510 && ! reload_in_progress
)
3512 = replace_equiv_address (operands
[0],
3513 copy_addr_to_reg (XEXP (operands
[0], 0)));
3515 if (GET_CODE (operands
[1]) == MEM
3516 && GET_CODE (XEXP (operands
[1], 0)) != REG
3517 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
3518 && ! reload_in_progress
)
3520 = replace_equiv_address (operands
[1],
3521 copy_addr_to_reg (XEXP (operands
[1], 0)));
3524 /* Emit a move from SOURCE to DEST in mode MODE. */
3526 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
3530 operands
[1] = source
;
3532 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
3533 if (GET_CODE (operands
[1]) == CONST_DOUBLE
3534 && ! FLOAT_MODE_P (mode
)
3535 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
3537 /* FIXME. This should never happen. */
3538 /* Since it seems that it does, do the safe thing and convert
3540 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
3542 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
3543 || FLOAT_MODE_P (mode
)
3544 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
3545 || CONST_DOUBLE_LOW (operands
[1]) < 0)
3546 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
3547 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
3549 /* Check if GCC is setting up a block move that will end up using FP
3550 registers as temporaries. We must make sure this is acceptable. */
3551 if (GET_CODE (operands
[0]) == MEM
3552 && GET_CODE (operands
[1]) == MEM
3554 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
3555 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
3556 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
3557 ? 32 : MEM_ALIGN (operands
[0])))
3558 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
3560 : MEM_ALIGN (operands
[1]))))
3561 && ! MEM_VOLATILE_P (operands
[0])
3562 && ! MEM_VOLATILE_P (operands
[1]))
3564 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
3565 adjust_address (operands
[1], SImode
, 0));
3566 emit_move_insn (adjust_address (operands
[0], SImode
, 4),
3567 adjust_address (operands
[1], SImode
, 4));
3571 if (!no_new_pseudos
&& GET_CODE (operands
[0]) == MEM
3572 && !gpc_reg_operand (operands
[1], mode
))
3573 operands
[1] = force_reg (mode
, operands
[1]);
3575 if (mode
== SFmode
&& ! TARGET_POWERPC
3576 && TARGET_HARD_FLOAT
&& TARGET_FPRS
3577 && GET_CODE (operands
[0]) == MEM
)
3581 if (reload_in_progress
|| reload_completed
)
3582 regnum
= true_regnum (operands
[1]);
3583 else if (GET_CODE (operands
[1]) == REG
)
3584 regnum
= REGNO (operands
[1]);
3588 /* If operands[1] is a register, on POWER it may have
3589 double-precision data in it, so truncate it to single
3591 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
3594 newreg
= (no_new_pseudos
? operands
[1] : gen_reg_rtx (mode
));
3595 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
3596 operands
[1] = newreg
;
3600 /* Recognize the case where operand[1] is a reference to thread-local
3601 data and load its address to a register. */
3602 if (rs6000_tls_referenced_p (operands
[1]))
3604 enum tls_model model
;
3605 rtx tmp
= operands
[1];
3608 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
3610 addend
= XEXP (XEXP (tmp
, 0), 1);
3611 tmp
= XEXP (XEXP (tmp
, 0), 0);
3614 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
3615 model
= SYMBOL_REF_TLS_MODEL (tmp
);
3616 gcc_assert (model
!= 0);
3618 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
3621 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
3622 tmp
= force_operand (tmp
, operands
[0]);
3627 /* Handle the case where reload calls us with an invalid address. */
3628 if (reload_in_progress
&& mode
== Pmode
3629 && (! general_operand (operands
[1], mode
)
3630 || ! nonimmediate_operand (operands
[0], mode
)))
3633 /* 128-bit constant floating-point values on Darwin should really be
3634 loaded as two parts. */
3635 if ((DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_DARWIN
)
3636 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
3637 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
3639 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
3640 know how to get a DFmode SUBREG of a TFmode. */
3641 rs6000_emit_move (simplify_gen_subreg (DImode
, operands
[0], mode
, 0),
3642 simplify_gen_subreg (DImode
, operands
[1], mode
, 0),
3644 rs6000_emit_move (simplify_gen_subreg (DImode
, operands
[0], mode
,
3645 GET_MODE_SIZE (DImode
)),
3646 simplify_gen_subreg (DImode
, operands
[1], mode
,
3647 GET_MODE_SIZE (DImode
)),
3652 /* FIXME: In the long term, this switch statement should go away
3653 and be replaced by a sequence of tests based on things like
3659 if (CONSTANT_P (operands
[1])
3660 && GET_CODE (operands
[1]) != CONST_INT
)
3661 operands
[1] = force_const_mem (mode
, operands
[1]);
3665 rs6000_eliminate_indexed_memrefs (operands
);
3670 if (CONSTANT_P (operands
[1])
3671 && ! easy_fp_constant (operands
[1], mode
))
3672 operands
[1] = force_const_mem (mode
, operands
[1]);
3683 if (CONSTANT_P (operands
[1])
3684 && !easy_vector_constant (operands
[1], mode
))
3685 operands
[1] = force_const_mem (mode
, operands
[1]);
3690 /* Use default pattern for address of ELF small data */
3693 && DEFAULT_ABI
== ABI_V4
3694 && (GET_CODE (operands
[1]) == SYMBOL_REF
3695 || GET_CODE (operands
[1]) == CONST
)
3696 && small_data_operand (operands
[1], mode
))
3698 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
3702 if (DEFAULT_ABI
== ABI_V4
3703 && mode
== Pmode
&& mode
== SImode
3704 && flag_pic
== 1 && got_operand (operands
[1], mode
))
3706 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
3710 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
3714 && CONSTANT_P (operands
[1])
3715 && GET_CODE (operands
[1]) != HIGH
3716 && GET_CODE (operands
[1]) != CONST_INT
)
3718 rtx target
= (no_new_pseudos
? operands
[0] : gen_reg_rtx (mode
));
3720 /* If this is a function address on -mcall-aixdesc,
3721 convert it to the address of the descriptor. */
3722 if (DEFAULT_ABI
== ABI_AIX
3723 && GET_CODE (operands
[1]) == SYMBOL_REF
3724 && XSTR (operands
[1], 0)[0] == '.')
3726 const char *name
= XSTR (operands
[1], 0);
3728 while (*name
== '.')
3730 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
3731 CONSTANT_POOL_ADDRESS_P (new_ref
)
3732 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
3733 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
3734 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
3735 SYMBOL_REF_DECL (new_ref
) = SYMBOL_REF_DECL (operands
[1]);
3736 operands
[1] = new_ref
;
3739 if (DEFAULT_ABI
== ABI_DARWIN
)
3742 if (MACHO_DYNAMIC_NO_PIC_P
)
3744 /* Take care of any required data indirection. */
3745 operands
[1] = rs6000_machopic_legitimize_pic_address (
3746 operands
[1], mode
, operands
[0]);
3747 if (operands
[0] != operands
[1])
3748 emit_insn (gen_rtx_SET (VOIDmode
,
3749 operands
[0], operands
[1]));
3753 emit_insn (gen_macho_high (target
, operands
[1]));
3754 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
3758 emit_insn (gen_elf_high (target
, operands
[1]));
3759 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
3763 /* If this is a SYMBOL_REF that refers to a constant pool entry,
3764 and we have put it in the TOC, we just need to make a TOC-relative
3767 && GET_CODE (operands
[1]) == SYMBOL_REF
3768 && constant_pool_expr_p (operands
[1])
3769 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
3770 get_pool_mode (operands
[1])))
3772 operands
[1] = create_TOC_reference (operands
[1]);
3774 else if (mode
== Pmode
3775 && CONSTANT_P (operands
[1])
3776 && ((GET_CODE (operands
[1]) != CONST_INT
3777 && ! easy_fp_constant (operands
[1], mode
))
3778 || (GET_CODE (operands
[1]) == CONST_INT
3779 && num_insns_constant (operands
[1], mode
) > 2)
3780 || (GET_CODE (operands
[0]) == REG
3781 && FP_REGNO_P (REGNO (operands
[0]))))
3782 && GET_CODE (operands
[1]) != HIGH
3783 && ! legitimate_constant_pool_address_p (operands
[1])
3784 && ! toc_relative_expr_p (operands
[1]))
3786 /* Emit a USE operation so that the constant isn't deleted if
3787 expensive optimizations are turned on because nobody
3788 references it. This should only be done for operands that
3789 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
3790 This should not be done for operands that contain LABEL_REFs.
3791 For now, we just handle the obvious case. */
3792 if (GET_CODE (operands
[1]) != LABEL_REF
)
3793 emit_insn (gen_rtx_USE (VOIDmode
, operands
[1]));
3796 /* Darwin uses a special PIC legitimizer. */
3797 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
3800 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
3802 if (operands
[0] != operands
[1])
3803 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
3808 /* If we are to limit the number of things we put in the TOC and
3809 this is a symbol plus a constant we can add in one insn,
3810 just put the symbol in the TOC and add the constant. Don't do
3811 this if reload is in progress. */
3812 if (GET_CODE (operands
[1]) == CONST
3813 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
3814 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
3815 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
3816 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
3817 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
3818 && ! side_effects_p (operands
[0]))
3821 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
3822 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
3824 sym
= force_reg (mode
, sym
);
3826 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
3828 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
3832 operands
[1] = force_const_mem (mode
, operands
[1]);
3835 && constant_pool_expr_p (XEXP (operands
[1], 0))
3836 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
3837 get_pool_constant (XEXP (operands
[1], 0)),
3838 get_pool_mode (XEXP (operands
[1], 0))))
3841 = gen_const_mem (mode
,
3842 create_TOC_reference (XEXP (operands
[1], 0)));
3843 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
3849 rs6000_eliminate_indexed_memrefs (operands
);
3853 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
3855 gen_rtx_SET (VOIDmode
,
3856 operands
[0], operands
[1]),
3857 gen_rtx_CLOBBER (VOIDmode
,
3858 gen_rtx_SCRATCH (SImode
)))));
3867 /* Above, we may have called force_const_mem which may have returned
3868 an invalid address. If we can, fix this up; otherwise, reload will
3869 have to deal with it. */
3870 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
3871 operands
[1] = validize_mem (operands
[1]);
3874 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
3877 /* Nonzero if we can use a floating-point register to pass this arg. */
3878 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
3879 (GET_MODE_CLASS (MODE) == MODE_FLOAT \
3880 && (CUM)->fregno <= FP_ARG_MAX_REG \
3881 && TARGET_HARD_FLOAT && TARGET_FPRS)
3883 /* Nonzero if we can use an AltiVec register to pass this arg. */
3884 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
3885 (ALTIVEC_VECTOR_MODE (MODE) \
3886 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
3887 && TARGET_ALTIVEC_ABI \
3890 /* Return a nonzero value to say to return the function value in
3891 memory, just as large structures are always returned. TYPE will be
3892 the data type of the value, and FNTYPE will be the type of the
3893 function doing the returning, or @code{NULL} for libcalls.
3895 The AIX ABI for the RS/6000 specifies that all structures are
3896 returned in memory. The Darwin ABI does the same. The SVR4 ABI
3897 specifies that structures <= 8 bytes are returned in r3/r4, but a
3898 draft put them in memory, and GCC used to implement the draft
3899 instead of the final standard. Therefore, aix_struct_return
3900 controls this instead of DEFAULT_ABI; V.4 targets needing backward
3901 compatibility can change DRAFT_V4_STRUCT_RET to override the
3902 default, and -m switches get the final word. See
3903 rs6000_override_options for more details.
3905 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
3906 long double support is enabled. These values are returned in memory.
3908 int_size_in_bytes returns -1 for variable size objects, which go in
3909 memory always. The cast to unsigned makes -1 > 8. */
3912 rs6000_return_in_memory (tree type
, tree fntype ATTRIBUTE_UNUSED
)
3914 /* In the darwin64 abi, try to use registers for larger structs
3916 if (rs6000_darwin64_abi
3917 && TREE_CODE (type
) == RECORD_TYPE
3918 && int_size_in_bytes (type
) > 0)
3920 CUMULATIVE_ARGS valcum
;
3924 valcum
.fregno
= FP_ARG_MIN_REG
;
3925 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
3926 /* Do a trial code generation as if this were going to be passed
3927 as an argument; if any part goes in memory, we return NULL. */
3928 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
3931 /* Otherwise fall through to more conventional ABI rules. */
3934 if (AGGREGATE_TYPE_P (type
)
3935 && (aix_struct_return
3936 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
3939 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
3940 modes only exist for GCC vector types if -maltivec. */
3941 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
3942 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
3945 /* Return synthetic vectors in memory. */
3946 if (TREE_CODE (type
) == VECTOR_TYPE
3947 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
3949 static bool warned_for_return_big_vectors
= false;
3950 if (!warned_for_return_big_vectors
)
3952 warning (0, "GCC vector returned by reference: "
3953 "non-standard ABI extension with no compatibility guarantee");
3954 warned_for_return_big_vectors
= true;
3959 if (DEFAULT_ABI
== ABI_V4
&& TYPE_MODE (type
) == TFmode
)
3965 /* Initialize a variable CUM of type CUMULATIVE_ARGS
3966 for a call to a function whose data type is FNTYPE.
3967 For a library call, FNTYPE is 0.
3969 For incoming args we set the number of arguments in the prototype large
3970 so we never return a PARALLEL. */
3973 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
3974 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
3975 int libcall
, int n_named_args
)
3977 static CUMULATIVE_ARGS zero_cumulative
;
3979 *cum
= zero_cumulative
;
3981 cum
->fregno
= FP_ARG_MIN_REG
;
3982 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
3983 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
3984 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
3985 ? CALL_LIBCALL
: CALL_NORMAL
);
3986 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
3987 cum
->stdarg
= fntype
3988 && (TYPE_ARG_TYPES (fntype
) != 0
3989 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
3990 != void_type_node
));
3992 cum
->nargs_prototype
= 0;
3993 if (incoming
|| cum
->prototype
)
3994 cum
->nargs_prototype
= n_named_args
;
3996 /* Check for a longcall attribute. */
3997 if ((!fntype
&& rs6000_default_long_calls
)
3999 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
4000 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
4001 cum
->call_cookie
|= CALL_LONG
;
4003 if (TARGET_DEBUG_ARG
)
4005 fprintf (stderr
, "\ninit_cumulative_args:");
4008 tree ret_type
= TREE_TYPE (fntype
);
4009 fprintf (stderr
, " ret code = %s,",
4010 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
4013 if (cum
->call_cookie
& CALL_LONG
)
4014 fprintf (stderr
, " longcall,");
4016 fprintf (stderr
, " proto = %d, nargs = %d\n",
4017 cum
->prototype
, cum
->nargs_prototype
);
4022 && TARGET_ALTIVEC_ABI
4023 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
4025 error ("Cannot return value in vector register because"
4026 " altivec instructions are disabled, use -maltivec"
4027 " to enable them.");
4031 /* Return true if TYPE must be passed on the stack and not in registers. */
4034 rs6000_must_pass_in_stack (enum machine_mode mode
, tree type
)
4036 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
4037 return must_pass_in_stack_var_size (mode
, type
);
4039 return must_pass_in_stack_var_size_or_pad (mode
, type
);
4042 /* If defined, a C expression which determines whether, and in which
4043 direction, to pad out an argument with extra space. The value
4044 should be of type `enum direction': either `upward' to pad above
4045 the argument, `downward' to pad below, or `none' to inhibit
4048 For the AIX ABI structs are always stored left shifted in their
4052 function_arg_padding (enum machine_mode mode
, tree type
)
4054 #ifndef AGGREGATE_PADDING_FIXED
4055 #define AGGREGATE_PADDING_FIXED 0
4057 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4058 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4061 if (!AGGREGATE_PADDING_FIXED
)
4063 /* GCC used to pass structures of the same size as integer types as
4064 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4065 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4066 passed padded downward, except that -mstrict-align further
4067 muddied the water in that multi-component structures of 2 and 4
4068 bytes in size were passed padded upward.
4070 The following arranges for best compatibility with previous
4071 versions of gcc, but removes the -mstrict-align dependency. */
4072 if (BYTES_BIG_ENDIAN
)
4074 HOST_WIDE_INT size
= 0;
4076 if (mode
== BLKmode
)
4078 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
4079 size
= int_size_in_bytes (type
);
4082 size
= GET_MODE_SIZE (mode
);
4084 if (size
== 1 || size
== 2 || size
== 4)
4090 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
4092 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
4096 /* Fall back to the default. */
4097 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
4100 /* If defined, a C expression that gives the alignment boundary, in bits,
4101 of an argument with the specified mode and type. If it is not defined,
4102 PARM_BOUNDARY is used for all arguments.
4104 V.4 wants long longs to be double word aligned.
4105 Doubleword align SPE vectors.
4106 Quadword align Altivec vectors.
4107 Quadword align large synthetic vector types. */
4110 function_arg_boundary (enum machine_mode mode
, tree type
)
4112 if (DEFAULT_ABI
== ABI_V4
&& GET_MODE_SIZE (mode
) == 8)
4114 else if (SPE_VECTOR_MODE (mode
)
4115 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4116 && int_size_in_bytes (type
) >= 8
4117 && int_size_in_bytes (type
) < 16))
4119 else if (ALTIVEC_VECTOR_MODE (mode
)
4120 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4121 && int_size_in_bytes (type
) >= 16))
4123 else if (rs6000_darwin64_abi
&& mode
== BLKmode
4124 && type
&& TYPE_ALIGN (type
) > 64)
4127 return PARM_BOUNDARY
;
4130 /* For a function parm of MODE and TYPE, return the starting word in
4131 the parameter area. NWORDS of the parameter area are already used. */
4134 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
4137 unsigned int parm_offset
;
4139 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
4140 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
4141 return nwords
+ (-(parm_offset
+ nwords
) & align
);
4144 /* Compute the size (in words) of a function argument. */
4146 static unsigned long
4147 rs6000_arg_size (enum machine_mode mode
, tree type
)
4151 if (mode
!= BLKmode
)
4152 size
= GET_MODE_SIZE (mode
);
4154 size
= int_size_in_bytes (type
);
4157 return (size
+ 3) >> 2;
4159 return (size
+ 7) >> 3;
4162 /* Use this to flush pending int fields. */
4165 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
4166 HOST_WIDE_INT bitpos
)
4168 unsigned int startbit
, endbit
;
4169 int intregs
, intoffset
;
4170 enum machine_mode mode
;
4172 if (cum
->intoffset
== -1)
4175 intoffset
= cum
->intoffset
;
4176 cum
->intoffset
= -1;
4178 if (intoffset
% BITS_PER_WORD
!= 0)
4180 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4182 if (mode
== BLKmode
)
4184 /* We couldn't find an appropriate mode, which happens,
4185 e.g., in packed structs when there are 3 bytes to load.
4186 Back intoffset back to the beginning of the word in this
4188 intoffset
= intoffset
& -BITS_PER_WORD
;
4192 startbit
= intoffset
& -BITS_PER_WORD
;
4193 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4194 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4195 cum
->words
+= intregs
;
4198 /* The darwin64 ABI calls for us to recurse down through structs,
4199 looking for elements passed in registers. Unfortunately, we have
4200 to track int register count here also because of misalignments
4201 in powerpc alignment mode. */
4204 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
4206 HOST_WIDE_INT startbitpos
)
4210 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4211 if (TREE_CODE (f
) == FIELD_DECL
)
4213 HOST_WIDE_INT bitpos
= startbitpos
;
4214 tree ftype
= TREE_TYPE (f
);
4215 enum machine_mode mode
= TYPE_MODE (ftype
);
4217 if (DECL_SIZE (f
) != 0
4218 && host_integerp (bit_position (f
), 1))
4219 bitpos
+= int_bit_position (f
);
4221 /* ??? FIXME: else assume zero offset. */
4223 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4224 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
4225 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4227 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4228 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4229 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4231 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
4233 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4237 else if (cum
->intoffset
== -1)
4238 cum
->intoffset
= bitpos
;
4242 /* Update the data in CUM to advance over an argument
4243 of mode MODE and data type TYPE.
4244 (TYPE is null for libcalls where that information may not be available.)
4246 Note that for args passed by reference, function_arg will be called
4247 with MODE and TYPE set to that of the pointer to the arg, not the arg
4251 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4252 tree type
, int named
, int depth
)
4256 /* Only tick off an argument if we're not recursing. */
4258 cum
->nargs_prototype
--;
4260 if (TARGET_ALTIVEC_ABI
4261 && (ALTIVEC_VECTOR_MODE (mode
)
4262 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4263 && int_size_in_bytes (type
) == 16)))
4267 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
4270 if (!TARGET_ALTIVEC
)
4271 error ("Cannot pass argument in vector register because"
4272 " altivec instructions are disabled, use -maltivec"
4273 " to enable them.");
4275 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4276 even if it is going to be passed in a vector register.
4277 Darwin does the same for variable-argument functions. */
4278 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4279 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
4289 /* Vector parameters must be 16-byte aligned. This places
4290 them at 2 mod 4 in terms of words in 32-bit mode, since
4291 the parameter save area starts at offset 24 from the
4292 stack. In 64-bit mode, they just have to start on an
4293 even word, since the parameter save area is 16-byte
4294 aligned. Space for GPRs is reserved even if the argument
4295 will be passed in memory. */
4297 align
= (2 - cum
->words
) & 3;
4299 align
= cum
->words
& 1;
4300 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
4302 if (TARGET_DEBUG_ARG
)
4304 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
4306 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
4307 cum
->nargs_prototype
, cum
->prototype
,
4308 GET_MODE_NAME (mode
));
4312 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
4314 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
4317 else if (rs6000_darwin64_abi
4319 && TREE_CODE (type
) == RECORD_TYPE
4320 && (size
= int_size_in_bytes (type
)) > 0)
4322 /* Variable sized types have size == -1 and are
4323 treated as if consisting entirely of ints.
4324 Pad to 16 byte boundary if needed. */
4325 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
4326 && (cum
->words
% 2) != 0)
4328 /* For varargs, we can just go up by the size of the struct. */
4330 cum
->words
+= (size
+ 7) / 8;
4333 /* It is tempting to say int register count just goes up by
4334 sizeof(type)/8, but this is wrong in a case such as
4335 { int; double; int; } [powerpc alignment]. We have to
4336 grovel through the fields for these too. */
4338 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
4339 rs6000_darwin64_record_arg_advance_flush (cum
,
4340 size
* BITS_PER_UNIT
);
4343 else if (DEFAULT_ABI
== ABI_V4
)
4345 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
4346 && (mode
== SFmode
|| mode
== DFmode
))
4348 if (cum
->fregno
<= FP_ARG_V4_MAX_REG
)
4353 cum
->words
+= cum
->words
& 1;
4354 cum
->words
+= rs6000_arg_size (mode
, type
);
4359 int n_words
= rs6000_arg_size (mode
, type
);
4360 int gregno
= cum
->sysv_gregno
;
4362 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4363 (r7,r8) or (r9,r10). As does any other 2 word item such
4364 as complex int due to a historical mistake. */
4366 gregno
+= (1 - gregno
) & 1;
4368 /* Multi-reg args are not split between registers and stack. */
4369 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
4371 /* Long long and SPE vectors are aligned on the stack.
4372 So are other 2 word items such as complex int due to
4373 a historical mistake. */
4375 cum
->words
+= cum
->words
& 1;
4376 cum
->words
+= n_words
;
4379 /* Note: continuing to accumulate gregno past when we've started
4380 spilling to the stack indicates the fact that we've started
4381 spilling to the stack to expand_builtin_saveregs. */
4382 cum
->sysv_gregno
= gregno
+ n_words
;
4385 if (TARGET_DEBUG_ARG
)
4387 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
4388 cum
->words
, cum
->fregno
);
4389 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
4390 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
4391 fprintf (stderr
, "mode = %4s, named = %d\n",
4392 GET_MODE_NAME (mode
), named
);
4397 int n_words
= rs6000_arg_size (mode
, type
);
4398 int start_words
= cum
->words
;
4399 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
4401 cum
->words
= align_words
+ n_words
;
4403 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
4404 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4405 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4407 if (TARGET_DEBUG_ARG
)
4409 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
4410 cum
->words
, cum
->fregno
);
4411 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
4412 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
4413 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
4414 named
, align_words
- start_words
, depth
);
4420 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
4427 r1
= gen_rtx_REG (DImode
, gregno
);
4428 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
4429 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
4432 r1
= gen_rtx_REG (DImode
, gregno
);
4433 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
4434 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
4435 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
4436 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
4443 /* Determine where to put a SIMD argument on the SPE. */
4445 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4448 int gregno
= cum
->sysv_gregno
;
4450 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
4451 are passed and returned in a pair of GPRs for ABI compatibility. */
4452 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DCmode
))
4454 int n_words
= rs6000_arg_size (mode
, type
);
4456 /* Doubles go in an odd/even register pair (r5/r6, etc). */
4458 gregno
+= (1 - gregno
) & 1;
4460 /* Multi-reg args are not split between registers and stack. */
4461 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
4464 return spe_build_register_parallel (mode
, gregno
);
4468 int n_words
= rs6000_arg_size (mode
, type
);
4470 /* SPE vectors are put in odd registers. */
4471 if (n_words
== 2 && (gregno
& 1) == 0)
4474 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
4477 enum machine_mode m
= SImode
;
4479 r1
= gen_rtx_REG (m
, gregno
);
4480 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
4481 r2
= gen_rtx_REG (m
, gregno
+ 1);
4482 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
4483 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
4490 if (gregno
<= GP_ARG_MAX_REG
)
4491 return gen_rtx_REG (mode
, gregno
);
4497 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
4498 structure between cum->intoffset and bitpos to integer registers. */
4501 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
4502 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
4504 enum machine_mode mode
;
4506 unsigned int startbit
, endbit
;
4507 int this_regno
, intregs
, intoffset
;
4510 if (cum
->intoffset
== -1)
4513 intoffset
= cum
->intoffset
;
4514 cum
->intoffset
= -1;
4516 /* If this is the trailing part of a word, try to only load that
4517 much into the register. Otherwise load the whole register. Note
4518 that in the latter case we may pick up unwanted bits. It's not a
4519 problem at the moment but may wish to revisit. */
4521 if (intoffset
% BITS_PER_WORD
!= 0)
4523 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4525 if (mode
== BLKmode
)
4527 /* We couldn't find an appropriate mode, which happens,
4528 e.g., in packed structs when there are 3 bytes to load.
4529 Back intoffset back to the beginning of the word in this
4531 intoffset
= intoffset
& -BITS_PER_WORD
;
4538 startbit
= intoffset
& -BITS_PER_WORD
;
4539 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4540 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4541 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
4543 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
4546 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
4550 intoffset
/= BITS_PER_UNIT
;
4553 regno
= GP_ARG_MIN_REG
+ this_regno
;
4554 reg
= gen_rtx_REG (mode
, regno
);
4556 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
4559 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
4563 while (intregs
> 0);
4566 /* Recursive workhorse for the following. */
4569 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, tree type
,
4570 HOST_WIDE_INT startbitpos
, rtx rvec
[],
4575 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4576 if (TREE_CODE (f
) == FIELD_DECL
)
4578 HOST_WIDE_INT bitpos
= startbitpos
;
4579 tree ftype
= TREE_TYPE (f
);
4580 enum machine_mode mode
= TYPE_MODE (ftype
);
4582 if (DECL_SIZE (f
) != 0
4583 && host_integerp (bit_position (f
), 1))
4584 bitpos
+= int_bit_position (f
);
4586 /* ??? FIXME: else assume zero offset. */
4588 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4589 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
4590 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4595 case SCmode
: mode
= SFmode
; break;
4596 case DCmode
: mode
= DFmode
; break;
4597 case TCmode
: mode
= TFmode
; break;
4601 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
4603 = gen_rtx_EXPR_LIST (VOIDmode
,
4604 gen_rtx_REG (mode
, cum
->fregno
++),
4605 GEN_INT (bitpos
/ BITS_PER_UNIT
));
4609 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
4611 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
4613 = gen_rtx_EXPR_LIST (VOIDmode
,
4614 gen_rtx_REG (mode
, cum
->vregno
++),
4615 GEN_INT (bitpos
/ BITS_PER_UNIT
));
4617 else if (cum
->intoffset
== -1)
4618 cum
->intoffset
= bitpos
;
4622 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
4623 the register(s) to be used for each field and subfield of a struct
4624 being passed by value, along with the offset of where the
4625 register's value may be found in the block. FP fields go in FP
4626 register, vector fields go in vector registers, and everything
4627 else goes in int registers, packed as in memory.
4629 This code is also used for function return values. RETVAL indicates
4630 whether this is the case.
4632 Much of this is taken from the Sparc V9 port, which has a similar
4633 calling convention. */
4636 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, tree type
,
4637 int named
, bool retval
)
4639 rtx rvec
[FIRST_PSEUDO_REGISTER
];
4640 int k
= 1, kbase
= 1;
4641 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
4642 /* This is a copy; modifications are not visible to our caller. */
4643 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
4644 CUMULATIVE_ARGS
*cum
= ©_cum
;
4646 /* Pad to 16 byte boundary if needed. */
4647 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
4648 && (cum
->words
% 2) != 0)
4655 /* Put entries into rvec[] for individual FP and vector fields, and
4656 for the chunks of memory that go in int regs. Note we start at
4657 element 1; 0 is reserved for an indication of using memory, and
4658 may or may not be filled in below. */
4659 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
4660 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
4662 /* If any part of the struct went on the stack put all of it there.
4663 This hack is because the generic code for
4664 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
4665 parts of the struct are not at the beginning. */
4669 return NULL_RTX
; /* doesn't go in registers at all */
4671 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
4673 if (k
> 1 || cum
->use_stack
)
4674 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
4679 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
4682 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
4686 rtx rvec
[GP_ARG_NUM_REG
+ 1];
4688 if (align_words
>= GP_ARG_NUM_REG
)
4691 n_units
= rs6000_arg_size (mode
, type
);
4693 /* Optimize the simple case where the arg fits in one gpr, except in
4694 the case of BLKmode due to assign_parms assuming that registers are
4695 BITS_PER_WORD wide. */
4697 || (n_units
== 1 && mode
!= BLKmode
))
4698 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
4701 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
4702 /* Not all of the arg fits in gprs. Say that it goes in memory too,
4703 using a magic NULL_RTX component.
4704 FIXME: This is not strictly correct. Only some of the arg
4705 belongs in memory, not all of it. However, there isn't any way
4706 to do this currently, apart from building rtx descriptions for
4707 the pieces of memory we want stored. Due to bugs in the generic
4708 code we can't use the normal function_arg_partial_nregs scheme
4709 with the PARALLEL arg description we emit here.
4710 In any case, the code to store the whole arg to memory is often
4711 more efficient than code to store pieces, and we know that space
4712 is available in the right place for the whole arg. */
4713 /* FIXME: This should be fixed since the conversion to
4714 TARGET_ARG_PARTIAL_BYTES. */
4715 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
4720 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
4721 rtx off
= GEN_INT (i
++ * 4);
4722 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
4724 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
4726 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
4729 /* Determine where to put an argument to a function.
4730 Value is zero to push the argument on the stack,
4731 or a hard register in which to store the argument.
4733 MODE is the argument's machine mode.
4734 TYPE is the data type of the argument (as a tree).
4735 This is null for libcalls where that information may
4737 CUM is a variable of type CUMULATIVE_ARGS which gives info about
4738 the preceding args and about the function being called. It is
4739 not modified in this routine.
4740 NAMED is nonzero if this argument is a named parameter
4741 (otherwise it is an extra parameter matching an ellipsis).
4743 On RS/6000 the first eight words of non-FP are normally in registers
4744 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
4745 Under V.4, the first 8 FP args are in registers.
4747 If this is floating-point and no prototype is specified, we use
4748 both an FP and integer register (or possibly FP reg and stack). Library
4749 functions (when CALL_LIBCALL is set) always have the proper types for args,
4750 so we can pass the FP value just in one register. emit_library_function
4751 doesn't support PARALLEL anyway.
4753 Note that for args passed by reference, function_arg will be called
4754 with MODE and TYPE set to that of the pointer to the arg, not the arg
4758 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4759 tree type
, int named
)
4761 enum rs6000_abi abi
= DEFAULT_ABI
;
4763 /* Return a marker to indicate whether CR1 needs to set or clear the
4764 bit that V.4 uses to say fp args were passed in registers.
4765 Assume that we don't need the marker for software floating point,
4766 or compiler generated library calls. */
4767 if (mode
== VOIDmode
)
4770 && cum
->nargs_prototype
< 0
4771 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
4772 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))
4774 /* For the SPE, we need to crxor CR6 always. */
4776 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
4777 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4778 return GEN_INT (cum
->call_cookie
4779 | ((cum
->fregno
== FP_ARG_MIN_REG
)
4780 ? CALL_V4_SET_FP_ARGS
4781 : CALL_V4_CLEAR_FP_ARGS
));
4784 return GEN_INT (cum
->call_cookie
);
4787 if (rs6000_darwin64_abi
&& mode
== BLKmode
4788 && TREE_CODE (type
) == RECORD_TYPE
)
4790 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
4791 if (rslt
!= NULL_RTX
)
4793 /* Else fall through to usual handling. */
4796 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
4797 if (TARGET_64BIT
&& ! cum
->prototype
)
4799 /* Vector parameters get passed in vector register
4800 and also in GPRs or memory, in absence of prototype. */
4803 align_words
= (cum
->words
+ 1) & ~1;
4805 if (align_words
>= GP_ARG_NUM_REG
)
4811 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
4813 return gen_rtx_PARALLEL (mode
,
4815 gen_rtx_EXPR_LIST (VOIDmode
,
4817 gen_rtx_EXPR_LIST (VOIDmode
,
4818 gen_rtx_REG (mode
, cum
->vregno
),
4822 return gen_rtx_REG (mode
, cum
->vregno
);
4823 else if (TARGET_ALTIVEC_ABI
4824 && (ALTIVEC_VECTOR_MODE (mode
)
4825 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4826 && int_size_in_bytes (type
) == 16)))
4828 if (named
|| abi
== ABI_V4
)
4832 /* Vector parameters to varargs functions under AIX or Darwin
4833 get passed in memory and possibly also in GPRs. */
4834 int align
, align_words
, n_words
;
4835 enum machine_mode part_mode
;
4837 /* Vector parameters must be 16-byte aligned. This places them at
4838 2 mod 4 in terms of words in 32-bit mode, since the parameter
4839 save area starts at offset 24 from the stack. In 64-bit mode,
4840 they just have to start on an even word, since the parameter
4841 save area is 16-byte aligned. */
4843 align
= (2 - cum
->words
) & 3;
4845 align
= cum
->words
& 1;
4846 align_words
= cum
->words
+ align
;
4848 /* Out of registers? Memory, then. */
4849 if (align_words
>= GP_ARG_NUM_REG
)
4852 if (TARGET_32BIT
&& TARGET_POWERPC64
)
4853 return rs6000_mixed_function_arg (mode
, type
, align_words
);
4855 /* The vector value goes in GPRs. Only the part of the
4856 value in GPRs is reported here. */
4858 n_words
= rs6000_arg_size (mode
, type
);
4859 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
4860 /* Fortunately, there are only two possibilities, the value
4861 is either wholly in GPRs or half in GPRs and half not. */
4864 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
4867 else if (TARGET_SPE_ABI
&& TARGET_SPE
4868 && (SPE_VECTOR_MODE (mode
)
4869 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
4870 || mode
== DCmode
))))
4871 return rs6000_spe_function_arg (cum
, mode
, type
);
4873 else if (abi
== ABI_V4
)
4875 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
4876 && (mode
== SFmode
|| mode
== DFmode
))
4878 if (cum
->fregno
<= FP_ARG_V4_MAX_REG
)
4879 return gen_rtx_REG (mode
, cum
->fregno
);
4885 int n_words
= rs6000_arg_size (mode
, type
);
4886 int gregno
= cum
->sysv_gregno
;
4888 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4889 (r7,r8) or (r9,r10). As does any other 2 word item such
4890 as complex int due to a historical mistake. */
4892 gregno
+= (1 - gregno
) & 1;
4894 /* Multi-reg args are not split between registers and stack. */
4895 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
4898 if (TARGET_32BIT
&& TARGET_POWERPC64
)
4899 return rs6000_mixed_function_arg (mode
, type
,
4900 gregno
- GP_ARG_MIN_REG
);
4901 return gen_rtx_REG (mode
, gregno
);
4906 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
4908 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
4910 rtx rvec
[GP_ARG_NUM_REG
+ 1];
4914 enum machine_mode fmode
= mode
;
4915 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
4917 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
4919 /* Currently, we only ever need one reg here because complex
4920 doubles are split. */
4921 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
&& fmode
== TFmode
);
4923 /* Long double split over regs and memory. */
4927 /* Do we also need to pass this arg in the parameter save
4930 && (cum
->nargs_prototype
<= 0
4931 || (DEFAULT_ABI
== ABI_AIX
4933 && align_words
>= GP_ARG_NUM_REG
)));
4935 if (!needs_psave
&& mode
== fmode
)
4936 return gen_rtx_REG (fmode
, cum
->fregno
);
4941 /* Describe the part that goes in gprs or the stack.
4942 This piece must come first, before the fprs. */
4943 if (align_words
< GP_ARG_NUM_REG
)
4945 unsigned long n_words
= rs6000_arg_size (mode
, type
);
4947 if (align_words
+ n_words
> GP_ARG_NUM_REG
4948 || (TARGET_32BIT
&& TARGET_POWERPC64
))
4950 /* If this is partially on the stack, then we only
4951 include the portion actually in registers here. */
4952 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
4955 if (align_words
+ n_words
> GP_ARG_NUM_REG
4956 && (TARGET_32BIT
&& TARGET_POWERPC64
))
4957 /* Not all of the arg fits in gprs. Say that it
4958 goes in memory too, using a magic NULL_RTX
4959 component. Also see comment in
4960 rs6000_mixed_function_arg for why the normal
4961 function_arg_partial_nregs scheme doesn't work
4963 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
4967 r
= gen_rtx_REG (rmode
,
4968 GP_ARG_MIN_REG
+ align_words
);
4969 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
4970 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
4972 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
4976 /* The whole arg fits in gprs. */
4977 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
4978 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
4982 /* It's entirely in memory. */
4983 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
4986 /* Describe where this piece goes in the fprs. */
4987 r
= gen_rtx_REG (fmode
, cum
->fregno
);
4988 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
4990 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
4992 else if (align_words
< GP_ARG_NUM_REG
)
4994 if (TARGET_32BIT
&& TARGET_POWERPC64
)
4995 return rs6000_mixed_function_arg (mode
, type
, align_words
);
4997 if (mode
== BLKmode
)
5000 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5007 /* For an arg passed partly in registers and partly in memory, this is
5008 the number of bytes passed in registers. For args passed entirely in
5009 registers or entirely in memory, zero. When an arg is described by a
5010 PARALLEL, perhaps using more than one register type, this function
5011 returns the number of bytes used by the first element of the PARALLEL. */
5014 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5015 tree type
, bool named
)
5020 if (DEFAULT_ABI
== ABI_V4
)
5023 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
5024 && cum
->nargs_prototype
>= 0)
5027 /* In this complicated case we just disable the partial_nregs code. */
5028 if (rs6000_darwin64_abi
&& mode
== BLKmode
5029 && TREE_CODE (type
) == RECORD_TYPE
5030 && int_size_in_bytes (type
) > 0)
5033 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5035 if (USE_FP_FOR_ARG_P (cum
, mode
, type
)
5036 /* If we are passing this arg in the fixed parameter save area
5037 (gprs or memory) as well as fprs, then this function should
5038 return the number of bytes passed in the parameter save area
5039 rather than bytes passed in fprs. */
5041 && (cum
->nargs_prototype
<= 0
5042 || (DEFAULT_ABI
== ABI_AIX
5044 && align_words
>= GP_ARG_NUM_REG
))))
5046 if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3) > FP_ARG_MAX_REG
+ 1)
5047 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
5048 else if (cum
->nargs_prototype
>= 0)
5052 if (align_words
< GP_ARG_NUM_REG
5053 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
5054 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
5056 if (ret
!= 0 && TARGET_DEBUG_ARG
)
5057 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
5062 /* A C expression that indicates when an argument must be passed by
5063 reference. If nonzero for an argument, a copy of that argument is
5064 made in memory and a pointer to the argument is passed instead of
5065 the argument itself. The pointer is passed in whatever way is
5066 appropriate for passing a pointer to that type.
5068 Under V.4, aggregates and long double are passed by reference.
5070 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5071 reference unless the AltiVec vector extension ABI is in force.
5073 As an extension to all ABIs, variable sized types are passed by
5077 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
5078 enum machine_mode mode
, tree type
,
5079 bool named ATTRIBUTE_UNUSED
)
5081 if (DEFAULT_ABI
== ABI_V4
&& mode
== TFmode
)
5083 if (TARGET_DEBUG_ARG
)
5084 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
5091 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
5093 if (TARGET_DEBUG_ARG
)
5094 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
5098 if (int_size_in_bytes (type
) < 0)
5100 if (TARGET_DEBUG_ARG
)
5101 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
5105 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5106 modes only exist for GCC vector types if -maltivec. */
5107 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
5109 if (TARGET_DEBUG_ARG
)
5110 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
5114 /* Pass synthetic vectors in memory. */
5115 if (TREE_CODE (type
) == VECTOR_TYPE
5116 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5118 static bool warned_for_pass_big_vectors
= false;
5119 if (TARGET_DEBUG_ARG
)
5120 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
5121 if (!warned_for_pass_big_vectors
)
5123 warning (0, "GCC vector passed by reference: "
5124 "non-standard ABI extension with no compatibility guarantee");
5125 warned_for_pass_big_vectors
= true;
5134 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
5137 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
5142 for (i
= 0; i
< nregs
; i
++)
5144 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
5145 if (reload_completed
)
5147 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
5150 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
5151 i
* GET_MODE_SIZE (reg_mode
));
5154 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
5158 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
5162 /* Perform any needed actions needed for a function that is receiving a
5163 variable number of arguments.
5167 MODE and TYPE are the mode and type of the current parameter.
5169 PRETEND_SIZE is a variable that should be set to the amount of stack
5170 that must be pushed by the prolog to pretend that our caller pushed
5173 Normally, this macro will push all remaining incoming registers on the
5174 stack and set PRETEND_SIZE to the length of the registers pushed. */
5177 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5178 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
5181 CUMULATIVE_ARGS next_cum
;
5182 int reg_size
= TARGET_32BIT
? 4 : 8;
5183 rtx save_area
= NULL_RTX
, mem
;
5184 int first_reg_offset
, set
;
5186 /* Skip the last named argument. */
5188 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
5190 if (DEFAULT_ABI
== ABI_V4
)
5193 save_area
= plus_constant (virtual_stack_vars_rtx
,
5194 - RS6000_VARARGS_SIZE
);
5196 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
5200 first_reg_offset
= next_cum
.words
;
5201 save_area
= virtual_incoming_args_rtx
;
5203 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
5204 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
5207 set
= get_varargs_alias_set ();
5208 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
5209 && cfun
->va_list_gpr_size
)
5211 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
5213 if (va_list_gpr_counter_field
)
5215 /* V4 va_list_gpr_size counts number of registers needed. */
5216 if (nregs
> cfun
->va_list_gpr_size
)
5217 nregs
= cfun
->va_list_gpr_size
;
5221 /* char * va_list instead counts number of bytes needed. */
5222 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
5223 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
5226 mem
= gen_rtx_MEM (BLKmode
,
5227 plus_constant (save_area
,
5228 first_reg_offset
* reg_size
)),
5229 set_mem_alias_set (mem
, set
);
5230 set_mem_align (mem
, BITS_PER_WORD
);
5232 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
5236 /* Save FP registers if needed. */
5237 if (DEFAULT_ABI
== ABI_V4
5238 && TARGET_HARD_FLOAT
&& TARGET_FPRS
5240 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5241 && cfun
->va_list_fpr_size
)
5243 int fregno
= next_cum
.fregno
, nregs
;
5244 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
5245 rtx lab
= gen_label_rtx ();
5246 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
) * 8);
5249 (gen_rtx_SET (VOIDmode
,
5251 gen_rtx_IF_THEN_ELSE (VOIDmode
,
5252 gen_rtx_NE (VOIDmode
, cr1
,
5254 gen_rtx_LABEL_REF (VOIDmode
, lab
),
5258 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
5259 fregno
++, off
+= 8, nregs
++)
5261 mem
= gen_rtx_MEM (DFmode
, plus_constant (save_area
, off
));
5262 set_mem_alias_set (mem
, set
);
5263 set_mem_align (mem
, GET_MODE_ALIGNMENT (DFmode
));
5264 emit_move_insn (mem
, gen_rtx_REG (DFmode
, fregno
));
5271 /* Create the va_list data type. */
5274 rs6000_build_builtin_va_list (void)
5276 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
5278 /* For AIX, prefer 'char *' because that's what the system
5279 header files like. */
5280 if (DEFAULT_ABI
!= ABI_V4
)
5281 return build_pointer_type (char_type_node
);
5283 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
5284 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
5286 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
5287 unsigned_char_type_node
);
5288 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
5289 unsigned_char_type_node
);
5290 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5292 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
5293 short_unsigned_type_node
);
5294 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
5296 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
5299 va_list_gpr_counter_field
= f_gpr
;
5300 va_list_fpr_counter_field
= f_fpr
;
5302 DECL_FIELD_CONTEXT (f_gpr
) = record
;
5303 DECL_FIELD_CONTEXT (f_fpr
) = record
;
5304 DECL_FIELD_CONTEXT (f_res
) = record
;
5305 DECL_FIELD_CONTEXT (f_ovf
) = record
;
5306 DECL_FIELD_CONTEXT (f_sav
) = record
;
5308 TREE_CHAIN (record
) = type_decl
;
5309 TYPE_NAME (record
) = type_decl
;
5310 TYPE_FIELDS (record
) = f_gpr
;
5311 TREE_CHAIN (f_gpr
) = f_fpr
;
5312 TREE_CHAIN (f_fpr
) = f_res
;
5313 TREE_CHAIN (f_res
) = f_ovf
;
5314 TREE_CHAIN (f_ovf
) = f_sav
;
5316 layout_type (record
);
5318 /* The correct type is an array type of one element. */
5319 return build_array_type (record
, build_index_type (size_zero_node
));
5322 /* Implement va_start. */
5325 rs6000_va_start (tree valist
, rtx nextarg
)
5327 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
5328 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
5329 tree gpr
, fpr
, ovf
, sav
, t
;
5331 /* Only SVR4 needs something special. */
5332 if (DEFAULT_ABI
!= ABI_V4
)
5334 std_expand_builtin_va_start (valist
, nextarg
);
5338 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
5339 f_fpr
= TREE_CHAIN (f_gpr
);
5340 f_res
= TREE_CHAIN (f_fpr
);
5341 f_ovf
= TREE_CHAIN (f_res
);
5342 f_sav
= TREE_CHAIN (f_ovf
);
5344 valist
= build_va_arg_indirect_ref (valist
);
5345 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
5346 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
5347 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
5348 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
5350 /* Count number of gp and fp argument registers used. */
5351 words
= current_function_args_info
.words
;
5352 n_gpr
= MIN (current_function_args_info
.sysv_gregno
- GP_ARG_MIN_REG
,
5354 n_fpr
= MIN (current_function_args_info
.fregno
- FP_ARG_MIN_REG
,
5357 if (TARGET_DEBUG_ARG
)
5358 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
5359 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
5360 words
, n_gpr
, n_fpr
);
5362 if (cfun
->va_list_gpr_size
)
5364 t
= build (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
5365 build_int_cst (NULL_TREE
, n_gpr
));
5366 TREE_SIDE_EFFECTS (t
) = 1;
5367 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5370 if (cfun
->va_list_fpr_size
)
5372 t
= build (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
5373 build_int_cst (NULL_TREE
, n_fpr
));
5374 TREE_SIDE_EFFECTS (t
) = 1;
5375 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5378 /* Find the overflow area. */
5379 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
5381 t
= build (PLUS_EXPR
, TREE_TYPE (ovf
), t
,
5382 build_int_cst (NULL_TREE
, words
* UNITS_PER_WORD
));
5383 t
= build (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
5384 TREE_SIDE_EFFECTS (t
) = 1;
5385 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5387 /* If there were no va_arg invocations, don't set up the register
5389 if (!cfun
->va_list_gpr_size
5390 && !cfun
->va_list_fpr_size
5391 && n_gpr
< GP_ARG_NUM_REG
5392 && n_fpr
< FP_ARG_V4_MAX_REG
)
5395 /* Find the register save area. */
5396 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
5397 t
= build (PLUS_EXPR
, TREE_TYPE (sav
), t
,
5398 build_int_cst (NULL_TREE
, -RS6000_VARARGS_SIZE
));
5399 t
= build (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
5400 TREE_SIDE_EFFECTS (t
) = 1;
5401 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5404 /* Implement va_arg. */
5407 rs6000_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
5409 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
5410 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
5411 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
5412 tree lab_false
, lab_over
, addr
;
5414 tree ptrtype
= build_pointer_type (type
);
5416 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
5418 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
5419 return build_va_arg_indirect_ref (t
);
5422 if (DEFAULT_ABI
!= ABI_V4
)
5424 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
5426 tree elem_type
= TREE_TYPE (type
);
5427 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
5428 int elem_size
= GET_MODE_SIZE (elem_mode
);
5430 if (elem_size
< UNITS_PER_WORD
)
5432 tree real_part
, imag_part
;
5433 tree post
= NULL_TREE
;
5435 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
5437 /* Copy the value into a temporary, lest the formal temporary
5438 be reused out from under us. */
5439 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
5440 append_to_statement_list (post
, pre_p
);
5442 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
5445 return build (COMPLEX_EXPR
, type
, real_part
, imag_part
);
5449 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
5452 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
5453 f_fpr
= TREE_CHAIN (f_gpr
);
5454 f_res
= TREE_CHAIN (f_fpr
);
5455 f_ovf
= TREE_CHAIN (f_res
);
5456 f_sav
= TREE_CHAIN (f_ovf
);
5458 valist
= build_va_arg_indirect_ref (valist
);
5459 gpr
= build (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
5460 fpr
= build (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
5461 ovf
= build (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
5462 sav
= build (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
5464 size
= int_size_in_bytes (type
);
5465 rsize
= (size
+ 3) / 4;
5468 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5469 && (TYPE_MODE (type
) == SFmode
|| TYPE_MODE (type
) == DFmode
))
5471 /* FP args go in FP registers, if present. */
5476 if (TYPE_MODE (type
) == DFmode
)
5481 /* Otherwise into GP registers. */
5490 /* Pull the value out of the saved registers.... */
5493 addr
= create_tmp_var (ptr_type_node
, "addr");
5494 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
5496 /* AltiVec vectors never go in registers when -mabi=altivec. */
5497 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5501 lab_false
= create_artificial_label ();
5502 lab_over
= create_artificial_label ();
5504 /* Long long and SPE vectors are aligned in the registers.
5505 As are any other 2 gpr item such as complex int due to a
5506 historical mistake. */
5510 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), reg
,
5511 size_int (n_reg
- 1));
5512 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, u
);
5515 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
5516 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
5517 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
5518 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
5519 gimplify_and_add (t
, pre_p
);
5523 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
5525 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, size_int (n_reg
));
5526 u
= build1 (CONVERT_EXPR
, integer_type_node
, u
);
5527 u
= build2 (MULT_EXPR
, integer_type_node
, u
, size_int (sav_scale
));
5528 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, u
);
5530 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
5531 gimplify_and_add (t
, pre_p
);
5533 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
5534 gimplify_and_add (t
, pre_p
);
5536 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
5537 append_to_statement_list (t
, pre_p
);
5541 /* Ensure that we don't find any more args in regs.
5542 Alignment has taken care of the n_reg == 2 case. */
5543 t
= build (MODIFY_EXPR
, TREE_TYPE (reg
), reg
, size_int (8));
5544 gimplify_and_add (t
, pre_p
);
5548 /* ... otherwise out of the overflow area. */
5550 /* Care for on-stack alignment if needed. */
5554 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
5555 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
5556 build_int_cst (NULL_TREE
, -align
));
5558 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
5560 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
5561 gimplify_and_add (u
, pre_p
);
5563 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
5564 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
5565 gimplify_and_add (t
, pre_p
);
5569 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
5570 append_to_statement_list (t
, pre_p
);
5573 addr
= fold_convert (ptrtype
, addr
);
5574 return build_va_arg_indirect_ref (addr
);
5580 def_builtin (int mask
, const char *name
, tree type
, int code
)
5582 if (mask
& target_flags
)
5584 if (rs6000_builtin_decls
[code
])
5587 rs6000_builtin_decls
[code
] =
5588 lang_hooks
.builtin_function (name
, type
, code
, BUILT_IN_MD
,
5593 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
5595 static const struct builtin_description bdesc_3arg
[] =
5597 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
5598 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
5599 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
5600 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
5601 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
5602 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
5603 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
5604 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
5605 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
5606 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
5607 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
5608 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
5609 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
5610 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
5611 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
5612 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
5613 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
5614 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
5615 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
5616 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
5617 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
5618 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
5619 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
5621 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
5622 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
5623 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
5624 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
5625 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
5626 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
5627 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
5628 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
5629 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
5630 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
5631 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
5632 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
5633 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
5634 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
5635 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
5638 /* DST operations: void foo (void *, const int, const char). */
5640 static const struct builtin_description bdesc_dst
[] =
5642 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
5643 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
5644 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
5645 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
5647 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
5648 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
5649 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
5650 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
5653 /* Simple binary operations: VECc = foo (VECa, VECb). */
5655 static struct builtin_description bdesc_2arg
[] =
5657 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
5658 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
5659 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
5660 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
5661 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
5662 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
5663 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
5664 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
5665 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
5666 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
5667 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
5668 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
5669 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
5670 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
5671 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
5672 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
5673 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
5674 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
5675 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
5676 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
5677 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
5678 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
5679 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
5680 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
5681 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
5682 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
5683 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
5684 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
5685 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
5686 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
5687 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
5688 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
5689 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
5690 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
5691 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
5692 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
5693 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
5694 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
5695 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
5696 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
5697 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
5698 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
5699 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
5700 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
5701 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
5702 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
5703 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
5704 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
5705 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
5706 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
5707 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
5708 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
5709 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
5710 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
5711 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
5712 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
5713 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
5714 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
5715 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
5716 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
5717 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
5718 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
5719 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
5720 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
5721 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
5722 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
5723 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
5724 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
5725 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
5726 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhss
, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS
},
5727 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
5728 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwss
, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS
},
5729 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
5730 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
5731 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
5732 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
5733 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
5734 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
5735 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
5736 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
5737 { MASK_ALTIVEC
, CODE_FOR_altivec_vslb
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
5738 { MASK_ALTIVEC
, CODE_FOR_altivec_vslh
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
5739 { MASK_ALTIVEC
, CODE_FOR_altivec_vslw
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
5740 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
5741 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
5742 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
5743 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
5744 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
5745 { MASK_ALTIVEC
, CODE_FOR_lshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
5746 { MASK_ALTIVEC
, CODE_FOR_lshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
5747 { MASK_ALTIVEC
, CODE_FOR_lshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
5748 { MASK_ALTIVEC
, CODE_FOR_ashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
5749 { MASK_ALTIVEC
, CODE_FOR_ashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
5750 { MASK_ALTIVEC
, CODE_FOR_ashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
5751 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
5752 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
5753 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
5754 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
5755 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
5756 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
5757 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
5758 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
5759 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
5760 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
5761 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
5762 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
5763 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
5764 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
5765 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
5766 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
5767 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
5768 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
5769 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
5771 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
5772 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
5773 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
5774 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
5775 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
5776 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
5777 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
5778 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
5779 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
5780 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
5781 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
5782 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
5783 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
5784 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
5785 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
5786 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
5787 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
5788 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
5789 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
5790 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
5791 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
5792 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
5793 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
5794 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
5795 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
5796 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
5797 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
5798 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
5799 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
5800 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
5801 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
5802 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
5803 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
5804 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
5805 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
5806 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
5807 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
5808 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
5809 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
5810 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
5811 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
5812 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
5813 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
5814 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
5815 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
5816 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
5817 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
5818 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
5819 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
5820 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
5821 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
5822 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
5823 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
5824 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
5825 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
5826 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
5827 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
5828 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
5829 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
5830 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
5831 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
5832 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
5833 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
5834 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
5835 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
5836 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
5837 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
5838 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
5839 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
5840 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
5841 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
5842 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
5843 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
5844 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
5845 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
5846 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
5847 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
5848 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
5849 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
5850 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
5851 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
5852 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
5853 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
5854 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
5855 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
5856 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
5857 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
5858 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
5859 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
5860 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
5861 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
5862 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
5863 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
5864 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
5865 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
5866 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
5867 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
5868 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
5869 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
5870 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
5871 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
5872 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
5873 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
5874 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
5875 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
5876 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
5877 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
5878 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
5879 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
5880 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
5881 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
5882 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
5883 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
5884 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
5885 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
5886 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
5887 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
5888 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
5889 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
5890 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
5891 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
5892 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
5893 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
5894 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
5895 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
5896 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
5897 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
5899 /* Place holder, leave as first spe builtin. */
5900 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
5901 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
5902 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
5903 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
5904 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
5905 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
5906 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
5907 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
5908 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
5909 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
5910 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
5911 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
5912 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
5913 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
5914 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
5915 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
5916 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
5917 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
5918 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
5919 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
5920 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
5921 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
5922 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
5923 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
5924 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
5925 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
5926 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
5927 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
5928 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
5929 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
5930 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
5931 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
5932 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
5933 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
5934 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
5935 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
5936 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
5937 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
5938 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
5939 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
5940 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
5941 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
5942 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
5943 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
5944 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
5945 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
5946 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
5947 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
5948 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
5949 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
5950 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
5951 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
5952 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
5953 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
5954 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
5955 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
5956 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
5957 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
5958 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
5959 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
5960 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
5961 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
5962 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
5963 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
5964 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
5965 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
5966 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
5967 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
5968 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
5969 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
5970 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
5971 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
5972 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
5973 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
5974 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
5975 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
5976 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
5977 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
5978 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
5979 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
5980 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
5981 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
5982 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
5983 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
5984 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
5985 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
5986 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
5987 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
5988 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
5989 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
5990 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
5991 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
5992 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
5993 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
5994 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
5995 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
5996 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
5997 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
5998 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
5999 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
6000 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
6001 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
6002 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
6003 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
6004 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
6005 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
6006 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
6007 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
6008 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
6010 /* SPE binary operations expecting a 5-bit unsigned literal. */
6011 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
6013 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
6014 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
6015 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
6016 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
6017 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
6018 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
6019 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
6020 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
6021 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
6022 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
6023 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
6024 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
6025 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
6026 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
6027 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
6028 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
6029 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
6030 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
6031 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
6032 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
6033 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
6034 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
6035 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
6036 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
6037 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
6038 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
6040 /* Place-holder. Leave as last binary SPE builtin. */
6041 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
6044 /* AltiVec predicates. */
6046 struct builtin_description_predicates
6048 const unsigned int mask
;
6049 const enum insn_code icode
;
6051 const char *const name
;
6052 const enum rs6000_builtins code
;
6055 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
6057 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
6058 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
6059 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
6060 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
6061 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
6062 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
6063 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
6064 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
6065 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
6066 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
6067 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
6068 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
6069 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
6071 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
6072 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
6073 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
6076 /* SPE predicates. */
6077 static struct builtin_description bdesc_spe_predicates
[] =
6079 /* Place-holder. Leave as first. */
6080 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
6081 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
6082 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
6083 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
6084 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
6085 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
6086 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
6087 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
6088 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
6089 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
6090 /* Place-holder. Leave as last. */
6091 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
6094 /* SPE evsel predicates. */
6095 static struct builtin_description bdesc_spe_evsel
[] =
6097 /* Place-holder. Leave as first. */
6098 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
6099 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
6100 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
6101 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
6102 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
6103 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
6104 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
6105 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
6106 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
6107 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
6108 /* Place-holder. Leave as last. */
6109 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
6112 /* ABS* operations. */
6114 static const struct builtin_description bdesc_abs
[] =
6116 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
6117 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
6118 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
6119 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
6120 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
6121 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
6122 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
6125 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6128 static struct builtin_description bdesc_1arg
[] =
6130 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
6131 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
6132 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
6133 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
6134 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
6135 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
6136 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
6137 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
6138 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
6139 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
6140 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
6141 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
6142 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
6143 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
6144 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
6145 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
6146 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
6148 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
6149 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
6150 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
6151 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
6152 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
6153 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
6154 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
6155 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
6156 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
6157 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
6158 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
6159 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
6160 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
6161 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
6162 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
6163 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
6164 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
6165 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
6166 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
6168 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6169 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6170 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
6171 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
6172 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
6173 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
6174 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
6175 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
6176 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
6177 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
6178 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
6179 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
6180 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
6181 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
6182 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
6183 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
6184 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
6185 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
6186 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
6187 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
6188 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
6189 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
6190 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
6191 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
6192 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
6193 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
6194 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
6195 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
6196 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
6197 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
6199 /* Place-holder. Leave as last unary SPE builtin. */
6200 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
}
6204 rs6000_expand_unop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6207 tree arg0
= TREE_VALUE (arglist
);
6208 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6209 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6210 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6212 if (icode
== CODE_FOR_nothing
)
6213 /* Builtin not supported on this processor. */
6216 /* If we got invalid arguments bail out before generating bad rtl. */
6217 if (arg0
== error_mark_node
)
6220 if (icode
== CODE_FOR_altivec_vspltisb
6221 || icode
== CODE_FOR_altivec_vspltish
6222 || icode
== CODE_FOR_altivec_vspltisw
6223 || icode
== CODE_FOR_spe_evsplatfi
6224 || icode
== CODE_FOR_spe_evsplati
)
6226 /* Only allow 5-bit *signed* literals. */
6227 if (GET_CODE (op0
) != CONST_INT
6228 || INTVAL (op0
) > 0x1f
6229 || INTVAL (op0
) < -0x1f)
6231 error ("argument 1 must be a 5-bit signed literal");
6237 || GET_MODE (target
) != tmode
6238 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6239 target
= gen_reg_rtx (tmode
);
6241 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6242 op0
= copy_to_mode_reg (mode0
, op0
);
6244 pat
= GEN_FCN (icode
) (target
, op0
);
6253 altivec_expand_abs_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6255 rtx pat
, scratch1
, scratch2
;
6256 tree arg0
= TREE_VALUE (arglist
);
6257 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6258 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6259 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6261 /* If we have invalid arguments, bail out before generating bad rtl. */
6262 if (arg0
== error_mark_node
)
6266 || GET_MODE (target
) != tmode
6267 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6268 target
= gen_reg_rtx (tmode
);
6270 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6271 op0
= copy_to_mode_reg (mode0
, op0
);
6273 scratch1
= gen_reg_rtx (mode0
);
6274 scratch2
= gen_reg_rtx (mode0
);
6276 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
6285 rs6000_expand_binop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6288 tree arg0
= TREE_VALUE (arglist
);
6289 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6290 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6291 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6292 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6293 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6294 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6296 if (icode
== CODE_FOR_nothing
)
6297 /* Builtin not supported on this processor. */
6300 /* If we got invalid arguments bail out before generating bad rtl. */
6301 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6304 if (icode
== CODE_FOR_altivec_vcfux
6305 || icode
== CODE_FOR_altivec_vcfsx
6306 || icode
== CODE_FOR_altivec_vctsxs
6307 || icode
== CODE_FOR_altivec_vctuxs
6308 || icode
== CODE_FOR_altivec_vspltb
6309 || icode
== CODE_FOR_altivec_vsplth
6310 || icode
== CODE_FOR_altivec_vspltw
6311 || icode
== CODE_FOR_spe_evaddiw
6312 || icode
== CODE_FOR_spe_evldd
6313 || icode
== CODE_FOR_spe_evldh
6314 || icode
== CODE_FOR_spe_evldw
6315 || icode
== CODE_FOR_spe_evlhhesplat
6316 || icode
== CODE_FOR_spe_evlhhossplat
6317 || icode
== CODE_FOR_spe_evlhhousplat
6318 || icode
== CODE_FOR_spe_evlwhe
6319 || icode
== CODE_FOR_spe_evlwhos
6320 || icode
== CODE_FOR_spe_evlwhou
6321 || icode
== CODE_FOR_spe_evlwhsplat
6322 || icode
== CODE_FOR_spe_evlwwsplat
6323 || icode
== CODE_FOR_spe_evrlwi
6324 || icode
== CODE_FOR_spe_evslwi
6325 || icode
== CODE_FOR_spe_evsrwis
6326 || icode
== CODE_FOR_spe_evsubifw
6327 || icode
== CODE_FOR_spe_evsrwiu
)
6329 /* Only allow 5-bit unsigned literals. */
6331 if (TREE_CODE (arg1
) != INTEGER_CST
6332 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
6334 error ("argument 2 must be a 5-bit unsigned literal");
6340 || GET_MODE (target
) != tmode
6341 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6342 target
= gen_reg_rtx (tmode
);
6344 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6345 op0
= copy_to_mode_reg (mode0
, op0
);
6346 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6347 op1
= copy_to_mode_reg (mode1
, op1
);
6349 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6358 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
6359 tree arglist
, rtx target
)
6362 tree cr6_form
= TREE_VALUE (arglist
);
6363 tree arg0
= TREE_VALUE (TREE_CHAIN (arglist
));
6364 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6365 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6366 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6367 enum machine_mode tmode
= SImode
;
6368 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6369 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6372 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
6374 error ("argument 1 of __builtin_altivec_predicate must be a constant");
6378 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
6380 gcc_assert (mode0
== mode1
);
6382 /* If we have invalid arguments, bail out before generating bad rtl. */
6383 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6387 || GET_MODE (target
) != tmode
6388 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6389 target
= gen_reg_rtx (tmode
);
6391 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6392 op0
= copy_to_mode_reg (mode0
, op0
);
6393 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6394 op1
= copy_to_mode_reg (mode1
, op1
);
6396 scratch
= gen_reg_rtx (mode0
);
6398 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
6399 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
6404 /* The vec_any* and vec_all* predicates use the same opcodes for two
6405 different operations, but the bits in CR6 will be different
6406 depending on what information we want. So we have to play tricks
6407 with CR6 to get the right bits out.
6409 If you think this is disgusting, look at the specs for the
6410 AltiVec predicates. */
6412 switch (cr6_form_int
)
6415 emit_insn (gen_cr6_test_for_zero (target
));
6418 emit_insn (gen_cr6_test_for_zero_reverse (target
));
6421 emit_insn (gen_cr6_test_for_lt (target
));
6424 emit_insn (gen_cr6_test_for_lt_reverse (target
));
6427 error ("argument 1 of __builtin_altivec_predicate is out of range");
6435 altivec_expand_lv_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6438 tree arg0
= TREE_VALUE (arglist
);
6439 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6440 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6441 enum machine_mode mode0
= Pmode
;
6442 enum machine_mode mode1
= Pmode
;
6443 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6444 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6446 if (icode
== CODE_FOR_nothing
)
6447 /* Builtin not supported on this processor. */
6450 /* If we got invalid arguments bail out before generating bad rtl. */
6451 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6455 || GET_MODE (target
) != tmode
6456 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6457 target
= gen_reg_rtx (tmode
);
6459 op1
= copy_to_mode_reg (mode1
, op1
);
6461 if (op0
== const0_rtx
)
6463 addr
= gen_rtx_MEM (tmode
, op1
);
6467 op0
= copy_to_mode_reg (mode0
, op0
);
6468 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
6471 pat
= GEN_FCN (icode
) (target
, addr
);
6481 spe_expand_stv_builtin (enum insn_code icode
, tree arglist
)
6483 tree arg0
= TREE_VALUE (arglist
);
6484 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6485 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6486 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6487 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6488 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6490 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
6491 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
6492 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
6494 /* Invalid arguments. Bail before doing anything stoopid! */
6495 if (arg0
== error_mark_node
6496 || arg1
== error_mark_node
6497 || arg2
== error_mark_node
)
6500 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
6501 op0
= copy_to_mode_reg (mode2
, op0
);
6502 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
6503 op1
= copy_to_mode_reg (mode0
, op1
);
6504 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
6505 op2
= copy_to_mode_reg (mode1
, op2
);
6507 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
6514 altivec_expand_stv_builtin (enum insn_code icode
, tree arglist
)
6516 tree arg0
= TREE_VALUE (arglist
);
6517 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6518 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6519 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6520 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6521 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6523 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6524 enum machine_mode mode1
= Pmode
;
6525 enum machine_mode mode2
= Pmode
;
6527 /* Invalid arguments. Bail before doing anything stoopid! */
6528 if (arg0
== error_mark_node
6529 || arg1
== error_mark_node
6530 || arg2
== error_mark_node
)
6533 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
6534 op0
= copy_to_mode_reg (tmode
, op0
);
6536 op2
= copy_to_mode_reg (mode2
, op2
);
6538 if (op1
== const0_rtx
)
6540 addr
= gen_rtx_MEM (tmode
, op2
);
6544 op1
= copy_to_mode_reg (mode1
, op1
);
6545 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
6548 pat
= GEN_FCN (icode
) (addr
, op0
);
6555 rs6000_expand_ternop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6558 tree arg0
= TREE_VALUE (arglist
);
6559 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6560 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6561 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6562 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6563 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6564 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6565 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6566 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6567 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
6569 if (icode
== CODE_FOR_nothing
)
6570 /* Builtin not supported on this processor. */
6573 /* If we got invalid arguments bail out before generating bad rtl. */
6574 if (arg0
== error_mark_node
6575 || arg1
== error_mark_node
6576 || arg2
== error_mark_node
)
6579 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
6580 || icode
== CODE_FOR_altivec_vsldoi_v4si
6581 || icode
== CODE_FOR_altivec_vsldoi_v8hi
6582 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
6584 /* Only allow 4-bit unsigned literals. */
6586 if (TREE_CODE (arg2
) != INTEGER_CST
6587 || TREE_INT_CST_LOW (arg2
) & ~0xf)
6589 error ("argument 3 must be a 4-bit unsigned literal");
6595 || GET_MODE (target
) != tmode
6596 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6597 target
= gen_reg_rtx (tmode
);
6599 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6600 op0
= copy_to_mode_reg (mode0
, op0
);
6601 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6602 op1
= copy_to_mode_reg (mode1
, op1
);
6603 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
6604 op2
= copy_to_mode_reg (mode2
, op2
);
6606 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6614 /* Expand the lvx builtins. */
6616 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
6618 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6619 tree arglist
= TREE_OPERAND (exp
, 1);
6620 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6622 enum machine_mode tmode
, mode0
;
6624 enum insn_code icode
;
6628 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
6629 icode
= CODE_FOR_altivec_lvx_v16qi
;
6631 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
6632 icode
= CODE_FOR_altivec_lvx_v8hi
;
6634 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
6635 icode
= CODE_FOR_altivec_lvx_v4si
;
6637 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
6638 icode
= CODE_FOR_altivec_lvx_v4sf
;
6647 arg0
= TREE_VALUE (arglist
);
6648 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6649 tmode
= insn_data
[icode
].operand
[0].mode
;
6650 mode0
= insn_data
[icode
].operand
[1].mode
;
6653 || GET_MODE (target
) != tmode
6654 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6655 target
= gen_reg_rtx (tmode
);
6657 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6658 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
6660 pat
= GEN_FCN (icode
) (target
, op0
);
6667 /* Expand the stvx builtins. */
6669 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
6672 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6673 tree arglist
= TREE_OPERAND (exp
, 1);
6674 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6676 enum machine_mode mode0
, mode1
;
6678 enum insn_code icode
;
6682 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
6683 icode
= CODE_FOR_altivec_stvx_v16qi
;
6685 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
6686 icode
= CODE_FOR_altivec_stvx_v8hi
;
6688 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
6689 icode
= CODE_FOR_altivec_stvx_v4si
;
6691 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
6692 icode
= CODE_FOR_altivec_stvx_v4sf
;
6699 arg0
= TREE_VALUE (arglist
);
6700 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6701 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6702 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6703 mode0
= insn_data
[icode
].operand
[0].mode
;
6704 mode1
= insn_data
[icode
].operand
[1].mode
;
6706 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
6707 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
6708 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
6709 op1
= copy_to_mode_reg (mode1
, op1
);
6711 pat
= GEN_FCN (icode
) (op0
, op1
);
6719 /* Expand the dst builtins. */
6721 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
6724 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6725 tree arglist
= TREE_OPERAND (exp
, 1);
6726 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6727 tree arg0
, arg1
, arg2
;
6728 enum machine_mode mode0
, mode1
, mode2
;
6729 rtx pat
, op0
, op1
, op2
;
6730 struct builtin_description
*d
;
6735 /* Handle DST variants. */
6736 d
= (struct builtin_description
*) bdesc_dst
;
6737 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
6738 if (d
->code
== fcode
)
6740 arg0
= TREE_VALUE (arglist
);
6741 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6742 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6743 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6744 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6745 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6746 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
6747 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
6748 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
6750 /* Invalid arguments, bail out before generating bad rtl. */
6751 if (arg0
== error_mark_node
6752 || arg1
== error_mark_node
6753 || arg2
== error_mark_node
)
6758 if (TREE_CODE (arg2
) != INTEGER_CST
6759 || TREE_INT_CST_LOW (arg2
) & ~0x3)
6761 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
6765 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
6766 op0
= copy_to_mode_reg (Pmode
, op0
);
6767 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
6768 op1
= copy_to_mode_reg (mode1
, op1
);
6770 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
6780 /* Expand the builtin in EXP and store the result in TARGET. Store
6781 true in *EXPANDEDP if we found a builtin to expand. */
6783 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
6785 struct builtin_description
*d
;
6786 struct builtin_description_predicates
*dp
;
6788 enum insn_code icode
;
6789 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6790 tree arglist
= TREE_OPERAND (exp
, 1);
6793 enum machine_mode tmode
, mode0
;
6794 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6796 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
6797 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
6800 error ("unresolved overload for Altivec builtin %qE", fndecl
);
6804 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
6808 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
6812 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
6820 case ALTIVEC_BUILTIN_STVX
:
6821 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, arglist
);
6822 case ALTIVEC_BUILTIN_STVEBX
:
6823 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, arglist
);
6824 case ALTIVEC_BUILTIN_STVEHX
:
6825 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, arglist
);
6826 case ALTIVEC_BUILTIN_STVEWX
:
6827 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, arglist
);
6828 case ALTIVEC_BUILTIN_STVXL
:
6829 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, arglist
);
6831 case ALTIVEC_BUILTIN_MFVSCR
:
6832 icode
= CODE_FOR_altivec_mfvscr
;
6833 tmode
= insn_data
[icode
].operand
[0].mode
;
6836 || GET_MODE (target
) != tmode
6837 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6838 target
= gen_reg_rtx (tmode
);
6840 pat
= GEN_FCN (icode
) (target
);
6846 case ALTIVEC_BUILTIN_MTVSCR
:
6847 icode
= CODE_FOR_altivec_mtvscr
;
6848 arg0
= TREE_VALUE (arglist
);
6849 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6850 mode0
= insn_data
[icode
].operand
[0].mode
;
6852 /* If we got invalid arguments bail out before generating bad rtl. */
6853 if (arg0
== error_mark_node
)
6856 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
6857 op0
= copy_to_mode_reg (mode0
, op0
);
6859 pat
= GEN_FCN (icode
) (op0
);
6864 case ALTIVEC_BUILTIN_DSSALL
:
6865 emit_insn (gen_altivec_dssall ());
6868 case ALTIVEC_BUILTIN_DSS
:
6869 icode
= CODE_FOR_altivec_dss
;
6870 arg0
= TREE_VALUE (arglist
);
6872 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6873 mode0
= insn_data
[icode
].operand
[0].mode
;
6875 /* If we got invalid arguments bail out before generating bad rtl. */
6876 if (arg0
== error_mark_node
)
6879 if (TREE_CODE (arg0
) != INTEGER_CST
6880 || TREE_INT_CST_LOW (arg0
) & ~0x3)
6882 error ("argument to dss must be a 2-bit unsigned literal");
6886 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
6887 op0
= copy_to_mode_reg (mode0
, op0
);
6889 emit_insn (gen_altivec_dss (op0
));
6893 /* Expand abs* operations. */
6894 d
= (struct builtin_description
*) bdesc_abs
;
6895 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
6896 if (d
->code
== fcode
)
6897 return altivec_expand_abs_builtin (d
->icode
, arglist
, target
);
6899 /* Expand the AltiVec predicates. */
6900 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
6901 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
6902 if (dp
->code
== fcode
)
6903 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
6906 /* LV* are funky. We initialized them differently. */
6909 case ALTIVEC_BUILTIN_LVSL
:
6910 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
6912 case ALTIVEC_BUILTIN_LVSR
:
6913 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
6915 case ALTIVEC_BUILTIN_LVEBX
:
6916 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
6918 case ALTIVEC_BUILTIN_LVEHX
:
6919 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
6921 case ALTIVEC_BUILTIN_LVEWX
:
6922 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
6924 case ALTIVEC_BUILTIN_LVXL
:
6925 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
6927 case ALTIVEC_BUILTIN_LVX
:
6928 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
6939 /* Binops that need to be initialized manually, but can be expanded
6940 automagically by rs6000_expand_binop_builtin. */
6941 static struct builtin_description bdesc_2arg_spe
[] =
6943 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
6944 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
6945 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
6946 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
6947 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
6948 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
6949 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
6950 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
6951 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
6952 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
6953 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
6954 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
6955 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
6956 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
6957 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
6958 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
6959 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
6960 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
6961 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
6962 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
6963 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
6964 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
6967 /* Expand the builtin in EXP and store the result in TARGET. Store
6968 true in *EXPANDEDP if we found a builtin to expand.
6970 This expands the SPE builtins that are not simple unary and binary
6973 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
6975 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6976 tree arglist
= TREE_OPERAND (exp
, 1);
6978 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6979 enum insn_code icode
;
6980 enum machine_mode tmode
, mode0
;
6982 struct builtin_description
*d
;
6987 /* Syntax check for a 5-bit unsigned immediate. */
6990 case SPE_BUILTIN_EVSTDD
:
6991 case SPE_BUILTIN_EVSTDH
:
6992 case SPE_BUILTIN_EVSTDW
:
6993 case SPE_BUILTIN_EVSTWHE
:
6994 case SPE_BUILTIN_EVSTWHO
:
6995 case SPE_BUILTIN_EVSTWWE
:
6996 case SPE_BUILTIN_EVSTWWO
:
6997 arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6998 if (TREE_CODE (arg1
) != INTEGER_CST
6999 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7001 error ("argument 2 must be a 5-bit unsigned literal");
7009 /* The evsplat*i instructions are not quite generic. */
7012 case SPE_BUILTIN_EVSPLATFI
:
7013 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
7015 case SPE_BUILTIN_EVSPLATI
:
7016 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
7022 d
= (struct builtin_description
*) bdesc_2arg_spe
;
7023 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
7024 if (d
->code
== fcode
)
7025 return rs6000_expand_binop_builtin (d
->icode
, arglist
, target
);
7027 d
= (struct builtin_description
*) bdesc_spe_predicates
;
7028 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
7029 if (d
->code
== fcode
)
7030 return spe_expand_predicate_builtin (d
->icode
, arglist
, target
);
7032 d
= (struct builtin_description
*) bdesc_spe_evsel
;
7033 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
7034 if (d
->code
== fcode
)
7035 return spe_expand_evsel_builtin (d
->icode
, arglist
, target
);
7039 case SPE_BUILTIN_EVSTDDX
:
7040 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, arglist
);
7041 case SPE_BUILTIN_EVSTDHX
:
7042 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, arglist
);
7043 case SPE_BUILTIN_EVSTDWX
:
7044 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, arglist
);
7045 case SPE_BUILTIN_EVSTWHEX
:
7046 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, arglist
);
7047 case SPE_BUILTIN_EVSTWHOX
:
7048 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, arglist
);
7049 case SPE_BUILTIN_EVSTWWEX
:
7050 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, arglist
);
7051 case SPE_BUILTIN_EVSTWWOX
:
7052 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, arglist
);
7053 case SPE_BUILTIN_EVSTDD
:
7054 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, arglist
);
7055 case SPE_BUILTIN_EVSTDH
:
7056 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, arglist
);
7057 case SPE_BUILTIN_EVSTDW
:
7058 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, arglist
);
7059 case SPE_BUILTIN_EVSTWHE
:
7060 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, arglist
);
7061 case SPE_BUILTIN_EVSTWHO
:
7062 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, arglist
);
7063 case SPE_BUILTIN_EVSTWWE
:
7064 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, arglist
);
7065 case SPE_BUILTIN_EVSTWWO
:
7066 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, arglist
);
7067 case SPE_BUILTIN_MFSPEFSCR
:
7068 icode
= CODE_FOR_spe_mfspefscr
;
7069 tmode
= insn_data
[icode
].operand
[0].mode
;
7072 || GET_MODE (target
) != tmode
7073 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7074 target
= gen_reg_rtx (tmode
);
7076 pat
= GEN_FCN (icode
) (target
);
7081 case SPE_BUILTIN_MTSPEFSCR
:
7082 icode
= CODE_FOR_spe_mtspefscr
;
7083 arg0
= TREE_VALUE (arglist
);
7084 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7085 mode0
= insn_data
[icode
].operand
[0].mode
;
7087 if (arg0
== error_mark_node
)
7090 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7091 op0
= copy_to_mode_reg (mode0
, op0
);
7093 pat
= GEN_FCN (icode
) (op0
);
7106 spe_expand_predicate_builtin (enum insn_code icode
, tree arglist
, rtx target
)
7108 rtx pat
, scratch
, tmp
;
7109 tree form
= TREE_VALUE (arglist
);
7110 tree arg0
= TREE_VALUE (TREE_CHAIN (arglist
));
7111 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7112 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7113 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7114 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7115 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7119 if (TREE_CODE (form
) != INTEGER_CST
)
7121 error ("argument 1 of __builtin_spe_predicate must be a constant");
7125 form_int
= TREE_INT_CST_LOW (form
);
7127 gcc_assert (mode0
== mode1
);
7129 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7133 || GET_MODE (target
) != SImode
7134 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
7135 target
= gen_reg_rtx (SImode
);
7137 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7138 op0
= copy_to_mode_reg (mode0
, op0
);
7139 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7140 op1
= copy_to_mode_reg (mode1
, op1
);
7142 scratch
= gen_reg_rtx (CCmode
);
7144 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
7149 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7150 _lower_. We use one compare, but look in different bits of the
7151 CR for each variant.
7153 There are 2 elements in each SPE simd type (upper/lower). The CR
7154 bits are set as follows:
7156 BIT0 | BIT 1 | BIT 2 | BIT 3
7157 U | L | (U | L) | (U & L)
7159 So, for an "all" relationship, BIT 3 would be set.
7160 For an "any" relationship, BIT 2 would be set. Etc.
7162 Following traditional nomenclature, these bits map to:
7164 BIT0 | BIT 1 | BIT 2 | BIT 3
7167 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
7172 /* All variant. OV bit. */
7174 /* We need to get to the OV bit, which is the ORDERED bit. We
7175 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
7176 that's ugly and will make validate_condition_mode die.
7177 So let's just use another pattern. */
7178 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
7180 /* Any variant. EQ bit. */
7184 /* Upper variant. LT bit. */
7188 /* Lower variant. GT bit. */
7193 error ("argument 1 of __builtin_spe_predicate is out of range");
7197 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
7198 emit_move_insn (target
, tmp
);
7203 /* The evsel builtins look like this:
7205 e = __builtin_spe_evsel_OP (a, b, c, d);
7209 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
7210 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
7214 spe_expand_evsel_builtin (enum insn_code icode
, tree arglist
, rtx target
)
7217 tree arg0
= TREE_VALUE (arglist
);
7218 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7219 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7220 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
7221 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7222 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7223 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
7224 rtx op3
= expand_expr (arg3
, NULL_RTX
, VOIDmode
, 0);
7225 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7226 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7228 gcc_assert (mode0
== mode1
);
7230 if (arg0
== error_mark_node
|| arg1
== error_mark_node
7231 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
7235 || GET_MODE (target
) != mode0
7236 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
7237 target
= gen_reg_rtx (mode0
);
7239 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7240 op0
= copy_to_mode_reg (mode0
, op0
);
7241 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
7242 op1
= copy_to_mode_reg (mode0
, op1
);
7243 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
7244 op2
= copy_to_mode_reg (mode0
, op2
);
7245 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
7246 op3
= copy_to_mode_reg (mode0
, op3
);
7248 /* Generate the compare. */
7249 scratch
= gen_reg_rtx (CCmode
);
7250 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
7255 if (mode0
== V2SImode
)
7256 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
7258 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
7263 /* Expand an expression EXP that calls a built-in function,
7264 with result going to TARGET if that's convenient
7265 (and in mode MODE if that's convenient).
7266 SUBTARGET may be used as the target for computing one of EXP's operands.
7267 IGNORE is nonzero if the value is to be ignored. */
7270 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
7271 enum machine_mode mode ATTRIBUTE_UNUSED
,
7272 int ignore ATTRIBUTE_UNUSED
)
7274 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7275 tree arglist
= TREE_OPERAND (exp
, 1);
7276 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7277 struct builtin_description
*d
;
7282 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
7283 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
7285 int icode
= (int) CODE_FOR_altivec_lvsr
;
7286 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7287 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
7291 gcc_assert (TARGET_ALTIVEC
);
7293 arg
= TREE_VALUE (arglist
);
7294 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
7295 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
7296 addr
= memory_address (mode
, op
);
7297 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
7301 /* For the load case need to negate the address. */
7302 op
= gen_reg_rtx (GET_MODE (addr
));
7303 emit_insn (gen_rtx_SET (VOIDmode
, op
,
7304 gen_rtx_NEG (GET_MODE (addr
), addr
)));
7306 op
= gen_rtx_MEM (mode
, op
);
7309 || GET_MODE (target
) != tmode
7310 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7311 target
= gen_reg_rtx (tmode
);
7313 /*pat = gen_altivec_lvsr (target, op);*/
7314 pat
= GEN_FCN (icode
) (target
, op
);
7324 ret
= altivec_expand_builtin (exp
, target
, &success
);
7331 ret
= spe_expand_builtin (exp
, target
, &success
);
7337 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
);
7339 /* Handle simple unary operations. */
7340 d
= (struct builtin_description
*) bdesc_1arg
;
7341 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
7342 if (d
->code
== fcode
)
7343 return rs6000_expand_unop_builtin (d
->icode
, arglist
, target
);
7345 /* Handle simple binary operations. */
7346 d
= (struct builtin_description
*) bdesc_2arg
;
7347 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
7348 if (d
->code
== fcode
)
7349 return rs6000_expand_binop_builtin (d
->icode
, arglist
, target
);
7351 /* Handle simple ternary operations. */
7352 d
= (struct builtin_description
*) bdesc_3arg
;
7353 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
7354 if (d
->code
== fcode
)
7355 return rs6000_expand_ternop_builtin (d
->icode
, arglist
, target
);
7361 build_opaque_vector_type (tree node
, int nunits
)
7363 node
= copy_node (node
);
7364 TYPE_MAIN_VARIANT (node
) = node
;
7365 return build_vector_type (node
, nunits
);
7369 rs6000_init_builtins (void)
7371 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
7372 V2SF_type_node
= build_vector_type (float_type_node
, 2);
7373 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
7374 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
7375 V4SF_type_node
= build_vector_type (float_type_node
, 4);
7376 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
7377 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
7379 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
7380 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
7381 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
7383 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
7384 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
7385 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
7386 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
7388 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
7389 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
7390 'vector unsigned short'. */
7392 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
7393 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
7394 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
7395 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
7397 long_integer_type_internal_node
= long_integer_type_node
;
7398 long_unsigned_type_internal_node
= long_unsigned_type_node
;
7399 intQI_type_internal_node
= intQI_type_node
;
7400 uintQI_type_internal_node
= unsigned_intQI_type_node
;
7401 intHI_type_internal_node
= intHI_type_node
;
7402 uintHI_type_internal_node
= unsigned_intHI_type_node
;
7403 intSI_type_internal_node
= intSI_type_node
;
7404 uintSI_type_internal_node
= unsigned_intSI_type_node
;
7405 float_type_internal_node
= float_type_node
;
7406 void_type_internal_node
= void_type_node
;
7408 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7409 get_identifier ("__bool char"),
7410 bool_char_type_node
));
7411 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7412 get_identifier ("__bool short"),
7413 bool_short_type_node
));
7414 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7415 get_identifier ("__bool int"),
7416 bool_int_type_node
));
7417 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7418 get_identifier ("__pixel"),
7421 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
7422 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
7423 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
7424 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
7426 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7427 get_identifier ("__vector unsigned char"),
7428 unsigned_V16QI_type_node
));
7429 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7430 get_identifier ("__vector signed char"),
7432 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7433 get_identifier ("__vector __bool char"),
7434 bool_V16QI_type_node
));
7436 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7437 get_identifier ("__vector unsigned short"),
7438 unsigned_V8HI_type_node
));
7439 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7440 get_identifier ("__vector signed short"),
7442 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7443 get_identifier ("__vector __bool short"),
7444 bool_V8HI_type_node
));
7446 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7447 get_identifier ("__vector unsigned int"),
7448 unsigned_V4SI_type_node
));
7449 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7450 get_identifier ("__vector signed int"),
7452 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7453 get_identifier ("__vector __bool int"),
7454 bool_V4SI_type_node
));
7456 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7457 get_identifier ("__vector float"),
7459 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7460 get_identifier ("__vector __pixel"),
7461 pixel_V8HI_type_node
));
7464 spe_init_builtins ();
7466 altivec_init_builtins ();
7467 if (TARGET_ALTIVEC
|| TARGET_SPE
)
7468 rs6000_common_init_builtins ();
7471 /* Search through a set of builtins and enable the mask bits.
7472 DESC is an array of builtins.
7473 SIZE is the total number of builtins.
7474 START is the builtin enum at which to start.
7475 END is the builtin enum at which to end. */
7477 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
7478 enum rs6000_builtins start
,
7479 enum rs6000_builtins end
)
7483 for (i
= 0; i
< size
; ++i
)
7484 if (desc
[i
].code
== start
)
7490 for (; i
< size
; ++i
)
7492 /* Flip all the bits on. */
7493 desc
[i
].mask
= target_flags
;
7494 if (desc
[i
].code
== end
)
7500 spe_init_builtins (void)
7502 tree endlink
= void_list_node
;
7503 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
7504 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
7505 struct builtin_description
*d
;
7508 tree v2si_ftype_4_v2si
7509 = build_function_type
7510 (opaque_V2SI_type_node
,
7511 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7512 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7513 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7514 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7517 tree v2sf_ftype_4_v2sf
7518 = build_function_type
7519 (opaque_V2SF_type_node
,
7520 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7521 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7522 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7523 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7526 tree int_ftype_int_v2si_v2si
7527 = build_function_type
7529 tree_cons (NULL_TREE
, integer_type_node
,
7530 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7531 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7534 tree int_ftype_int_v2sf_v2sf
7535 = build_function_type
7537 tree_cons (NULL_TREE
, integer_type_node
,
7538 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7539 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
7542 tree void_ftype_v2si_puint_int
7543 = build_function_type (void_type_node
,
7544 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7545 tree_cons (NULL_TREE
, puint_type_node
,
7546 tree_cons (NULL_TREE
,
7550 tree void_ftype_v2si_puint_char
7551 = build_function_type (void_type_node
,
7552 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7553 tree_cons (NULL_TREE
, puint_type_node
,
7554 tree_cons (NULL_TREE
,
7558 tree void_ftype_v2si_pv2si_int
7559 = build_function_type (void_type_node
,
7560 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7561 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
7562 tree_cons (NULL_TREE
,
7566 tree void_ftype_v2si_pv2si_char
7567 = build_function_type (void_type_node
,
7568 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7569 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
7570 tree_cons (NULL_TREE
,
7575 = build_function_type (void_type_node
,
7576 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
7579 = build_function_type (integer_type_node
, endlink
);
7581 tree v2si_ftype_pv2si_int
7582 = build_function_type (opaque_V2SI_type_node
,
7583 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
7584 tree_cons (NULL_TREE
, integer_type_node
,
7587 tree v2si_ftype_puint_int
7588 = build_function_type (opaque_V2SI_type_node
,
7589 tree_cons (NULL_TREE
, puint_type_node
,
7590 tree_cons (NULL_TREE
, integer_type_node
,
7593 tree v2si_ftype_pushort_int
7594 = build_function_type (opaque_V2SI_type_node
,
7595 tree_cons (NULL_TREE
, pushort_type_node
,
7596 tree_cons (NULL_TREE
, integer_type_node
,
7599 tree v2si_ftype_signed_char
7600 = build_function_type (opaque_V2SI_type_node
,
7601 tree_cons (NULL_TREE
, signed_char_type_node
,
7604 /* The initialization of the simple binary and unary builtins is
7605 done in rs6000_common_init_builtins, but we have to enable the
7606 mask bits here manually because we have run out of `target_flags'
7607 bits. We really need to redesign this mask business. */
7609 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
7610 ARRAY_SIZE (bdesc_2arg
),
7613 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
7614 ARRAY_SIZE (bdesc_1arg
),
7616 SPE_BUILTIN_EVSUBFUSIAAW
);
7617 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
7618 ARRAY_SIZE (bdesc_spe_predicates
),
7619 SPE_BUILTIN_EVCMPEQ
,
7620 SPE_BUILTIN_EVFSTSTLT
);
7621 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
7622 ARRAY_SIZE (bdesc_spe_evsel
),
7623 SPE_BUILTIN_EVSEL_CMPGTS
,
7624 SPE_BUILTIN_EVSEL_FSTSTEQ
);
7626 (*lang_hooks
.decls
.pushdecl
)
7627 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
7628 opaque_V2SI_type_node
));
7630 /* Initialize irregular SPE builtins. */
7632 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
7633 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
7634 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
7635 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
7636 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
7637 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
7638 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
7639 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
7640 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
7641 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
7642 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
7643 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
7644 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
7645 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
7646 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
7647 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
7648 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
7649 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
7652 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
7653 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
7654 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
7655 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
7656 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
7657 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
7658 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
7659 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
7660 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
7661 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
7662 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
7663 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
7664 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
7665 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
7666 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
7667 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
7668 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
7669 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
7670 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
7671 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
7672 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
7673 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
7676 d
= (struct builtin_description
*) bdesc_spe_predicates
;
7677 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
7681 switch (insn_data
[d
->icode
].operand
[1].mode
)
7684 type
= int_ftype_int_v2si_v2si
;
7687 type
= int_ftype_int_v2sf_v2sf
;
7693 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
7696 /* Evsel predicates. */
7697 d
= (struct builtin_description
*) bdesc_spe_evsel
;
7698 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
7702 switch (insn_data
[d
->icode
].operand
[1].mode
)
7705 type
= v2si_ftype_4_v2si
;
7708 type
= v2sf_ftype_4_v2sf
;
7714 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
7719 altivec_init_builtins (void)
7721 struct builtin_description
*d
;
7722 struct builtin_description_predicates
*dp
;
7724 tree pfloat_type_node
= build_pointer_type (float_type_node
);
7725 tree pint_type_node
= build_pointer_type (integer_type_node
);
7726 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
7727 tree pchar_type_node
= build_pointer_type (char_type_node
);
7729 tree pvoid_type_node
= build_pointer_type (void_type_node
);
7731 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
7732 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
7733 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
7734 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
7736 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
7738 tree int_ftype_opaque
7739 = build_function_type_list (integer_type_node
,
7740 opaque_V4SI_type_node
, NULL_TREE
);
7742 tree opaque_ftype_opaque_int
7743 = build_function_type_list (opaque_V4SI_type_node
,
7744 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
7745 tree opaque_ftype_opaque_opaque_int
7746 = build_function_type_list (opaque_V4SI_type_node
,
7747 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
7748 integer_type_node
, NULL_TREE
);
7749 tree int_ftype_int_opaque_opaque
7750 = build_function_type_list (integer_type_node
,
7751 integer_type_node
, opaque_V4SI_type_node
,
7752 opaque_V4SI_type_node
, NULL_TREE
);
7753 tree int_ftype_int_v4si_v4si
7754 = build_function_type_list (integer_type_node
,
7755 integer_type_node
, V4SI_type_node
,
7756 V4SI_type_node
, NULL_TREE
);
7757 tree v4sf_ftype_pcfloat
7758 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
7759 tree void_ftype_pfloat_v4sf
7760 = build_function_type_list (void_type_node
,
7761 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
7762 tree v4si_ftype_pcint
7763 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
7764 tree void_ftype_pint_v4si
7765 = build_function_type_list (void_type_node
,
7766 pint_type_node
, V4SI_type_node
, NULL_TREE
);
7767 tree v8hi_ftype_pcshort
7768 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
7769 tree void_ftype_pshort_v8hi
7770 = build_function_type_list (void_type_node
,
7771 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
7772 tree v16qi_ftype_pcchar
7773 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
7774 tree void_ftype_pchar_v16qi
7775 = build_function_type_list (void_type_node
,
7776 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
7777 tree void_ftype_v4si
7778 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
7779 tree v8hi_ftype_void
7780 = build_function_type (V8HI_type_node
, void_list_node
);
7781 tree void_ftype_void
7782 = build_function_type (void_type_node
, void_list_node
);
7784 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
7786 tree opaque_ftype_long_pcvoid
7787 = build_function_type_list (opaque_V4SI_type_node
,
7788 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
7789 tree v16qi_ftype_long_pcvoid
7790 = build_function_type_list (V16QI_type_node
,
7791 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
7792 tree v8hi_ftype_long_pcvoid
7793 = build_function_type_list (V8HI_type_node
,
7794 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
7795 tree v4si_ftype_long_pcvoid
7796 = build_function_type_list (V4SI_type_node
,
7797 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
7799 tree void_ftype_opaque_long_pvoid
7800 = build_function_type_list (void_type_node
,
7801 opaque_V4SI_type_node
, long_integer_type_node
,
7802 pvoid_type_node
, NULL_TREE
);
7803 tree void_ftype_v4si_long_pvoid
7804 = build_function_type_list (void_type_node
,
7805 V4SI_type_node
, long_integer_type_node
,
7806 pvoid_type_node
, NULL_TREE
);
7807 tree void_ftype_v16qi_long_pvoid
7808 = build_function_type_list (void_type_node
,
7809 V16QI_type_node
, long_integer_type_node
,
7810 pvoid_type_node
, NULL_TREE
);
7811 tree void_ftype_v8hi_long_pvoid
7812 = build_function_type_list (void_type_node
,
7813 V8HI_type_node
, long_integer_type_node
,
7814 pvoid_type_node
, NULL_TREE
);
7815 tree int_ftype_int_v8hi_v8hi
7816 = build_function_type_list (integer_type_node
,
7817 integer_type_node
, V8HI_type_node
,
7818 V8HI_type_node
, NULL_TREE
);
7819 tree int_ftype_int_v16qi_v16qi
7820 = build_function_type_list (integer_type_node
,
7821 integer_type_node
, V16QI_type_node
,
7822 V16QI_type_node
, NULL_TREE
);
7823 tree int_ftype_int_v4sf_v4sf
7824 = build_function_type_list (integer_type_node
,
7825 integer_type_node
, V4SF_type_node
,
7826 V4SF_type_node
, NULL_TREE
);
7827 tree v4si_ftype_v4si
7828 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
7829 tree v8hi_ftype_v8hi
7830 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
7831 tree v16qi_ftype_v16qi
7832 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
7833 tree v4sf_ftype_v4sf
7834 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
7835 tree void_ftype_pcvoid_int_int
7836 = build_function_type_list (void_type_node
,
7837 pcvoid_type_node
, integer_type_node
,
7838 integer_type_node
, NULL_TREE
);
7840 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
7841 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
7842 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
7843 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
7844 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
7845 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
7846 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
7847 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
7848 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
7849 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
7850 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
7851 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
7852 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
7853 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
7854 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
7855 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
7856 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
7857 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
7858 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
7859 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
7860 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
7861 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
7862 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
7863 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
7864 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
7865 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
7866 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
7867 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
7868 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
7869 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
7870 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
7871 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
7872 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
7873 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
7874 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
7875 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
7876 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
7877 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
7878 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
7879 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
7880 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
7881 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
7882 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
7883 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
7884 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
7885 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
7887 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
7889 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
7890 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
7891 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
7892 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
7893 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
7894 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
7895 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
7896 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
7897 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
7898 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
7900 /* Add the DST variants. */
7901 d
= (struct builtin_description
*) bdesc_dst
;
7902 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
7903 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
7905 /* Initialize the predicates. */
7906 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
7907 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
7909 enum machine_mode mode1
;
7911 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7912 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
7917 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
7922 type
= int_ftype_int_opaque_opaque
;
7925 type
= int_ftype_int_v4si_v4si
;
7928 type
= int_ftype_int_v8hi_v8hi
;
7931 type
= int_ftype_int_v16qi_v16qi
;
7934 type
= int_ftype_int_v4sf_v4sf
;
7940 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
7943 /* Initialize the abs* operators. */
7944 d
= (struct builtin_description
*) bdesc_abs
;
7945 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
7947 enum machine_mode mode0
;
7950 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
7955 type
= v4si_ftype_v4si
;
7958 type
= v8hi_ftype_v8hi
;
7961 type
= v16qi_ftype_v16qi
;
7964 type
= v4sf_ftype_v4sf
;
7970 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
7977 /* Initialize target builtin that implements
7978 targetm.vectorize.builtin_mask_for_load. */
7980 decl
= lang_hooks
.builtin_function ("__builtin_altivec_mask_for_load",
7981 v16qi_ftype_long_pcvoid
,
7982 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
7984 tree_cons (get_identifier ("const"),
7985 NULL_TREE
, NULL_TREE
));
7986 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
7987 altivec_builtin_mask_for_load
= decl
;
7992 rs6000_common_init_builtins (void)
7994 struct builtin_description
*d
;
7997 tree v4sf_ftype_v4sf_v4sf_v16qi
7998 = build_function_type_list (V4SF_type_node
,
7999 V4SF_type_node
, V4SF_type_node
,
8000 V16QI_type_node
, NULL_TREE
);
8001 tree v4si_ftype_v4si_v4si_v16qi
8002 = build_function_type_list (V4SI_type_node
,
8003 V4SI_type_node
, V4SI_type_node
,
8004 V16QI_type_node
, NULL_TREE
);
8005 tree v8hi_ftype_v8hi_v8hi_v16qi
8006 = build_function_type_list (V8HI_type_node
,
8007 V8HI_type_node
, V8HI_type_node
,
8008 V16QI_type_node
, NULL_TREE
);
8009 tree v16qi_ftype_v16qi_v16qi_v16qi
8010 = build_function_type_list (V16QI_type_node
,
8011 V16QI_type_node
, V16QI_type_node
,
8012 V16QI_type_node
, NULL_TREE
);
8014 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
8016 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
8017 tree v16qi_ftype_int
8018 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
8019 tree v8hi_ftype_v16qi
8020 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
8021 tree v4sf_ftype_v4sf
8022 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8024 tree v2si_ftype_v2si_v2si
8025 = build_function_type_list (opaque_V2SI_type_node
,
8026 opaque_V2SI_type_node
,
8027 opaque_V2SI_type_node
, NULL_TREE
);
8029 tree v2sf_ftype_v2sf_v2sf
8030 = build_function_type_list (opaque_V2SF_type_node
,
8031 opaque_V2SF_type_node
,
8032 opaque_V2SF_type_node
, NULL_TREE
);
8034 tree v2si_ftype_int_int
8035 = build_function_type_list (opaque_V2SI_type_node
,
8036 integer_type_node
, integer_type_node
,
8039 tree opaque_ftype_opaque
8040 = build_function_type_list (opaque_V4SI_type_node
,
8041 opaque_V4SI_type_node
, NULL_TREE
);
8043 tree v2si_ftype_v2si
8044 = build_function_type_list (opaque_V2SI_type_node
,
8045 opaque_V2SI_type_node
, NULL_TREE
);
8047 tree v2sf_ftype_v2sf
8048 = build_function_type_list (opaque_V2SF_type_node
,
8049 opaque_V2SF_type_node
, NULL_TREE
);
8051 tree v2sf_ftype_v2si
8052 = build_function_type_list (opaque_V2SF_type_node
,
8053 opaque_V2SI_type_node
, NULL_TREE
);
8055 tree v2si_ftype_v2sf
8056 = build_function_type_list (opaque_V2SI_type_node
,
8057 opaque_V2SF_type_node
, NULL_TREE
);
8059 tree v2si_ftype_v2si_char
8060 = build_function_type_list (opaque_V2SI_type_node
,
8061 opaque_V2SI_type_node
,
8062 char_type_node
, NULL_TREE
);
8064 tree v2si_ftype_int_char
8065 = build_function_type_list (opaque_V2SI_type_node
,
8066 integer_type_node
, char_type_node
, NULL_TREE
);
8068 tree v2si_ftype_char
8069 = build_function_type_list (opaque_V2SI_type_node
,
8070 char_type_node
, NULL_TREE
);
8072 tree int_ftype_int_int
8073 = build_function_type_list (integer_type_node
,
8074 integer_type_node
, integer_type_node
,
8077 tree opaque_ftype_opaque_opaque
8078 = build_function_type_list (opaque_V4SI_type_node
,
8079 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
8080 tree v4si_ftype_v4si_v4si
8081 = build_function_type_list (V4SI_type_node
,
8082 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8083 tree v4sf_ftype_v4si_int
8084 = build_function_type_list (V4SF_type_node
,
8085 V4SI_type_node
, integer_type_node
, NULL_TREE
);
8086 tree v4si_ftype_v4sf_int
8087 = build_function_type_list (V4SI_type_node
,
8088 V4SF_type_node
, integer_type_node
, NULL_TREE
);
8089 tree v4si_ftype_v4si_int
8090 = build_function_type_list (V4SI_type_node
,
8091 V4SI_type_node
, integer_type_node
, NULL_TREE
);
8092 tree v8hi_ftype_v8hi_int
8093 = build_function_type_list (V8HI_type_node
,
8094 V8HI_type_node
, integer_type_node
, NULL_TREE
);
8095 tree v16qi_ftype_v16qi_int
8096 = build_function_type_list (V16QI_type_node
,
8097 V16QI_type_node
, integer_type_node
, NULL_TREE
);
8098 tree v16qi_ftype_v16qi_v16qi_int
8099 = build_function_type_list (V16QI_type_node
,
8100 V16QI_type_node
, V16QI_type_node
,
8101 integer_type_node
, NULL_TREE
);
8102 tree v8hi_ftype_v8hi_v8hi_int
8103 = build_function_type_list (V8HI_type_node
,
8104 V8HI_type_node
, V8HI_type_node
,
8105 integer_type_node
, NULL_TREE
);
8106 tree v4si_ftype_v4si_v4si_int
8107 = build_function_type_list (V4SI_type_node
,
8108 V4SI_type_node
, V4SI_type_node
,
8109 integer_type_node
, NULL_TREE
);
8110 tree v4sf_ftype_v4sf_v4sf_int
8111 = build_function_type_list (V4SF_type_node
,
8112 V4SF_type_node
, V4SF_type_node
,
8113 integer_type_node
, NULL_TREE
);
8114 tree v4sf_ftype_v4sf_v4sf
8115 = build_function_type_list (V4SF_type_node
,
8116 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8117 tree opaque_ftype_opaque_opaque_opaque
8118 = build_function_type_list (opaque_V4SI_type_node
,
8119 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
8120 opaque_V4SI_type_node
, NULL_TREE
);
8121 tree v4sf_ftype_v4sf_v4sf_v4si
8122 = build_function_type_list (V4SF_type_node
,
8123 V4SF_type_node
, V4SF_type_node
,
8124 V4SI_type_node
, NULL_TREE
);
8125 tree v4sf_ftype_v4sf_v4sf_v4sf
8126 = build_function_type_list (V4SF_type_node
,
8127 V4SF_type_node
, V4SF_type_node
,
8128 V4SF_type_node
, NULL_TREE
);
8129 tree v4si_ftype_v4si_v4si_v4si
8130 = build_function_type_list (V4SI_type_node
,
8131 V4SI_type_node
, V4SI_type_node
,
8132 V4SI_type_node
, NULL_TREE
);
8133 tree v8hi_ftype_v8hi_v8hi
8134 = build_function_type_list (V8HI_type_node
,
8135 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8136 tree v8hi_ftype_v8hi_v8hi_v8hi
8137 = build_function_type_list (V8HI_type_node
,
8138 V8HI_type_node
, V8HI_type_node
,
8139 V8HI_type_node
, NULL_TREE
);
8140 tree v4si_ftype_v8hi_v8hi_v4si
8141 = build_function_type_list (V4SI_type_node
,
8142 V8HI_type_node
, V8HI_type_node
,
8143 V4SI_type_node
, NULL_TREE
);
8144 tree v4si_ftype_v16qi_v16qi_v4si
8145 = build_function_type_list (V4SI_type_node
,
8146 V16QI_type_node
, V16QI_type_node
,
8147 V4SI_type_node
, NULL_TREE
);
8148 tree v16qi_ftype_v16qi_v16qi
8149 = build_function_type_list (V16QI_type_node
,
8150 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8151 tree v4si_ftype_v4sf_v4sf
8152 = build_function_type_list (V4SI_type_node
,
8153 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8154 tree v8hi_ftype_v16qi_v16qi
8155 = build_function_type_list (V8HI_type_node
,
8156 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8157 tree v4si_ftype_v8hi_v8hi
8158 = build_function_type_list (V4SI_type_node
,
8159 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8160 tree v8hi_ftype_v4si_v4si
8161 = build_function_type_list (V8HI_type_node
,
8162 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8163 tree v16qi_ftype_v8hi_v8hi
8164 = build_function_type_list (V16QI_type_node
,
8165 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8166 tree v4si_ftype_v16qi_v4si
8167 = build_function_type_list (V4SI_type_node
,
8168 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
8169 tree v4si_ftype_v16qi_v16qi
8170 = build_function_type_list (V4SI_type_node
,
8171 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8172 tree v4si_ftype_v8hi_v4si
8173 = build_function_type_list (V4SI_type_node
,
8174 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
8175 tree v4si_ftype_v8hi
8176 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
8177 tree int_ftype_v4si_v4si
8178 = build_function_type_list (integer_type_node
,
8179 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8180 tree int_ftype_v4sf_v4sf
8181 = build_function_type_list (integer_type_node
,
8182 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8183 tree int_ftype_v16qi_v16qi
8184 = build_function_type_list (integer_type_node
,
8185 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8186 tree int_ftype_v8hi_v8hi
8187 = build_function_type_list (integer_type_node
,
8188 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8190 /* Add the simple ternary operators. */
8191 d
= (struct builtin_description
*) bdesc_3arg
;
8192 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
8194 enum machine_mode mode0
, mode1
, mode2
, mode3
;
8196 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8197 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8208 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8211 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8212 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8213 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8214 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
8217 /* When all four are of the same mode. */
8218 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
8223 type
= opaque_ftype_opaque_opaque_opaque
;
8226 type
= v4si_ftype_v4si_v4si_v4si
;
8229 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
8232 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
8235 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
8241 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
8246 type
= v4si_ftype_v4si_v4si_v16qi
;
8249 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
8252 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
8255 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
8261 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
8262 && mode3
== V4SImode
)
8263 type
= v4si_ftype_v16qi_v16qi_v4si
;
8264 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
8265 && mode3
== V4SImode
)
8266 type
= v4si_ftype_v8hi_v8hi_v4si
;
8267 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
8268 && mode3
== V4SImode
)
8269 type
= v4sf_ftype_v4sf_v4sf_v4si
;
8271 /* vchar, vchar, vchar, 4 bit literal. */
8272 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
8274 type
= v16qi_ftype_v16qi_v16qi_int
;
8276 /* vshort, vshort, vshort, 4 bit literal. */
8277 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
8279 type
= v8hi_ftype_v8hi_v8hi_int
;
8281 /* vint, vint, vint, 4 bit literal. */
8282 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
8284 type
= v4si_ftype_v4si_v4si_int
;
8286 /* vfloat, vfloat, vfloat, 4 bit literal. */
8287 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
8289 type
= v4sf_ftype_v4sf_v4sf_int
;
8294 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8297 /* Add the simple binary operators. */
8298 d
= (struct builtin_description
*) bdesc_2arg
;
8299 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
8301 enum machine_mode mode0
, mode1
, mode2
;
8303 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8304 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8314 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8317 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8318 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8319 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8322 /* When all three operands are of the same mode. */
8323 if (mode0
== mode1
&& mode1
== mode2
)
8328 type
= opaque_ftype_opaque_opaque
;
8331 type
= v4sf_ftype_v4sf_v4sf
;
8334 type
= v4si_ftype_v4si_v4si
;
8337 type
= v16qi_ftype_v16qi_v16qi
;
8340 type
= v8hi_ftype_v8hi_v8hi
;
8343 type
= v2si_ftype_v2si_v2si
;
8346 type
= v2sf_ftype_v2sf_v2sf
;
8349 type
= int_ftype_int_int
;
8356 /* A few other combos we really don't want to do manually. */
8358 /* vint, vfloat, vfloat. */
8359 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
8360 type
= v4si_ftype_v4sf_v4sf
;
8362 /* vshort, vchar, vchar. */
8363 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
8364 type
= v8hi_ftype_v16qi_v16qi
;
8366 /* vint, vshort, vshort. */
8367 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
8368 type
= v4si_ftype_v8hi_v8hi
;
8370 /* vshort, vint, vint. */
8371 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
8372 type
= v8hi_ftype_v4si_v4si
;
8374 /* vchar, vshort, vshort. */
8375 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
8376 type
= v16qi_ftype_v8hi_v8hi
;
8378 /* vint, vchar, vint. */
8379 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
8380 type
= v4si_ftype_v16qi_v4si
;
8382 /* vint, vchar, vchar. */
8383 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
8384 type
= v4si_ftype_v16qi_v16qi
;
8386 /* vint, vshort, vint. */
8387 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
8388 type
= v4si_ftype_v8hi_v4si
;
8390 /* vint, vint, 5 bit literal. */
8391 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
8392 type
= v4si_ftype_v4si_int
;
8394 /* vshort, vshort, 5 bit literal. */
8395 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
8396 type
= v8hi_ftype_v8hi_int
;
8398 /* vchar, vchar, 5 bit literal. */
8399 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
8400 type
= v16qi_ftype_v16qi_int
;
8402 /* vfloat, vint, 5 bit literal. */
8403 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
8404 type
= v4sf_ftype_v4si_int
;
8406 /* vint, vfloat, 5 bit literal. */
8407 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
8408 type
= v4si_ftype_v4sf_int
;
8410 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
8411 type
= v2si_ftype_int_int
;
8413 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
8414 type
= v2si_ftype_v2si_char
;
8416 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
8417 type
= v2si_ftype_int_char
;
8422 gcc_assert (mode0
== SImode
);
8426 type
= int_ftype_v4si_v4si
;
8429 type
= int_ftype_v4sf_v4sf
;
8432 type
= int_ftype_v16qi_v16qi
;
8435 type
= int_ftype_v8hi_v8hi
;
8442 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8445 /* Add the simple unary operators. */
8446 d
= (struct builtin_description
*) bdesc_1arg
;
8447 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
8449 enum machine_mode mode0
, mode1
;
8451 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8452 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8461 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8464 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8465 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8468 if (mode0
== V4SImode
&& mode1
== QImode
)
8469 type
= v4si_ftype_int
;
8470 else if (mode0
== V8HImode
&& mode1
== QImode
)
8471 type
= v8hi_ftype_int
;
8472 else if (mode0
== V16QImode
&& mode1
== QImode
)
8473 type
= v16qi_ftype_int
;
8474 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
8475 type
= opaque_ftype_opaque
;
8476 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
8477 type
= v4sf_ftype_v4sf
;
8478 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
8479 type
= v8hi_ftype_v16qi
;
8480 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
8481 type
= v4si_ftype_v8hi
;
8482 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
8483 type
= v2si_ftype_v2si
;
8484 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
8485 type
= v2sf_ftype_v2sf
;
8486 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
8487 type
= v2sf_ftype_v2si
;
8488 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
8489 type
= v2si_ftype_v2sf
;
8490 else if (mode0
== V2SImode
&& mode1
== QImode
)
8491 type
= v2si_ftype_char
;
8495 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8500 rs6000_init_libfuncs (void)
8502 if (!TARGET_HARD_FLOAT
)
8505 if (DEFAULT_ABI
!= ABI_V4
)
8507 if (TARGET_XCOFF
&& ! TARGET_POWER2
&& ! TARGET_POWERPC
)
8509 /* AIX library routines for float->int conversion. */
8510 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
8511 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
8512 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
8513 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
8516 /* AIX/Darwin/64-bit Linux quad floating point routines. */
8517 if (!TARGET_XL_COMPAT
)
8519 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
8520 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
8521 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
8522 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
8526 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
8527 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
8528 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
8529 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
8534 /* 32-bit SVR4 quad floating point routines. */
8536 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
8537 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
8538 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
8539 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
8540 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
8541 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
8542 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
8544 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
8545 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
8546 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
8547 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
8548 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
8549 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
8551 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
8552 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
8553 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
8554 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
8555 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
8556 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
8557 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
8562 /* Expand a block clear operation, and return 1 if successful. Return 0
8563 if we should let the compiler generate normal code.
8565 operands[0] is the destination
8566 operands[1] is the length
8567 operands[2] is the alignment */
8570 expand_block_clear (rtx operands
[])
8572 rtx orig_dest
= operands
[0];
8573 rtx bytes_rtx
= operands
[1];
8574 rtx align_rtx
= operands
[2];
8575 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
8576 HOST_WIDE_INT align
;
8577 HOST_WIDE_INT bytes
;
8582 /* If this is not a fixed size move, just call memcpy */
8586 /* This must be a fixed size alignment */
8587 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
8588 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
8590 /* Anything to clear? */
8591 bytes
= INTVAL (bytes_rtx
);
8595 /* Use the builtin memset after a point, to avoid huge code bloat.
8596 When optimize_size, avoid any significant code bloat; calling
8597 memset is about 4 instructions, so allow for one instruction to
8598 load zero and three to do clearing. */
8599 if (TARGET_ALTIVEC
&& align
>= 128)
8601 else if (TARGET_POWERPC64
&& align
>= 32)
8606 if (optimize_size
&& bytes
> 3 * clear_step
)
8608 if (! optimize_size
&& bytes
> 8 * clear_step
)
8611 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
8613 enum machine_mode mode
= BLKmode
;
8616 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
8621 else if (bytes
>= 8 && TARGET_POWERPC64
8622 /* 64-bit loads and stores require word-aligned
8624 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
8629 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
8630 { /* move 4 bytes */
8634 else if (bytes
== 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
8635 { /* move 2 bytes */
8639 else /* move 1 byte at a time */
8645 dest
= adjust_address (orig_dest
, mode
, offset
);
8647 emit_move_insn (dest
, CONST0_RTX (mode
));
8654 /* Expand a block move operation, and return 1 if successful. Return 0
8655 if we should let the compiler generate normal code.
8657 operands[0] is the destination
8658 operands[1] is the source
8659 operands[2] is the length
8660 operands[3] is the alignment */
8662 #define MAX_MOVE_REG 4
8665 expand_block_move (rtx operands
[])
8667 rtx orig_dest
= operands
[0];
8668 rtx orig_src
= operands
[1];
8669 rtx bytes_rtx
= operands
[2];
8670 rtx align_rtx
= operands
[3];
8671 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
8676 rtx stores
[MAX_MOVE_REG
];
8679 /* If this is not a fixed size move, just call memcpy */
8683 /* This must be a fixed size alignment */
8684 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
8685 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
8687 /* Anything to move? */
8688 bytes
= INTVAL (bytes_rtx
);
8692 /* store_one_arg depends on expand_block_move to handle at least the size of
8693 reg_parm_stack_space. */
8694 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
8697 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
8700 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
8701 rtx (*mov
) (rtx
, rtx
);
8703 enum machine_mode mode
= BLKmode
;
8706 /* Altivec first, since it will be faster than a string move
8707 when it applies, and usually not significantly larger. */
8708 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
8712 gen_func
.mov
= gen_movv4si
;
8714 else if (TARGET_STRING
8715 && bytes
> 24 /* move up to 32 bytes at a time */
8723 && ! fixed_regs
[12])
8725 move_bytes
= (bytes
> 32) ? 32 : bytes
;
8726 gen_func
.movmemsi
= gen_movmemsi_8reg
;
8728 else if (TARGET_STRING
8729 && bytes
> 16 /* move up to 24 bytes at a time */
8735 && ! fixed_regs
[10])
8737 move_bytes
= (bytes
> 24) ? 24 : bytes
;
8738 gen_func
.movmemsi
= gen_movmemsi_6reg
;
8740 else if (TARGET_STRING
8741 && bytes
> 8 /* move up to 16 bytes at a time */
8747 move_bytes
= (bytes
> 16) ? 16 : bytes
;
8748 gen_func
.movmemsi
= gen_movmemsi_4reg
;
8750 else if (bytes
>= 8 && TARGET_POWERPC64
8751 /* 64-bit loads and stores require word-aligned
8753 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
8757 gen_func
.mov
= gen_movdi
;
8759 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
8760 { /* move up to 8 bytes at a time */
8761 move_bytes
= (bytes
> 8) ? 8 : bytes
;
8762 gen_func
.movmemsi
= gen_movmemsi_2reg
;
8764 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
8765 { /* move 4 bytes */
8768 gen_func
.mov
= gen_movsi
;
8770 else if (bytes
== 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
8771 { /* move 2 bytes */
8774 gen_func
.mov
= gen_movhi
;
8776 else if (TARGET_STRING
&& bytes
> 1)
8777 { /* move up to 4 bytes at a time */
8778 move_bytes
= (bytes
> 4) ? 4 : bytes
;
8779 gen_func
.movmemsi
= gen_movmemsi_1reg
;
8781 else /* move 1 byte at a time */
8785 gen_func
.mov
= gen_movqi
;
8788 src
= adjust_address (orig_src
, mode
, offset
);
8789 dest
= adjust_address (orig_dest
, mode
, offset
);
8791 if (mode
!= BLKmode
)
8793 rtx tmp_reg
= gen_reg_rtx (mode
);
8795 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
8796 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
8799 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
8802 for (i
= 0; i
< num_reg
; i
++)
8803 emit_insn (stores
[i
]);
8807 if (mode
== BLKmode
)
8809 /* Move the address into scratch registers. The movmemsi
8810 patterns require zero offset. */
8811 if (!REG_P (XEXP (src
, 0)))
8813 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
8814 src
= replace_equiv_address (src
, src_reg
);
8816 set_mem_size (src
, GEN_INT (move_bytes
));
8818 if (!REG_P (XEXP (dest
, 0)))
8820 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
8821 dest
= replace_equiv_address (dest
, dest_reg
);
8823 set_mem_size (dest
, GEN_INT (move_bytes
));
8825 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
8826 GEN_INT (move_bytes
& 31),
8835 /* Return a string to perform a load_multiple operation.
8836 operands[0] is the vector.
8837 operands[1] is the source address.
8838 operands[2] is the first destination register. */
8841 rs6000_output_load_multiple (rtx operands
[3])
8843 /* We have to handle the case where the pseudo used to contain the address
8844 is assigned to one of the output registers. */
8846 int words
= XVECLEN (operands
[0], 0);
8849 if (XVECLEN (operands
[0], 0) == 1)
8850 return "{l|lwz} %2,0(%1)";
8852 for (i
= 0; i
< words
; i
++)
8853 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
8854 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
8858 xop
[0] = GEN_INT (4 * (words
-1));
8859 xop
[1] = operands
[1];
8860 xop
[2] = operands
[2];
8861 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
8866 xop
[0] = GEN_INT (4 * (words
-1));
8867 xop
[1] = operands
[1];
8868 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
8869 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
);
8874 for (j
= 0; j
< words
; j
++)
8877 xop
[0] = GEN_INT (j
* 4);
8878 xop
[1] = operands
[1];
8879 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
8880 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
8882 xop
[0] = GEN_INT (i
* 4);
8883 xop
[1] = operands
[1];
8884 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
8889 return "{lsi|lswi} %2,%1,%N0";
8893 /* A validation routine: say whether CODE, a condition code, and MODE
8894 match. The other alternatives either don't make sense or should
8895 never be generated. */
8898 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
8900 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
8901 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
8902 && GET_MODE_CLASS (mode
) == MODE_CC
);
8904 /* These don't make sense. */
8905 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
8906 || mode
!= CCUNSmode
);
8908 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
8909 || mode
== CCUNSmode
);
8911 gcc_assert (mode
== CCFPmode
8912 || (code
!= ORDERED
&& code
!= UNORDERED
8913 && code
!= UNEQ
&& code
!= LTGT
8914 && code
!= UNGT
&& code
!= UNLT
8915 && code
!= UNGE
&& code
!= UNLE
));
8917 /* These should never be generated except for
8918 flag_finite_math_only. */
8919 gcc_assert (mode
!= CCFPmode
8920 || flag_finite_math_only
8921 || (code
!= LE
&& code
!= GE
8922 && code
!= UNEQ
&& code
!= LTGT
8923 && code
!= UNGT
&& code
!= UNLT
));
8925 /* These are invalid; the information is not there. */
8926 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
8930 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
8931 mask required to convert the result of a rotate insn into a shift
8932 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
8935 includes_lshift_p (rtx shiftop
, rtx andop
)
8937 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
8939 shift_mask
<<= INTVAL (shiftop
);
8941 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
8944 /* Similar, but for right shift. */
8947 includes_rshift_p (rtx shiftop
, rtx andop
)
8949 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
8951 shift_mask
>>= INTVAL (shiftop
);
8953 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
8956 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
8957 to perform a left shift. It must have exactly SHIFTOP least
8958 significant 0's, then one or more 1's, then zero or more 0's. */
8961 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
8963 if (GET_CODE (andop
) == CONST_INT
)
8965 HOST_WIDE_INT c
, lsb
, shift_mask
;
8968 if (c
== 0 || c
== ~0)
8972 shift_mask
<<= INTVAL (shiftop
);
8974 /* Find the least significant one bit. */
8977 /* It must coincide with the LSB of the shift mask. */
8978 if (-lsb
!= shift_mask
)
8981 /* Invert to look for the next transition (if any). */
8984 /* Remove the low group of ones (originally low group of zeros). */
8987 /* Again find the lsb, and check we have all 1's above. */
8991 else if (GET_CODE (andop
) == CONST_DOUBLE
8992 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
8994 HOST_WIDE_INT low
, high
, lsb
;
8995 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
8997 low
= CONST_DOUBLE_LOW (andop
);
8998 if (HOST_BITS_PER_WIDE_INT
< 64)
8999 high
= CONST_DOUBLE_HIGH (andop
);
9001 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
9002 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
9005 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
9007 shift_mask_high
= ~0;
9008 if (INTVAL (shiftop
) > 32)
9009 shift_mask_high
<<= INTVAL (shiftop
) - 32;
9013 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
9020 return high
== -lsb
;
9023 shift_mask_low
= ~0;
9024 shift_mask_low
<<= INTVAL (shiftop
);
9028 if (-lsb
!= shift_mask_low
)
9031 if (HOST_BITS_PER_WIDE_INT
< 64)
9036 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
9039 return high
== -lsb
;
9043 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
9049 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9050 to perform a left shift. It must have SHIFTOP or more least
9051 significant 0's, with the remainder of the word 1's. */
9054 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
9056 if (GET_CODE (andop
) == CONST_INT
)
9058 HOST_WIDE_INT c
, lsb
, shift_mask
;
9061 shift_mask
<<= INTVAL (shiftop
);
9064 /* Find the least significant one bit. */
9067 /* It must be covered by the shift mask.
9068 This test also rejects c == 0. */
9069 if ((lsb
& shift_mask
) == 0)
9072 /* Check we have all 1's above the transition, and reject all 1's. */
9073 return c
== -lsb
&& lsb
!= 1;
9075 else if (GET_CODE (andop
) == CONST_DOUBLE
9076 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
9078 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
9080 low
= CONST_DOUBLE_LOW (andop
);
9082 if (HOST_BITS_PER_WIDE_INT
< 64)
9084 HOST_WIDE_INT high
, shift_mask_high
;
9086 high
= CONST_DOUBLE_HIGH (andop
);
9090 shift_mask_high
= ~0;
9091 if (INTVAL (shiftop
) > 32)
9092 shift_mask_high
<<= INTVAL (shiftop
) - 32;
9096 if ((lsb
& shift_mask_high
) == 0)
9099 return high
== -lsb
;
9105 shift_mask_low
= ~0;
9106 shift_mask_low
<<= INTVAL (shiftop
);
9110 if ((lsb
& shift_mask_low
) == 0)
9113 return low
== -lsb
&& lsb
!= 1;
9119 /* Return 1 if operands will generate a valid arguments to rlwimi
9120 instruction for insert with right shift in 64-bit mode. The mask may
9121 not start on the first bit or stop on the last bit because wrap-around
9122 effects of instruction do not correspond to semantics of RTL insn. */
9125 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
9127 if (INTVAL (startop
) < 64
9128 && INTVAL (startop
) > 32
9129 && (INTVAL (sizeop
) + INTVAL (startop
) < 64)
9130 && (INTVAL (sizeop
) + INTVAL (startop
) > 33)
9131 && (INTVAL (sizeop
) + INTVAL (startop
) + INTVAL (shiftop
) < 96)
9132 && (INTVAL (sizeop
) + INTVAL (startop
) + INTVAL (shiftop
) >= 64)
9133 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
9139 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
9140 for lfq and stfq insns iff the registers are hard registers. */
9143 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
9145 /* We might have been passed a SUBREG. */
9146 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
9149 /* We might have been passed non floating point registers. */
9150 if (!FP_REGNO_P (REGNO (reg1
))
9151 || !FP_REGNO_P (REGNO (reg2
)))
9154 return (REGNO (reg1
) == REGNO (reg2
) - 1);
9157 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
9158 addr1 and addr2 must be in consecutive memory locations
9159 (addr2 == addr1 + 8). */
9162 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
9168 /* The mems cannot be volatile. */
9169 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
9172 addr1
= XEXP (mem1
, 0);
9173 addr2
= XEXP (mem2
, 0);
9175 /* Extract an offset (if used) from the first addr. */
9176 if (GET_CODE (addr1
) == PLUS
)
9178 /* If not a REG, return zero. */
9179 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
9183 reg1
= REGNO (XEXP (addr1
, 0));
9184 /* The offset must be constant! */
9185 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
9187 offset1
= INTVAL (XEXP (addr1
, 1));
9190 else if (GET_CODE (addr1
) != REG
)
9194 reg1
= REGNO (addr1
);
9195 /* This was a simple (mem (reg)) expression. Offset is 0. */
9199 /* Make sure the second address is a (mem (plus (reg) (const_int)))
9200 or if it is (mem (reg)) then make sure that offset1 is -8 and the same
9201 register as addr1. */
9202 if (offset1
== -8 && GET_CODE (addr2
) == REG
&& reg1
== REGNO (addr2
))
9204 if (GET_CODE (addr2
) != PLUS
)
9207 if (GET_CODE (XEXP (addr2
, 0)) != REG
9208 || GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
9211 if (reg1
!= REGNO (XEXP (addr2
, 0)))
9214 /* The offset for the second addr must be 8 more than the first addr. */
9215 if (INTVAL (XEXP (addr2
, 1)) != offset1
+ 8)
9218 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
9223 /* Return the register class of a scratch register needed to copy IN into
9224 or out of a register in CLASS in MODE. If it can be done directly,
9225 NO_REGS is returned. */
9228 secondary_reload_class (enum reg_class
class,
9229 enum machine_mode mode ATTRIBUTE_UNUSED
,
9234 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
9236 && MACHOPIC_INDIRECT
9240 /* We cannot copy a symbolic operand directly into anything
9241 other than BASE_REGS for TARGET_ELF. So indicate that a
9242 register from BASE_REGS is needed as an intermediate
9245 On Darwin, pic addresses require a load from memory, which
9246 needs a base register. */
9247 if (class != BASE_REGS
9248 && (GET_CODE (in
) == SYMBOL_REF
9249 || GET_CODE (in
) == HIGH
9250 || GET_CODE (in
) == LABEL_REF
9251 || GET_CODE (in
) == CONST
))
9255 if (GET_CODE (in
) == REG
)
9258 if (regno
>= FIRST_PSEUDO_REGISTER
)
9260 regno
= true_regnum (in
);
9261 if (regno
>= FIRST_PSEUDO_REGISTER
)
9265 else if (GET_CODE (in
) == SUBREG
)
9267 regno
= true_regnum (in
);
9268 if (regno
>= FIRST_PSEUDO_REGISTER
)
9274 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
9276 if (class == GENERAL_REGS
|| class == BASE_REGS
9277 || (regno
>= 0 && INT_REGNO_P (regno
)))
9280 /* Constants, memory, and FP registers can go into FP registers. */
9281 if ((regno
== -1 || FP_REGNO_P (regno
))
9282 && (class == FLOAT_REGS
|| class == NON_SPECIAL_REGS
))
9285 /* Memory, and AltiVec registers can go into AltiVec registers. */
9286 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
9287 && class == ALTIVEC_REGS
)
9290 /* We can copy among the CR registers. */
9291 if ((class == CR_REGS
|| class == CR0_REGS
)
9292 && regno
>= 0 && CR_REGNO_P (regno
))
9295 /* Otherwise, we need GENERAL_REGS. */
9296 return GENERAL_REGS
;
9299 /* Given a comparison operation, return the bit number in CCR to test. We
9300 know this is a valid comparison.
9302 SCC_P is 1 if this is for an scc. That means that %D will have been
9303 used instead of %C, so the bits will be in different places.
9305 Return -1 if OP isn't a valid comparison for some reason. */
9308 ccr_bit (rtx op
, int scc_p
)
9310 enum rtx_code code
= GET_CODE (op
);
9311 enum machine_mode cc_mode
;
9316 if (!COMPARISON_P (op
))
9321 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
9323 cc_mode
= GET_MODE (reg
);
9324 cc_regnum
= REGNO (reg
);
9325 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
9327 validate_condition_mode (code
, cc_mode
);
9329 /* When generating a sCOND operation, only positive conditions are
9332 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
9333 || code
== GTU
|| code
== LTU
);
9338 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
9340 return base_bit
+ 2;
9341 case GT
: case GTU
: case UNLE
:
9342 return base_bit
+ 1;
9343 case LT
: case LTU
: case UNGE
:
9345 case ORDERED
: case UNORDERED
:
9346 return base_bit
+ 3;
9349 /* If scc, we will have done a cror to put the bit in the
9350 unordered position. So test that bit. For integer, this is ! LT
9351 unless this is an scc insn. */
9352 return scc_p
? base_bit
+ 3 : base_bit
;
9355 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
9362 /* Return the GOT register. */
9365 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
9367 /* The second flow pass currently (June 1999) can't update
9368 regs_ever_live without disturbing other parts of the compiler, so
9369 update it here to make the prolog/epilogue code happy. */
9370 if (no_new_pseudos
&& ! regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
])
9371 regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
9373 current_function_uses_pic_offset_table
= 1;
9375 return pic_offset_table_rtx
;
9378 /* Function to init struct machine_function.
9379 This will be called, via a pointer variable,
9380 from push_function_context. */
9382 static struct machine_function
*
9383 rs6000_init_machine_status (void)
9385 return ggc_alloc_cleared (sizeof (machine_function
));
9388 /* These macros test for integers and extract the low-order bits. */
9390 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
9391 && GET_MODE (X) == VOIDmode)
9393 #define INT_LOWPART(X) \
9394 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
9400 unsigned long val
= INT_LOWPART (op
);
9402 /* If the high bit is zero, the value is the first 1 bit we find
9404 if ((val
& 0x80000000) == 0)
9406 gcc_assert (val
& 0xffffffff);
9409 while (((val
<<= 1) & 0x80000000) == 0)
9414 /* If the high bit is set and the low bit is not, or the mask is all
9415 1's, the value is zero. */
9416 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
9419 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
9422 while (((val
>>= 1) & 1) != 0)
9432 unsigned long val
= INT_LOWPART (op
);
9434 /* If the low bit is zero, the value is the first 1 bit we find from
9438 gcc_assert (val
& 0xffffffff);
9441 while (((val
>>= 1) & 1) == 0)
9447 /* If the low bit is set and the high bit is not, or the mask is all
9448 1's, the value is 31. */
9449 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
9452 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
9455 while (((val
<<= 1) & 0x80000000) != 0)
9461 /* Locate some local-dynamic symbol still in use by this function
9462 so that we can print its name in some tls_ld pattern. */
9465 rs6000_get_some_local_dynamic_name (void)
9469 if (cfun
->machine
->some_ld_name
)
9470 return cfun
->machine
->some_ld_name
;
9472 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9474 && for_each_rtx (&PATTERN (insn
),
9475 rs6000_get_some_local_dynamic_name_1
, 0))
9476 return cfun
->machine
->some_ld_name
;
9481 /* Helper function for rs6000_get_some_local_dynamic_name. */
9484 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
9488 if (GET_CODE (x
) == SYMBOL_REF
)
9490 const char *str
= XSTR (x
, 0);
9491 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
9493 cfun
->machine
->some_ld_name
= str
;
9501 /* Write out a function code label. */
9504 rs6000_output_function_entry (FILE *file
, const char *fname
)
9506 if (fname
[0] != '.')
9508 switch (DEFAULT_ABI
)
9517 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
9526 RS6000_OUTPUT_BASENAME (file
, fname
);
9528 assemble_name (file
, fname
);
9531 /* Print an operand. Recognize special options, documented below. */
9534 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
9535 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
9537 #define SMALL_DATA_RELOC "sda21"
9538 #define SMALL_DATA_REG 0
9542 print_operand (FILE *file
, rtx x
, int code
)
9546 unsigned HOST_WIDE_INT uval
;
9551 /* Write out an instruction after the call which may be replaced
9552 with glue code by the loader. This depends on the AIX version. */
9553 asm_fprintf (file
, RS6000_CALL_GLUE
);
9556 /* %a is output_address. */
9559 /* If X is a constant integer whose low-order 5 bits are zero,
9560 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
9561 in the AIX assembler where "sri" with a zero shift count
9562 writes a trash instruction. */
9563 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
9570 /* If constant, low-order 16 bits of constant, unsigned.
9571 Otherwise, write normally. */
9573 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
9575 print_operand (file
, x
, 0);
9579 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
9580 for 64-bit mask direction. */
9581 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
9584 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
9588 /* X is a CR register. Print the number of the GT bit of the CR. */
9589 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
9590 output_operand_lossage ("invalid %%E value");
9592 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
9596 /* Like 'J' but get to the EQ bit. */
9597 gcc_assert (GET_CODE (x
) == REG
);
9599 /* Bit 1 is EQ bit. */
9600 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 2;
9602 fprintf (file
, "%d", i
);
9606 /* X is a CR register. Print the number of the EQ bit of the CR */
9607 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
9608 output_operand_lossage ("invalid %%E value");
9610 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
9614 /* X is a CR register. Print the shift count needed to move it
9615 to the high-order four bits. */
9616 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
9617 output_operand_lossage ("invalid %%f value");
9619 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
9623 /* Similar, but print the count for the rotate in the opposite
9625 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
9626 output_operand_lossage ("invalid %%F value");
9628 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
9632 /* X is a constant integer. If it is negative, print "m",
9633 otherwise print "z". This is to make an aze or ame insn. */
9634 if (GET_CODE (x
) != CONST_INT
)
9635 output_operand_lossage ("invalid %%G value");
9636 else if (INTVAL (x
) >= 0)
9643 /* If constant, output low-order five bits. Otherwise, write
9646 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
9648 print_operand (file
, x
, 0);
9652 /* If constant, output low-order six bits. Otherwise, write
9655 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
9657 print_operand (file
, x
, 0);
9661 /* Print `i' if this is a constant, else nothing. */
9667 /* Write the bit number in CCR for jump. */
9670 output_operand_lossage ("invalid %%j code");
9672 fprintf (file
, "%d", i
);
9676 /* Similar, but add one for shift count in rlinm for scc and pass
9677 scc flag to `ccr_bit'. */
9680 output_operand_lossage ("invalid %%J code");
9682 /* If we want bit 31, write a shift count of zero, not 32. */
9683 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
9687 /* X must be a constant. Write the 1's complement of the
9690 output_operand_lossage ("invalid %%k value");
9692 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
9696 /* X must be a symbolic constant on ELF. Write an
9697 expression suitable for an 'addi' that adds in the low 16
9699 if (GET_CODE (x
) != CONST
)
9701 print_operand_address (file
, x
);
9706 if (GET_CODE (XEXP (x
, 0)) != PLUS
9707 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
9708 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
9709 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
9710 output_operand_lossage ("invalid %%K value");
9711 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
9713 /* For GNU as, there must be a non-alphanumeric character
9714 between 'l' and the number. The '-' is added by
9715 print_operand() already. */
9716 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
9718 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
9722 /* %l is output_asm_label. */
9725 /* Write second word of DImode or DFmode reference. Works on register
9726 or non-indexed memory only. */
9727 if (GET_CODE (x
) == REG
)
9728 fputs (reg_names
[REGNO (x
) + 1], file
);
9729 else if (GET_CODE (x
) == MEM
)
9731 /* Handle possible auto-increment. Since it is pre-increment and
9732 we have already done it, we can just use an offset of word. */
9733 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
9734 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
9735 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
9738 output_address (XEXP (adjust_address_nv (x
, SImode
,
9742 if (small_data_operand (x
, GET_MODE (x
)))
9743 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
9744 reg_names
[SMALL_DATA_REG
]);
9749 /* MB value for a mask operand. */
9750 if (! mask_operand (x
, SImode
))
9751 output_operand_lossage ("invalid %%m value");
9753 fprintf (file
, "%d", extract_MB (x
));
9757 /* ME value for a mask operand. */
9758 if (! mask_operand (x
, SImode
))
9759 output_operand_lossage ("invalid %%M value");
9761 fprintf (file
, "%d", extract_ME (x
));
9764 /* %n outputs the negative of its operand. */
9767 /* Write the number of elements in the vector times 4. */
9768 if (GET_CODE (x
) != PARALLEL
)
9769 output_operand_lossage ("invalid %%N value");
9771 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
9775 /* Similar, but subtract 1 first. */
9776 if (GET_CODE (x
) != PARALLEL
)
9777 output_operand_lossage ("invalid %%O value");
9779 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
9783 /* X is a CONST_INT that is a power of two. Output the logarithm. */
9785 || INT_LOWPART (x
) < 0
9786 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
9787 output_operand_lossage ("invalid %%p value");
9789 fprintf (file
, "%d", i
);
9793 /* The operand must be an indirect memory reference. The result
9794 is the register name. */
9795 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
9796 || REGNO (XEXP (x
, 0)) >= 32)
9797 output_operand_lossage ("invalid %%P value");
9799 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
9803 /* This outputs the logical code corresponding to a boolean
9804 expression. The expression may have one or both operands
9805 negated (if one, only the first one). For condition register
9806 logical operations, it will also treat the negated
9807 CR codes as NOTs, but not handle NOTs of them. */
9809 const char *const *t
= 0;
9811 enum rtx_code code
= GET_CODE (x
);
9812 static const char * const tbl
[3][3] = {
9813 { "and", "andc", "nor" },
9814 { "or", "orc", "nand" },
9815 { "xor", "eqv", "xor" } };
9819 else if (code
== IOR
)
9821 else if (code
== XOR
)
9824 output_operand_lossage ("invalid %%q value");
9826 if (GET_CODE (XEXP (x
, 0)) != NOT
)
9830 if (GET_CODE (XEXP (x
, 1)) == NOT
)
9848 /* X is a CR register. Print the mask for `mtcrf'. */
9849 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
9850 output_operand_lossage ("invalid %%R value");
9852 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
9856 /* Low 5 bits of 32 - value */
9858 output_operand_lossage ("invalid %%s value");
9860 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
9864 /* PowerPC64 mask position. All 0's is excluded.
9865 CONST_INT 32-bit mask is considered sign-extended so any
9866 transition must occur within the CONST_INT, not on the boundary. */
9867 if (! mask64_operand (x
, DImode
))
9868 output_operand_lossage ("invalid %%S value");
9870 uval
= INT_LOWPART (x
);
9872 if (uval
& 1) /* Clear Left */
9874 #if HOST_BITS_PER_WIDE_INT > 64
9875 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
9879 else /* Clear Right */
9882 #if HOST_BITS_PER_WIDE_INT > 64
9883 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
9889 gcc_assert (i
>= 0);
9890 fprintf (file
, "%d", i
);
9894 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
9895 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
9897 /* Bit 3 is OV bit. */
9898 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
9900 /* If we want bit 31, write a shift count of zero, not 32. */
9901 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
9905 /* Print the symbolic name of a branch target register. */
9906 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LINK_REGISTER_REGNUM
9907 && REGNO (x
) != COUNT_REGISTER_REGNUM
))
9908 output_operand_lossage ("invalid %%T value");
9909 else if (REGNO (x
) == LINK_REGISTER_REGNUM
)
9910 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
9912 fputs ("ctr", file
);
9916 /* High-order 16 bits of constant for use in unsigned operand. */
9918 output_operand_lossage ("invalid %%u value");
9920 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
9921 (INT_LOWPART (x
) >> 16) & 0xffff);
9925 /* High-order 16 bits of constant for use in signed operand. */
9927 output_operand_lossage ("invalid %%v value");
9929 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
9930 (INT_LOWPART (x
) >> 16) & 0xffff);
9934 /* Print `u' if this has an auto-increment or auto-decrement. */
9935 if (GET_CODE (x
) == MEM
9936 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
9937 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
))
9942 /* Print the trap code for this operand. */
9943 switch (GET_CODE (x
))
9946 fputs ("eq", file
); /* 4 */
9949 fputs ("ne", file
); /* 24 */
9952 fputs ("lt", file
); /* 16 */
9955 fputs ("le", file
); /* 20 */
9958 fputs ("gt", file
); /* 8 */
9961 fputs ("ge", file
); /* 12 */
9964 fputs ("llt", file
); /* 2 */
9967 fputs ("lle", file
); /* 6 */
9970 fputs ("lgt", file
); /* 1 */
9973 fputs ("lge", file
); /* 5 */
9981 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
9984 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
9985 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
9987 print_operand (file
, x
, 0);
9991 /* MB value for a PowerPC64 rldic operand. */
9992 val
= (GET_CODE (x
) == CONST_INT
9993 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
9998 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
9999 if ((val
<<= 1) < 0)
10002 #if HOST_BITS_PER_WIDE_INT == 32
10003 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
10004 i
+= 32; /* zero-extend high-part was all 0's */
10005 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
10007 val
= CONST_DOUBLE_LOW (x
);
10013 for ( ; i
< 64; i
++)
10014 if ((val
<<= 1) < 0)
10019 fprintf (file
, "%d", i
+ 1);
10023 if (GET_CODE (x
) == MEM
10024 && legitimate_indexed_address_p (XEXP (x
, 0), 0))
10029 /* Like 'L', for third word of TImode */
10030 if (GET_CODE (x
) == REG
)
10031 fputs (reg_names
[REGNO (x
) + 2], file
);
10032 else if (GET_CODE (x
) == MEM
)
10034 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10035 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10036 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
10038 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
10039 if (small_data_operand (x
, GET_MODE (x
)))
10040 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10041 reg_names
[SMALL_DATA_REG
]);
10046 /* X is a SYMBOL_REF. Write out the name preceded by a
10047 period and without any trailing data in brackets. Used for function
10048 names. If we are configured for System V (or the embedded ABI) on
10049 the PowerPC, do not emit the period, since those systems do not use
10050 TOCs and the like. */
10051 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
10053 /* Mark the decl as referenced so that cgraph will output the
10055 if (SYMBOL_REF_DECL (x
))
10056 mark_decl_referenced (SYMBOL_REF_DECL (x
));
10058 /* For macho, check to see if we need a stub. */
10061 const char *name
= XSTR (x
, 0);
10063 if (MACHOPIC_INDIRECT
10064 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
10065 name
= machopic_indirection_name (x
, /*stub_p=*/true);
10067 assemble_name (file
, name
);
10069 else if (!DOT_SYMBOLS
)
10070 assemble_name (file
, XSTR (x
, 0));
10072 rs6000_output_function_entry (file
, XSTR (x
, 0));
10076 /* Like 'L', for last word of TImode. */
10077 if (GET_CODE (x
) == REG
)
10078 fputs (reg_names
[REGNO (x
) + 3], file
);
10079 else if (GET_CODE (x
) == MEM
)
10081 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10082 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10083 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
10085 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
10086 if (small_data_operand (x
, GET_MODE (x
)))
10087 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10088 reg_names
[SMALL_DATA_REG
]);
10092 /* Print AltiVec or SPE memory operand. */
10097 gcc_assert (GET_CODE (x
) == MEM
);
10103 /* Handle [reg]. */
10104 if (GET_CODE (tmp
) == REG
)
10106 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
10109 /* Handle [reg+UIMM]. */
10110 else if (GET_CODE (tmp
) == PLUS
&&
10111 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
10115 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
10117 x
= INTVAL (XEXP (tmp
, 1));
10118 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
10122 /* Fall through. Must be [reg+reg]. */
10125 && GET_CODE (tmp
) == AND
10126 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
10127 && INTVAL (XEXP (tmp
, 1)) == -16)
10128 tmp
= XEXP (tmp
, 0);
10129 if (GET_CODE (tmp
) == REG
)
10130 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
10133 gcc_assert (GET_CODE (tmp
) == PLUS
10134 && GET_CODE (XEXP (tmp
, 1)) == REG
);
10136 if (REGNO (XEXP (tmp
, 0)) == 0)
10137 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
10138 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
10140 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
10141 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
10147 if (GET_CODE (x
) == REG
)
10148 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
10149 else if (GET_CODE (x
) == MEM
)
10151 /* We need to handle PRE_INC and PRE_DEC here, since we need to
10152 know the width from the mode. */
10153 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
10154 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
10155 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
10156 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10157 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
10158 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
10160 output_address (XEXP (x
, 0));
10163 output_addr_const (file
, x
);
10167 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
10171 output_operand_lossage ("invalid %%xn code");
10175 /* Print the address of an operand. */
10178 print_operand_address (FILE *file
, rtx x
)
10180 if (GET_CODE (x
) == REG
)
10181 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
10182 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
10183 || GET_CODE (x
) == LABEL_REF
)
10185 output_addr_const (file
, x
);
10186 if (small_data_operand (x
, GET_MODE (x
)))
10187 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10188 reg_names
[SMALL_DATA_REG
]);
10190 gcc_assert (!TARGET_TOC
);
10192 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
10194 if (REGNO (XEXP (x
, 0)) == 0)
10195 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
10196 reg_names
[ REGNO (XEXP (x
, 0)) ]);
10198 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
10199 reg_names
[ REGNO (XEXP (x
, 1)) ]);
10201 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
10202 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
10203 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
10205 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
10206 && CONSTANT_P (XEXP (x
, 1)))
10208 output_addr_const (file
, XEXP (x
, 1));
10209 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
10213 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
10214 && CONSTANT_P (XEXP (x
, 1)))
10216 fprintf (file
, "lo16(");
10217 output_addr_const (file
, XEXP (x
, 1));
10218 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
10221 else if (legitimate_constant_pool_address_p (x
))
10223 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
10225 rtx contains_minus
= XEXP (x
, 1);
10229 /* Find the (minus (sym) (toc)) buried in X, and temporarily
10230 turn it into (sym) for output_addr_const. */
10231 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
10232 contains_minus
= XEXP (contains_minus
, 0);
10234 minus
= XEXP (contains_minus
, 0);
10235 symref
= XEXP (minus
, 0);
10236 XEXP (contains_minus
, 0) = symref
;
10241 name
= XSTR (symref
, 0);
10242 newname
= alloca (strlen (name
) + sizeof ("@toc"));
10243 strcpy (newname
, name
);
10244 strcat (newname
, "@toc");
10245 XSTR (symref
, 0) = newname
;
10247 output_addr_const (file
, XEXP (x
, 1));
10249 XSTR (symref
, 0) = name
;
10250 XEXP (contains_minus
, 0) = minus
;
10253 output_addr_const (file
, XEXP (x
, 1));
10255 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
10258 gcc_unreachable ();
10261 /* Target hook for assembling integer objects. The PowerPC version has
10262 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
10263 is defined. It also needs to handle DI-mode objects on 64-bit
10267 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
10269 #ifdef RELOCATABLE_NEEDS_FIXUP
10270 /* Special handling for SI values. */
10271 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
10273 extern int in_toc_section (void);
10274 static int recurse
= 0;
10276 /* For -mrelocatable, we mark all addresses that need to be fixed up
10277 in the .fixup section. */
10278 if (TARGET_RELOCATABLE
10279 && !in_toc_section ()
10280 && !in_text_section ()
10281 && !in_unlikely_text_section ()
10283 && GET_CODE (x
) != CONST_INT
10284 && GET_CODE (x
) != CONST_DOUBLE
10290 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
10292 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
10293 fprintf (asm_out_file
, "\t.long\t(");
10294 output_addr_const (asm_out_file
, x
);
10295 fprintf (asm_out_file
, ")@fixup\n");
10296 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
10297 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
10298 fprintf (asm_out_file
, "\t.long\t");
10299 assemble_name (asm_out_file
, buf
);
10300 fprintf (asm_out_file
, "\n\t.previous\n");
10304 /* Remove initial .'s to turn a -mcall-aixdesc function
10305 address into the address of the descriptor, not the function
10307 else if (GET_CODE (x
) == SYMBOL_REF
10308 && XSTR (x
, 0)[0] == '.'
10309 && DEFAULT_ABI
== ABI_AIX
)
10311 const char *name
= XSTR (x
, 0);
10312 while (*name
== '.')
10315 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
10319 #endif /* RELOCATABLE_NEEDS_FIXUP */
10320 return default_assemble_integer (x
, size
, aligned_p
);
10323 #ifdef HAVE_GAS_HIDDEN
10324 /* Emit an assembler directive to set symbol visibility for DECL to
10325 VISIBILITY_TYPE. */
10328 rs6000_assemble_visibility (tree decl
, int vis
)
10330 /* Functions need to have their entry point symbol visibility set as
10331 well as their descriptor symbol visibility. */
10332 if (DEFAULT_ABI
== ABI_AIX
10334 && TREE_CODE (decl
) == FUNCTION_DECL
)
10336 static const char * const visibility_types
[] = {
10337 NULL
, "internal", "hidden", "protected"
10340 const char *name
, *type
;
10342 name
= ((* targetm
.strip_name_encoding
)
10343 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
10344 type
= visibility_types
[vis
];
10346 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
10347 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
10350 default_assemble_visibility (decl
, vis
);
10355 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
10357 /* Reversal of FP compares takes care -- an ordered compare
10358 becomes an unordered compare and vice versa. */
10359 if (mode
== CCFPmode
10360 && (!flag_finite_math_only
10361 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
10362 || code
== UNEQ
|| code
== LTGT
))
10363 return reverse_condition_maybe_unordered (code
);
10365 return reverse_condition (code
);
10368 /* Generate a compare for CODE. Return a brand-new rtx that
10369 represents the result of the compare. */
10372 rs6000_generate_compare (enum rtx_code code
)
10374 enum machine_mode comp_mode
;
10375 rtx compare_result
;
10377 if (rs6000_compare_fp_p
)
10378 comp_mode
= CCFPmode
;
10379 else if (code
== GTU
|| code
== LTU
10380 || code
== GEU
|| code
== LEU
)
10381 comp_mode
= CCUNSmode
;
10382 else if ((code
== EQ
|| code
== NE
)
10383 && GET_CODE (rs6000_compare_op0
) == SUBREG
10384 && GET_CODE (rs6000_compare_op1
) == SUBREG
10385 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
10386 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
10387 /* These are unsigned values, perhaps there will be a later
10388 ordering compare that can be shared with this one.
10389 Unfortunately we cannot detect the signedness of the operands
10390 for non-subregs. */
10391 comp_mode
= CCUNSmode
;
10393 comp_mode
= CCmode
;
10395 /* First, the compare. */
10396 compare_result
= gen_reg_rtx (comp_mode
);
10398 /* SPE FP compare instructions on the GPRs. Yuck! */
10399 if ((TARGET_E500
&& !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
10400 && rs6000_compare_fp_p
)
10402 rtx cmp
, or_result
, compare_result2
;
10403 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
10405 if (op_mode
== VOIDmode
)
10406 op_mode
= GET_MODE (rs6000_compare_op1
);
10408 /* Note: The E500 comparison instructions set the GT bit (x +
10409 1), on success. This explains the mess. */
10413 case EQ
: case UNEQ
: case NE
: case LTGT
:
10417 cmp
= flag_unsafe_math_optimizations
10418 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
10419 rs6000_compare_op1
)
10420 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
10421 rs6000_compare_op1
);
10425 cmp
= flag_unsafe_math_optimizations
10426 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
10427 rs6000_compare_op1
)
10428 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
10429 rs6000_compare_op1
);
10433 gcc_unreachable ();
10437 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
10441 cmp
= flag_unsafe_math_optimizations
10442 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
10443 rs6000_compare_op1
)
10444 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
10445 rs6000_compare_op1
);
10449 cmp
= flag_unsafe_math_optimizations
10450 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
10451 rs6000_compare_op1
)
10452 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
10453 rs6000_compare_op1
);
10457 gcc_unreachable ();
10461 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
10465 cmp
= flag_unsafe_math_optimizations
10466 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
10467 rs6000_compare_op1
)
10468 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
10469 rs6000_compare_op1
);
10473 cmp
= flag_unsafe_math_optimizations
10474 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
10475 rs6000_compare_op1
)
10476 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
10477 rs6000_compare_op1
);
10481 gcc_unreachable ();
10485 gcc_unreachable ();
10488 /* Synthesize LE and GE from LT/GT || EQ. */
10489 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
10495 case LE
: code
= LT
; break;
10496 case GE
: code
= GT
; break;
10497 case LEU
: code
= LT
; break;
10498 case GEU
: code
= GT
; break;
10499 default: gcc_unreachable ();
10502 compare_result2
= gen_reg_rtx (CCFPmode
);
10508 cmp
= flag_unsafe_math_optimizations
10509 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
10510 rs6000_compare_op1
)
10511 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
10512 rs6000_compare_op1
);
10516 cmp
= flag_unsafe_math_optimizations
10517 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
10518 rs6000_compare_op1
)
10519 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
10520 rs6000_compare_op1
);
10524 gcc_unreachable ();
10528 /* OR them together. */
10529 or_result
= gen_reg_rtx (CCFPmode
);
10530 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
10532 compare_result
= or_result
;
10537 if (code
== NE
|| code
== LTGT
)
10547 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
10548 CLOBBERs to match cmptf_internal2 pattern. */
10549 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
10550 && GET_MODE (rs6000_compare_op0
) == TFmode
10551 && (DEFAULT_ABI
== ABI_AIX
|| DEFAULT_ABI
== ABI_DARWIN
)
10552 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
10553 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
10555 gen_rtx_SET (VOIDmode
,
10557 gen_rtx_COMPARE (comp_mode
,
10558 rs6000_compare_op0
,
10559 rs6000_compare_op1
)),
10560 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
10561 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
10562 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
10563 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
10564 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
10565 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
10566 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
10567 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
10569 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
10570 gen_rtx_COMPARE (comp_mode
,
10571 rs6000_compare_op0
,
10572 rs6000_compare_op1
)));
10575 /* Some kinds of FP comparisons need an OR operation;
10576 under flag_finite_math_only we don't bother. */
10577 if (rs6000_compare_fp_p
10578 && !flag_finite_math_only
10579 && !(TARGET_HARD_FLOAT
&& TARGET_E500
&& !TARGET_FPRS
)
10580 && (code
== LE
|| code
== GE
10581 || code
== UNEQ
|| code
== LTGT
10582 || code
== UNGT
|| code
== UNLT
))
10584 enum rtx_code or1
, or2
;
10585 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
10586 rtx or_result
= gen_reg_rtx (CCEQmode
);
10590 case LE
: or1
= LT
; or2
= EQ
; break;
10591 case GE
: or1
= GT
; or2
= EQ
; break;
10592 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
10593 case LTGT
: or1
= LT
; or2
= GT
; break;
10594 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
10595 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
10596 default: gcc_unreachable ();
10598 validate_condition_mode (or1
, comp_mode
);
10599 validate_condition_mode (or2
, comp_mode
);
10600 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
10601 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
10602 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
10603 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
10605 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
10607 compare_result
= or_result
;
10611 validate_condition_mode (code
, GET_MODE (compare_result
));
10613 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
10617 /* Emit the RTL for an sCOND pattern. */
10620 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
10623 enum machine_mode op_mode
;
10624 enum rtx_code cond_code
;
10626 condition_rtx
= rs6000_generate_compare (code
);
10627 cond_code
= GET_CODE (condition_rtx
);
10629 if (TARGET_E500
&& rs6000_compare_fp_p
10630 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
10634 PUT_MODE (condition_rtx
, SImode
);
10635 t
= XEXP (condition_rtx
, 0);
10637 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
10639 if (cond_code
== NE
)
10640 emit_insn (gen_e500_flip_gt_bit (t
, t
));
10642 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
10646 if (cond_code
== NE
10647 || cond_code
== GE
|| cond_code
== LE
10648 || cond_code
== GEU
|| cond_code
== LEU
10649 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
10651 rtx not_result
= gen_reg_rtx (CCEQmode
);
10652 rtx not_op
, rev_cond_rtx
;
10653 enum machine_mode cc_mode
;
10655 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
10657 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
10658 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
10659 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
10660 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
10661 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
10664 op_mode
= GET_MODE (rs6000_compare_op0
);
10665 if (op_mode
== VOIDmode
)
10666 op_mode
= GET_MODE (rs6000_compare_op1
);
10668 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
10670 PUT_MODE (condition_rtx
, DImode
);
10671 convert_move (result
, condition_rtx
, 0);
10675 PUT_MODE (condition_rtx
, SImode
);
10676 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
10680 /* Emit a branch of kind CODE to location LOC. */
10683 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
10685 rtx condition_rtx
, loc_ref
;
10687 condition_rtx
= rs6000_generate_compare (code
);
10688 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
10689 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
10690 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
10691 loc_ref
, pc_rtx
)));
10694 /* Return the string to output a conditional branch to LABEL, which is
10695 the operand number of the label, or -1 if the branch is really a
10696 conditional return.
10698 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
10699 condition code register and its mode specifies what kind of
10700 comparison we made.
10702 REVERSED is nonzero if we should reverse the sense of the comparison.
10704 INSN is the insn. */
10707 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
10709 static char string
[64];
10710 enum rtx_code code
= GET_CODE (op
);
10711 rtx cc_reg
= XEXP (op
, 0);
10712 enum machine_mode mode
= GET_MODE (cc_reg
);
10713 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
10714 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
10715 int really_reversed
= reversed
^ need_longbranch
;
10721 validate_condition_mode (code
, mode
);
10723 /* Work out which way this really branches. We could use
10724 reverse_condition_maybe_unordered here always but this
10725 makes the resulting assembler clearer. */
10726 if (really_reversed
)
10728 /* Reversal of FP compares takes care -- an ordered compare
10729 becomes an unordered compare and vice versa. */
10730 if (mode
== CCFPmode
)
10731 code
= reverse_condition_maybe_unordered (code
);
10733 code
= reverse_condition (code
);
10736 if ((TARGET_E500
&& !TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
10738 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
10743 /* Opposite of GT. */
10752 gcc_unreachable ();
10758 /* Not all of these are actually distinct opcodes, but
10759 we distinguish them for clarity of the resulting assembler. */
10760 case NE
: case LTGT
:
10761 ccode
= "ne"; break;
10762 case EQ
: case UNEQ
:
10763 ccode
= "eq"; break;
10765 ccode
= "ge"; break;
10766 case GT
: case GTU
: case UNGT
:
10767 ccode
= "gt"; break;
10769 ccode
= "le"; break;
10770 case LT
: case LTU
: case UNLT
:
10771 ccode
= "lt"; break;
10772 case UNORDERED
: ccode
= "un"; break;
10773 case ORDERED
: ccode
= "nu"; break;
10774 case UNGE
: ccode
= "nl"; break;
10775 case UNLE
: ccode
= "ng"; break;
10777 gcc_unreachable ();
10780 /* Maybe we have a guess as to how likely the branch is.
10781 The old mnemonics don't have a way to specify this information. */
10783 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
10784 if (note
!= NULL_RTX
)
10786 /* PROB is the difference from 50%. */
10787 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
10789 /* Only hint for highly probable/improbable branches on newer
10790 cpus as static prediction overrides processor dynamic
10791 prediction. For older cpus we may as well always hint, but
10792 assume not taken for branches that are very close to 50% as a
10793 mispredicted taken branch is more expensive than a
10794 mispredicted not-taken branch. */
10795 if (rs6000_always_hint
10796 || abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48)
10798 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
10799 && ((prob
> 0) ^ need_longbranch
))
10807 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
10809 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
10811 /* We need to escape any '%' characters in the reg_names string.
10812 Assume they'd only be the first character.... */
10813 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
10815 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
10819 /* If the branch distance was too far, we may have to use an
10820 unconditional branch to go the distance. */
10821 if (need_longbranch
)
10822 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
10824 s
+= sprintf (s
, ",%s", label
);
10830 /* Return the string to flip the GT bit on a CR. */
10832 output_e500_flip_gt_bit (rtx dst
, rtx src
)
10834 static char string
[64];
10837 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
10838 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
10841 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
10842 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
10844 sprintf (string
, "crnot %d,%d", a
, b
);
10848 /* Return insn index for the vector compare instruction for given CODE,
10849 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
10853 get_vec_cmp_insn (enum rtx_code code
,
10854 enum machine_mode dest_mode
,
10855 enum machine_mode op_mode
)
10857 if (!TARGET_ALTIVEC
)
10858 return INSN_NOT_AVAILABLE
;
10863 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
10864 return UNSPEC_VCMPEQUB
;
10865 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
10866 return UNSPEC_VCMPEQUH
;
10867 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
10868 return UNSPEC_VCMPEQUW
;
10869 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
10870 return UNSPEC_VCMPEQFP
;
10873 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
10874 return UNSPEC_VCMPGEFP
;
10876 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
10877 return UNSPEC_VCMPGTSB
;
10878 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
10879 return UNSPEC_VCMPGTSH
;
10880 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
10881 return UNSPEC_VCMPGTSW
;
10882 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
10883 return UNSPEC_VCMPGTFP
;
10886 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
10887 return UNSPEC_VCMPGTUB
;
10888 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
10889 return UNSPEC_VCMPGTUH
;
10890 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
10891 return UNSPEC_VCMPGTUW
;
10896 return INSN_NOT_AVAILABLE
;
10899 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
10900 DMODE is expected destination mode. This is a recursive function. */
10903 rs6000_emit_vector_compare (enum rtx_code rcode
,
10905 enum machine_mode dmode
)
10909 enum machine_mode dest_mode
;
10910 enum machine_mode op_mode
= GET_MODE (op1
);
10912 gcc_assert (TARGET_ALTIVEC
);
10913 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
10915 /* Floating point vector compare instructions uses destination V4SImode.
10916 Move destination to appropriate mode later. */
10917 if (dmode
== V4SFmode
)
10918 dest_mode
= V4SImode
;
10922 mask
= gen_reg_rtx (dest_mode
);
10923 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
10925 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
10927 bool swap_operands
= false;
10928 bool try_again
= false;
10933 swap_operands
= true;
10938 swap_operands
= true;
10942 /* Treat A != B as ~(A==B). */
10944 enum insn_code nor_code
;
10945 rtx eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
10948 nor_code
= one_cmpl_optab
->handlers
[(int)dest_mode
].insn_code
;
10949 gcc_assert (nor_code
!= CODE_FOR_nothing
);
10950 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
10952 if (dmode
!= dest_mode
)
10954 rtx temp
= gen_reg_rtx (dest_mode
);
10955 convert_move (temp
, mask
, 0);
10965 /* Try GT/GTU/LT/LTU OR EQ */
10968 enum insn_code ior_code
;
10969 enum rtx_code new_code
;
10990 gcc_unreachable ();
10993 c_rtx
= rs6000_emit_vector_compare (new_code
,
10994 op0
, op1
, dest_mode
);
10995 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
10998 ior_code
= ior_optab
->handlers
[(int)dest_mode
].insn_code
;
10999 gcc_assert (ior_code
!= CODE_FOR_nothing
);
11000 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
11001 if (dmode
!= dest_mode
)
11003 rtx temp
= gen_reg_rtx (dest_mode
);
11004 convert_move (temp
, mask
, 0);
11011 gcc_unreachable ();
11016 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
11017 /* You only get two chances. */
11018 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
11030 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
11031 gen_rtx_UNSPEC (dest_mode
,
11032 gen_rtvec (2, op0
, op1
),
11034 if (dmode
!= dest_mode
)
11036 rtx temp
= gen_reg_rtx (dest_mode
);
11037 convert_move (temp
, mask
, 0);
11043 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
11044 valid insn doesn exist for given mode. */
11047 get_vsel_insn (enum machine_mode mode
)
11052 return UNSPEC_VSEL4SI
;
11055 return UNSPEC_VSEL4SF
;
11058 return UNSPEC_VSEL8HI
;
11061 return UNSPEC_VSEL16QI
;
11064 return INSN_NOT_AVAILABLE
;
11067 return INSN_NOT_AVAILABLE
;
11070 /* Emit vector select insn where DEST is destination using
11071 operands OP1, OP2 and MASK. */
11074 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
11077 enum machine_mode dest_mode
= GET_MODE (dest
);
11078 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
11080 temp
= gen_reg_rtx (dest_mode
);
11082 /* For each vector element, select op1 when mask is 1 otherwise
11084 t
= gen_rtx_SET (VOIDmode
, temp
,
11085 gen_rtx_UNSPEC (dest_mode
,
11086 gen_rtvec (3, op2
, op1
, mask
),
11089 emit_move_insn (dest
, temp
);
11093 /* Emit vector conditional expression.
11094 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
11095 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
11098 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
11099 rtx cond
, rtx cc_op0
, rtx cc_op1
)
11101 enum machine_mode dest_mode
= GET_MODE (dest
);
11102 enum rtx_code rcode
= GET_CODE (cond
);
11105 if (!TARGET_ALTIVEC
)
11108 /* Get the vector mask for the given relational operations. */
11109 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
11111 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
11116 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
11117 operands of the last comparison is nonzero/true, FALSE_COND if it
11118 is zero/false. Return 0 if the hardware has no such operation. */
11121 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
11123 enum rtx_code code
= GET_CODE (op
);
11124 rtx op0
= rs6000_compare_op0
;
11125 rtx op1
= rs6000_compare_op1
;
11126 REAL_VALUE_TYPE c1
;
11127 enum machine_mode compare_mode
= GET_MODE (op0
);
11128 enum machine_mode result_mode
= GET_MODE (dest
);
11130 bool is_against_zero
;
11132 /* These modes should always match. */
11133 if (GET_MODE (op1
) != compare_mode
11134 /* In the isel case however, we can use a compare immediate, so
11135 op1 may be a small constant. */
11136 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
11138 if (GET_MODE (true_cond
) != result_mode
)
11140 if (GET_MODE (false_cond
) != result_mode
)
11143 /* First, work out if the hardware can do this at all, or
11144 if it's too slow.... */
11145 if (! rs6000_compare_fp_p
)
11148 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
11151 else if (TARGET_E500
&& TARGET_HARD_FLOAT
&& !TARGET_FPRS
11152 && GET_MODE_CLASS (compare_mode
) == MODE_FLOAT
)
11155 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
11157 /* A floating-point subtract might overflow, underflow, or produce
11158 an inexact result, thus changing the floating-point flags, so it
11159 can't be generated if we care about that. It's safe if one side
11160 of the construct is zero, since then no subtract will be
11162 if (GET_MODE_CLASS (compare_mode
) == MODE_FLOAT
11163 && flag_trapping_math
&& ! is_against_zero
)
11166 /* Eliminate half of the comparisons by switching operands, this
11167 makes the remaining code simpler. */
11168 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
11169 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
11171 code
= reverse_condition_maybe_unordered (code
);
11173 true_cond
= false_cond
;
11177 /* UNEQ and LTGT take four instructions for a comparison with zero,
11178 it'll probably be faster to use a branch here too. */
11179 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
11182 if (GET_CODE (op1
) == CONST_DOUBLE
)
11183 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
11185 /* We're going to try to implement comparisons by performing
11186 a subtract, then comparing against zero. Unfortunately,
11187 Inf - Inf is NaN which is not zero, and so if we don't
11188 know that the operand is finite and the comparison
11189 would treat EQ different to UNORDERED, we can't do it. */
11190 if (HONOR_INFINITIES (compare_mode
)
11191 && code
!= GT
&& code
!= UNGE
11192 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
11193 /* Constructs of the form (a OP b ? a : b) are safe. */
11194 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
11195 || (! rtx_equal_p (op0
, true_cond
)
11196 && ! rtx_equal_p (op1
, true_cond
))))
11199 /* At this point we know we can use fsel. */
11201 /* Reduce the comparison to a comparison against zero. */
11202 if (! is_against_zero
)
11204 temp
= gen_reg_rtx (compare_mode
);
11205 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11206 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
11208 op1
= CONST0_RTX (compare_mode
);
11211 /* If we don't care about NaNs we can reduce some of the comparisons
11212 down to faster ones. */
11213 if (! HONOR_NANS (compare_mode
))
11219 true_cond
= false_cond
;
11232 /* Now, reduce everything down to a GE. */
11239 temp
= gen_reg_rtx (compare_mode
);
11240 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11245 temp
= gen_reg_rtx (compare_mode
);
11246 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
11251 temp
= gen_reg_rtx (compare_mode
);
11252 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11253 gen_rtx_NEG (compare_mode
,
11254 gen_rtx_ABS (compare_mode
, op0
))));
11259 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
11260 temp
= gen_reg_rtx (result_mode
);
11261 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11262 gen_rtx_IF_THEN_ELSE (result_mode
,
11263 gen_rtx_GE (VOIDmode
,
11265 true_cond
, false_cond
)));
11266 false_cond
= true_cond
;
11269 temp
= gen_reg_rtx (compare_mode
);
11270 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11275 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
11276 temp
= gen_reg_rtx (result_mode
);
11277 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11278 gen_rtx_IF_THEN_ELSE (result_mode
,
11279 gen_rtx_GE (VOIDmode
,
11281 true_cond
, false_cond
)));
11282 true_cond
= false_cond
;
11285 temp
= gen_reg_rtx (compare_mode
);
11286 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11291 gcc_unreachable ();
11294 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
11295 gen_rtx_IF_THEN_ELSE (result_mode
,
11296 gen_rtx_GE (VOIDmode
,
11298 true_cond
, false_cond
)));
11302 /* Same as above, but for ints (isel). */
11305 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
11307 rtx condition_rtx
, cr
;
11309 /* All isel implementations thus far are 32-bits. */
11310 if (GET_MODE (rs6000_compare_op0
) != SImode
)
11313 /* We still have to do the compare, because isel doesn't do a
11314 compare, it just looks at the CRx bits set by a previous compare
11316 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
11317 cr
= XEXP (condition_rtx
, 0);
11319 if (GET_MODE (cr
) == CCmode
)
11320 emit_insn (gen_isel_signed (dest
, condition_rtx
,
11321 true_cond
, false_cond
, cr
));
11323 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
11324 true_cond
, false_cond
, cr
));
11330 output_isel (rtx
*operands
)
11332 enum rtx_code code
;
11334 code
= GET_CODE (operands
[1]);
11335 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
11337 PUT_CODE (operands
[1], reverse_condition (code
));
11338 return "isel %0,%3,%2,%j1";
11341 return "isel %0,%2,%3,%j1";
11345 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
11347 enum machine_mode mode
= GET_MODE (op0
);
11351 if (code
== SMAX
|| code
== SMIN
)
11356 if (code
== SMAX
|| code
== UMAX
)
11357 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
11358 op0
, op1
, mode
, 0);
11360 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
11361 op1
, op0
, mode
, 0);
11362 gcc_assert (target
);
11363 if (target
!= dest
)
11364 emit_move_insn (dest
, target
);
11367 /* Emit instructions to perform a load-reserved/store-conditional operation.
11368 The operation performed is an atomic
11369 (set M (CODE:MODE M OP))
11370 If not NULL, BEFORE is atomically set to M before the operation, and
11371 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
11372 If SYNC_P then a memory barrier is emitted before the operation.
11373 Either OP or M may be wrapped in a NOT operation. */
11376 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
11377 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
11380 enum machine_mode used_mode
;
11381 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
11384 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
11385 rtx shift
= NULL_RTX
;
11388 emit_insn (gen_memory_barrier ());
11390 if (GET_CODE (m
) == NOT
)
11391 used_m
= XEXP (m
, 0);
11395 /* If this is smaller than SImode, we'll have to use SImode with
11397 if (mode
== QImode
|| mode
== HImode
)
11401 if (MEM_ALIGN (used_m
) >= 32)
11404 if (BYTES_BIG_ENDIAN
)
11405 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
11407 shift
= GEN_INT (ishift
);
11411 rtx addrSI
, aligned_addr
;
11413 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
,
11414 XEXP (used_m
, 0)));
11415 shift
= gen_reg_rtx (SImode
);
11417 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
11420 aligned_addr
= expand_binop (Pmode
, and_optab
,
11422 GEN_INT (-4), NULL_RTX
,
11423 1, OPTAB_LIB_WIDEN
);
11424 used_m
= change_address (used_m
, SImode
, aligned_addr
);
11425 set_mem_align (used_m
, 32);
11426 /* It's safe to keep the old alias set of USED_M, because
11427 the operation is atomic and only affects the original
11429 if (GET_CODE (m
) == NOT
)
11430 m
= gen_rtx_NOT (SImode
, used_m
);
11435 if (GET_CODE (op
) == NOT
)
11437 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
11438 oldop
= gen_rtx_NOT (SImode
, oldop
);
11441 oldop
= lowpart_subreg (SImode
, op
, mode
);
11446 newop
= expand_binop (SImode
, and_optab
,
11447 oldop
, GEN_INT (imask
), NULL_RTX
,
11448 1, OPTAB_LIB_WIDEN
);
11449 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
11453 newop
= expand_binop (SImode
, ior_optab
,
11454 oldop
, GEN_INT (~imask
), NULL_RTX
,
11455 1, OPTAB_LIB_WIDEN
);
11456 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
11463 newop
= expand_binop (SImode
, and_optab
,
11464 oldop
, GEN_INT (imask
), NULL_RTX
,
11465 1, OPTAB_LIB_WIDEN
);
11466 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
11468 mask
= gen_reg_rtx (SImode
);
11469 emit_move_insn (mask
, GEN_INT (imask
));
11470 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
11472 newop
= gen_rtx_AND (SImode
, gen_rtx_PLUS (SImode
, m
, newop
),
11474 newop
= gen_rtx_IOR (SImode
, newop
,
11475 gen_rtx_AND (SImode
,
11476 gen_rtx_NOT (SImode
, mask
),
11482 gcc_unreachable ();
11486 used_mode
= SImode
;
11487 before
= gen_reg_rtx (used_mode
);
11488 after
= gen_reg_rtx (used_mode
);
11493 before
= before_param
;
11494 after
= after_param
;
11496 if (before
== NULL_RTX
)
11497 before
= gen_reg_rtx (used_mode
);
11498 if (after
== NULL_RTX
)
11499 after
= gen_reg_rtx (used_mode
);
11502 if (code
== PLUS
&& used_mode
!= mode
)
11503 the_op
= op
; /* Computed above. */
11504 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
11505 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
11507 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
11509 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
11510 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
11511 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
11512 gen_rtx_UNSPEC (used_mode
, gen_rtvec (1, the_op
),
11514 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
11516 if (code
== PLUS
&& used_mode
!= mode
)
11517 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
11518 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
11520 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
11521 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
11523 /* Shift and mask the return values properly. */
11524 if (used_mode
!= mode
&& before_param
)
11526 emit_insn (gen_lshrsi3 (before
, before
, shift
));
11527 convert_move (before_param
, before
, 1);
11530 if (used_mode
!= mode
&& after_param
)
11532 emit_insn (gen_lshrsi3 (after
, after
, shift
));
11533 convert_move (after_param
, after
, 1);
11536 /* The previous sequence will end with a branch that's dependent on
11537 the conditional store, so placing an isync will ensure that no
11538 other instructions (especially, no load or store instructions)
11539 can start before the atomic operation completes. */
11541 emit_insn (gen_isync ());
11544 /* Emit instructions to move SRC to DST. Called by splitters for
11545 multi-register moves. It will emit at most one instruction for
11546 each register that is accessed; that is, it won't emit li/lis pairs
11547 (or equivalent for 64-bit code). One of SRC or DST must be a hard
11551 rs6000_split_multireg_move (rtx dst
, rtx src
)
11553 /* The register number of the first register being moved. */
11555 /* The mode that is to be moved. */
11556 enum machine_mode mode
;
11557 /* The mode that the move is being done in, and its size. */
11558 enum machine_mode reg_mode
;
11560 /* The number of registers that will be moved. */
11563 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
11564 mode
= GET_MODE (dst
);
11565 nregs
= HARD_REGNO_NREGS (reg
, mode
);
11566 if (FP_REGNO_P (reg
))
11568 else if (ALTIVEC_REGNO_P (reg
))
11569 reg_mode
= V16QImode
;
11571 reg_mode
= word_mode
;
11572 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
11574 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
11576 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
11578 /* Move register range backwards, if we might have destructive
11581 for (i
= nregs
- 1; i
>= 0; i
--)
11582 emit_insn (gen_rtx_SET (VOIDmode
,
11583 simplify_gen_subreg (reg_mode
, dst
, mode
,
11584 i
* reg_mode_size
),
11585 simplify_gen_subreg (reg_mode
, src
, mode
,
11586 i
* reg_mode_size
)));
11592 bool used_update
= false;
11594 if (MEM_P (src
) && INT_REGNO_P (reg
))
11598 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
11599 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
11602 breg
= XEXP (XEXP (src
, 0), 0);
11603 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
11604 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
11605 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
11606 emit_insn (TARGET_32BIT
11607 ? gen_addsi3 (breg
, breg
, delta_rtx
)
11608 : gen_adddi3 (breg
, breg
, delta_rtx
));
11609 src
= gen_rtx_MEM (mode
, breg
);
11611 else if (! offsettable_memref_p (src
))
11613 rtx newsrc
, basereg
;
11614 basereg
= gen_rtx_REG (Pmode
, reg
);
11615 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
11616 newsrc
= gen_rtx_MEM (GET_MODE (src
), basereg
);
11617 MEM_COPY_ATTRIBUTES (newsrc
, src
);
11621 breg
= XEXP (src
, 0);
11622 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
11623 breg
= XEXP (breg
, 0);
11625 /* If the base register we are using to address memory is
11626 also a destination reg, then change that register last. */
11628 && REGNO (breg
) >= REGNO (dst
)
11629 && REGNO (breg
) < REGNO (dst
) + nregs
)
11630 j
= REGNO (breg
) - REGNO (dst
);
11633 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
11637 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
11638 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
11641 breg
= XEXP (XEXP (dst
, 0), 0);
11642 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
11643 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
11644 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
11646 /* We have to update the breg before doing the store.
11647 Use store with update, if available. */
11651 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
11652 emit_insn (TARGET_32BIT
11653 ? (TARGET_POWERPC64
11654 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
11655 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
11656 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
11657 used_update
= true;
11660 emit_insn (TARGET_32BIT
11661 ? gen_addsi3 (breg
, breg
, delta_rtx
)
11662 : gen_adddi3 (breg
, breg
, delta_rtx
));
11663 dst
= gen_rtx_MEM (mode
, breg
);
11666 gcc_assert (offsettable_memref_p (dst
));
11669 for (i
= 0; i
< nregs
; i
++)
11671 /* Calculate index to next subword. */
11676 /* If compiler already emitted move of first word by
11677 store with update, no need to do anything. */
11678 if (j
== 0 && used_update
)
11681 emit_insn (gen_rtx_SET (VOIDmode
,
11682 simplify_gen_subreg (reg_mode
, dst
, mode
,
11683 j
* reg_mode_size
),
11684 simplify_gen_subreg (reg_mode
, src
, mode
,
11685 j
* reg_mode_size
)));
11691 /* This page contains routines that are used to determine what the
11692 function prologue and epilogue code will do and write them out. */
11694 /* Return the first fixed-point register that is required to be
11695 saved. 32 if none. */
11698 first_reg_to_save (void)
11702 /* Find lowest numbered live register. */
11703 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
11704 if (regs_ever_live
[first_reg
]
11705 && (! call_used_regs
[first_reg
]
11706 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
11707 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
11708 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
11709 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
11714 && current_function_uses_pic_offset_table
11715 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
11716 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
11722 /* Similar, for FP regs. */
11725 first_fp_reg_to_save (void)
11729 /* Find lowest numbered live register. */
11730 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
11731 if (regs_ever_live
[first_reg
])
11737 /* Similar, for AltiVec regs. */
11740 first_altivec_reg_to_save (void)
11744 /* Stack frame remains as is unless we are in AltiVec ABI. */
11745 if (! TARGET_ALTIVEC_ABI
)
11746 return LAST_ALTIVEC_REGNO
+ 1;
11748 /* Find lowest numbered live register. */
11749 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
11750 if (regs_ever_live
[i
])
11756 /* Return a 32-bit mask of the AltiVec registers we need to set in
11757 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
11758 the 32-bit word is 0. */
11760 static unsigned int
11761 compute_vrsave_mask (void)
11763 unsigned int i
, mask
= 0;
11765 /* First, find out if we use _any_ altivec registers. */
11766 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
11767 if (regs_ever_live
[i
])
11768 mask
|= ALTIVEC_REG_BIT (i
);
11773 /* Next, remove the argument registers from the set. These must
11774 be in the VRSAVE mask set by the caller, so we don't need to add
11775 them in again. More importantly, the mask we compute here is
11776 used to generate CLOBBERs in the set_vrsave insn, and we do not
11777 wish the argument registers to die. */
11778 for (i
= cfun
->args_info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
11779 mask
&= ~ALTIVEC_REG_BIT (i
);
11781 /* Similarly, remove the return value from the set. */
11784 diddle_return_value (is_altivec_return_reg
, &yes
);
11786 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
11792 /* For a very restricted set of circumstances, we can cut down the
11793 size of prologues/epilogues by calling our own save/restore-the-world
11797 compute_save_world_info (rs6000_stack_t
*info_ptr
)
11799 info_ptr
->world_save_p
= 1;
11800 info_ptr
->world_save_p
11801 = (WORLD_SAVE_P (info_ptr
)
11802 && DEFAULT_ABI
== ABI_DARWIN
11803 && ! (current_function_calls_setjmp
&& flag_exceptions
)
11804 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
11805 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
11806 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
11807 && info_ptr
->cr_save_p
);
11809 /* This will not work in conjunction with sibcalls. Make sure there
11810 are none. (This check is expensive, but seldom executed.) */
11811 if (WORLD_SAVE_P (info_ptr
))
11814 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
11815 if ( GET_CODE (insn
) == CALL_INSN
11816 && SIBLING_CALL_P (insn
))
11818 info_ptr
->world_save_p
= 0;
11823 if (WORLD_SAVE_P (info_ptr
))
11825 /* Even if we're not touching VRsave, make sure there's room on the
11826 stack for it, if it looks like we're calling SAVE_WORLD, which
11827 will attempt to save it. */
11828 info_ptr
->vrsave_size
= 4;
11830 /* "Save" the VRsave register too if we're saving the world. */
11831 if (info_ptr
->vrsave_mask
== 0)
11832 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
11834 /* Because the Darwin register save/restore routines only handle
11835 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
11837 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
11838 && (info_ptr
->first_altivec_reg_save
11839 >= FIRST_SAVED_ALTIVEC_REGNO
));
11846 is_altivec_return_reg (rtx reg
, void *xyes
)
11848 bool *yes
= (bool *) xyes
;
11849 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
11854 /* Calculate the stack information for the current function. This is
11855 complicated by having two separate calling sequences, the AIX calling
11856 sequence and the V.4 calling sequence.
11858 AIX (and Darwin/Mac OS X) stack frames look like:
11860 SP----> +---------------------------------------+
11861 | back chain to caller | 0 0
11862 +---------------------------------------+
11863 | saved CR | 4 8 (8-11)
11864 +---------------------------------------+
11866 +---------------------------------------+
11867 | reserved for compilers | 12 24
11868 +---------------------------------------+
11869 | reserved for binders | 16 32
11870 +---------------------------------------+
11871 | saved TOC pointer | 20 40
11872 +---------------------------------------+
11873 | Parameter save area (P) | 24 48
11874 +---------------------------------------+
11875 | Alloca space (A) | 24+P etc.
11876 +---------------------------------------+
11877 | Local variable space (L) | 24+P+A
11878 +---------------------------------------+
11879 | Float/int conversion temporary (X) | 24+P+A+L
11880 +---------------------------------------+
11881 | Save area for AltiVec registers (W) | 24+P+A+L+X
11882 +---------------------------------------+
11883 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
11884 +---------------------------------------+
11885 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
11886 +---------------------------------------+
11887 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
11888 +---------------------------------------+
11889 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
11890 +---------------------------------------+
11891 old SP->| back chain to caller's caller |
11892 +---------------------------------------+
11894 The required alignment for AIX configurations is two words (i.e., 8
11898 V.4 stack frames look like:
11900 SP----> +---------------------------------------+
11901 | back chain to caller | 0
11902 +---------------------------------------+
11903 | caller's saved LR | 4
11904 +---------------------------------------+
11905 | Parameter save area (P) | 8
11906 +---------------------------------------+
11907 | Alloca space (A) | 8+P
11908 +---------------------------------------+
11909 | Varargs save area (V) | 8+P+A
11910 +---------------------------------------+
11911 | Local variable space (L) | 8+P+A+V
11912 +---------------------------------------+
11913 | Float/int conversion temporary (X) | 8+P+A+V+L
11914 +---------------------------------------+
11915 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
11916 +---------------------------------------+
11917 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
11918 +---------------------------------------+
11919 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
11920 +---------------------------------------+
11921 | SPE: area for 64-bit GP registers |
11922 +---------------------------------------+
11923 | SPE alignment padding |
11924 +---------------------------------------+
11925 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
11926 +---------------------------------------+
11927 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
11928 +---------------------------------------+
11929 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
11930 +---------------------------------------+
11931 old SP->| back chain to caller's caller |
11932 +---------------------------------------+
11934 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
11935 given. (But note below and in sysv4.h that we require only 8 and
11936 may round up the size of our stack frame anyways. The historical
11937 reason is early versions of powerpc-linux which didn't properly
11938 align the stack at program startup. A happy side-effect is that
11939 -mno-eabi libraries can be used with -meabi programs.)
11941 The EABI configuration defaults to the V.4 layout. However,
11942 the stack alignment requirements may differ. If -mno-eabi is not
11943 given, the required stack alignment is 8 bytes; if -mno-eabi is
11944 given, the required alignment is 16 bytes. (But see V.4 comment
11947 #ifndef ABI_STACK_BOUNDARY
11948 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
11951 static rs6000_stack_t
*
11952 rs6000_stack_info (void)
11954 static rs6000_stack_t info
, zero_info
;
11955 rs6000_stack_t
*info_ptr
= &info
;
11956 int reg_size
= TARGET_32BIT
? 4 : 8;
11959 HOST_WIDE_INT non_fixed_size
;
11961 /* Zero all fields portably. */
11966 /* Cache value so we don't rescan instruction chain over and over. */
11967 if (cfun
->machine
->insn_chain_scanned_p
== 0)
11968 cfun
->machine
->insn_chain_scanned_p
11969 = spe_func_has_64bit_regs_p () + 1;
11970 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
11973 /* Select which calling sequence. */
11974 info_ptr
->abi
= DEFAULT_ABI
;
11976 /* Calculate which registers need to be saved & save area size. */
11977 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
11978 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
11979 even if it currently looks like we won't. */
11980 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
11981 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
11982 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
11983 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
11984 info_ptr
->gp_size
= reg_size
* (32 - RS6000_PIC_OFFSET_TABLE_REGNUM
);
11986 info_ptr
->gp_size
= reg_size
* (32 - info_ptr
->first_gp_reg_save
);
11988 /* For the SPE, we have an additional upper 32-bits on each GPR.
11989 Ideally we should save the entire 64-bits only when the upper
11990 half is used in SIMD instructions. Since we only record
11991 registers live (not the size they are used in), this proves
11992 difficult because we'd have to traverse the instruction chain at
11993 the right time, taking reload into account. This is a real pain,
11994 so we opt to save the GPRs in 64-bits always if but one register
11995 gets used in 64-bits. Otherwise, all the registers in the frame
11996 get saved in 32-bits.
11998 So... since when we save all GPRs (except the SP) in 64-bits, the
11999 traditional GP save area will be empty. */
12000 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12001 info_ptr
->gp_size
= 0;
12003 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
12004 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
12006 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
12007 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
12008 - info_ptr
->first_altivec_reg_save
);
12010 /* Does this function call anything? */
12011 info_ptr
->calls_p
= (! current_function_is_leaf
12012 || cfun
->machine
->ra_needs_full_frame
);
12014 /* Determine if we need to save the link register. */
12015 if (rs6000_ra_ever_killed ()
12016 || (DEFAULT_ABI
== ABI_AIX
12017 && current_function_profile
12018 && !TARGET_PROFILE_KERNEL
)
12019 #ifdef TARGET_RELOCATABLE
12020 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
12022 || (info_ptr
->first_fp_reg_save
!= 64
12023 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
12024 || info_ptr
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
12025 || (DEFAULT_ABI
== ABI_V4
&& current_function_calls_alloca
)
12026 || (DEFAULT_ABI
== ABI_DARWIN
12028 && current_function_uses_pic_offset_table
)
12029 || info_ptr
->calls_p
)
12031 info_ptr
->lr_save_p
= 1;
12032 regs_ever_live
[LINK_REGISTER_REGNUM
] = 1;
12035 /* Determine if we need to save the condition code registers. */
12036 if (regs_ever_live
[CR2_REGNO
]
12037 || regs_ever_live
[CR3_REGNO
]
12038 || regs_ever_live
[CR4_REGNO
])
12040 info_ptr
->cr_save_p
= 1;
12041 if (DEFAULT_ABI
== ABI_V4
)
12042 info_ptr
->cr_size
= reg_size
;
12045 /* If the current function calls __builtin_eh_return, then we need
12046 to allocate stack space for registers that will hold data for
12047 the exception handler. */
12048 if (current_function_calls_eh_return
)
12051 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
12054 /* SPE saves EH registers in 64-bits. */
12055 ehrd_size
= i
* (TARGET_SPE_ABI
12056 && info_ptr
->spe_64bit_regs_used
!= 0
12057 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
12062 /* Determine various sizes. */
12063 info_ptr
->reg_size
= reg_size
;
12064 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
12065 info_ptr
->varargs_size
= RS6000_VARARGS_AREA
;
12066 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
12067 info_ptr
->parm_size
= RS6000_ALIGN (current_function_outgoing_args_size
,
12068 TARGET_ALTIVEC
? 16 : 8);
12070 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12071 info_ptr
->spe_gp_size
= 8 * (32 - info_ptr
->first_gp_reg_save
);
12073 info_ptr
->spe_gp_size
= 0;
12075 if (TARGET_ALTIVEC_ABI
)
12076 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
12078 info_ptr
->vrsave_mask
= 0;
12080 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
12081 info_ptr
->vrsave_size
= 4;
12083 info_ptr
->vrsave_size
= 0;
12085 compute_save_world_info (info_ptr
);
12087 /* Calculate the offsets. */
12088 switch (DEFAULT_ABI
)
12092 gcc_unreachable ();
12096 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
12097 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
12099 if (TARGET_ALTIVEC_ABI
)
12101 info_ptr
->vrsave_save_offset
12102 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
12104 /* Align stack so vector save area is on a quadword boundary. */
12105 if (info_ptr
->altivec_size
!= 0)
12106 info_ptr
->altivec_padding_size
12107 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
12109 info_ptr
->altivec_padding_size
= 0;
12111 info_ptr
->altivec_save_offset
12112 = info_ptr
->vrsave_save_offset
12113 - info_ptr
->altivec_padding_size
12114 - info_ptr
->altivec_size
;
12116 /* Adjust for AltiVec case. */
12117 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
12120 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
12121 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
12122 info_ptr
->lr_save_offset
= 2*reg_size
;
12126 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
12127 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
12128 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
12130 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12132 /* Align stack so SPE GPR save area is aligned on a
12133 double-word boundary. */
12134 if (info_ptr
->spe_gp_size
!= 0)
12135 info_ptr
->spe_padding_size
12136 = 8 - (-info_ptr
->cr_save_offset
% 8);
12138 info_ptr
->spe_padding_size
= 0;
12140 info_ptr
->spe_gp_save_offset
12141 = info_ptr
->cr_save_offset
12142 - info_ptr
->spe_padding_size
12143 - info_ptr
->spe_gp_size
;
12145 /* Adjust for SPE case. */
12146 info_ptr
->toc_save_offset
12147 = info_ptr
->spe_gp_save_offset
- info_ptr
->toc_size
;
12149 else if (TARGET_ALTIVEC_ABI
)
12151 info_ptr
->vrsave_save_offset
12152 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
12154 /* Align stack so vector save area is on a quadword boundary. */
12155 if (info_ptr
->altivec_size
!= 0)
12156 info_ptr
->altivec_padding_size
12157 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
12159 info_ptr
->altivec_padding_size
= 0;
12161 info_ptr
->altivec_save_offset
12162 = info_ptr
->vrsave_save_offset
12163 - info_ptr
->altivec_padding_size
12164 - info_ptr
->altivec_size
;
12166 /* Adjust for AltiVec case. */
12167 info_ptr
->toc_save_offset
12168 = info_ptr
->altivec_save_offset
- info_ptr
->toc_size
;
12171 info_ptr
->toc_save_offset
= info_ptr
->cr_save_offset
- info_ptr
->toc_size
;
12172 info_ptr
->ehrd_offset
= info_ptr
->toc_save_offset
- ehrd_size
;
12173 info_ptr
->lr_save_offset
= reg_size
;
12177 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
12178 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
12179 + info_ptr
->gp_size
12180 + info_ptr
->altivec_size
12181 + info_ptr
->altivec_padding_size
12182 + info_ptr
->spe_gp_size
12183 + info_ptr
->spe_padding_size
12185 + info_ptr
->cr_size
12186 + info_ptr
->lr_size
12187 + info_ptr
->vrsave_size
12188 + info_ptr
->toc_size
,
12191 non_fixed_size
= (info_ptr
->vars_size
12192 + info_ptr
->parm_size
12193 + info_ptr
->save_size
12194 + info_ptr
->varargs_size
);
12196 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
12197 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
12199 /* Determine if we need to allocate any stack frame:
12201 For AIX we need to push the stack if a frame pointer is needed
12202 (because the stack might be dynamically adjusted), if we are
12203 debugging, if we make calls, or if the sum of fp_save, gp_save,
12204 and local variables are more than the space needed to save all
12205 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
12206 + 18*8 = 288 (GPR13 reserved).
12208 For V.4 we don't have the stack cushion that AIX uses, but assume
12209 that the debugger can handle stackless frames. */
12211 if (info_ptr
->calls_p
)
12212 info_ptr
->push_p
= 1;
12214 else if (DEFAULT_ABI
== ABI_V4
)
12215 info_ptr
->push_p
= non_fixed_size
!= 0;
12217 else if (frame_pointer_needed
)
12218 info_ptr
->push_p
= 1;
12220 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
12221 info_ptr
->push_p
= 1;
12224 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
12226 /* Zero offsets if we're not saving those registers. */
12227 if (info_ptr
->fp_size
== 0)
12228 info_ptr
->fp_save_offset
= 0;
12230 if (info_ptr
->gp_size
== 0)
12231 info_ptr
->gp_save_offset
= 0;
12233 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
12234 info_ptr
->altivec_save_offset
= 0;
12236 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
12237 info_ptr
->vrsave_save_offset
= 0;
12239 if (! TARGET_SPE_ABI
12240 || info_ptr
->spe_64bit_regs_used
== 0
12241 || info_ptr
->spe_gp_size
== 0)
12242 info_ptr
->spe_gp_save_offset
= 0;
12244 if (! info_ptr
->lr_save_p
)
12245 info_ptr
->lr_save_offset
= 0;
12247 if (! info_ptr
->cr_save_p
)
12248 info_ptr
->cr_save_offset
= 0;
12250 if (! info_ptr
->toc_save_p
)
12251 info_ptr
->toc_save_offset
= 0;
12256 /* Return true if the current function uses any GPRs in 64-bit SIMD
12260 spe_func_has_64bit_regs_p (void)
12264 /* Functions that save and restore all the call-saved registers will
12265 need to save/restore the registers in 64-bits. */
12266 if (current_function_calls_eh_return
12267 || current_function_calls_setjmp
12268 || current_function_has_nonlocal_goto
)
12271 insns
= get_insns ();
12273 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
12279 /* FIXME: This should be implemented with attributes...
12281 (set_attr "spe64" "true")....then,
12282 if (get_spe64(insn)) return true;
12284 It's the only reliable way to do the stuff below. */
12286 i
= PATTERN (insn
);
12287 if (GET_CODE (i
) == SET
)
12289 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
12291 if (SPE_VECTOR_MODE (mode
))
12293 if (TARGET_E500_DOUBLE
&& mode
== DFmode
)
12303 debug_stack_info (rs6000_stack_t
*info
)
12305 const char *abi_string
;
12308 info
= rs6000_stack_info ();
12310 fprintf (stderr
, "\nStack information for function %s:\n",
12311 ((current_function_decl
&& DECL_NAME (current_function_decl
))
12312 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
12317 default: abi_string
= "Unknown"; break;
12318 case ABI_NONE
: abi_string
= "NONE"; break;
12319 case ABI_AIX
: abi_string
= "AIX"; break;
12320 case ABI_DARWIN
: abi_string
= "Darwin"; break;
12321 case ABI_V4
: abi_string
= "V.4"; break;
12324 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
12326 if (TARGET_ALTIVEC_ABI
)
12327 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
12329 if (TARGET_SPE_ABI
)
12330 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
12332 if (info
->first_gp_reg_save
!= 32)
12333 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
12335 if (info
->first_fp_reg_save
!= 64)
12336 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
12338 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
12339 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
12340 info
->first_altivec_reg_save
);
12342 if (info
->lr_save_p
)
12343 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
12345 if (info
->cr_save_p
)
12346 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
12348 if (info
->toc_save_p
)
12349 fprintf (stderr
, "\ttoc_save_p = %5d\n", info
->toc_save_p
);
12351 if (info
->vrsave_mask
)
12352 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
12355 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
12358 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
12360 if (info
->gp_save_offset
)
12361 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
12363 if (info
->fp_save_offset
)
12364 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
12366 if (info
->altivec_save_offset
)
12367 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
12368 info
->altivec_save_offset
);
12370 if (info
->spe_gp_save_offset
)
12371 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
12372 info
->spe_gp_save_offset
);
12374 if (info
->vrsave_save_offset
)
12375 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
12376 info
->vrsave_save_offset
);
12378 if (info
->lr_save_offset
)
12379 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
12381 if (info
->cr_save_offset
)
12382 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
12384 if (info
->toc_save_offset
)
12385 fprintf (stderr
, "\ttoc_save_offset = %5d\n", info
->toc_save_offset
);
12387 if (info
->varargs_save_offset
)
12388 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
12390 if (info
->total_size
)
12391 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
12394 if (info
->varargs_size
)
12395 fprintf (stderr
, "\tvarargs_size = %5d\n", info
->varargs_size
);
12397 if (info
->vars_size
)
12398 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
12401 if (info
->parm_size
)
12402 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
12404 if (info
->fixed_size
)
12405 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
12408 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
12410 if (info
->spe_gp_size
)
12411 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
12414 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
12416 if (info
->altivec_size
)
12417 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
12419 if (info
->vrsave_size
)
12420 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
12422 if (info
->altivec_padding_size
)
12423 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
12424 info
->altivec_padding_size
);
12426 if (info
->spe_padding_size
)
12427 fprintf (stderr
, "\tspe_padding_size = %5d\n",
12428 info
->spe_padding_size
);
12431 fprintf (stderr
, "\tlr_size = %5d\n", info
->lr_size
);
12434 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
12436 if (info
->toc_size
)
12437 fprintf (stderr
, "\ttoc_size = %5d\n", info
->toc_size
);
12439 if (info
->save_size
)
12440 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
12442 if (info
->reg_size
!= 4)
12443 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
12445 fprintf (stderr
, "\n");
12449 rs6000_return_addr (int count
, rtx frame
)
12451 /* Currently we don't optimize very well between prolog and body
12452 code and for PIC code the code can be actually quite bad, so
12453 don't try to be too clever here. */
12454 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
12456 cfun
->machine
->ra_needs_full_frame
= 1;
12463 plus_constant (copy_to_reg
12464 (gen_rtx_MEM (Pmode
,
12465 memory_address (Pmode
, frame
))),
12466 RETURN_ADDRESS_OFFSET
)));
12469 cfun
->machine
->ra_need_lr
= 1;
12470 return get_hard_reg_initial_val (Pmode
, LINK_REGISTER_REGNUM
);
12473 /* Say whether a function is a candidate for sibcall handling or not.
12474 We do not allow indirect calls to be optimized into sibling calls.
12475 Also, we can't do it if there are any vector parameters; there's
12476 nowhere to put the VRsave code so it works; note that functions with
12477 vector parameters are required to have a prototype, so the argument
12478 type info must be available here. (The tail recursion case can work
12479 with vector parameters, but there's no way to distinguish here.) */
12481 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
12486 if (TARGET_ALTIVEC_VRSAVE
)
12488 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
12489 type
; type
= TREE_CHAIN (type
))
12491 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
12495 if (DEFAULT_ABI
== ABI_DARWIN
12496 || (*targetm
.binds_local_p
) (decl
))
12498 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
12500 if (!lookup_attribute ("longcall", attr_list
)
12501 || lookup_attribute ("shortcall", attr_list
))
12509 rs6000_ra_ever_killed (void)
12515 if (current_function_is_thunk
)
12518 /* regs_ever_live has LR marked as used if any sibcalls are present,
12519 but this should not force saving and restoring in the
12520 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
12521 clobbers LR, so that is inappropriate. */
12523 /* Also, the prologue can generate a store into LR that
12524 doesn't really count, like this:
12527 bcl to set PIC register
12531 When we're called from the epilogue, we need to avoid counting
12532 this as a store. */
12534 push_topmost_sequence ();
12535 top
= get_insns ();
12536 pop_topmost_sequence ();
12537 reg
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
12539 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
12543 if (FIND_REG_INC_NOTE (insn
, reg
))
12545 else if (GET_CODE (insn
) == CALL_INSN
12546 && !SIBLING_CALL_P (insn
))
12548 else if (set_of (reg
, insn
) != NULL_RTX
12549 && !prologue_epilogue_contains (insn
))
12556 /* Add a REG_MAYBE_DEAD note to the insn. */
12558 rs6000_maybe_dead (rtx insn
)
12560 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
,
12565 /* Emit instructions needed to load the TOC register.
12566 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
12567 a constant pool; or for SVR4 -fpic. */
12570 rs6000_emit_load_toc_table (int fromprolog
)
12573 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
12575 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
12578 rtx lab
, tmp1
, tmp2
, got
, tempLR
;
12580 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
12581 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
12583 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
12585 got
= rs6000_got_sym ();
12586 tmp1
= tmp2
= dest
;
12589 tmp1
= gen_reg_rtx (Pmode
);
12590 tmp2
= gen_reg_rtx (Pmode
);
12592 tempLR
= (fromprolog
12593 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
12594 : gen_reg_rtx (Pmode
));
12595 insn
= emit_insn (gen_load_toc_v4_PIC_1 (tempLR
, lab
));
12597 rs6000_maybe_dead (insn
);
12598 insn
= emit_move_insn (tmp1
, tempLR
);
12600 rs6000_maybe_dead (insn
);
12601 insn
= emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
12603 rs6000_maybe_dead (insn
);
12604 insn
= emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
12606 rs6000_maybe_dead (insn
);
12608 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
12610 rtx tempLR
= (fromprolog
12611 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
12612 : gen_reg_rtx (Pmode
));
12614 insn
= emit_insn (gen_load_toc_v4_pic_si (tempLR
));
12616 rs6000_maybe_dead (insn
);
12617 insn
= emit_move_insn (dest
, tempLR
);
12619 rs6000_maybe_dead (insn
);
12621 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
12624 rtx tempLR
= (fromprolog
12625 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
12626 : gen_reg_rtx (Pmode
));
12627 rtx temp0
= (fromprolog
12628 ? gen_rtx_REG (Pmode
, 0)
12629 : gen_reg_rtx (Pmode
));
12635 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
12636 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
12638 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
12639 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
12641 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR
,
12643 rs6000_maybe_dead (emit_move_insn (dest
, tempLR
));
12644 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
,
12652 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
12653 emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, tocsym
));
12654 emit_move_insn (dest
, tempLR
);
12655 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
12657 insn
= emit_insn (gen_addsi3 (dest
, temp0
, dest
));
12659 rs6000_maybe_dead (insn
);
12661 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
12663 /* This is for AIX code running in non-PIC ELF32. */
12666 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
12667 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
12669 insn
= emit_insn (gen_elf_high (dest
, realsym
));
12671 rs6000_maybe_dead (insn
);
12672 insn
= emit_insn (gen_elf_low (dest
, dest
, realsym
));
12674 rs6000_maybe_dead (insn
);
12678 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
12681 insn
= emit_insn (gen_load_toc_aix_si (dest
));
12683 insn
= emit_insn (gen_load_toc_aix_di (dest
));
12685 rs6000_maybe_dead (insn
);
12689 /* Emit instructions to restore the link register after determining where
12690 its value has been stored. */
12693 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
12695 rs6000_stack_t
*info
= rs6000_stack_info ();
12698 operands
[0] = source
;
12699 operands
[1] = scratch
;
12701 if (info
->lr_save_p
)
12703 rtx frame_rtx
= stack_pointer_rtx
;
12704 HOST_WIDE_INT sp_offset
= 0;
12707 if (frame_pointer_needed
12708 || current_function_calls_alloca
12709 || info
->total_size
> 32767)
12711 emit_move_insn (operands
[1], gen_rtx_MEM (Pmode
, frame_rtx
));
12712 frame_rtx
= operands
[1];
12714 else if (info
->push_p
)
12715 sp_offset
= info
->total_size
;
12717 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
12718 tmp
= gen_rtx_MEM (Pmode
, tmp
);
12719 emit_move_insn (tmp
, operands
[0]);
12722 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
), operands
[0]);
12725 static GTY(()) int set
= -1;
12728 get_TOC_alias_set (void)
12731 set
= new_alias_set ();
12735 /* This returns nonzero if the current function uses the TOC. This is
12736 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
12737 is generated by the ABI_V4 load_toc_* patterns. */
12744 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
12747 rtx pat
= PATTERN (insn
);
12750 if (GET_CODE (pat
) == PARALLEL
)
12751 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
12753 rtx sub
= XVECEXP (pat
, 0, i
);
12754 if (GET_CODE (sub
) == USE
)
12756 sub
= XEXP (sub
, 0);
12757 if (GET_CODE (sub
) == UNSPEC
12758 && XINT (sub
, 1) == UNSPEC_TOC
)
12768 create_TOC_reference (rtx symbol
)
12770 return gen_rtx_PLUS (Pmode
,
12771 gen_rtx_REG (Pmode
, TOC_REGISTER
),
12772 gen_rtx_CONST (Pmode
,
12773 gen_rtx_MINUS (Pmode
, symbol
,
12774 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
12777 /* If _Unwind_* has been called from within the same module,
12778 toc register is not guaranteed to be saved to 40(1) on function
12779 entry. Save it there in that case. */
12782 rs6000_aix_emit_builtin_unwind_init (void)
12785 rtx stack_top
= gen_reg_rtx (Pmode
);
12786 rtx opcode_addr
= gen_reg_rtx (Pmode
);
12787 rtx opcode
= gen_reg_rtx (SImode
);
12788 rtx tocompare
= gen_reg_rtx (SImode
);
12789 rtx no_toc_save_needed
= gen_label_rtx ();
12791 mem
= gen_rtx_MEM (Pmode
, hard_frame_pointer_rtx
);
12792 emit_move_insn (stack_top
, mem
);
12794 mem
= gen_rtx_MEM (Pmode
,
12795 gen_rtx_PLUS (Pmode
, stack_top
,
12796 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
12797 emit_move_insn (opcode_addr
, mem
);
12798 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
12799 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
12800 : 0xE8410028, SImode
));
12802 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
12803 SImode
, NULL_RTX
, NULL_RTX
,
12804 no_toc_save_needed
);
12806 mem
= gen_rtx_MEM (Pmode
,
12807 gen_rtx_PLUS (Pmode
, stack_top
,
12808 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
12809 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
12810 emit_label (no_toc_save_needed
);
12813 /* This ties together stack memory (MEM with an alias set of
12814 rs6000_sr_alias_set) and the change to the stack pointer. */
12817 rs6000_emit_stack_tie (void)
12819 rtx mem
= gen_rtx_MEM (BLKmode
, gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
12821 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
12822 emit_insn (gen_stack_tie (mem
));
12825 /* Emit the correct code for allocating stack space, as insns.
12826 If COPY_R12, make sure a copy of the old frame is left in r12.
12827 The generated code may use hard register 0 as a temporary. */
12830 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
12833 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
12834 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
12835 rtx todec
= gen_int_mode (-size
, Pmode
);
12837 if (INTVAL (todec
) != -size
)
12839 warning (0, "stack frame too large");
12840 emit_insn (gen_trap ());
12844 if (current_function_limit_stack
)
12846 if (REG_P (stack_limit_rtx
)
12847 && REGNO (stack_limit_rtx
) > 1
12848 && REGNO (stack_limit_rtx
) <= 31)
12850 emit_insn (TARGET_32BIT
12851 ? gen_addsi3 (tmp_reg
,
12854 : gen_adddi3 (tmp_reg
,
12858 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
12861 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
12863 && DEFAULT_ABI
== ABI_V4
)
12865 rtx toload
= gen_rtx_CONST (VOIDmode
,
12866 gen_rtx_PLUS (Pmode
,
12870 emit_insn (gen_elf_high (tmp_reg
, toload
));
12871 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
12872 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
12876 warning (0, "stack limit expression is not supported");
12879 if (copy_r12
|| ! TARGET_UPDATE
)
12880 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
12886 /* Need a note here so that try_split doesn't get confused. */
12887 if (get_last_insn () == NULL_RTX
)
12888 emit_note (NOTE_INSN_DELETED
);
12889 insn
= emit_move_insn (tmp_reg
, todec
);
12890 try_split (PATTERN (insn
), insn
, 0);
12894 insn
= emit_insn (TARGET_32BIT
12895 ? gen_movsi_update (stack_reg
, stack_reg
,
12897 : gen_movdi_di_update (stack_reg
, stack_reg
,
12898 todec
, stack_reg
));
12902 insn
= emit_insn (TARGET_32BIT
12903 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
12904 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
12905 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
12906 gen_rtx_REG (Pmode
, 12));
12909 RTX_FRAME_RELATED_P (insn
) = 1;
12911 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
12912 gen_rtx_SET (VOIDmode
, stack_reg
,
12913 gen_rtx_PLUS (Pmode
, stack_reg
,
12918 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
12919 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
12920 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
12921 deduce these equivalences by itself so it wasn't necessary to hold
12922 its hand so much. */
12925 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
12926 rtx reg2
, rtx rreg
)
12930 /* copy_rtx will not make unique copies of registers, so we need to
12931 ensure we don't have unwanted sharing here. */
12933 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
12936 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
12938 real
= copy_rtx (PATTERN (insn
));
12940 if (reg2
!= NULL_RTX
)
12941 real
= replace_rtx (real
, reg2
, rreg
);
12943 real
= replace_rtx (real
, reg
,
12944 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
12945 STACK_POINTER_REGNUM
),
12948 /* We expect that 'real' is either a SET or a PARALLEL containing
12949 SETs (and possibly other stuff). In a PARALLEL, all the SETs
12950 are important so they all have to be marked RTX_FRAME_RELATED_P. */
12952 if (GET_CODE (real
) == SET
)
12956 temp
= simplify_rtx (SET_SRC (set
));
12958 SET_SRC (set
) = temp
;
12959 temp
= simplify_rtx (SET_DEST (set
));
12961 SET_DEST (set
) = temp
;
12962 if (GET_CODE (SET_DEST (set
)) == MEM
)
12964 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
12966 XEXP (SET_DEST (set
), 0) = temp
;
12973 gcc_assert (GET_CODE (real
) == PARALLEL
);
12974 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
12975 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
12977 rtx set
= XVECEXP (real
, 0, i
);
12979 temp
= simplify_rtx (SET_SRC (set
));
12981 SET_SRC (set
) = temp
;
12982 temp
= simplify_rtx (SET_DEST (set
));
12984 SET_DEST (set
) = temp
;
12985 if (GET_CODE (SET_DEST (set
)) == MEM
)
12987 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
12989 XEXP (SET_DEST (set
), 0) = temp
;
12991 RTX_FRAME_RELATED_P (set
) = 1;
12996 real
= spe_synthesize_frame_save (real
);
12998 RTX_FRAME_RELATED_P (insn
) = 1;
12999 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13004 /* Given an SPE frame note, return a PARALLEL of SETs with the
13005 original note, plus a synthetic register save. */
13008 spe_synthesize_frame_save (rtx real
)
13010 rtx synth
, offset
, reg
, real2
;
13012 if (GET_CODE (real
) != SET
13013 || GET_MODE (SET_SRC (real
)) != V2SImode
)
13016 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
13017 frame related note. The parallel contains a set of the register
13018 being saved, and another set to a synthetic register (n+1200).
13019 This is so we can differentiate between 64-bit and 32-bit saves.
13020 Words cannot describe this nastiness. */
13022 gcc_assert (GET_CODE (SET_DEST (real
)) == MEM
13023 && GET_CODE (XEXP (SET_DEST (real
), 0)) == PLUS
13024 && GET_CODE (SET_SRC (real
)) == REG
);
13027 (set (mem (plus (reg x) (const y)))
13030 (set (mem (plus (reg x) (const y+4)))
13034 real2
= copy_rtx (real
);
13035 PUT_MODE (SET_DEST (real2
), SImode
);
13036 reg
= SET_SRC (real2
);
13037 real2
= replace_rtx (real2
, reg
, gen_rtx_REG (SImode
, REGNO (reg
)));
13038 synth
= copy_rtx (real2
);
13040 if (BYTES_BIG_ENDIAN
)
13042 offset
= XEXP (XEXP (SET_DEST (real2
), 0), 1);
13043 real2
= replace_rtx (real2
, offset
, GEN_INT (INTVAL (offset
) + 4));
13046 reg
= SET_SRC (synth
);
13048 synth
= replace_rtx (synth
, reg
,
13049 gen_rtx_REG (SImode
, REGNO (reg
) + 1200));
13051 offset
= XEXP (XEXP (SET_DEST (synth
), 0), 1);
13052 synth
= replace_rtx (synth
, offset
,
13053 GEN_INT (INTVAL (offset
)
13054 + (BYTES_BIG_ENDIAN
? 0 : 4)));
13056 RTX_FRAME_RELATED_P (synth
) = 1;
13057 RTX_FRAME_RELATED_P (real2
) = 1;
13058 if (BYTES_BIG_ENDIAN
)
13059 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, synth
, real2
));
13061 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, real2
, synth
));
13066 /* Returns an insn that has a vrsave set operation with the
13067 appropriate CLOBBERs. */
13070 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
13073 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
13074 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
13077 = gen_rtx_SET (VOIDmode
,
13079 gen_rtx_UNSPEC_VOLATILE (SImode
,
13080 gen_rtvec (2, reg
, vrsave
),
13085 /* We need to clobber the registers in the mask so the scheduler
13086 does not move sets to VRSAVE before sets of AltiVec registers.
13088 However, if the function receives nonlocal gotos, reload will set
13089 all call saved registers live. We will end up with:
13091 (set (reg 999) (mem))
13092 (parallel [ (set (reg vrsave) (unspec blah))
13093 (clobber (reg 999))])
13095 The clobber will cause the store into reg 999 to be dead, and
13096 flow will attempt to delete an epilogue insn. In this case, we
13097 need an unspec use/set of the register. */
13099 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13100 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13102 if (!epiloguep
|| call_used_regs
[i
])
13103 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
13104 gen_rtx_REG (V4SImode
, i
));
13107 rtx reg
= gen_rtx_REG (V4SImode
, i
);
13110 = gen_rtx_SET (VOIDmode
,
13112 gen_rtx_UNSPEC (V4SImode
,
13113 gen_rtvec (1, reg
), 27));
13117 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
13119 for (i
= 0; i
< nclobs
; ++i
)
13120 XVECEXP (insn
, 0, i
) = clobs
[i
];
13125 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
13126 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
13129 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
13130 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
13132 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
13133 rtx replacea
, replaceb
;
13135 int_rtx
= GEN_INT (offset
);
13137 /* Some cases that need register indexed addressing. */
13138 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
13139 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
13141 && SPE_VECTOR_MODE (mode
)
13142 && !SPE_CONST_OFFSET_OK (offset
)))
13144 /* Whomever calls us must make sure r11 is available in the
13145 flow path of instructions in the prologue. */
13146 offset_rtx
= gen_rtx_REG (Pmode
, 11);
13147 emit_move_insn (offset_rtx
, int_rtx
);
13149 replacea
= offset_rtx
;
13150 replaceb
= int_rtx
;
13154 offset_rtx
= int_rtx
;
13155 replacea
= NULL_RTX
;
13156 replaceb
= NULL_RTX
;
13159 reg
= gen_rtx_REG (mode
, regno
);
13160 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
13161 mem
= gen_rtx_MEM (mode
, addr
);
13162 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13164 insn
= emit_move_insn (mem
, reg
);
13166 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
13169 /* Emit an offset memory reference suitable for a frame store, while
13170 converting to a valid addressing mode. */
13173 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
13175 rtx int_rtx
, offset_rtx
;
13177 int_rtx
= GEN_INT (offset
);
13179 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
13180 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
13182 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
13183 emit_move_insn (offset_rtx
, int_rtx
);
13186 offset_rtx
= int_rtx
;
13188 return gen_rtx_MEM (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
13191 #ifndef TARGET_FIX_AND_CONTINUE
13192 #define TARGET_FIX_AND_CONTINUE 0
13195 /* Emit function prologue as insns. */
13198 rs6000_emit_prologue (void)
13200 rs6000_stack_t
*info
= rs6000_stack_info ();
13201 enum machine_mode reg_mode
= Pmode
;
13202 int reg_size
= TARGET_32BIT
? 4 : 8;
13203 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
13204 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
13205 rtx frame_reg_rtx
= sp_reg_rtx
;
13206 rtx cr_save_rtx
= NULL_RTX
;
13208 int saving_FPRs_inline
;
13209 int using_store_multiple
;
13210 HOST_WIDE_INT sp_offset
= 0;
13212 if (TARGET_FIX_AND_CONTINUE
)
13214 /* gdb on darwin arranges to forward a function from the old
13215 address by modifying the first 5 instructions of the function
13216 to branch to the overriding function. This is necessary to
13217 permit function pointers that point to the old function to
13218 actually forward to the new function. */
13219 emit_insn (gen_nop ());
13220 emit_insn (gen_nop ());
13221 emit_insn (gen_nop ());
13222 emit_insn (gen_nop ());
13223 emit_insn (gen_nop ());
13226 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
13228 reg_mode
= V2SImode
;
13232 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
13233 && (!TARGET_SPE_ABI
13234 || info
->spe_64bit_regs_used
== 0)
13235 && info
->first_gp_reg_save
< 31);
13236 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
13237 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
13238 || current_function_calls_eh_return
13239 || cfun
->machine
->ra_need_lr
);
13241 /* For V.4, update stack before we do any saving and set back pointer. */
13243 && (DEFAULT_ABI
== ABI_V4
13244 || current_function_calls_eh_return
))
13246 if (info
->total_size
< 32767)
13247 sp_offset
= info
->total_size
;
13249 frame_reg_rtx
= frame_ptr_rtx
;
13250 rs6000_emit_allocate_stack (info
->total_size
,
13251 (frame_reg_rtx
!= sp_reg_rtx
13252 && (info
->cr_save_p
13254 || info
->first_fp_reg_save
< 64
13255 || info
->first_gp_reg_save
< 32
13257 if (frame_reg_rtx
!= sp_reg_rtx
)
13258 rs6000_emit_stack_tie ();
13261 /* Handle world saves specially here. */
13262 if (WORLD_SAVE_P (info
))
13268 /* save_world expects lr in r0. */
13269 if (info
->lr_save_p
)
13271 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
13272 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
13273 RTX_FRAME_RELATED_P (insn
) = 1;
13276 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
13277 assumptions about the offsets of various bits of the stack
13279 gcc_assert (info
->gp_save_offset
== -220
13280 && info
->fp_save_offset
== -144
13281 && info
->lr_save_offset
== 8
13282 && info
->cr_save_offset
== 4
13285 && (!current_function_calls_eh_return
13286 || info
->ehrd_offset
== -432)
13287 && info
->vrsave_save_offset
== -224
13288 && info
->altivec_save_offset
== (-224 -16 -192));
13290 treg
= gen_rtx_REG (SImode
, 11);
13291 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
13293 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
13294 in R11. It also clobbers R12, so beware! */
13296 /* Preserve CR2 for save_world prologues */
13298 sz
+= 32 - info
->first_gp_reg_save
;
13299 sz
+= 64 - info
->first_fp_reg_save
;
13300 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
13301 p
= rtvec_alloc (sz
);
13303 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
13304 gen_rtx_REG (Pmode
,
13305 LINK_REGISTER_REGNUM
));
13306 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
13307 gen_rtx_SYMBOL_REF (Pmode
,
13309 /* We do floats first so that the instruction pattern matches
13311 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
13313 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
13314 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13315 GEN_INT (info
->fp_save_offset
13316 + sp_offset
+ 8 * i
));
13317 rtx mem
= gen_rtx_MEM (DFmode
, addr
);
13318 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13320 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13322 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
13324 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
13325 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13326 GEN_INT (info
->altivec_save_offset
13327 + sp_offset
+ 16 * i
));
13328 rtx mem
= gen_rtx_MEM (V4SImode
, addr
);
13329 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13331 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13333 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13335 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13336 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13337 GEN_INT (info
->gp_save_offset
13338 + sp_offset
+ reg_size
* i
));
13339 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13340 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13342 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13346 /* CR register traditionally saved as CR2. */
13347 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
13348 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13349 GEN_INT (info
->cr_save_offset
13351 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13352 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13354 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13356 /* Prevent any attempt to delete the setting of r0 and treg! */
13357 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 0));
13358 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, treg
);
13359 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
, sp_reg_rtx
);
13361 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13362 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13363 NULL_RTX
, NULL_RTX
);
13365 if (current_function_calls_eh_return
)
13370 unsigned int regno
= EH_RETURN_DATA_REGNO (i
);
13371 if (regno
== INVALID_REGNUM
)
13373 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
13374 info
->ehrd_offset
+ sp_offset
13375 + reg_size
* (int) i
,
13381 /* Save AltiVec registers if needed. */
13382 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
13386 /* There should be a non inline version of this, for when we
13387 are saving lots of vector registers. */
13388 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13389 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13391 rtx areg
, savereg
, mem
;
13394 offset
= info
->altivec_save_offset
+ sp_offset
13395 + 16 * (i
- info
->first_altivec_reg_save
);
13397 savereg
= gen_rtx_REG (V4SImode
, i
);
13399 areg
= gen_rtx_REG (Pmode
, 0);
13400 emit_move_insn (areg
, GEN_INT (offset
));
13402 /* AltiVec addressing mode is [reg+reg]. */
13403 mem
= gen_rtx_MEM (V4SImode
,
13404 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
13406 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13408 insn
= emit_move_insn (mem
, savereg
);
13410 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13411 areg
, GEN_INT (offset
));
13415 /* VRSAVE is a bit vector representing which AltiVec registers
13416 are used. The OS uses this to determine which vector
13417 registers to save on a context switch. We need to save
13418 VRSAVE on the stack frame, add whatever AltiVec registers we
13419 used in this function, and do the corresponding magic in the
13422 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
13423 && info
->vrsave_mask
!= 0)
13425 rtx reg
, mem
, vrsave
;
13428 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
13429 as frame_reg_rtx and r11 as the static chain pointer for
13430 nested functions. */
13431 reg
= gen_rtx_REG (SImode
, 0);
13432 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
13434 emit_insn (gen_get_vrsave_internal (reg
));
13436 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
13438 if (!WORLD_SAVE_P (info
))
13441 offset
= info
->vrsave_save_offset
+ sp_offset
;
13443 = gen_rtx_MEM (SImode
,
13444 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, GEN_INT (offset
)));
13445 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13446 insn
= emit_move_insn (mem
, reg
);
13449 /* Include the registers in the mask. */
13450 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
13452 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
13455 /* If we use the link register, get it into r0. */
13456 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
13458 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
13459 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
13460 RTX_FRAME_RELATED_P (insn
) = 1;
13463 /* If we need to save CR, put it into r12. */
13464 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
13468 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
13469 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
13470 RTX_FRAME_RELATED_P (insn
) = 1;
13471 /* Now, there's no way that dwarf2out_frame_debug_expr is going
13472 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
13473 But that's OK. All we have to do is specify that _one_ condition
13474 code register is saved in this stack slot. The thrower's epilogue
13475 will then restore all the call-saved registers.
13476 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
13477 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
13478 gen_rtx_REG (SImode
, CR2_REGNO
));
13479 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13484 /* Do any required saving of fpr's. If only one or two to save, do
13485 it ourselves. Otherwise, call function. */
13486 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
13489 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
13490 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
13491 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
13492 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
13493 info
->first_fp_reg_save
+ i
,
13494 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
13497 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
13501 const char *alloc_rname
;
13503 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
13505 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
13506 gen_rtx_REG (Pmode
,
13507 LINK_REGISTER_REGNUM
));
13508 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
13509 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
13510 alloc_rname
= ggc_strdup (rname
);
13511 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
13512 gen_rtx_SYMBOL_REF (Pmode
,
13514 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
13516 rtx addr
, reg
, mem
;
13517 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
13518 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13519 GEN_INT (info
->fp_save_offset
13520 + sp_offset
+ 8*i
));
13521 mem
= gen_rtx_MEM (DFmode
, addr
);
13522 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13524 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13526 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13527 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13528 NULL_RTX
, NULL_RTX
);
13531 /* Save GPRs. This is done as a PARALLEL if we are using
13532 the store-multiple instructions. */
13533 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
13537 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
13538 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13540 rtx addr
, reg
, mem
;
13541 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13542 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13543 GEN_INT (info
->gp_save_offset
13546 mem
= gen_rtx_MEM (reg_mode
, addr
);
13547 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13549 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13551 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13552 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13553 NULL_RTX
, NULL_RTX
);
13555 else if (!WORLD_SAVE_P (info
))
13558 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13559 if ((regs_ever_live
[info
->first_gp_reg_save
+i
]
13560 && (! call_used_regs
[info
->first_gp_reg_save
+i
]
13561 || (i
+info
->first_gp_reg_save
13562 == RS6000_PIC_OFFSET_TABLE_REGNUM
13563 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
13564 || (i
+info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
13565 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
13566 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
13568 rtx addr
, reg
, mem
;
13569 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13571 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
13573 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
13576 if (!SPE_CONST_OFFSET_OK (offset
))
13578 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
13579 emit_move_insn (b
, GEN_INT (offset
));
13582 b
= GEN_INT (offset
);
13584 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
13585 mem
= gen_rtx_MEM (V2SImode
, addr
);
13586 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13587 insn
= emit_move_insn (mem
, reg
);
13589 if (GET_CODE (b
) == CONST_INT
)
13590 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13591 NULL_RTX
, NULL_RTX
);
13593 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13594 b
, GEN_INT (offset
));
13598 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13599 GEN_INT (info
->gp_save_offset
13602 mem
= gen_rtx_MEM (reg_mode
, addr
);
13603 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13605 insn
= emit_move_insn (mem
, reg
);
13606 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13607 NULL_RTX
, NULL_RTX
);
13612 /* ??? There's no need to emit actual instructions here, but it's the
13613 easiest way to get the frame unwind information emitted. */
13614 if (!WORLD_SAVE_P (info
) && current_function_calls_eh_return
)
13616 unsigned int i
, regno
;
13618 /* In AIX ABI we need to pretend we save r2 here. */
13621 rtx addr
, reg
, mem
;
13623 reg
= gen_rtx_REG (reg_mode
, 2);
13624 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13625 GEN_INT (sp_offset
+ 5 * reg_size
));
13626 mem
= gen_rtx_MEM (reg_mode
, addr
);
13627 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13629 insn
= emit_move_insn (mem
, reg
);
13630 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13631 NULL_RTX
, NULL_RTX
);
13632 PATTERN (insn
) = gen_blockage ();
13637 regno
= EH_RETURN_DATA_REGNO (i
);
13638 if (regno
== INVALID_REGNUM
)
13641 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
13642 info
->ehrd_offset
+ sp_offset
13643 + reg_size
* (int) i
,
13648 /* Save lr if we used it. */
13649 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
13651 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13652 GEN_INT (info
->lr_save_offset
+ sp_offset
));
13653 rtx reg
= gen_rtx_REG (Pmode
, 0);
13654 rtx mem
= gen_rtx_MEM (Pmode
, addr
);
13655 /* This should not be of rs6000_sr_alias_set, because of
13656 __builtin_return_address. */
13658 insn
= emit_move_insn (mem
, reg
);
13659 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13660 NULL_RTX
, NULL_RTX
);
13663 /* Save CR if we use any that must be preserved. */
13664 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
13666 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13667 GEN_INT (info
->cr_save_offset
+ sp_offset
));
13668 rtx mem
= gen_rtx_MEM (SImode
, addr
);
13669 /* See the large comment above about why CR2_REGNO is used. */
13670 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
13672 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13674 /* If r12 was used to hold the original sp, copy cr into r0 now
13676 if (REGNO (frame_reg_rtx
) == 12)
13680 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
13681 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
13682 RTX_FRAME_RELATED_P (insn
) = 1;
13683 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
13684 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13689 insn
= emit_move_insn (mem
, cr_save_rtx
);
13691 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13692 NULL_RTX
, NULL_RTX
);
13695 /* Update stack and set back pointer unless this is V.4,
13696 for which it was done previously. */
13697 if (!WORLD_SAVE_P (info
) && info
->push_p
13698 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
13699 rs6000_emit_allocate_stack (info
->total_size
, FALSE
);
13701 /* Set frame pointer, if needed. */
13702 if (frame_pointer_needed
)
13704 insn
= emit_move_insn (gen_rtx_REG (Pmode
, FRAME_POINTER_REGNUM
),
13706 RTX_FRAME_RELATED_P (insn
) = 1;
13709 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
13710 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
13711 || (DEFAULT_ABI
== ABI_V4
13712 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
13713 && regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
]))
13715 /* If emit_load_toc_table will use the link register, we need to save
13716 it. We use R12 for this purpose because emit_load_toc_table
13717 can use register 0. This allows us to use a plain 'blr' to return
13718 from the procedure more often. */
13719 int save_LR_around_toc_setup
= (TARGET_ELF
13720 && DEFAULT_ABI
!= ABI_AIX
13722 && ! info
->lr_save_p
13723 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
13724 if (save_LR_around_toc_setup
)
13726 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13728 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
13729 rs6000_maybe_dead (insn
);
13730 RTX_FRAME_RELATED_P (insn
) = 1;
13732 rs6000_emit_load_toc_table (TRUE
);
13734 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
13735 rs6000_maybe_dead (insn
);
13736 RTX_FRAME_RELATED_P (insn
) = 1;
13739 rs6000_emit_load_toc_table (TRUE
);
13743 if (DEFAULT_ABI
== ABI_DARWIN
13744 && flag_pic
&& current_function_uses_pic_offset_table
)
13746 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13747 rtx src
= machopic_function_base_sym ();
13749 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr
, src
)));
13751 insn
= emit_move_insn (gen_rtx_REG (Pmode
,
13752 RS6000_PIC_OFFSET_TABLE_REGNUM
),
13754 rs6000_maybe_dead (insn
);
13759 /* Write function prologue. */
13762 rs6000_output_function_prologue (FILE *file
,
13763 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
13765 rs6000_stack_t
*info
= rs6000_stack_info ();
13767 if (TARGET_DEBUG_STACK
)
13768 debug_stack_info (info
);
13770 /* Write .extern for any function we will call to save and restore
13772 if (info
->first_fp_reg_save
< 64
13773 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
13774 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
13775 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
13776 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
13777 RESTORE_FP_SUFFIX
);
13779 /* Write .extern for AIX common mode routines, if needed. */
13780 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
13782 fputs ("\t.extern __mulh\n", file
);
13783 fputs ("\t.extern __mull\n", file
);
13784 fputs ("\t.extern __divss\n", file
);
13785 fputs ("\t.extern __divus\n", file
);
13786 fputs ("\t.extern __quoss\n", file
);
13787 fputs ("\t.extern __quous\n", file
);
13788 common_mode_defined
= 1;
13791 if (! HAVE_prologue
)
13795 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
13796 the "toplevel" insn chain. */
13797 emit_note (NOTE_INSN_DELETED
);
13798 rs6000_emit_prologue ();
13799 emit_note (NOTE_INSN_DELETED
);
13801 /* Expand INSN_ADDRESSES so final() doesn't crash. */
13805 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
13807 INSN_ADDRESSES_NEW (insn
, addr
);
13812 if (TARGET_DEBUG_STACK
)
13813 debug_rtx_list (get_insns (), 100);
13814 final (get_insns (), file
, FALSE
);
13818 rs6000_pic_labelno
++;
13821 /* Emit function epilogue as insns.
13823 At present, dwarf2out_frame_debug_expr doesn't understand
13824 register restores, so we don't bother setting RTX_FRAME_RELATED_P
13825 anywhere in the epilogue. Most of the insns below would in any case
13826 need special notes to explain where r11 is in relation to the stack. */
13829 rs6000_emit_epilogue (int sibcall
)
13831 rs6000_stack_t
*info
;
13832 int restoring_FPRs_inline
;
13833 int using_load_multiple
;
13834 int using_mfcr_multiple
;
13835 int use_backchain_to_restore_sp
;
13837 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
13838 rtx frame_reg_rtx
= sp_reg_rtx
;
13839 enum machine_mode reg_mode
= Pmode
;
13840 int reg_size
= TARGET_32BIT
? 4 : 8;
13843 info
= rs6000_stack_info ();
13845 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
13847 reg_mode
= V2SImode
;
13851 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
13852 && (!TARGET_SPE_ABI
13853 || info
->spe_64bit_regs_used
== 0)
13854 && info
->first_gp_reg_save
< 31);
13855 restoring_FPRs_inline
= (sibcall
13856 || current_function_calls_eh_return
13857 || info
->first_fp_reg_save
== 64
13858 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
13859 use_backchain_to_restore_sp
= (frame_pointer_needed
13860 || current_function_calls_alloca
13861 || info
->total_size
> 32767);
13862 using_mfcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
13863 || rs6000_cpu
== PROCESSOR_PPC603
13864 || rs6000_cpu
== PROCESSOR_PPC750
13867 if (WORLD_SAVE_P (info
))
13871 const char *alloc_rname
;
13874 /* eh_rest_world_r10 will return to the location saved in the LR
13875 stack slot (which is not likely to be our caller.)
13876 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
13877 rest_world is similar, except any R10 parameter is ignored.
13878 The exception-handling stuff that was here in 2.95 is no
13879 longer necessary. */
13883 + 32 - info
->first_gp_reg_save
13884 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
13885 + 63 + 1 - info
->first_fp_reg_save
);
13887 strcpy (rname
, ((current_function_calls_eh_return
) ?
13888 "*eh_rest_world_r10" : "*rest_world"));
13889 alloc_rname
= ggc_strdup (rname
);
13892 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
13893 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
13894 gen_rtx_REG (Pmode
,
13895 LINK_REGISTER_REGNUM
));
13897 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
13898 /* The instruction pattern requires a clobber here;
13899 it is shared with the restVEC helper. */
13901 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
13904 /* CR register traditionally saved as CR2. */
13905 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
13906 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13907 GEN_INT (info
->cr_save_offset
));
13908 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13909 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13911 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13914 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13916 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13917 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13918 GEN_INT (info
->gp_save_offset
13920 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13921 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13923 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13925 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
13927 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
13928 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13929 GEN_INT (info
->altivec_save_offset
13931 rtx mem
= gen_rtx_MEM (V4SImode
, addr
);
13932 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13934 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13936 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
13938 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
13939 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13940 GEN_INT (info
->fp_save_offset
13942 rtx mem
= gen_rtx_MEM (DFmode
, addr
);
13943 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13945 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13948 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
13950 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
13952 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
13954 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
13956 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
13957 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13962 /* If we have a frame pointer, a call to alloca, or a large stack
13963 frame, restore the old stack pointer using the backchain. Otherwise,
13964 we know what size to update it with. */
13965 if (use_backchain_to_restore_sp
)
13967 /* Under V.4, don't reset the stack pointer until after we're done
13968 loading the saved registers. */
13969 if (DEFAULT_ABI
== ABI_V4
)
13970 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
13972 emit_move_insn (frame_reg_rtx
,
13973 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
13976 else if (info
->push_p
)
13978 if (DEFAULT_ABI
== ABI_V4
13979 || current_function_calls_eh_return
)
13980 sp_offset
= info
->total_size
;
13983 emit_insn (TARGET_32BIT
13984 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
13985 GEN_INT (info
->total_size
))
13986 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
13987 GEN_INT (info
->total_size
)));
13991 /* Restore AltiVec registers if needed. */
13992 if (TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
13996 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13997 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13999 rtx addr
, areg
, mem
;
14001 areg
= gen_rtx_REG (Pmode
, 0);
14003 (areg
, GEN_INT (info
->altivec_save_offset
14005 + 16 * (i
- info
->first_altivec_reg_save
)));
14007 /* AltiVec addressing mode is [reg+reg]. */
14008 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
14009 mem
= gen_rtx_MEM (V4SImode
, addr
);
14010 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14012 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
14016 /* Restore VRSAVE if needed. */
14017 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
14018 && info
->vrsave_mask
!= 0)
14020 rtx addr
, mem
, reg
;
14022 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14023 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
14024 mem
= gen_rtx_MEM (SImode
, addr
);
14025 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14026 reg
= gen_rtx_REG (SImode
, 12);
14027 emit_move_insn (reg
, mem
);
14029 emit_insn (generate_set_vrsave (reg
, info
, 1));
14032 /* Get the old lr if we saved it. */
14033 if (info
->lr_save_p
)
14035 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
14036 info
->lr_save_offset
+ sp_offset
);
14038 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14040 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
14043 /* Get the old cr if we saved it. */
14044 if (info
->cr_save_p
)
14046 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14047 GEN_INT (info
->cr_save_offset
+ sp_offset
));
14048 rtx mem
= gen_rtx_MEM (SImode
, addr
);
14050 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14052 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
14055 /* Set LR here to try to overlap restores below. */
14056 if (info
->lr_save_p
)
14057 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
),
14058 gen_rtx_REG (Pmode
, 0));
14060 /* Load exception handler data registers, if needed. */
14061 if (current_function_calls_eh_return
)
14063 unsigned int i
, regno
;
14067 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14068 GEN_INT (sp_offset
+ 5 * reg_size
));
14069 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14071 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14073 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
14080 regno
= EH_RETURN_DATA_REGNO (i
);
14081 if (regno
== INVALID_REGNUM
)
14084 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
14085 info
->ehrd_offset
+ sp_offset
14086 + reg_size
* (int) i
);
14087 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14089 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
14093 /* Restore GPRs. This is done as a PARALLEL if we are using
14094 the load-multiple instructions. */
14095 if (using_load_multiple
)
14098 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14099 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14101 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14102 GEN_INT (info
->gp_save_offset
14105 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14107 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14110 gen_rtx_SET (VOIDmode
,
14111 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
14114 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14117 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14118 if ((regs_ever_live
[info
->first_gp_reg_save
+i
]
14119 && (! call_used_regs
[info
->first_gp_reg_save
+i
]
14120 || (i
+info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14121 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14122 || (i
+info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14123 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14124 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14126 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14127 GEN_INT (info
->gp_save_offset
14130 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14132 /* Restore 64-bit quantities for SPE. */
14133 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14135 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14138 if (!SPE_CONST_OFFSET_OK (offset
))
14140 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14141 emit_move_insn (b
, GEN_INT (offset
));
14144 b
= GEN_INT (offset
);
14146 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
14147 mem
= gen_rtx_MEM (V2SImode
, addr
);
14150 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14152 emit_move_insn (gen_rtx_REG (reg_mode
,
14153 info
->first_gp_reg_save
+ i
), mem
);
14156 /* Restore fpr's if we need to do it without calling a function. */
14157 if (restoring_FPRs_inline
)
14158 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14159 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
14160 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
14163 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14164 GEN_INT (info
->fp_save_offset
14167 mem
= gen_rtx_MEM (DFmode
, addr
);
14168 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14170 emit_move_insn (gen_rtx_REG (DFmode
,
14171 info
->first_fp_reg_save
+ i
),
14175 /* If we saved cr, restore it here. Just those that were used. */
14176 if (info
->cr_save_p
)
14178 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
14181 if (using_mfcr_multiple
)
14183 for (i
= 0; i
< 8; i
++)
14184 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14186 gcc_assert (count
);
14189 if (using_mfcr_multiple
&& count
> 1)
14194 p
= rtvec_alloc (count
);
14197 for (i
= 0; i
< 8; i
++)
14198 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14200 rtvec r
= rtvec_alloc (2);
14201 RTVEC_ELT (r
, 0) = r12_rtx
;
14202 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
14203 RTVEC_ELT (p
, ndx
) =
14204 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
14205 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
14208 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14209 gcc_assert (ndx
== count
);
14212 for (i
= 0; i
< 8; i
++)
14213 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14215 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
14221 /* If this is V.4, unwind the stack pointer after all of the loads
14222 have been done. We need to emit a block here so that sched
14223 doesn't decide to move the sp change before the register restores
14224 (which may not have any obvious dependency on the stack). This
14225 doesn't hurt performance, because there is no scheduling that can
14226 be done after this point. */
14227 if (DEFAULT_ABI
== ABI_V4
14228 || current_function_calls_eh_return
)
14230 if (frame_reg_rtx
!= sp_reg_rtx
)
14231 rs6000_emit_stack_tie ();
14233 if (use_backchain_to_restore_sp
)
14235 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
14237 else if (sp_offset
!= 0)
14239 emit_insn (TARGET_32BIT
14240 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
14241 GEN_INT (sp_offset
))
14242 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
14243 GEN_INT (sp_offset
)));
14247 if (current_function_calls_eh_return
)
14249 rtx sa
= EH_RETURN_STACKADJ_RTX
;
14250 emit_insn (TARGET_32BIT
14251 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
14252 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
14258 if (! restoring_FPRs_inline
)
14259 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
14261 p
= rtvec_alloc (2);
14263 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
14264 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
14265 gen_rtx_REG (Pmode
,
14266 LINK_REGISTER_REGNUM
));
14268 /* If we have to restore more than two FP registers, branch to the
14269 restore function. It will return to our caller. */
14270 if (! restoring_FPRs_inline
)
14274 const char *alloc_rname
;
14276 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
14277 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
14278 alloc_rname
= ggc_strdup (rname
);
14279 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
14280 gen_rtx_SYMBOL_REF (Pmode
,
14283 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14286 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
14287 GEN_INT (info
->fp_save_offset
+ 8*i
));
14288 mem
= gen_rtx_MEM (DFmode
, addr
);
14289 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14291 RTVEC_ELT (p
, i
+3) =
14292 gen_rtx_SET (VOIDmode
,
14293 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
14298 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14302 /* Write function epilogue. */
14305 rs6000_output_function_epilogue (FILE *file
,
14306 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
14308 rs6000_stack_t
*info
= rs6000_stack_info ();
14310 if (! HAVE_epilogue
)
14312 rtx insn
= get_last_insn ();
14313 /* If the last insn was a BARRIER, we don't have to write anything except
14314 the trace table. */
14315 if (GET_CODE (insn
) == NOTE
)
14316 insn
= prev_nonnote_insn (insn
);
14317 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
14319 /* This is slightly ugly, but at least we don't have two
14320 copies of the epilogue-emitting code. */
14323 /* A NOTE_INSN_DELETED is supposed to be at the start
14324 and end of the "toplevel" insn chain. */
14325 emit_note (NOTE_INSN_DELETED
);
14326 rs6000_emit_epilogue (FALSE
);
14327 emit_note (NOTE_INSN_DELETED
);
14329 /* Expand INSN_ADDRESSES so final() doesn't crash. */
14333 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
14335 INSN_ADDRESSES_NEW (insn
, addr
);
14340 if (TARGET_DEBUG_STACK
)
14341 debug_rtx_list (get_insns (), 100);
14342 final (get_insns (), file
, FALSE
);
14348 macho_branch_islands ();
14349 /* Mach-O doesn't support labels at the end of objects, so if
14350 it looks like we might want one, insert a NOP. */
14352 rtx insn
= get_last_insn ();
14355 && NOTE_LINE_NUMBER (insn
) != NOTE_INSN_DELETED_LABEL
)
14356 insn
= PREV_INSN (insn
);
14360 && NOTE_LINE_NUMBER (insn
) == NOTE_INSN_DELETED_LABEL
)))
14361 fputs ("\tnop\n", file
);
14365 /* Output a traceback table here. See /usr/include/sys/debug.h for info
14368 We don't output a traceback table if -finhibit-size-directive was
14369 used. The documentation for -finhibit-size-directive reads
14370 ``don't output a @code{.size} assembler directive, or anything
14371 else that would cause trouble if the function is split in the
14372 middle, and the two halves are placed at locations far apart in
14373 memory.'' The traceback table has this property, since it
14374 includes the offset from the start of the function to the
14375 traceback table itself.
14377 System V.4 Powerpc's (and the embedded ABI derived from it) use a
14378 different traceback table. */
14379 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
14380 && rs6000_traceback
!= traceback_none
)
14382 const char *fname
= NULL
;
14383 const char *language_string
= lang_hooks
.name
;
14384 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
14386 int optional_tbtab
;
14388 if (rs6000_traceback
== traceback_full
)
14389 optional_tbtab
= 1;
14390 else if (rs6000_traceback
== traceback_part
)
14391 optional_tbtab
= 0;
14393 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
14395 if (optional_tbtab
)
14397 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
14398 while (*fname
== '.') /* V.4 encodes . in the name */
14401 /* Need label immediately before tbtab, so we can compute
14402 its offset from the function start. */
14403 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
14404 ASM_OUTPUT_LABEL (file
, fname
);
14407 /* The .tbtab pseudo-op can only be used for the first eight
14408 expressions, since it can't handle the possibly variable
14409 length fields that follow. However, if you omit the optional
14410 fields, the assembler outputs zeros for all optional fields
14411 anyways, giving each variable length field is minimum length
14412 (as defined in sys/debug.h). Thus we can not use the .tbtab
14413 pseudo-op at all. */
14415 /* An all-zero word flags the start of the tbtab, for debuggers
14416 that have to find it by searching forward from the entry
14417 point or from the current pc. */
14418 fputs ("\t.long 0\n", file
);
14420 /* Tbtab format type. Use format type 0. */
14421 fputs ("\t.byte 0,", file
);
14423 /* Language type. Unfortunately, there does not seem to be any
14424 official way to discover the language being compiled, so we
14425 use language_string.
14426 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
14427 Java is 13. Objective-C is 14. */
14428 if (! strcmp (language_string
, "GNU C"))
14430 else if (! strcmp (language_string
, "GNU F77")
14431 || ! strcmp (language_string
, "GNU F95"))
14433 else if (! strcmp (language_string
, "GNU Pascal"))
14435 else if (! strcmp (language_string
, "GNU Ada"))
14437 else if (! strcmp (language_string
, "GNU C++"))
14439 else if (! strcmp (language_string
, "GNU Java"))
14441 else if (! strcmp (language_string
, "GNU Objective-C"))
14444 gcc_unreachable ();
14445 fprintf (file
, "%d,", i
);
14447 /* 8 single bit fields: global linkage (not set for C extern linkage,
14448 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
14449 from start of procedure stored in tbtab, internal function, function
14450 has controlled storage, function has no toc, function uses fp,
14451 function logs/aborts fp operations. */
14452 /* Assume that fp operations are used if any fp reg must be saved. */
14453 fprintf (file
, "%d,",
14454 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
14456 /* 6 bitfields: function is interrupt handler, name present in
14457 proc table, function calls alloca, on condition directives
14458 (controls stack walks, 3 bits), saves condition reg, saves
14460 /* The `function calls alloca' bit seems to be set whenever reg 31 is
14461 set up as a frame pointer, even when there is no alloca call. */
14462 fprintf (file
, "%d,",
14463 ((optional_tbtab
<< 6)
14464 | ((optional_tbtab
& frame_pointer_needed
) << 5)
14465 | (info
->cr_save_p
<< 1)
14466 | (info
->lr_save_p
)));
14468 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
14470 fprintf (file
, "%d,",
14471 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
14473 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
14474 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
14476 if (optional_tbtab
)
14478 /* Compute the parameter info from the function decl argument
14481 int next_parm_info_bit
= 31;
14483 for (decl
= DECL_ARGUMENTS (current_function_decl
);
14484 decl
; decl
= TREE_CHAIN (decl
))
14486 rtx parameter
= DECL_INCOMING_RTL (decl
);
14487 enum machine_mode mode
= GET_MODE (parameter
);
14489 if (GET_CODE (parameter
) == REG
)
14491 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
14509 gcc_unreachable ();
14512 /* If only one bit will fit, don't or in this entry. */
14513 if (next_parm_info_bit
> 0)
14514 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
14515 next_parm_info_bit
-= 2;
14519 fixed_parms
+= ((GET_MODE_SIZE (mode
)
14520 + (UNITS_PER_WORD
- 1))
14522 next_parm_info_bit
-= 1;
14528 /* Number of fixed point parameters. */
14529 /* This is actually the number of words of fixed point parameters; thus
14530 an 8 byte struct counts as 2; and thus the maximum value is 8. */
14531 fprintf (file
, "%d,", fixed_parms
);
14533 /* 2 bitfields: number of floating point parameters (7 bits), parameters
14535 /* This is actually the number of fp registers that hold parameters;
14536 and thus the maximum value is 13. */
14537 /* Set parameters on stack bit if parameters are not in their original
14538 registers, regardless of whether they are on the stack? Xlc
14539 seems to set the bit when not optimizing. */
14540 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
14542 if (! optional_tbtab
)
14545 /* Optional fields follow. Some are variable length. */
14547 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
14548 11 double float. */
14549 /* There is an entry for each parameter in a register, in the order that
14550 they occur in the parameter list. Any intervening arguments on the
14551 stack are ignored. If the list overflows a long (max possible length
14552 34 bits) then completely leave off all elements that don't fit. */
14553 /* Only emit this long if there was at least one parameter. */
14554 if (fixed_parms
|| float_parms
)
14555 fprintf (file
, "\t.long %d\n", parm_info
);
14557 /* Offset from start of code to tb table. */
14558 fputs ("\t.long ", file
);
14559 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
14561 RS6000_OUTPUT_BASENAME (file
, fname
);
14563 assemble_name (file
, fname
);
14565 rs6000_output_function_entry (file
, fname
);
14568 /* Interrupt handler mask. */
14569 /* Omit this long, since we never set the interrupt handler bit
14572 /* Number of CTL (controlled storage) anchors. */
14573 /* Omit this long, since the has_ctl bit is never set above. */
14575 /* Displacement into stack of each CTL anchor. */
14576 /* Omit this list of longs, because there are no CTL anchors. */
14578 /* Length of function name. */
14581 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
14583 /* Function name. */
14584 assemble_string (fname
, strlen (fname
));
14586 /* Register for alloca automatic storage; this is always reg 31.
14587 Only emit this if the alloca bit was set above. */
14588 if (frame_pointer_needed
)
14589 fputs ("\t.byte 31\n", file
);
14591 fputs ("\t.align 2\n", file
);
14595 /* A C compound statement that outputs the assembler code for a thunk
14596 function, used to implement C++ virtual function calls with
14597 multiple inheritance. The thunk acts as a wrapper around a virtual
14598 function, adjusting the implicit object parameter before handing
14599 control off to the real function.
14601 First, emit code to add the integer DELTA to the location that
14602 contains the incoming first argument. Assume that this argument
14603 contains a pointer, and is the one used to pass the `this' pointer
14604 in C++. This is the incoming argument *before* the function
14605 prologue, e.g. `%o0' on a sparc. The addition must preserve the
14606 values of all other incoming arguments.
14608 After the addition, emit code to jump to FUNCTION, which is a
14609 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
14610 not touch the return address. Hence returning from FUNCTION will
14611 return to whoever called the current `thunk'.
14613 The effect must be as if FUNCTION had been called directly with the
14614 adjusted first argument. This macro is responsible for emitting
14615 all of the code for a thunk function; output_function_prologue()
14616 and output_function_epilogue() are not invoked.
14618 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
14619 been extracted from it.) It might possibly be useful on some
14620 targets, but probably not.
14622 If you do not define this macro, the target-independent code in the
14623 C++ frontend will generate a less efficient heavyweight thunk that
14624 calls FUNCTION instead of jumping to it. The generic approach does
14625 not support varargs. */
14628 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
14629 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
14632 rtx
this, insn
, funexp
;
14634 reload_completed
= 1;
14635 epilogue_completed
= 1;
14636 no_new_pseudos
= 1;
14637 reset_block_changes ();
14639 /* Mark the end of the (empty) prologue. */
14640 emit_note (NOTE_INSN_PROLOGUE_END
);
14642 /* Find the "this" pointer. If the function returns a structure,
14643 the structure return pointer is in r3. */
14644 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
14645 this = gen_rtx_REG (Pmode
, 4);
14647 this = gen_rtx_REG (Pmode
, 3);
14649 /* Apply the constant offset, if required. */
14652 rtx delta_rtx
= GEN_INT (delta
);
14653 emit_insn (TARGET_32BIT
14654 ? gen_addsi3 (this, this, delta_rtx
)
14655 : gen_adddi3 (this, this, delta_rtx
));
14658 /* Apply the offset from the vtable, if required. */
14661 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
14662 rtx tmp
= gen_rtx_REG (Pmode
, 12);
14664 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
14665 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
14667 emit_insn (TARGET_32BIT
14668 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
14669 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
14670 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
14674 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
14676 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
14678 emit_insn (TARGET_32BIT
14679 ? gen_addsi3 (this, this, tmp
)
14680 : gen_adddi3 (this, this, tmp
));
14683 /* Generate a tail call to the target function. */
14684 if (!TREE_USED (function
))
14686 assemble_external (function
);
14687 TREE_USED (function
) = 1;
14689 funexp
= XEXP (DECL_RTL (function
), 0);
14690 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
14693 if (MACHOPIC_INDIRECT
)
14694 funexp
= machopic_indirect_call_target (funexp
);
14697 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
14698 generate sibcall RTL explicitly. */
14699 insn
= emit_call_insn (
14700 gen_rtx_PARALLEL (VOIDmode
,
14702 gen_rtx_CALL (VOIDmode
,
14703 funexp
, const0_rtx
),
14704 gen_rtx_USE (VOIDmode
, const0_rtx
),
14705 gen_rtx_USE (VOIDmode
,
14706 gen_rtx_REG (SImode
,
14707 LINK_REGISTER_REGNUM
)),
14708 gen_rtx_RETURN (VOIDmode
))));
14709 SIBLING_CALL_P (insn
) = 1;
14712 /* Run just enough of rest_of_compilation to get the insns emitted.
14713 There's not really enough bulk here to make other passes such as
14714 instruction scheduling worth while. Note that use_thunk calls
14715 assemble_start_function and assemble_end_function. */
14716 insn
= get_insns ();
14717 insn_locators_initialize ();
14718 shorten_branches (insn
);
14719 final_start_function (insn
, file
, 1);
14720 final (insn
, file
, 1);
14721 final_end_function ();
14723 reload_completed
= 0;
14724 epilogue_completed
= 0;
14725 no_new_pseudos
= 0;
14728 /* A quick summary of the various types of 'constant-pool tables'
14731 Target Flags Name One table per
14732 AIX (none) AIX TOC object file
14733 AIX -mfull-toc AIX TOC object file
14734 AIX -mminimal-toc AIX minimal TOC translation unit
14735 SVR4/EABI (none) SVR4 SDATA object file
14736 SVR4/EABI -fpic SVR4 pic object file
14737 SVR4/EABI -fPIC SVR4 PIC translation unit
14738 SVR4/EABI -mrelocatable EABI TOC function
14739 SVR4/EABI -maix AIX TOC object file
14740 SVR4/EABI -maix -mminimal-toc
14741 AIX minimal TOC translation unit
14743 Name Reg. Set by entries contains:
14744 made by addrs? fp? sum?
14746 AIX TOC 2 crt0 as Y option option
14747 AIX minimal TOC 30 prolog gcc Y Y option
14748 SVR4 SDATA 13 crt0 gcc N Y N
14749 SVR4 pic 30 prolog ld Y not yet N
14750 SVR4 PIC 30 prolog gcc Y option option
14751 EABI TOC 30 prolog gcc Y option option
14755 /* Hash functions for the hash table. */
14758 rs6000_hash_constant (rtx k
)
14760 enum rtx_code code
= GET_CODE (k
);
14761 enum machine_mode mode
= GET_MODE (k
);
14762 unsigned result
= (code
<< 3) ^ mode
;
14763 const char *format
;
14766 format
= GET_RTX_FORMAT (code
);
14767 flen
= strlen (format
);
14773 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
14776 if (mode
!= VOIDmode
)
14777 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
14789 for (; fidx
< flen
; fidx
++)
14790 switch (format
[fidx
])
14795 const char *str
= XSTR (k
, fidx
);
14796 len
= strlen (str
);
14797 result
= result
* 613 + len
;
14798 for (i
= 0; i
< len
; i
++)
14799 result
= result
* 613 + (unsigned) str
[i
];
14804 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
14808 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
14811 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
14812 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
14816 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
14817 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
14824 gcc_unreachable ();
14831 toc_hash_function (const void *hash_entry
)
14833 const struct toc_hash_struct
*thc
=
14834 (const struct toc_hash_struct
*) hash_entry
;
14835 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
14838 /* Compare H1 and H2 for equivalence. */
14841 toc_hash_eq (const void *h1
, const void *h2
)
14843 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
14844 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
14846 if (((const struct toc_hash_struct
*) h1
)->key_mode
14847 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
14850 return rtx_equal_p (r1
, r2
);
14853 /* These are the names given by the C++ front-end to vtables, and
14854 vtable-like objects. Ideally, this logic should not be here;
14855 instead, there should be some programmatic way of inquiring as
14856 to whether or not an object is a vtable. */
14858 #define VTABLE_NAME_P(NAME) \
14859 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
14860 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
14861 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
14862 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
14863 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
14866 rs6000_output_symbol_ref (FILE *file
, rtx x
)
14868 /* Currently C++ toc references to vtables can be emitted before it
14869 is decided whether the vtable is public or private. If this is
14870 the case, then the linker will eventually complain that there is
14871 a reference to an unknown section. Thus, for vtables only,
14872 we emit the TOC reference to reference the symbol and not the
14874 const char *name
= XSTR (x
, 0);
14876 if (VTABLE_NAME_P (name
))
14878 RS6000_OUTPUT_BASENAME (file
, name
);
14881 assemble_name (file
, name
);
14884 /* Output a TOC entry. We derive the entry name from what is being
14888 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
14891 const char *name
= buf
;
14892 const char *real_name
;
14896 gcc_assert (!TARGET_NO_TOC
);
14898 /* When the linker won't eliminate them, don't output duplicate
14899 TOC entries (this happens on AIX if there is any kind of TOC,
14900 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
14902 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
14904 struct toc_hash_struct
*h
;
14907 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
14908 time because GGC is not initialized at that point. */
14909 if (toc_hash_table
== NULL
)
14910 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
14911 toc_hash_eq
, NULL
);
14913 h
= ggc_alloc (sizeof (*h
));
14915 h
->key_mode
= mode
;
14916 h
->labelno
= labelno
;
14918 found
= htab_find_slot (toc_hash_table
, h
, 1);
14919 if (*found
== NULL
)
14921 else /* This is indeed a duplicate.
14922 Set this label equal to that label. */
14924 fputs ("\t.set ", file
);
14925 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
14926 fprintf (file
, "%d,", labelno
);
14927 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
14928 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
14934 /* If we're going to put a double constant in the TOC, make sure it's
14935 aligned properly when strict alignment is on. */
14936 if (GET_CODE (x
) == CONST_DOUBLE
14937 && STRICT_ALIGNMENT
14938 && GET_MODE_BITSIZE (mode
) >= 64
14939 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
14940 ASM_OUTPUT_ALIGN (file
, 3);
14943 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
14945 /* Handle FP constants specially. Note that if we have a minimal
14946 TOC, things we put here aren't actually in the TOC, so we can allow
14948 if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == TFmode
)
14950 REAL_VALUE_TYPE rv
;
14953 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
14954 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
14958 if (TARGET_MINIMAL_TOC
)
14959 fputs (DOUBLE_INT_ASM_OP
, file
);
14961 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
14962 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14963 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14964 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
14965 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14966 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14971 if (TARGET_MINIMAL_TOC
)
14972 fputs ("\t.long ", file
);
14974 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
14975 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14976 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14977 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
14978 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14979 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14983 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == DFmode
)
14985 REAL_VALUE_TYPE rv
;
14988 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
14989 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
14993 if (TARGET_MINIMAL_TOC
)
14994 fputs (DOUBLE_INT_ASM_OP
, file
);
14996 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
14997 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
14998 fprintf (file
, "0x%lx%08lx\n",
14999 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15004 if (TARGET_MINIMAL_TOC
)
15005 fputs ("\t.long ", file
);
15007 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
15008 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15009 fprintf (file
, "0x%lx,0x%lx\n",
15010 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15014 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == SFmode
)
15016 REAL_VALUE_TYPE rv
;
15019 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
15020 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
15024 if (TARGET_MINIMAL_TOC
)
15025 fputs (DOUBLE_INT_ASM_OP
, file
);
15027 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
15028 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
15033 if (TARGET_MINIMAL_TOC
)
15034 fputs ("\t.long ", file
);
15036 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
15037 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
15041 else if (GET_MODE (x
) == VOIDmode
15042 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
15044 unsigned HOST_WIDE_INT low
;
15045 HOST_WIDE_INT high
;
15047 if (GET_CODE (x
) == CONST_DOUBLE
)
15049 low
= CONST_DOUBLE_LOW (x
);
15050 high
= CONST_DOUBLE_HIGH (x
);
15053 #if HOST_BITS_PER_WIDE_INT == 32
15056 high
= (low
& 0x80000000) ? ~0 : 0;
15060 low
= INTVAL (x
) & 0xffffffff;
15061 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
15065 /* TOC entries are always Pmode-sized, but since this
15066 is a bigendian machine then if we're putting smaller
15067 integer constants in the TOC we have to pad them.
15068 (This is still a win over putting the constants in
15069 a separate constant pool, because then we'd have
15070 to have both a TOC entry _and_ the actual constant.)
15072 For a 32-bit target, CONST_INT values are loaded and shifted
15073 entirely within `low' and can be stored in one TOC entry. */
15075 /* It would be easy to make this work, but it doesn't now. */
15076 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
15078 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
15080 #if HOST_BITS_PER_WIDE_INT == 32
15081 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
15082 POINTER_SIZE
, &low
, &high
, 0);
15085 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
15086 high
= (HOST_WIDE_INT
) low
>> 32;
15093 if (TARGET_MINIMAL_TOC
)
15094 fputs (DOUBLE_INT_ASM_OP
, file
);
15096 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15097 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15098 fprintf (file
, "0x%lx%08lx\n",
15099 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15104 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
15106 if (TARGET_MINIMAL_TOC
)
15107 fputs ("\t.long ", file
);
15109 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15110 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15111 fprintf (file
, "0x%lx,0x%lx\n",
15112 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15116 if (TARGET_MINIMAL_TOC
)
15117 fputs ("\t.long ", file
);
15119 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
15120 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
15126 if (GET_CODE (x
) == CONST
)
15128 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
15130 base
= XEXP (XEXP (x
, 0), 0);
15131 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
15134 switch (GET_CODE (base
))
15137 name
= XSTR (base
, 0);
15141 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
15142 CODE_LABEL_NUMBER (XEXP (base
, 0)));
15146 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
15150 gcc_unreachable ();
15153 real_name
= (*targetm
.strip_name_encoding
) (name
);
15154 if (TARGET_MINIMAL_TOC
)
15155 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
15158 fprintf (file
, "\t.tc %s", real_name
);
15161 fprintf (file
, ".N%d", - offset
);
15163 fprintf (file
, ".P%d", offset
);
15165 fputs ("[TC],", file
);
15168 /* Currently C++ toc references to vtables can be emitted before it
15169 is decided whether the vtable is public or private. If this is
15170 the case, then the linker will eventually complain that there is
15171 a TOC reference to an unknown section. Thus, for vtables only,
15172 we emit the TOC reference to reference the symbol and not the
15174 if (VTABLE_NAME_P (name
))
15176 RS6000_OUTPUT_BASENAME (file
, name
);
15178 fprintf (file
, "%d", offset
);
15179 else if (offset
> 0)
15180 fprintf (file
, "+%d", offset
);
15183 output_addr_const (file
, x
);
15187 /* Output an assembler pseudo-op to write an ASCII string of N characters
15188 starting at P to FILE.
15190 On the RS/6000, we have to do this using the .byte operation and
15191 write out special characters outside the quoted string.
15192 Also, the assembler is broken; very long strings are truncated,
15193 so we must artificially break them up early. */
15196 output_ascii (FILE *file
, const char *p
, int n
)
15199 int i
, count_string
;
15200 const char *for_string
= "\t.byte \"";
15201 const char *for_decimal
= "\t.byte ";
15202 const char *to_close
= NULL
;
15205 for (i
= 0; i
< n
; i
++)
15208 if (c
>= ' ' && c
< 0177)
15211 fputs (for_string
, file
);
15214 /* Write two quotes to get one. */
15222 for_decimal
= "\"\n\t.byte ";
15226 if (count_string
>= 512)
15228 fputs (to_close
, file
);
15230 for_string
= "\t.byte \"";
15231 for_decimal
= "\t.byte ";
15239 fputs (for_decimal
, file
);
15240 fprintf (file
, "%d", c
);
15242 for_string
= "\n\t.byte \"";
15243 for_decimal
= ", ";
15249 /* Now close the string if we have written one. Then end the line. */
15251 fputs (to_close
, file
);
15254 /* Generate a unique section name for FILENAME for a section type
15255 represented by SECTION_DESC. Output goes into BUF.
15257 SECTION_DESC can be any string, as long as it is different for each
15258 possible section type.
15260 We name the section in the same manner as xlc. The name begins with an
15261 underscore followed by the filename (after stripping any leading directory
15262 names) with the last period replaced by the string SECTION_DESC. If
15263 FILENAME does not contain a period, SECTION_DESC is appended to the end of
15267 rs6000_gen_section_name (char **buf
, const char *filename
,
15268 const char *section_desc
)
15270 const char *q
, *after_last_slash
, *last_period
= 0;
15274 after_last_slash
= filename
;
15275 for (q
= filename
; *q
; q
++)
15278 after_last_slash
= q
+ 1;
15279 else if (*q
== '.')
15283 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
15284 *buf
= (char *) xmalloc (len
);
15289 for (q
= after_last_slash
; *q
; q
++)
15291 if (q
== last_period
)
15293 strcpy (p
, section_desc
);
15294 p
+= strlen (section_desc
);
15298 else if (ISALNUM (*q
))
15302 if (last_period
== 0)
15303 strcpy (p
, section_desc
);
15308 /* Emit profile function. */
15311 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
15313 /* Non-standard profiling for kernels, which just saves LR then calls
15314 _mcount without worrying about arg saves. The idea is to change
15315 the function prologue as little as possible as it isn't easy to
15316 account for arg save/restore code added just for _mcount. */
15317 if (TARGET_PROFILE_KERNEL
)
15320 if (DEFAULT_ABI
== ABI_AIX
)
15322 #ifndef NO_PROFILE_COUNTERS
15323 # define NO_PROFILE_COUNTERS 0
15325 if (NO_PROFILE_COUNTERS
)
15326 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
15330 const char *label_name
;
15333 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
15334 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
15335 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
15337 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
15341 else if (DEFAULT_ABI
== ABI_DARWIN
)
15343 const char *mcount_name
= RS6000_MCOUNT
;
15344 int caller_addr_regno
= LINK_REGISTER_REGNUM
;
15346 /* Be conservative and always set this, at least for now. */
15347 current_function_uses_pic_offset_table
= 1;
15350 /* For PIC code, set up a stub and collect the caller's address
15351 from r0, which is where the prologue puts it. */
15352 if (MACHOPIC_INDIRECT
15353 && current_function_uses_pic_offset_table
)
15354 caller_addr_regno
= 0;
15356 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
15358 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
15362 /* Write function profiler code. */
15365 output_function_profiler (FILE *file
, int labelno
)
15370 switch (DEFAULT_ABI
)
15373 gcc_unreachable ();
15379 warning (0, "no profiling of 64-bit code for this ABI");
15382 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
15383 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
15386 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
15387 asm_fprintf (file
, "\t{st|stw} %s,%d(%s)\n",
15388 reg_names
[0], save_lr
, reg_names
[1]);
15389 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
15390 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
15391 assemble_name (file
, buf
);
15392 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
15394 else if (flag_pic
> 1)
15396 asm_fprintf (file
, "\t{st|stw} %s,%d(%s)\n",
15397 reg_names
[0], save_lr
, reg_names
[1]);
15398 /* Now, we need to get the address of the label. */
15399 fputs ("\tbl 1f\n\t.long ", file
);
15400 assemble_name (file
, buf
);
15401 fputs ("-.\n1:", file
);
15402 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
15403 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
15404 reg_names
[0], reg_names
[11]);
15405 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
15406 reg_names
[0], reg_names
[0], reg_names
[11]);
15410 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
15411 assemble_name (file
, buf
);
15412 fputs ("@ha\n", file
);
15413 asm_fprintf (file
, "\t{st|stw} %s,%d(%s)\n",
15414 reg_names
[0], save_lr
, reg_names
[1]);
15415 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
15416 assemble_name (file
, buf
);
15417 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
15420 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
15421 fprintf (file
, "\tbl %s%s\n",
15422 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
15427 if (!TARGET_PROFILE_KERNEL
)
15429 /* Don't do anything, done in output_profile_hook (). */
15433 gcc_assert (!TARGET_32BIT
);
15435 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
15436 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
15438 if (cfun
->static_chain_decl
!= NULL
)
15440 asm_fprintf (file
, "\tstd %s,24(%s)\n",
15441 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
15442 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
15443 asm_fprintf (file
, "\tld %s,24(%s)\n",
15444 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
15447 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
15454 /* Power4 load update and store update instructions are cracked into a
15455 load or store and an integer insn which are executed in the same cycle.
15456 Branches have their own dispatch slot which does not count against the
15457 GCC issue rate, but it changes the program flow so there are no other
15458 instructions to issue in this cycle. */
15461 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
15462 int verbose ATTRIBUTE_UNUSED
,
15463 rtx insn
, int more
)
15465 if (GET_CODE (PATTERN (insn
)) == USE
15466 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15469 if (rs6000_sched_groups
)
15471 if (is_microcoded_insn (insn
))
15473 else if (is_cracked_insn (insn
))
15474 return more
> 2 ? more
- 2 : 0;
15480 /* Adjust the cost of a scheduling dependency. Return the new cost of
15481 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
15484 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
15486 if (! recog_memoized (insn
))
15489 if (REG_NOTE_KIND (link
) != 0)
15492 if (REG_NOTE_KIND (link
) == 0)
15494 /* Data dependency; DEP_INSN writes a register that INSN reads
15495 some cycles later. */
15497 /* Separate a load from a narrower, dependent store. */
15498 if (rs6000_sched_groups
15499 && GET_CODE (PATTERN (insn
)) == SET
15500 && GET_CODE (PATTERN (dep_insn
)) == SET
15501 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
15502 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
15503 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
15504 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
15507 switch (get_attr_type (insn
))
15510 /* Tell the first scheduling pass about the latency between
15511 a mtctr and bctr (and mtlr and br/blr). The first
15512 scheduling pass will not know about this latency since
15513 the mtctr instruction, which has the latency associated
15514 to it, will be generated by reload. */
15515 return TARGET_POWER
? 5 : 4;
15517 /* Leave some extra cycles between a compare and its
15518 dependent branch, to inhibit expensive mispredicts. */
15519 if ((rs6000_cpu_attr
== CPU_PPC603
15520 || rs6000_cpu_attr
== CPU_PPC604
15521 || rs6000_cpu_attr
== CPU_PPC604E
15522 || rs6000_cpu_attr
== CPU_PPC620
15523 || rs6000_cpu_attr
== CPU_PPC630
15524 || rs6000_cpu_attr
== CPU_PPC750
15525 || rs6000_cpu_attr
== CPU_PPC7400
15526 || rs6000_cpu_attr
== CPU_PPC7450
15527 || rs6000_cpu_attr
== CPU_POWER4
15528 || rs6000_cpu_attr
== CPU_POWER5
)
15529 && recog_memoized (dep_insn
)
15530 && (INSN_CODE (dep_insn
) >= 0)
15531 && (get_attr_type (dep_insn
) == TYPE_CMP
15532 || get_attr_type (dep_insn
) == TYPE_COMPARE
15533 || get_attr_type (dep_insn
) == TYPE_DELAYED_COMPARE
15534 || get_attr_type (dep_insn
) == TYPE_IMUL_COMPARE
15535 || get_attr_type (dep_insn
) == TYPE_LMUL_COMPARE
15536 || get_attr_type (dep_insn
) == TYPE_FPCOMPARE
15537 || get_attr_type (dep_insn
) == TYPE_CR_LOGICAL
15538 || get_attr_type (dep_insn
) == TYPE_DELAYED_CR
))
15543 /* Fall out to return default cost. */
15549 /* The function returns a true if INSN is microcoded.
15550 Return false otherwise. */
15553 is_microcoded_insn (rtx insn
)
15555 if (!insn
|| !INSN_P (insn
)
15556 || GET_CODE (PATTERN (insn
)) == USE
15557 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15560 if (rs6000_sched_groups
)
15562 enum attr_type type
= get_attr_type (insn
);
15563 if (type
== TYPE_LOAD_EXT_U
15564 || type
== TYPE_LOAD_EXT_UX
15565 || type
== TYPE_LOAD_UX
15566 || type
== TYPE_STORE_UX
15567 || type
== TYPE_MFCR
)
15574 /* The function returns a nonzero value if INSN can be scheduled only
15575 as the first insn in a dispatch group ("dispatch-slot restricted").
15576 In this case, the returned value indicates how many dispatch slots
15577 the insn occupies (at the beginning of the group).
15578 Return 0 otherwise. */
15581 is_dispatch_slot_restricted (rtx insn
)
15583 enum attr_type type
;
15585 if (!rs6000_sched_groups
)
15589 || insn
== NULL_RTX
15590 || GET_CODE (insn
) == NOTE
15591 || GET_CODE (PATTERN (insn
)) == USE
15592 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15595 type
= get_attr_type (insn
);
15602 case TYPE_DELAYED_CR
:
15603 case TYPE_CR_LOGICAL
:
15611 if (rs6000_cpu
== PROCESSOR_POWER5
15612 && is_cracked_insn (insn
))
15618 /* The function returns true if INSN is cracked into 2 instructions
15619 by the processor (and therefore occupies 2 issue slots). */
15622 is_cracked_insn (rtx insn
)
15624 if (!insn
|| !INSN_P (insn
)
15625 || GET_CODE (PATTERN (insn
)) == USE
15626 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15629 if (rs6000_sched_groups
)
15631 enum attr_type type
= get_attr_type (insn
);
15632 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
15633 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
15634 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
15635 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
15636 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
15637 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
15638 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
15639 || type
== TYPE_INSERT_WORD
)
15646 /* The function returns true if INSN can be issued only from
15647 the branch slot. */
15650 is_branch_slot_insn (rtx insn
)
15652 if (!insn
|| !INSN_P (insn
)
15653 || GET_CODE (PATTERN (insn
)) == USE
15654 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15657 if (rs6000_sched_groups
)
15659 enum attr_type type
= get_attr_type (insn
);
15660 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
15668 /* A C statement (sans semicolon) to update the integer scheduling
15669 priority INSN_PRIORITY (INSN). Increase the priority to execute the
15670 INSN earlier, reduce the priority to execute INSN later. Do not
15671 define this macro if you do not need to adjust the scheduling
15672 priorities of insns. */
15675 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
15677 /* On machines (like the 750) which have asymmetric integer units,
15678 where one integer unit can do multiply and divides and the other
15679 can't, reduce the priority of multiply/divide so it is scheduled
15680 before other integer operations. */
15683 if (! INSN_P (insn
))
15686 if (GET_CODE (PATTERN (insn
)) == USE
)
15689 switch (rs6000_cpu_attr
) {
15691 switch (get_attr_type (insn
))
15698 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
15699 priority
, priority
);
15700 if (priority
>= 0 && priority
< 0x01000000)
15707 if (is_dispatch_slot_restricted (insn
)
15708 && reload_completed
15709 && current_sched_info
->sched_max_insns_priority
15710 && rs6000_sched_restricted_insns_priority
)
15713 /* Prioritize insns that can be dispatched only in the first
15715 if (rs6000_sched_restricted_insns_priority
== 1)
15716 /* Attach highest priority to insn. This means that in
15717 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
15718 precede 'priority' (critical path) considerations. */
15719 return current_sched_info
->sched_max_insns_priority
;
15720 else if (rs6000_sched_restricted_insns_priority
== 2)
15721 /* Increase priority of insn by a minimal amount. This means that in
15722 haifa-sched.c:ready_sort(), only 'priority' (critical path)
15723 considerations precede dispatch-slot restriction considerations. */
15724 return (priority
+ 1);
15730 /* Return how many instructions the machine can issue per cycle. */
15733 rs6000_issue_rate (void)
15735 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
15736 if (!reload_completed
)
15739 switch (rs6000_cpu_attr
) {
15740 case CPU_RIOS1
: /* ? */
15742 case CPU_PPC601
: /* ? */
15765 /* Return how many instructions to look ahead for better insn
15769 rs6000_use_sched_lookahead (void)
15771 if (rs6000_cpu_attr
== CPU_PPC8540
)
15776 /* Determine is PAT refers to memory. */
15779 is_mem_ref (rtx pat
)
15785 if (GET_CODE (pat
) == MEM
)
15788 /* Recursively process the pattern. */
15789 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
15791 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
15794 ret
|= is_mem_ref (XEXP (pat
, i
));
15795 else if (fmt
[i
] == 'E')
15796 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
15797 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
15803 /* Determine if PAT is a PATTERN of a load insn. */
15806 is_load_insn1 (rtx pat
)
15808 if (!pat
|| pat
== NULL_RTX
)
15811 if (GET_CODE (pat
) == SET
)
15812 return is_mem_ref (SET_SRC (pat
));
15814 if (GET_CODE (pat
) == PARALLEL
)
15818 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15819 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
15826 /* Determine if INSN loads from memory. */
15829 is_load_insn (rtx insn
)
15831 if (!insn
|| !INSN_P (insn
))
15834 if (GET_CODE (insn
) == CALL_INSN
)
15837 return is_load_insn1 (PATTERN (insn
));
15840 /* Determine if PAT is a PATTERN of a store insn. */
15843 is_store_insn1 (rtx pat
)
15845 if (!pat
|| pat
== NULL_RTX
)
15848 if (GET_CODE (pat
) == SET
)
15849 return is_mem_ref (SET_DEST (pat
));
15851 if (GET_CODE (pat
) == PARALLEL
)
15855 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15856 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
15863 /* Determine if INSN stores to memory. */
15866 is_store_insn (rtx insn
)
15868 if (!insn
|| !INSN_P (insn
))
15871 return is_store_insn1 (PATTERN (insn
));
15874 /* Returns whether the dependence between INSN and NEXT is considered
15875 costly by the given target. */
15878 rs6000_is_costly_dependence (rtx insn
, rtx next
, rtx link
, int cost
,
15881 /* If the flag is not enabled - no dependence is considered costly;
15882 allow all dependent insns in the same group.
15883 This is the most aggressive option. */
15884 if (rs6000_sched_costly_dep
== no_dep_costly
)
15887 /* If the flag is set to 1 - a dependence is always considered costly;
15888 do not allow dependent instructions in the same group.
15889 This is the most conservative option. */
15890 if (rs6000_sched_costly_dep
== all_deps_costly
)
15893 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
15894 && is_load_insn (next
)
15895 && is_store_insn (insn
))
15896 /* Prevent load after store in the same group. */
15899 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
15900 && is_load_insn (next
)
15901 && is_store_insn (insn
)
15902 && (!link
|| (int) REG_NOTE_KIND (link
) == 0))
15903 /* Prevent load after store in the same group if it is a true
15907 /* The flag is set to X; dependences with latency >= X are considered costly,
15908 and will not be scheduled in the same group. */
15909 if (rs6000_sched_costly_dep
<= max_dep_latency
15910 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
15916 /* Return the next insn after INSN that is found before TAIL is reached,
15917 skipping any "non-active" insns - insns that will not actually occupy
15918 an issue slot. Return NULL_RTX if such an insn is not found. */
15921 get_next_active_insn (rtx insn
, rtx tail
)
15925 if (!insn
|| insn
== tail
)
15928 next_insn
= NEXT_INSN (insn
);
15931 && next_insn
!= tail
15932 && (GET_CODE (next_insn
) == NOTE
15933 || GET_CODE (PATTERN (next_insn
)) == USE
15934 || GET_CODE (PATTERN (next_insn
)) == CLOBBER
))
15936 next_insn
= NEXT_INSN (next_insn
);
15939 if (!next_insn
|| next_insn
== tail
)
15945 /* Return whether the presence of INSN causes a dispatch group termination
15946 of group WHICH_GROUP.
15948 If WHICH_GROUP == current_group, this function will return true if INSN
15949 causes the termination of the current group (i.e, the dispatch group to
15950 which INSN belongs). This means that INSN will be the last insn in the
15951 group it belongs to.
15953 If WHICH_GROUP == previous_group, this function will return true if INSN
15954 causes the termination of the previous group (i.e, the dispatch group that
15955 precedes the group to which INSN belongs). This means that INSN will be
15956 the first insn in the group it belongs to). */
15959 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
15961 enum attr_type type
;
15966 type
= get_attr_type (insn
);
15968 if (is_microcoded_insn (insn
))
15971 if (which_group
== current_group
)
15973 if (is_branch_slot_insn (insn
))
15977 else if (which_group
== previous_group
)
15979 if (is_dispatch_slot_restricted (insn
))
15987 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
15988 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
15991 is_costly_group (rtx
*group_insns
, rtx next_insn
)
15996 int issue_rate
= rs6000_issue_rate ();
15998 for (i
= 0; i
< issue_rate
; i
++)
16000 rtx insn
= group_insns
[i
];
16003 for (link
= INSN_DEPEND (insn
); link
!= 0; link
= XEXP (link
, 1))
16005 rtx next
= XEXP (link
, 0);
16006 if (next
== next_insn
)
16008 cost
= insn_cost (insn
, link
, next_insn
);
16009 if (rs6000_is_costly_dependence (insn
, next_insn
, link
, cost
, 0))
16018 /* Utility of the function redefine_groups.
16019 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
16020 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
16021 to keep it "far" (in a separate group) from GROUP_INSNS, following
16022 one of the following schemes, depending on the value of the flag
16023 -minsert_sched_nops = X:
16024 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
16025 in order to force NEXT_INSN into a separate group.
16026 (2) X < sched_finish_regroup_exact: insert exactly X nops.
16027 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
16028 insertion (has a group just ended, how many vacant issue slots remain in the
16029 last group, and how many dispatch groups were encountered so far). */
16032 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
16033 rtx next_insn
, bool *group_end
, int can_issue_more
,
16038 int issue_rate
= rs6000_issue_rate ();
16039 bool end
= *group_end
;
16042 if (next_insn
== NULL_RTX
)
16043 return can_issue_more
;
16045 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
16046 return can_issue_more
;
16048 force
= is_costly_group (group_insns
, next_insn
);
16050 return can_issue_more
;
16052 if (sched_verbose
> 6)
16053 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
16054 *group_count
,can_issue_more
);
16056 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
16059 can_issue_more
= 0;
16061 /* Since only a branch can be issued in the last issue_slot, it is
16062 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
16063 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
16064 in this case the last nop will start a new group and the branch
16065 will be forced to the new group. */
16066 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
16069 while (can_issue_more
> 0)
16072 emit_insn_before (nop
, next_insn
);
16080 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
16082 int n_nops
= rs6000_sched_insert_nops
;
16084 /* Nops can't be issued from the branch slot, so the effective
16085 issue_rate for nops is 'issue_rate - 1'. */
16086 if (can_issue_more
== 0)
16087 can_issue_more
= issue_rate
;
16089 if (can_issue_more
== 0)
16091 can_issue_more
= issue_rate
- 1;
16094 for (i
= 0; i
< issue_rate
; i
++)
16096 group_insns
[i
] = 0;
16103 emit_insn_before (nop
, next_insn
);
16104 if (can_issue_more
== issue_rate
- 1) /* new group begins */
16107 if (can_issue_more
== 0)
16109 can_issue_more
= issue_rate
- 1;
16112 for (i
= 0; i
< issue_rate
; i
++)
16114 group_insns
[i
] = 0;
16120 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
16123 /* Is next_insn going to start a new group? */
16126 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
16127 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
16128 || (can_issue_more
< issue_rate
&&
16129 insn_terminates_group_p (next_insn
, previous_group
)));
16130 if (*group_end
&& end
)
16133 if (sched_verbose
> 6)
16134 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
16135 *group_count
, can_issue_more
);
16136 return can_issue_more
;
16139 return can_issue_more
;
16142 /* This function tries to synch the dispatch groups that the compiler "sees"
16143 with the dispatch groups that the processor dispatcher is expected to
16144 form in practice. It tries to achieve this synchronization by forcing the
16145 estimated processor grouping on the compiler (as opposed to the function
16146 'pad_goups' which tries to force the scheduler's grouping on the processor).
16148 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
16149 examines the (estimated) dispatch groups that will be formed by the processor
16150 dispatcher. It marks these group boundaries to reflect the estimated
16151 processor grouping, overriding the grouping that the scheduler had marked.
16152 Depending on the value of the flag '-minsert-sched-nops' this function can
16153 force certain insns into separate groups or force a certain distance between
16154 them by inserting nops, for example, if there exists a "costly dependence"
16157 The function estimates the group boundaries that the processor will form as
16158 follows: It keeps track of how many vacant issue slots are available after
16159 each insn. A subsequent insn will start a new group if one of the following
16161 - no more vacant issue slots remain in the current dispatch group.
16162 - only the last issue slot, which is the branch slot, is vacant, but the next
16163 insn is not a branch.
16164 - only the last 2 or less issue slots, including the branch slot, are vacant,
16165 which means that a cracked insn (which occupies two issue slots) can't be
16166 issued in this group.
16167 - less than 'issue_rate' slots are vacant, and the next insn always needs to
16168 start a new group. */
16171 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
16173 rtx insn
, next_insn
;
16175 int can_issue_more
;
16178 int group_count
= 0;
16182 issue_rate
= rs6000_issue_rate ();
16183 group_insns
= alloca (issue_rate
* sizeof (rtx
));
16184 for (i
= 0; i
< issue_rate
; i
++)
16186 group_insns
[i
] = 0;
16188 can_issue_more
= issue_rate
;
16190 insn
= get_next_active_insn (prev_head_insn
, tail
);
16193 while (insn
!= NULL_RTX
)
16195 slot
= (issue_rate
- can_issue_more
);
16196 group_insns
[slot
] = insn
;
16198 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
16199 if (insn_terminates_group_p (insn
, current_group
))
16200 can_issue_more
= 0;
16202 next_insn
= get_next_active_insn (insn
, tail
);
16203 if (next_insn
== NULL_RTX
)
16204 return group_count
+ 1;
16206 /* Is next_insn going to start a new group? */
16208 = (can_issue_more
== 0
16209 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
16210 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
16211 || (can_issue_more
< issue_rate
&&
16212 insn_terminates_group_p (next_insn
, previous_group
)));
16214 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
16215 next_insn
, &group_end
, can_issue_more
,
16221 can_issue_more
= 0;
16222 for (i
= 0; i
< issue_rate
; i
++)
16224 group_insns
[i
] = 0;
16228 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
16229 PUT_MODE (next_insn
, VOIDmode
);
16230 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
16231 PUT_MODE (next_insn
, TImode
);
16234 if (can_issue_more
== 0)
16235 can_issue_more
= issue_rate
;
16238 return group_count
;
16241 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
16242 dispatch group boundaries that the scheduler had marked. Pad with nops
16243 any dispatch groups which have vacant issue slots, in order to force the
16244 scheduler's grouping on the processor dispatcher. The function
16245 returns the number of dispatch groups found. */
16248 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
16250 rtx insn
, next_insn
;
16253 int can_issue_more
;
16255 int group_count
= 0;
16257 /* Initialize issue_rate. */
16258 issue_rate
= rs6000_issue_rate ();
16259 can_issue_more
= issue_rate
;
16261 insn
= get_next_active_insn (prev_head_insn
, tail
);
16262 next_insn
= get_next_active_insn (insn
, tail
);
16264 while (insn
!= NULL_RTX
)
16267 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
16269 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
16271 if (next_insn
== NULL_RTX
)
16276 /* If the scheduler had marked group termination at this location
16277 (between insn and next_indn), and neither insn nor next_insn will
16278 force group termination, pad the group with nops to force group
16281 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
16282 && !insn_terminates_group_p (insn
, current_group
)
16283 && !insn_terminates_group_p (next_insn
, previous_group
))
16285 if (!is_branch_slot_insn (next_insn
))
16288 while (can_issue_more
)
16291 emit_insn_before (nop
, next_insn
);
16296 can_issue_more
= issue_rate
;
16301 next_insn
= get_next_active_insn (insn
, tail
);
16304 return group_count
;
16307 /* The following function is called at the end of scheduling BB.
16308 After reload, it inserts nops at insn group bundling. */
16311 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
16316 fprintf (dump
, "=== Finishing schedule.\n");
16318 if (reload_completed
&& rs6000_sched_groups
)
16320 if (rs6000_sched_insert_nops
== sched_finish_none
)
16323 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
16324 n_groups
= pad_groups (dump
, sched_verbose
,
16325 current_sched_info
->prev_head
,
16326 current_sched_info
->next_tail
);
16328 n_groups
= redefine_groups (dump
, sched_verbose
,
16329 current_sched_info
->prev_head
,
16330 current_sched_info
->next_tail
);
16332 if (sched_verbose
>= 6)
16334 fprintf (dump
, "ngroups = %d\n", n_groups
);
16335 print_rtl (dump
, current_sched_info
->prev_head
);
16336 fprintf (dump
, "Done finish_sched\n");
16341 /* Length in units of the trampoline for entering a nested function. */
16344 rs6000_trampoline_size (void)
16348 switch (DEFAULT_ABI
)
16351 gcc_unreachable ();
16354 ret
= (TARGET_32BIT
) ? 12 : 24;
16359 ret
= (TARGET_32BIT
) ? 40 : 48;
16366 /* Emit RTL insns to initialize the variable parts of a trampoline.
16367 FNADDR is an RTX for the address of the function's pure code.
16368 CXT is an RTX for the static chain value for the function. */
16371 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
16373 enum machine_mode pmode
= Pmode
;
16374 int regsize
= (TARGET_32BIT
) ? 4 : 8;
16375 rtx ctx_reg
= force_reg (pmode
, cxt
);
16377 switch (DEFAULT_ABI
)
16380 gcc_unreachable ();
16382 /* Macros to shorten the code expansions below. */
16383 #define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
16384 #define MEM_PLUS(addr,offset) \
16385 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
16387 /* Under AIX, just build the 3 word function descriptor */
16390 rtx fn_reg
= gen_reg_rtx (pmode
);
16391 rtx toc_reg
= gen_reg_rtx (pmode
);
16392 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
16393 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
16394 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
16395 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
16396 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
16400 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
16403 emit_library_call (gen_rtx_SYMBOL_REF (SImode
, "__trampoline_setup"),
16404 FALSE
, VOIDmode
, 4,
16406 GEN_INT (rs6000_trampoline_size ()), SImode
,
16416 /* Table of valid machine attributes. */
16418 const struct attribute_spec rs6000_attribute_table
[] =
16420 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
16421 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
16422 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
16423 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
16424 #ifdef SUBTARGET_ATTRIBUTE_TABLE
16425 SUBTARGET_ATTRIBUTE_TABLE
,
16427 { NULL
, 0, 0, false, false, false, NULL
}
16430 /* Handle the "altivec" attribute. The attribute may have
16431 arguments as follows:
16433 __attribute__((altivec(vector__)))
16434 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
16435 __attribute__((altivec(bool__))) (always followed by 'unsigned')
16437 and may appear more than once (e.g., 'vector bool char') in a
16438 given declaration. */
16441 rs6000_handle_altivec_attribute (tree
*node
,
16442 tree name ATTRIBUTE_UNUSED
,
16444 int flags ATTRIBUTE_UNUSED
,
16445 bool *no_add_attrs
)
16447 tree type
= *node
, result
= NULL_TREE
;
16448 enum machine_mode mode
;
16451 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
16452 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
16453 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
16456 while (POINTER_TYPE_P (type
)
16457 || TREE_CODE (type
) == FUNCTION_TYPE
16458 || TREE_CODE (type
) == METHOD_TYPE
16459 || TREE_CODE (type
) == ARRAY_TYPE
)
16460 type
= TREE_TYPE (type
);
16462 mode
= TYPE_MODE (type
);
16464 /* Check for invalid AltiVec type qualifiers. */
16465 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
16468 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
16469 else if (rs6000_warn_altivec_long
)
16470 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
16472 else if (type
== long_long_unsigned_type_node
16473 || type
== long_long_integer_type_node
)
16474 error ("use of %<long long%> in AltiVec types is invalid");
16475 else if (type
== double_type_node
)
16476 error ("use of %<double%> in AltiVec types is invalid");
16477 else if (type
== long_double_type_node
)
16478 error ("use of %<long double%> in AltiVec types is invalid");
16479 else if (type
== boolean_type_node
)
16480 error ("use of boolean types in AltiVec types is invalid");
16481 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
16482 error ("use of %<complex%> in AltiVec types is invalid");
16484 switch (altivec_type
)
16487 unsigned_p
= TYPE_UNSIGNED (type
);
16491 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
16494 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
16497 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
16499 case SFmode
: result
= V4SF_type_node
; break;
16500 /* If the user says 'vector int bool', we may be handed the 'bool'
16501 attribute _before_ the 'vector' attribute, and so select the
16502 proper type in the 'b' case below. */
16503 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
16511 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
16512 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
16513 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
16520 case V8HImode
: result
= pixel_V8HI_type_node
;
16526 if (result
&& result
!= type
&& TYPE_READONLY (type
))
16527 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
16529 *no_add_attrs
= true; /* No need to hang on to the attribute. */
16532 *node
= reconstruct_complex_type (*node
, result
);
16537 /* AltiVec defines four built-in scalar types that serve as vector
16538 elements; we must teach the compiler how to mangle them. */
16540 static const char *
16541 rs6000_mangle_fundamental_type (tree type
)
16543 if (type
== bool_char_type_node
) return "U6__boolc";
16544 if (type
== bool_short_type_node
) return "U6__bools";
16545 if (type
== pixel_type_node
) return "u7__pixel";
16546 if (type
== bool_int_type_node
) return "U6__booli";
16548 /* For all other types, use normal C++ mangling. */
16552 /* Handle a "longcall" or "shortcall" attribute; arguments as in
16553 struct attribute_spec.handler. */
16556 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
16557 tree args ATTRIBUTE_UNUSED
,
16558 int flags ATTRIBUTE_UNUSED
,
16559 bool *no_add_attrs
)
16561 if (TREE_CODE (*node
) != FUNCTION_TYPE
16562 && TREE_CODE (*node
) != FIELD_DECL
16563 && TREE_CODE (*node
) != TYPE_DECL
)
16565 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
16566 IDENTIFIER_POINTER (name
));
16567 *no_add_attrs
= true;
16573 /* Set longcall attributes on all functions declared when
16574 rs6000_default_long_calls is true. */
16576 rs6000_set_default_type_attributes (tree type
)
16578 if (rs6000_default_long_calls
16579 && (TREE_CODE (type
) == FUNCTION_TYPE
16580 || TREE_CODE (type
) == METHOD_TYPE
))
16581 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
16583 TYPE_ATTRIBUTES (type
));
16586 /* Return a reference suitable for calling a function with the
16587 longcall attribute. */
16590 rs6000_longcall_ref (rtx call_ref
)
16592 const char *call_name
;
16595 if (GET_CODE (call_ref
) != SYMBOL_REF
)
16598 /* System V adds '.' to the internal name, so skip them. */
16599 call_name
= XSTR (call_ref
, 0);
16600 if (*call_name
== '.')
16602 while (*call_name
== '.')
16605 node
= get_identifier (call_name
);
16606 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
16609 return force_reg (Pmode
, call_ref
);
16612 #ifdef USING_ELFOS_H
16614 /* A C statement or statements to switch to the appropriate section
16615 for output of RTX in mode MODE. You can assume that RTX is some
16616 kind of constant in RTL. The argument MODE is redundant except in
16617 the case of a `const_int' rtx. Select the section by calling
16618 `text_section' or one of the alternatives for other sections.
16620 Do not define this macro if you put all constants in the read-only
16624 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
16625 unsigned HOST_WIDE_INT align
)
16627 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
16630 default_elf_select_rtx_section (mode
, x
, align
);
16633 /* A C statement or statements to switch to the appropriate
16634 section for output of DECL. DECL is either a `VAR_DECL' node
16635 or a constant of some sort. RELOC indicates whether forming
16636 the initial value of DECL requires link-time relocations. */
16639 rs6000_elf_select_section (tree decl
, int reloc
,
16640 unsigned HOST_WIDE_INT align
)
16642 /* Pretend that we're always building for a shared library when
16643 ABI_AIX, because otherwise we end up with dynamic relocations
16644 in read-only sections. This happens for function pointers,
16645 references to vtables in typeinfo, and probably other cases. */
16646 default_elf_select_section_1 (decl
, reloc
, align
,
16647 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
16650 /* A C statement to build up a unique section name, expressed as a
16651 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
16652 RELOC indicates whether the initial value of EXP requires
16653 link-time relocations. If you do not define this macro, GCC will use
16654 the symbol name prefixed by `.' as the section name. Note - this
16655 macro can now be called for uninitialized data items as well as
16656 initialized data and functions. */
16659 rs6000_elf_unique_section (tree decl
, int reloc
)
16661 /* As above, pretend that we're always building for a shared library
16662 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
16663 default_unique_section_1 (decl
, reloc
,
16664 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
16667 /* For a SYMBOL_REF, set generic flags and then perform some
16668 target-specific processing.
16670 When the AIX ABI is requested on a non-AIX system, replace the
16671 function name with the real name (with a leading .) rather than the
16672 function descriptor name. This saves a lot of overriding code to
16673 read the prefixes. */
16676 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
16678 default_encode_section_info (decl
, rtl
, first
);
16681 && TREE_CODE (decl
) == FUNCTION_DECL
16683 && DEFAULT_ABI
== ABI_AIX
)
16685 rtx sym_ref
= XEXP (rtl
, 0);
16686 size_t len
= strlen (XSTR (sym_ref
, 0));
16687 char *str
= alloca (len
+ 2);
16689 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
16690 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
16695 rs6000_elf_in_small_data_p (tree decl
)
16697 if (rs6000_sdata
== SDATA_NONE
)
16700 /* We want to merge strings, so we never consider them small data. */
16701 if (TREE_CODE (decl
) == STRING_CST
)
16704 /* Functions are never in the small data area. */
16705 if (TREE_CODE (decl
) == FUNCTION_DECL
)
16708 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
16710 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
16711 if (strcmp (section
, ".sdata") == 0
16712 || strcmp (section
, ".sdata2") == 0
16713 || strcmp (section
, ".sbss") == 0
16714 || strcmp (section
, ".sbss2") == 0
16715 || strcmp (section
, ".PPC.EMB.sdata0") == 0
16716 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
16721 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
16724 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
16725 /* If it's not public, and we're not going to reference it there,
16726 there's no need to put it in the small data section. */
16727 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
16734 #endif /* USING_ELFOS_H */
16737 /* Return a REG that occurs in ADDR with coefficient 1.
16738 ADDR can be effectively incremented by incrementing REG.
16740 r0 is special and we must not select it as an address
16741 register by this routine since our caller will try to
16742 increment the returned register via an "la" instruction. */
16745 find_addr_reg (rtx addr
)
16747 while (GET_CODE (addr
) == PLUS
)
16749 if (GET_CODE (XEXP (addr
, 0)) == REG
16750 && REGNO (XEXP (addr
, 0)) != 0)
16751 addr
= XEXP (addr
, 0);
16752 else if (GET_CODE (XEXP (addr
, 1)) == REG
16753 && REGNO (XEXP (addr
, 1)) != 0)
16754 addr
= XEXP (addr
, 1);
16755 else if (CONSTANT_P (XEXP (addr
, 0)))
16756 addr
= XEXP (addr
, 1);
16757 else if (CONSTANT_P (XEXP (addr
, 1)))
16758 addr
= XEXP (addr
, 0);
16760 gcc_unreachable ();
16762 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
16767 rs6000_fatal_bad_address (rtx op
)
16769 fatal_insn ("bad address", op
);
16774 static tree branch_island_list
= 0;
16776 /* Remember to generate a branch island for far calls to the given
16780 add_compiler_branch_island (tree label_name
, tree function_name
,
16783 tree branch_island
= build_tree_list (function_name
, label_name
);
16784 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
16785 TREE_CHAIN (branch_island
) = branch_island_list
;
16786 branch_island_list
= branch_island
;
16789 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
16790 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
16791 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
16792 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
16794 /* Generate far-jump branch islands for everything on the
16795 branch_island_list. Invoked immediately after the last instruction
16796 of the epilogue has been emitted; the branch-islands must be
16797 appended to, and contiguous with, the function body. Mach-O stubs
16798 are generated in machopic_output_stub(). */
16801 macho_branch_islands (void)
16804 tree branch_island
;
16806 for (branch_island
= branch_island_list
;
16808 branch_island
= TREE_CHAIN (branch_island
))
16810 const char *label
=
16811 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
16813 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
16814 char name_buf
[512];
16815 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
16816 if (name
[0] == '*' || name
[0] == '&')
16817 strcpy (name_buf
, name
+1);
16821 strcpy (name_buf
+1, name
);
16823 strcpy (tmp_buf
, "\n");
16824 strcat (tmp_buf
, label
);
16825 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
16826 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
16827 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
16828 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
16831 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
16832 strcat (tmp_buf
, label
);
16833 strcat (tmp_buf
, "_pic\n");
16834 strcat (tmp_buf
, label
);
16835 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
16837 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
16838 strcat (tmp_buf
, name_buf
);
16839 strcat (tmp_buf
, " - ");
16840 strcat (tmp_buf
, label
);
16841 strcat (tmp_buf
, "_pic)\n");
16843 strcat (tmp_buf
, "\tmtlr r0\n");
16845 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
16846 strcat (tmp_buf
, name_buf
);
16847 strcat (tmp_buf
, " - ");
16848 strcat (tmp_buf
, label
);
16849 strcat (tmp_buf
, "_pic)\n");
16851 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
16855 strcat (tmp_buf
, ":\nlis r12,hi16(");
16856 strcat (tmp_buf
, name_buf
);
16857 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
16858 strcat (tmp_buf
, name_buf
);
16859 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
16861 output_asm_insn (tmp_buf
, 0);
16862 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
16863 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
16864 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
16865 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
16868 branch_island_list
= 0;
16871 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
16872 already there or not. */
16875 no_previous_def (tree function_name
)
16877 tree branch_island
;
16878 for (branch_island
= branch_island_list
;
16880 branch_island
= TREE_CHAIN (branch_island
))
16881 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
16886 /* GET_PREV_LABEL gets the label name from the previous definition of
16890 get_prev_label (tree function_name
)
16892 tree branch_island
;
16893 for (branch_island
= branch_island_list
;
16895 branch_island
= TREE_CHAIN (branch_island
))
16896 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
16897 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
16901 /* INSN is either a function call or a millicode call. It may have an
16902 unconditional jump in its delay slot.
16904 CALL_DEST is the routine we are calling. */
16907 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
16908 int cookie_operand_number
)
16910 static char buf
[256];
16911 if (GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
16912 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
16915 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
16917 if (no_previous_def (funname
))
16919 int line_number
= 0;
16920 rtx label_rtx
= gen_label_rtx ();
16921 char *label_buf
, temp_buf
[256];
16922 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
16923 CODE_LABEL_NUMBER (label_rtx
));
16924 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
16925 labelname
= get_identifier (label_buf
);
16926 for (; insn
&& GET_CODE (insn
) != NOTE
; insn
= PREV_INSN (insn
));
16928 line_number
= NOTE_LINE_NUMBER (insn
);
16929 add_compiler_branch_island (labelname
, funname
, line_number
);
16932 labelname
= get_prev_label (funname
);
16934 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
16935 instruction will reach 'foo', otherwise link as 'bl L42'".
16936 "L42" should be a 'branch island', that will do a far jump to
16937 'foo'. Branch islands are generated in
16938 macho_branch_islands(). */
16939 sprintf (buf
, "jbsr %%z%d,%.246s",
16940 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
16943 sprintf (buf
, "bl %%z%d", dest_operand_number
);
16947 /* Generate PIC and indirect symbol stubs. */
16950 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
16952 unsigned int length
;
16953 char *symbol_name
, *lazy_ptr_name
;
16954 char *local_label_0
;
16955 static int label
= 0;
16957 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
16958 symb
= (*targetm
.strip_name_encoding
) (symb
);
16961 length
= strlen (symb
);
16962 symbol_name
= alloca (length
+ 32);
16963 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
16965 lazy_ptr_name
= alloca (length
+ 32);
16966 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
16969 machopic_picsymbol_stub1_section ();
16971 machopic_symbol_stub1_section ();
16975 fprintf (file
, "\t.align 5\n");
16977 fprintf (file
, "%s:\n", stub
);
16978 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
16981 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
16982 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
16984 fprintf (file
, "\tmflr r0\n");
16985 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
16986 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
16987 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
16988 lazy_ptr_name
, local_label_0
);
16989 fprintf (file
, "\tmtlr r0\n");
16990 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
16991 (TARGET_64BIT
? "ldu" : "lwzu"),
16992 lazy_ptr_name
, local_label_0
);
16993 fprintf (file
, "\tmtctr r12\n");
16994 fprintf (file
, "\tbctr\n");
16998 fprintf (file
, "\t.align 4\n");
17000 fprintf (file
, "%s:\n", stub
);
17001 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17003 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
17004 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
17005 (TARGET_64BIT
? "ldu" : "lwzu"),
17007 fprintf (file
, "\tmtctr r12\n");
17008 fprintf (file
, "\tbctr\n");
17011 machopic_lazy_symbol_ptr_section ();
17012 fprintf (file
, "%s:\n", lazy_ptr_name
);
17013 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17014 fprintf (file
, "%sdyld_stub_binding_helper\n",
17015 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
17018 /* Legitimize PIC addresses. If the address is already
17019 position-independent, we return ORIG. Newly generated
17020 position-independent addresses go into a reg. This is REG if non
17021 zero, otherwise we allocate register(s) as necessary. */
17023 #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x8000) < 0x10000)
17026 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
17031 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
17032 reg
= gen_reg_rtx (Pmode
);
17034 if (GET_CODE (orig
) == CONST
)
17038 if (GET_CODE (XEXP (orig
, 0)) == PLUS
17039 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
17042 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
17044 /* Use a different reg for the intermediate value, as
17045 it will be marked UNCHANGING. */
17046 reg_temp
= no_new_pseudos
? reg
: gen_reg_rtx (Pmode
);
17047 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
17050 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
17053 if (GET_CODE (offset
) == CONST_INT
)
17055 if (SMALL_INT (offset
))
17056 return plus_constant (base
, INTVAL (offset
));
17057 else if (! reload_in_progress
&& ! reload_completed
)
17058 offset
= force_reg (Pmode
, offset
);
17061 rtx mem
= force_const_mem (Pmode
, orig
);
17062 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
17065 return gen_rtx_PLUS (Pmode
, base
, offset
);
17068 /* Fall back on generic machopic code. */
17069 return machopic_legitimize_pic_address (orig
, mode
, reg
);
17072 /* This is just a placeholder to make linking work without having to
17073 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
17074 ever needed for Darwin (not too likely!) this would have to get a
17075 real definition. */
17082 /* Output a .machine directive for the Darwin assembler, and call
17083 the generic start_file routine. */
17086 rs6000_darwin_file_start (void)
17088 static const struct
17094 { "ppc64", "ppc64", MASK_64BIT
},
17095 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
17096 { "power4", "ppc970", 0 },
17097 { "G5", "ppc970", 0 },
17098 { "7450", "ppc7450", 0 },
17099 { "7400", "ppc7400", MASK_ALTIVEC
},
17100 { "G4", "ppc7400", 0 },
17101 { "750", "ppc750", 0 },
17102 { "740", "ppc750", 0 },
17103 { "G3", "ppc750", 0 },
17104 { "604e", "ppc604e", 0 },
17105 { "604", "ppc604", 0 },
17106 { "603e", "ppc603", 0 },
17107 { "603", "ppc603", 0 },
17108 { "601", "ppc601", 0 },
17109 { NULL
, "ppc", 0 } };
17110 const char *cpu_id
= "";
17113 rs6000_file_start ();
17115 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
17116 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
17117 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
17118 && rs6000_select
[i
].string
[0] != '\0')
17119 cpu_id
= rs6000_select
[i
].string
;
17121 /* Look through the mapping array. Pick the first name that either
17122 matches the argument, has a bit set in IF_SET that is also set
17123 in the target flags, or has a NULL name. */
17126 while (mapping
[i
].arg
!= NULL
17127 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
17128 && (mapping
[i
].if_set
& target_flags
) == 0)
17131 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
17134 #endif /* TARGET_MACHO */
17137 static unsigned int
17138 rs6000_elf_section_type_flags (tree decl
, const char *name
, int reloc
)
17140 return default_section_type_flags_1 (decl
, name
, reloc
,
17141 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
17144 /* Record an element in the table of global constructors. SYMBOL is
17145 a SYMBOL_REF of the function to be called; PRIORITY is a number
17146 between 0 and MAX_INIT_PRIORITY.
17148 This differs from default_named_section_asm_out_constructor in
17149 that we have special handling for -mrelocatable. */
17152 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
17154 const char *section
= ".ctors";
17157 if (priority
!= DEFAULT_INIT_PRIORITY
)
17159 sprintf (buf
, ".ctors.%.5u",
17160 /* Invert the numbering so the linker puts us in the proper
17161 order; constructors are run from right to left, and the
17162 linker sorts in increasing order. */
17163 MAX_INIT_PRIORITY
- priority
);
17167 named_section_flags (section
, SECTION_WRITE
);
17168 assemble_align (POINTER_SIZE
);
17170 if (TARGET_RELOCATABLE
)
17172 fputs ("\t.long (", asm_out_file
);
17173 output_addr_const (asm_out_file
, symbol
);
17174 fputs (")@fixup\n", asm_out_file
);
17177 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
17181 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
17183 const char *section
= ".dtors";
17186 if (priority
!= DEFAULT_INIT_PRIORITY
)
17188 sprintf (buf
, ".dtors.%.5u",
17189 /* Invert the numbering so the linker puts us in the proper
17190 order; constructors are run from right to left, and the
17191 linker sorts in increasing order. */
17192 MAX_INIT_PRIORITY
- priority
);
17196 named_section_flags (section
, SECTION_WRITE
);
17197 assemble_align (POINTER_SIZE
);
17199 if (TARGET_RELOCATABLE
)
17201 fputs ("\t.long (", asm_out_file
);
17202 output_addr_const (asm_out_file
, symbol
);
17203 fputs (")@fixup\n", asm_out_file
);
17206 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
17210 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
17214 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
17215 ASM_OUTPUT_LABEL (file
, name
);
17216 fputs (DOUBLE_INT_ASM_OP
, file
);
17217 rs6000_output_function_entry (file
, name
);
17218 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
17221 fputs ("\t.size\t", file
);
17222 assemble_name (file
, name
);
17223 fputs (",24\n\t.type\t.", file
);
17224 assemble_name (file
, name
);
17225 fputs (",@function\n", file
);
17226 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
17228 fputs ("\t.globl\t.", file
);
17229 assemble_name (file
, name
);
17234 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
17235 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
17236 rs6000_output_function_entry (file
, name
);
17237 fputs (":\n", file
);
17241 if (TARGET_RELOCATABLE
17242 && !TARGET_SECURE_PLT
17243 && (get_pool_size () != 0 || current_function_profile
)
17248 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
17250 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
17251 fprintf (file
, "\t.long ");
17252 assemble_name (file
, buf
);
17254 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
17255 assemble_name (file
, buf
);
17259 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
17260 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
17262 if (DEFAULT_ABI
== ABI_AIX
)
17264 const char *desc_name
, *orig_name
;
17266 orig_name
= (*targetm
.strip_name_encoding
) (name
);
17267 desc_name
= orig_name
;
17268 while (*desc_name
== '.')
17271 if (TREE_PUBLIC (decl
))
17272 fprintf (file
, "\t.globl %s\n", desc_name
);
17274 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
17275 fprintf (file
, "%s:\n", desc_name
);
17276 fprintf (file
, "\t.long %s\n", orig_name
);
17277 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
17278 if (DEFAULT_ABI
== ABI_AIX
)
17279 fputs ("\t.long 0\n", file
);
17280 fprintf (file
, "\t.previous\n");
17282 ASM_OUTPUT_LABEL (file
, name
);
17286 rs6000_elf_end_indicate_exec_stack (void)
17289 file_end_indicate_exec_stack ();
17295 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
17297 fputs (GLOBAL_ASM_OP
, stream
);
17298 RS6000_OUTPUT_BASENAME (stream
, name
);
17299 putc ('\n', stream
);
17303 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
17304 tree decl ATTRIBUTE_UNUSED
)
17307 static const char * const suffix
[3] = { "PR", "RO", "RW" };
17309 if (flags
& SECTION_CODE
)
17311 else if (flags
& SECTION_WRITE
)
17316 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
17317 (flags
& SECTION_CODE
) ? "." : "",
17318 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
17322 rs6000_xcoff_select_section (tree decl
, int reloc
,
17323 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
17325 if (decl_readonly_section_1 (decl
, reloc
, 1))
17327 if (TREE_PUBLIC (decl
))
17328 read_only_data_section ();
17330 read_only_private_data_section ();
17334 if (TREE_PUBLIC (decl
))
17337 private_data_section ();
17342 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
17346 /* Use select_section for private and uninitialized data. */
17347 if (!TREE_PUBLIC (decl
)
17348 || DECL_COMMON (decl
)
17349 || DECL_INITIAL (decl
) == NULL_TREE
17350 || DECL_INITIAL (decl
) == error_mark_node
17351 || (flag_zero_initialized_in_bss
17352 && initializer_zerop (DECL_INITIAL (decl
))))
17355 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
17356 name
= (*targetm
.strip_name_encoding
) (name
);
17357 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
17360 /* Select section for constant in constant pool.
17362 On RS/6000, all constants are in the private read-only data area.
17363 However, if this is being placed in the TOC it must be output as a
17367 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
17368 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
17370 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
17373 read_only_private_data_section ();
17376 /* Remove any trailing [DS] or the like from the symbol name. */
17378 static const char *
17379 rs6000_xcoff_strip_name_encoding (const char *name
)
17384 len
= strlen (name
);
17385 if (name
[len
- 1] == ']')
17386 return ggc_alloc_string (name
, len
- 4);
17391 /* Section attributes. AIX is always PIC. */
17393 static unsigned int
17394 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
17396 unsigned int align
;
17397 unsigned int flags
= default_section_type_flags_1 (decl
, name
, reloc
, 1);
17399 /* Align to at least UNIT size. */
17400 if (flags
& SECTION_CODE
)
17401 align
= MIN_UNITS_PER_WORD
;
17403 /* Increase alignment of large objects if not already stricter. */
17404 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
17405 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
17406 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
17408 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
17411 /* Output at beginning of assembler file.
17413 Initialize the section names for the RS/6000 at this point.
17415 Specify filename, including full path, to assembler.
17417 We want to go into the TOC section so at least one .toc will be emitted.
17418 Also, in order to output proper .bs/.es pairs, we need at least one static
17419 [RW] section emitted.
17421 Finally, declare mcount when profiling to make the assembler happy. */
17424 rs6000_xcoff_file_start (void)
17426 rs6000_gen_section_name (&xcoff_bss_section_name
,
17427 main_input_filename
, ".bss_");
17428 rs6000_gen_section_name (&xcoff_private_data_section_name
,
17429 main_input_filename
, ".rw_");
17430 rs6000_gen_section_name (&xcoff_read_only_section_name
,
17431 main_input_filename
, ".ro_");
17433 fputs ("\t.file\t", asm_out_file
);
17434 output_quoted_string (asm_out_file
, main_input_filename
);
17435 fputc ('\n', asm_out_file
);
17436 if (write_symbols
!= NO_DEBUG
)
17437 private_data_section ();
17440 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
17441 rs6000_file_start ();
17444 /* Output at end of assembler file.
17445 On the RS/6000, referencing data should automatically pull in text. */
17448 rs6000_xcoff_file_end (void)
17451 fputs ("_section_.text:\n", asm_out_file
);
17453 fputs (TARGET_32BIT
17454 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
17457 #endif /* TARGET_XCOFF */
17460 /* Cross-module name binding. Darwin does not support overriding
17461 functions at dynamic-link time. */
17464 rs6000_binds_local_p (tree decl
)
17466 return default_binds_local_p_1 (decl
, 0);
17470 /* Compute a (partial) cost for rtx X. Return true if the complete
17471 cost has been computed, and false if subexpressions should be
17472 scanned. In either case, *TOTAL contains the cost result. */
17475 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
17477 enum machine_mode mode
= GET_MODE (x
);
17481 /* On the RS/6000, if it is valid in the insn, it is free. */
17483 if (((outer_code
== SET
17484 || outer_code
== PLUS
17485 || outer_code
== MINUS
)
17486 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
17487 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')))
17488 || (outer_code
== AND
17489 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17490 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
17491 mode
== SImode
? 'L' : 'J'))
17492 || mask_operand (x
, VOIDmode
)))
17493 || ((outer_code
== IOR
|| outer_code
== XOR
)
17494 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17495 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
17496 mode
== SImode
? 'L' : 'J'))))
17497 || outer_code
== ASHIFT
17498 || outer_code
== ASHIFTRT
17499 || outer_code
== LSHIFTRT
17500 || outer_code
== ROTATE
17501 || outer_code
== ROTATERT
17502 || outer_code
== ZERO_EXTRACT
17503 || (outer_code
== MULT
17504 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
17505 || ((outer_code
== DIV
|| outer_code
== UDIV
17506 || outer_code
== MOD
|| outer_code
== UMOD
)
17507 && exact_log2 (INTVAL (x
)) >= 0)
17508 || (outer_code
== COMPARE
17509 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
17510 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')))
17511 || (outer_code
== EQ
17512 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
17513 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17514 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
17515 mode
== SImode
? 'L' : 'J'))))
17516 || (outer_code
== GTU
17517 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
17518 || (outer_code
== LTU
17519 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'P')))
17524 else if ((outer_code
== PLUS
17525 && reg_or_add_cint64_operand (x
, VOIDmode
))
17526 || (outer_code
== MINUS
17527 && reg_or_sub_cint64_operand (x
, VOIDmode
))
17528 || ((outer_code
== SET
17529 || outer_code
== IOR
17530 || outer_code
== XOR
)
17532 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
17534 *total
= COSTS_N_INSNS (1);
17541 && ((outer_code
== AND
17542 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17543 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')
17544 || mask64_operand (x
, DImode
)))
17545 || ((outer_code
== IOR
|| outer_code
== XOR
)
17546 && CONST_DOUBLE_HIGH (x
) == 0
17547 && (CONST_DOUBLE_LOW (x
)
17548 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)))
17553 else if (mode
== DImode
17554 && (outer_code
== SET
17555 || outer_code
== IOR
17556 || outer_code
== XOR
)
17557 && CONST_DOUBLE_HIGH (x
) == 0)
17559 *total
= COSTS_N_INSNS (1);
17568 /* When optimizing for size, MEM should be slightly more expensive
17569 than generating address, e.g., (plus (reg) (const)).
17570 L1 cache latency is about two instructions. */
17571 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
17579 if (mode
== DFmode
)
17581 if (GET_CODE (XEXP (x
, 0)) == MULT
)
17583 /* FNMA accounted in outer NEG. */
17584 if (outer_code
== NEG
)
17585 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
17587 *total
= rs6000_cost
->dmul
;
17590 *total
= rs6000_cost
->fp
;
17592 else if (mode
== SFmode
)
17594 /* FNMA accounted in outer NEG. */
17595 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
17598 *total
= rs6000_cost
->fp
;
17600 else if (GET_CODE (XEXP (x
, 0)) == MULT
)
17602 /* The rs6000 doesn't have shift-and-add instructions. */
17603 rs6000_rtx_costs (XEXP (x
, 0), MULT
, PLUS
, total
);
17604 *total
+= COSTS_N_INSNS (1);
17607 *total
= COSTS_N_INSNS (1);
17611 if (mode
== DFmode
)
17613 if (GET_CODE (XEXP (x
, 0)) == MULT
)
17615 /* FNMA accounted in outer NEG. */
17616 if (outer_code
== NEG
)
17619 *total
= rs6000_cost
->dmul
;
17622 *total
= rs6000_cost
->fp
;
17624 else if (mode
== SFmode
)
17626 /* FNMA accounted in outer NEG. */
17627 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
17630 *total
= rs6000_cost
->fp
;
17632 else if (GET_CODE (XEXP (x
, 0)) == MULT
)
17634 /* The rs6000 doesn't have shift-and-sub instructions. */
17635 rs6000_rtx_costs (XEXP (x
, 0), MULT
, MINUS
, total
);
17636 *total
+= COSTS_N_INSNS (1);
17639 *total
= COSTS_N_INSNS (1);
17643 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
17644 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x
, 1)), 'I'))
17646 if (INTVAL (XEXP (x
, 1)) >= -256
17647 && INTVAL (XEXP (x
, 1)) <= 255)
17648 *total
= rs6000_cost
->mulsi_const9
;
17650 *total
= rs6000_cost
->mulsi_const
;
17652 /* FMA accounted in outer PLUS/MINUS. */
17653 else if ((mode
== DFmode
|| mode
== SFmode
)
17654 && (outer_code
== PLUS
|| outer_code
== MINUS
))
17656 else if (mode
== DFmode
)
17657 *total
= rs6000_cost
->dmul
;
17658 else if (mode
== SFmode
)
17659 *total
= rs6000_cost
->fp
;
17660 else if (mode
== DImode
)
17661 *total
= rs6000_cost
->muldi
;
17663 *total
= rs6000_cost
->mulsi
;
17668 if (FLOAT_MODE_P (mode
))
17670 *total
= mode
== DFmode
? rs6000_cost
->ddiv
17671 : rs6000_cost
->sdiv
;
17678 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
17679 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
17681 if (code
== DIV
|| code
== MOD
)
17683 *total
= COSTS_N_INSNS (2);
17686 *total
= COSTS_N_INSNS (1);
17690 if (GET_MODE (XEXP (x
, 1)) == DImode
)
17691 *total
= rs6000_cost
->divdi
;
17693 *total
= rs6000_cost
->divsi
;
17695 /* Add in shift and subtract for MOD. */
17696 if (code
== MOD
|| code
== UMOD
)
17697 *total
+= COSTS_N_INSNS (2);
17701 *total
= COSTS_N_INSNS (4);
17705 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
17716 *total
= COSTS_N_INSNS (1);
17724 /* Handle mul_highpart. */
17725 if (outer_code
== TRUNCATE
17726 && GET_CODE (XEXP (x
, 0)) == MULT
)
17728 if (mode
== DImode
)
17729 *total
= rs6000_cost
->muldi
;
17731 *total
= rs6000_cost
->mulsi
;
17734 else if (outer_code
== AND
)
17737 *total
= COSTS_N_INSNS (1);
17742 if (GET_CODE (XEXP (x
, 0)) == MEM
)
17745 *total
= COSTS_N_INSNS (1);
17751 if (!FLOAT_MODE_P (mode
))
17753 *total
= COSTS_N_INSNS (1);
17759 case UNSIGNED_FLOAT
:
17763 case FLOAT_TRUNCATE
:
17764 *total
= rs6000_cost
->fp
;
17768 switch (XINT (x
, 1))
17771 *total
= rs6000_cost
->fp
;
17783 *total
= COSTS_N_INSNS (1);
17786 else if (FLOAT_MODE_P (mode
)
17787 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
17789 *total
= rs6000_cost
->fp
;
17797 /* Carry bit requires mode == Pmode.
17798 NEG or PLUS already counted so only add one. */
17800 && (outer_code
== NEG
|| outer_code
== PLUS
))
17802 *total
= COSTS_N_INSNS (1);
17805 if (outer_code
== SET
)
17807 if (XEXP (x
, 1) == const0_rtx
)
17809 *total
= COSTS_N_INSNS (2);
17812 else if (mode
== Pmode
)
17814 *total
= COSTS_N_INSNS (3);
17823 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
17825 *total
= COSTS_N_INSNS (2);
17829 if (outer_code
== COMPARE
)
17843 /* A C expression returning the cost of moving data from a register of class
17844 CLASS1 to one of CLASS2. */
17847 rs6000_register_move_cost (enum machine_mode mode
,
17848 enum reg_class from
, enum reg_class to
)
17850 /* Moves from/to GENERAL_REGS. */
17851 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
17852 || reg_classes_intersect_p (from
, GENERAL_REGS
))
17854 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
17857 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
17858 return (rs6000_memory_move_cost (mode
, from
, 0)
17859 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
17861 /* It's more expensive to move CR_REGS than CR0_REGS because of the
17863 else if (from
== CR_REGS
)
17867 /* A move will cost one instruction per GPR moved. */
17868 return 2 * HARD_REGNO_NREGS (0, mode
);
17871 /* Moving between two similar registers is just one instruction. */
17872 else if (reg_classes_intersect_p (to
, from
))
17873 return mode
== TFmode
? 4 : 2;
17875 /* Everything else has to go through GENERAL_REGS. */
17877 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
17878 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
17881 /* A C expressions returning the cost of moving data of MODE from a register to
17885 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
17886 int in ATTRIBUTE_UNUSED
)
17888 if (reg_classes_intersect_p (class, GENERAL_REGS
))
17889 return 4 * HARD_REGNO_NREGS (0, mode
);
17890 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
17891 return 4 * HARD_REGNO_NREGS (32, mode
);
17892 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
17893 return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO
, mode
);
17895 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
17898 /* Return an RTX representing where to find the function value of a
17899 function returning MODE. */
17901 rs6000_complex_function_value (enum machine_mode mode
)
17903 unsigned int regno
;
17905 enum machine_mode inner
= GET_MODE_INNER (mode
);
17906 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
17908 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
17909 regno
= FP_ARG_RETURN
;
17912 regno
= GP_ARG_RETURN
;
17914 /* 32-bit is OK since it'll go in r3/r4. */
17915 if (TARGET_32BIT
&& inner_bytes
>= 4)
17916 return gen_rtx_REG (mode
, regno
);
17919 if (inner_bytes
>= 8)
17920 return gen_rtx_REG (mode
, regno
);
17922 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
17924 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
17925 GEN_INT (inner_bytes
));
17926 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
17929 /* Define how to find the value returned by a function.
17930 VALTYPE is the data type of the value (as a tree).
17931 If the precise function being called is known, FUNC is its FUNCTION_DECL;
17932 otherwise, FUNC is 0.
17934 On the SPE, both FPs and vectors are returned in r3.
17936 On RS/6000 an integer value is in r3 and a floating-point value is in
17937 fp1, unless -msoft-float. */
17940 rs6000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
17942 enum machine_mode mode
;
17943 unsigned int regno
;
17945 /* Special handling for structs in darwin64. */
17946 if (rs6000_darwin64_abi
17947 && TYPE_MODE (valtype
) == BLKmode
17948 && TREE_CODE (valtype
) == RECORD_TYPE
17949 && int_size_in_bytes (valtype
) > 0)
17951 CUMULATIVE_ARGS valcum
;
17955 valcum
.fregno
= FP_ARG_MIN_REG
;
17956 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
17957 /* Do a trial code generation as if this were going to be passed as
17958 an argument; if any part goes in memory, we return NULL. */
17959 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
17962 /* Otherwise fall through to standard ABI rules. */
17965 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
17967 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
17968 return gen_rtx_PARALLEL (DImode
,
17970 gen_rtx_EXPR_LIST (VOIDmode
,
17971 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
17973 gen_rtx_EXPR_LIST (VOIDmode
,
17974 gen_rtx_REG (SImode
,
17975 GP_ARG_RETURN
+ 1),
17979 if ((INTEGRAL_TYPE_P (valtype
)
17980 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
17981 || POINTER_TYPE_P (valtype
))
17982 mode
= TARGET_32BIT
? SImode
: DImode
;
17984 mode
= TYPE_MODE (valtype
);
17986 if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
17987 regno
= FP_ARG_RETURN
;
17988 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
17989 && targetm
.calls
.split_complex_arg
)
17990 return rs6000_complex_function_value (mode
);
17991 else if (TREE_CODE (valtype
) == VECTOR_TYPE
17992 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
17993 && ALTIVEC_VECTOR_MODE (mode
))
17994 regno
= ALTIVEC_ARG_RETURN
;
17995 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
17996 && (mode
== DFmode
|| mode
== DCmode
))
17997 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
17999 regno
= GP_ARG_RETURN
;
18001 return gen_rtx_REG (mode
, regno
);
18004 /* Define how to find the value returned by a library function
18005 assuming the value has mode MODE. */
18007 rs6000_libcall_value (enum machine_mode mode
)
18009 unsigned int regno
;
18011 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
18013 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
18014 return gen_rtx_PARALLEL (DImode
,
18016 gen_rtx_EXPR_LIST (VOIDmode
,
18017 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
18019 gen_rtx_EXPR_LIST (VOIDmode
,
18020 gen_rtx_REG (SImode
,
18021 GP_ARG_RETURN
+ 1),
18025 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
18026 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
18027 regno
= FP_ARG_RETURN
;
18028 else if (ALTIVEC_VECTOR_MODE (mode
)
18029 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
18030 regno
= ALTIVEC_ARG_RETURN
;
18031 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
18032 return rs6000_complex_function_value (mode
);
18033 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
18034 && (mode
== DFmode
|| mode
== DCmode
))
18035 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
18037 regno
= GP_ARG_RETURN
;
18039 return gen_rtx_REG (mode
, regno
);
18042 /* Define the offset between two registers, FROM to be eliminated and its
18043 replacement TO, at the start of a routine. */
18045 rs6000_initial_elimination_offset (int from
, int to
)
18047 rs6000_stack_t
*info
= rs6000_stack_info ();
18048 HOST_WIDE_INT offset
;
18050 if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
18051 offset
= info
->push_p
? 0 : -info
->total_size
;
18052 else if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
18053 offset
= info
->total_size
;
18054 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
18055 offset
= info
->push_p
? info
->total_size
: 0;
18056 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
18059 gcc_unreachable ();
18064 /* Return true if TYPE is a SPE or AltiVec opaque type. */
18067 rs6000_is_opaque_type (tree type
)
18069 return (type
== opaque_V2SI_type_node
18070 || type
== opaque_V2SF_type_node
18071 || type
== opaque_p_V2SI_type_node
18072 || type
== opaque_V4SI_type_node
);
18076 rs6000_dwarf_register_span (rtx reg
)
18081 && (SPE_VECTOR_MODE (GET_MODE (reg
))
18082 || (TARGET_E500_DOUBLE
&& GET_MODE (reg
) == DFmode
)))
18087 regno
= REGNO (reg
);
18089 /* The duality of the SPE register size wreaks all kinds of havoc.
18090 This is a way of distinguishing r0 in 32-bits from r0 in
18093 gen_rtx_PARALLEL (VOIDmode
,
18096 gen_rtx_REG (SImode
, regno
+ 1200),
18097 gen_rtx_REG (SImode
, regno
))
18099 gen_rtx_REG (SImode
, regno
),
18100 gen_rtx_REG (SImode
, regno
+ 1200)));
18103 /* Map internal gcc register numbers to DWARF2 register numbers. */
18106 rs6000_dbx_register_number (unsigned int regno
)
18108 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
18110 if (regno
== MQ_REGNO
)
18112 if (regno
== LINK_REGISTER_REGNUM
)
18114 if (regno
== COUNT_REGISTER_REGNUM
)
18116 if (CR_REGNO_P (regno
))
18117 return regno
- CR0_REGNO
+ 86;
18118 if (regno
== XER_REGNO
)
18120 if (ALTIVEC_REGNO_P (regno
))
18121 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
18122 if (regno
== VRSAVE_REGNO
)
18124 if (regno
== VSCR_REGNO
)
18126 if (regno
== SPE_ACC_REGNO
)
18128 if (regno
== SPEFSCR_REGNO
)
18130 /* SPE high reg number. We get these values of regno from
18131 rs6000_dwarf_register_span. */
18132 gcc_assert (regno
>= 1200 && regno
< 1232);
18136 /* target hook eh_return_filter_mode */
18137 static enum machine_mode
18138 rs6000_eh_return_filter_mode (void)
18140 return TARGET_32BIT
? SImode
: word_mode
;
18143 /* Target hook for vector_mode_supported_p. */
18145 rs6000_vector_mode_supported_p (enum machine_mode mode
)
18148 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
18151 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
18158 /* Target hook for invalid_arg_for_unprototyped_fn. */
18159 static const char *
18160 invalid_arg_for_unprototyped_fn (tree typelist
, tree funcdecl
, tree val
)
18162 return (!rs6000_darwin64_abi
18164 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
18165 && (funcdecl
== NULL_TREE
18166 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
18167 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
18168 ? N_("AltiVec argument passed to unprototyped function")
18172 #include "gt-rs6000.h"