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
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
12577 rtx temp
= (fromprolog
12578 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
12579 : gen_reg_rtx (Pmode
));
12580 insn
= emit_insn (gen_load_toc_v4_pic_si (temp
));
12582 rs6000_maybe_dead (insn
);
12583 insn
= emit_move_insn (dest
, temp
);
12585 rs6000_maybe_dead (insn
);
12587 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
12590 rtx tempLR
= (fromprolog
12591 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
12592 : gen_reg_rtx (Pmode
));
12593 rtx temp0
= (fromprolog
12594 ? gen_rtx_REG (Pmode
, 0)
12595 : gen_reg_rtx (Pmode
));
12601 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
12602 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
12604 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
12605 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
12607 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR
,
12609 rs6000_maybe_dead (emit_move_insn (dest
, tempLR
));
12610 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
,
12618 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
12619 emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, tocsym
));
12620 emit_move_insn (dest
, tempLR
);
12621 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
12623 insn
= emit_insn (gen_addsi3 (dest
, temp0
, dest
));
12625 rs6000_maybe_dead (insn
);
12627 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
12629 /* This is for AIX code running in non-PIC ELF32. */
12632 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
12633 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
12635 insn
= emit_insn (gen_elf_high (dest
, realsym
));
12637 rs6000_maybe_dead (insn
);
12638 insn
= emit_insn (gen_elf_low (dest
, dest
, realsym
));
12640 rs6000_maybe_dead (insn
);
12644 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
12647 insn
= emit_insn (gen_load_toc_aix_si (dest
));
12649 insn
= emit_insn (gen_load_toc_aix_di (dest
));
12651 rs6000_maybe_dead (insn
);
12655 /* Emit instructions to restore the link register after determining where
12656 its value has been stored. */
12659 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
12661 rs6000_stack_t
*info
= rs6000_stack_info ();
12664 operands
[0] = source
;
12665 operands
[1] = scratch
;
12667 if (info
->lr_save_p
)
12669 rtx frame_rtx
= stack_pointer_rtx
;
12670 HOST_WIDE_INT sp_offset
= 0;
12673 if (frame_pointer_needed
12674 || current_function_calls_alloca
12675 || info
->total_size
> 32767)
12677 emit_move_insn (operands
[1], gen_rtx_MEM (Pmode
, frame_rtx
));
12678 frame_rtx
= operands
[1];
12680 else if (info
->push_p
)
12681 sp_offset
= info
->total_size
;
12683 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
12684 tmp
= gen_rtx_MEM (Pmode
, tmp
);
12685 emit_move_insn (tmp
, operands
[0]);
12688 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
), operands
[0]);
12691 static GTY(()) int set
= -1;
12694 get_TOC_alias_set (void)
12697 set
= new_alias_set ();
12701 /* This returns nonzero if the current function uses the TOC. This is
12702 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
12703 is generated by the ABI_V4 load_toc_* patterns. */
12710 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
12713 rtx pat
= PATTERN (insn
);
12716 if (GET_CODE (pat
) == PARALLEL
)
12717 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
12719 rtx sub
= XVECEXP (pat
, 0, i
);
12720 if (GET_CODE (sub
) == USE
)
12722 sub
= XEXP (sub
, 0);
12723 if (GET_CODE (sub
) == UNSPEC
12724 && XINT (sub
, 1) == UNSPEC_TOC
)
12734 create_TOC_reference (rtx symbol
)
12736 return gen_rtx_PLUS (Pmode
,
12737 gen_rtx_REG (Pmode
, TOC_REGISTER
),
12738 gen_rtx_CONST (Pmode
,
12739 gen_rtx_MINUS (Pmode
, symbol
,
12740 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
12743 /* If _Unwind_* has been called from within the same module,
12744 toc register is not guaranteed to be saved to 40(1) on function
12745 entry. Save it there in that case. */
12748 rs6000_aix_emit_builtin_unwind_init (void)
12751 rtx stack_top
= gen_reg_rtx (Pmode
);
12752 rtx opcode_addr
= gen_reg_rtx (Pmode
);
12753 rtx opcode
= gen_reg_rtx (SImode
);
12754 rtx tocompare
= gen_reg_rtx (SImode
);
12755 rtx no_toc_save_needed
= gen_label_rtx ();
12757 mem
= gen_rtx_MEM (Pmode
, hard_frame_pointer_rtx
);
12758 emit_move_insn (stack_top
, mem
);
12760 mem
= gen_rtx_MEM (Pmode
,
12761 gen_rtx_PLUS (Pmode
, stack_top
,
12762 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
12763 emit_move_insn (opcode_addr
, mem
);
12764 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
12765 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
12766 : 0xE8410028, SImode
));
12768 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
12769 SImode
, NULL_RTX
, NULL_RTX
,
12770 no_toc_save_needed
);
12772 mem
= gen_rtx_MEM (Pmode
,
12773 gen_rtx_PLUS (Pmode
, stack_top
,
12774 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
12775 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
12776 emit_label (no_toc_save_needed
);
12779 /* This ties together stack memory (MEM with an alias set of
12780 rs6000_sr_alias_set) and the change to the stack pointer. */
12783 rs6000_emit_stack_tie (void)
12785 rtx mem
= gen_rtx_MEM (BLKmode
, gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
12787 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
12788 emit_insn (gen_stack_tie (mem
));
12791 /* Emit the correct code for allocating stack space, as insns.
12792 If COPY_R12, make sure a copy of the old frame is left in r12.
12793 The generated code may use hard register 0 as a temporary. */
12796 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
12799 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
12800 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
12801 rtx todec
= gen_int_mode (-size
, Pmode
);
12803 if (INTVAL (todec
) != -size
)
12805 warning (0, "stack frame too large");
12806 emit_insn (gen_trap ());
12810 if (current_function_limit_stack
)
12812 if (REG_P (stack_limit_rtx
)
12813 && REGNO (stack_limit_rtx
) > 1
12814 && REGNO (stack_limit_rtx
) <= 31)
12816 emit_insn (TARGET_32BIT
12817 ? gen_addsi3 (tmp_reg
,
12820 : gen_adddi3 (tmp_reg
,
12824 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
12827 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
12829 && DEFAULT_ABI
== ABI_V4
)
12831 rtx toload
= gen_rtx_CONST (VOIDmode
,
12832 gen_rtx_PLUS (Pmode
,
12836 emit_insn (gen_elf_high (tmp_reg
, toload
));
12837 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
12838 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
12842 warning (0, "stack limit expression is not supported");
12845 if (copy_r12
|| ! TARGET_UPDATE
)
12846 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
12852 /* Need a note here so that try_split doesn't get confused. */
12853 if (get_last_insn () == NULL_RTX
)
12854 emit_note (NOTE_INSN_DELETED
);
12855 insn
= emit_move_insn (tmp_reg
, todec
);
12856 try_split (PATTERN (insn
), insn
, 0);
12860 insn
= emit_insn (TARGET_32BIT
12861 ? gen_movsi_update (stack_reg
, stack_reg
,
12863 : gen_movdi_di_update (stack_reg
, stack_reg
,
12864 todec
, stack_reg
));
12868 insn
= emit_insn (TARGET_32BIT
12869 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
12870 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
12871 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
12872 gen_rtx_REG (Pmode
, 12));
12875 RTX_FRAME_RELATED_P (insn
) = 1;
12877 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
12878 gen_rtx_SET (VOIDmode
, stack_reg
,
12879 gen_rtx_PLUS (Pmode
, stack_reg
,
12884 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
12885 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
12886 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
12887 deduce these equivalences by itself so it wasn't necessary to hold
12888 its hand so much. */
12891 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
12892 rtx reg2
, rtx rreg
)
12896 /* copy_rtx will not make unique copies of registers, so we need to
12897 ensure we don't have unwanted sharing here. */
12899 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
12902 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
12904 real
= copy_rtx (PATTERN (insn
));
12906 if (reg2
!= NULL_RTX
)
12907 real
= replace_rtx (real
, reg2
, rreg
);
12909 real
= replace_rtx (real
, reg
,
12910 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
12911 STACK_POINTER_REGNUM
),
12914 /* We expect that 'real' is either a SET or a PARALLEL containing
12915 SETs (and possibly other stuff). In a PARALLEL, all the SETs
12916 are important so they all have to be marked RTX_FRAME_RELATED_P. */
12918 if (GET_CODE (real
) == SET
)
12922 temp
= simplify_rtx (SET_SRC (set
));
12924 SET_SRC (set
) = temp
;
12925 temp
= simplify_rtx (SET_DEST (set
));
12927 SET_DEST (set
) = temp
;
12928 if (GET_CODE (SET_DEST (set
)) == MEM
)
12930 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
12932 XEXP (SET_DEST (set
), 0) = temp
;
12939 gcc_assert (GET_CODE (real
) == PARALLEL
);
12940 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
12941 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
12943 rtx set
= XVECEXP (real
, 0, i
);
12945 temp
= simplify_rtx (SET_SRC (set
));
12947 SET_SRC (set
) = temp
;
12948 temp
= simplify_rtx (SET_DEST (set
));
12950 SET_DEST (set
) = temp
;
12951 if (GET_CODE (SET_DEST (set
)) == MEM
)
12953 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
12955 XEXP (SET_DEST (set
), 0) = temp
;
12957 RTX_FRAME_RELATED_P (set
) = 1;
12962 real
= spe_synthesize_frame_save (real
);
12964 RTX_FRAME_RELATED_P (insn
) = 1;
12965 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
12970 /* Given an SPE frame note, return a PARALLEL of SETs with the
12971 original note, plus a synthetic register save. */
12974 spe_synthesize_frame_save (rtx real
)
12976 rtx synth
, offset
, reg
, real2
;
12978 if (GET_CODE (real
) != SET
12979 || GET_MODE (SET_SRC (real
)) != V2SImode
)
12982 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
12983 frame related note. The parallel contains a set of the register
12984 being saved, and another set to a synthetic register (n+1200).
12985 This is so we can differentiate between 64-bit and 32-bit saves.
12986 Words cannot describe this nastiness. */
12988 gcc_assert (GET_CODE (SET_DEST (real
)) == MEM
12989 && GET_CODE (XEXP (SET_DEST (real
), 0)) == PLUS
12990 && GET_CODE (SET_SRC (real
)) == REG
);
12993 (set (mem (plus (reg x) (const y)))
12996 (set (mem (plus (reg x) (const y+4)))
13000 real2
= copy_rtx (real
);
13001 PUT_MODE (SET_DEST (real2
), SImode
);
13002 reg
= SET_SRC (real2
);
13003 real2
= replace_rtx (real2
, reg
, gen_rtx_REG (SImode
, REGNO (reg
)));
13004 synth
= copy_rtx (real2
);
13006 if (BYTES_BIG_ENDIAN
)
13008 offset
= XEXP (XEXP (SET_DEST (real2
), 0), 1);
13009 real2
= replace_rtx (real2
, offset
, GEN_INT (INTVAL (offset
) + 4));
13012 reg
= SET_SRC (synth
);
13014 synth
= replace_rtx (synth
, reg
,
13015 gen_rtx_REG (SImode
, REGNO (reg
) + 1200));
13017 offset
= XEXP (XEXP (SET_DEST (synth
), 0), 1);
13018 synth
= replace_rtx (synth
, offset
,
13019 GEN_INT (INTVAL (offset
)
13020 + (BYTES_BIG_ENDIAN
? 0 : 4)));
13022 RTX_FRAME_RELATED_P (synth
) = 1;
13023 RTX_FRAME_RELATED_P (real2
) = 1;
13024 if (BYTES_BIG_ENDIAN
)
13025 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, synth
, real2
));
13027 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, real2
, synth
));
13032 /* Returns an insn that has a vrsave set operation with the
13033 appropriate CLOBBERs. */
13036 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
13039 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
13040 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
13043 = gen_rtx_SET (VOIDmode
,
13045 gen_rtx_UNSPEC_VOLATILE (SImode
,
13046 gen_rtvec (2, reg
, vrsave
),
13051 /* We need to clobber the registers in the mask so the scheduler
13052 does not move sets to VRSAVE before sets of AltiVec registers.
13054 However, if the function receives nonlocal gotos, reload will set
13055 all call saved registers live. We will end up with:
13057 (set (reg 999) (mem))
13058 (parallel [ (set (reg vrsave) (unspec blah))
13059 (clobber (reg 999))])
13061 The clobber will cause the store into reg 999 to be dead, and
13062 flow will attempt to delete an epilogue insn. In this case, we
13063 need an unspec use/set of the register. */
13065 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13066 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13068 if (!epiloguep
|| call_used_regs
[i
])
13069 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
13070 gen_rtx_REG (V4SImode
, i
));
13073 rtx reg
= gen_rtx_REG (V4SImode
, i
);
13076 = gen_rtx_SET (VOIDmode
,
13078 gen_rtx_UNSPEC (V4SImode
,
13079 gen_rtvec (1, reg
), 27));
13083 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
13085 for (i
= 0; i
< nclobs
; ++i
)
13086 XVECEXP (insn
, 0, i
) = clobs
[i
];
13091 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
13092 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
13095 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
13096 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
13098 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
13099 rtx replacea
, replaceb
;
13101 int_rtx
= GEN_INT (offset
);
13103 /* Some cases that need register indexed addressing. */
13104 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
13105 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
13107 && SPE_VECTOR_MODE (mode
)
13108 && !SPE_CONST_OFFSET_OK (offset
)))
13110 /* Whomever calls us must make sure r11 is available in the
13111 flow path of instructions in the prologue. */
13112 offset_rtx
= gen_rtx_REG (Pmode
, 11);
13113 emit_move_insn (offset_rtx
, int_rtx
);
13115 replacea
= offset_rtx
;
13116 replaceb
= int_rtx
;
13120 offset_rtx
= int_rtx
;
13121 replacea
= NULL_RTX
;
13122 replaceb
= NULL_RTX
;
13125 reg
= gen_rtx_REG (mode
, regno
);
13126 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
13127 mem
= gen_rtx_MEM (mode
, addr
);
13128 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13130 insn
= emit_move_insn (mem
, reg
);
13132 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
13135 /* Emit an offset memory reference suitable for a frame store, while
13136 converting to a valid addressing mode. */
13139 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
13141 rtx int_rtx
, offset_rtx
;
13143 int_rtx
= GEN_INT (offset
);
13145 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
13146 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
13148 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
13149 emit_move_insn (offset_rtx
, int_rtx
);
13152 offset_rtx
= int_rtx
;
13154 return gen_rtx_MEM (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
13157 #ifndef TARGET_FIX_AND_CONTINUE
13158 #define TARGET_FIX_AND_CONTINUE 0
13161 /* Emit function prologue as insns. */
13164 rs6000_emit_prologue (void)
13166 rs6000_stack_t
*info
= rs6000_stack_info ();
13167 enum machine_mode reg_mode
= Pmode
;
13168 int reg_size
= TARGET_32BIT
? 4 : 8;
13169 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
13170 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
13171 rtx frame_reg_rtx
= sp_reg_rtx
;
13172 rtx cr_save_rtx
= NULL_RTX
;
13174 int saving_FPRs_inline
;
13175 int using_store_multiple
;
13176 HOST_WIDE_INT sp_offset
= 0;
13178 if (TARGET_FIX_AND_CONTINUE
)
13180 /* gdb on darwin arranges to forward a function from the old
13181 address by modifying the first 5 instructions of the function
13182 to branch to the overriding function. This is necessary to
13183 permit function pointers that point to the old function to
13184 actually forward to the new function. */
13185 emit_insn (gen_nop ());
13186 emit_insn (gen_nop ());
13187 emit_insn (gen_nop ());
13188 emit_insn (gen_nop ());
13189 emit_insn (gen_nop ());
13192 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
13194 reg_mode
= V2SImode
;
13198 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
13199 && (!TARGET_SPE_ABI
13200 || info
->spe_64bit_regs_used
== 0)
13201 && info
->first_gp_reg_save
< 31);
13202 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
13203 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
13204 || current_function_calls_eh_return
13205 || cfun
->machine
->ra_need_lr
);
13207 /* For V.4, update stack before we do any saving and set back pointer. */
13209 && (DEFAULT_ABI
== ABI_V4
13210 || current_function_calls_eh_return
))
13212 if (info
->total_size
< 32767)
13213 sp_offset
= info
->total_size
;
13215 frame_reg_rtx
= frame_ptr_rtx
;
13216 rs6000_emit_allocate_stack (info
->total_size
,
13217 (frame_reg_rtx
!= sp_reg_rtx
13218 && (info
->cr_save_p
13220 || info
->first_fp_reg_save
< 64
13221 || info
->first_gp_reg_save
< 32
13223 if (frame_reg_rtx
!= sp_reg_rtx
)
13224 rs6000_emit_stack_tie ();
13227 /* Handle world saves specially here. */
13228 if (WORLD_SAVE_P (info
))
13234 /* save_world expects lr in r0. */
13235 if (info
->lr_save_p
)
13237 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
13238 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
13239 RTX_FRAME_RELATED_P (insn
) = 1;
13242 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
13243 assumptions about the offsets of various bits of the stack
13245 gcc_assert (info
->gp_save_offset
== -220
13246 && info
->fp_save_offset
== -144
13247 && info
->lr_save_offset
== 8
13248 && info
->cr_save_offset
== 4
13251 && (!current_function_calls_eh_return
13252 || info
->ehrd_offset
== -432)
13253 && info
->vrsave_save_offset
== -224
13254 && info
->altivec_save_offset
== (-224 -16 -192));
13256 treg
= gen_rtx_REG (SImode
, 11);
13257 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
13259 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
13260 in R11. It also clobbers R12, so beware! */
13262 /* Preserve CR2 for save_world prologues */
13264 sz
+= 32 - info
->first_gp_reg_save
;
13265 sz
+= 64 - info
->first_fp_reg_save
;
13266 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
13267 p
= rtvec_alloc (sz
);
13269 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
13270 gen_rtx_REG (Pmode
,
13271 LINK_REGISTER_REGNUM
));
13272 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
13273 gen_rtx_SYMBOL_REF (Pmode
,
13275 /* We do floats first so that the instruction pattern matches
13277 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
13279 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
13280 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13281 GEN_INT (info
->fp_save_offset
13282 + sp_offset
+ 8 * i
));
13283 rtx mem
= gen_rtx_MEM (DFmode
, addr
);
13284 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13286 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13288 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
13290 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
13291 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13292 GEN_INT (info
->altivec_save_offset
13293 + sp_offset
+ 16 * i
));
13294 rtx mem
= gen_rtx_MEM (V4SImode
, addr
);
13295 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13297 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13299 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13301 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13302 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13303 GEN_INT (info
->gp_save_offset
13304 + sp_offset
+ reg_size
* i
));
13305 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13306 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13308 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13312 /* CR register traditionally saved as CR2. */
13313 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
13314 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13315 GEN_INT (info
->cr_save_offset
13317 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13318 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13320 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13322 /* Prevent any attempt to delete the setting of r0 and treg! */
13323 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 0));
13324 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, treg
);
13325 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
, sp_reg_rtx
);
13327 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13328 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13329 NULL_RTX
, NULL_RTX
);
13331 if (current_function_calls_eh_return
)
13336 unsigned int regno
= EH_RETURN_DATA_REGNO (i
);
13337 if (regno
== INVALID_REGNUM
)
13339 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
13340 info
->ehrd_offset
+ sp_offset
13341 + reg_size
* (int) i
,
13347 /* Save AltiVec registers if needed. */
13348 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
13352 /* There should be a non inline version of this, for when we
13353 are saving lots of vector registers. */
13354 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13355 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13357 rtx areg
, savereg
, mem
;
13360 offset
= info
->altivec_save_offset
+ sp_offset
13361 + 16 * (i
- info
->first_altivec_reg_save
);
13363 savereg
= gen_rtx_REG (V4SImode
, i
);
13365 areg
= gen_rtx_REG (Pmode
, 0);
13366 emit_move_insn (areg
, GEN_INT (offset
));
13368 /* AltiVec addressing mode is [reg+reg]. */
13369 mem
= gen_rtx_MEM (V4SImode
,
13370 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
13372 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13374 insn
= emit_move_insn (mem
, savereg
);
13376 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13377 areg
, GEN_INT (offset
));
13381 /* VRSAVE is a bit vector representing which AltiVec registers
13382 are used. The OS uses this to determine which vector
13383 registers to save on a context switch. We need to save
13384 VRSAVE on the stack frame, add whatever AltiVec registers we
13385 used in this function, and do the corresponding magic in the
13388 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
13389 && info
->vrsave_mask
!= 0)
13391 rtx reg
, mem
, vrsave
;
13394 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
13395 as frame_reg_rtx and r11 as the static chain pointer for
13396 nested functions. */
13397 reg
= gen_rtx_REG (SImode
, 0);
13398 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
13400 emit_insn (gen_get_vrsave_internal (reg
));
13402 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
13404 if (!WORLD_SAVE_P (info
))
13407 offset
= info
->vrsave_save_offset
+ sp_offset
;
13409 = gen_rtx_MEM (SImode
,
13410 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, GEN_INT (offset
)));
13411 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13412 insn
= emit_move_insn (mem
, reg
);
13415 /* Include the registers in the mask. */
13416 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
13418 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
13421 /* If we use the link register, get it into r0. */
13422 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
13424 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
13425 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
13426 RTX_FRAME_RELATED_P (insn
) = 1;
13429 /* If we need to save CR, put it into r12. */
13430 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
13434 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
13435 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
13436 RTX_FRAME_RELATED_P (insn
) = 1;
13437 /* Now, there's no way that dwarf2out_frame_debug_expr is going
13438 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
13439 But that's OK. All we have to do is specify that _one_ condition
13440 code register is saved in this stack slot. The thrower's epilogue
13441 will then restore all the call-saved registers.
13442 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
13443 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
13444 gen_rtx_REG (SImode
, CR2_REGNO
));
13445 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13450 /* Do any required saving of fpr's. If only one or two to save, do
13451 it ourselves. Otherwise, call function. */
13452 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
13455 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
13456 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
13457 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
13458 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
13459 info
->first_fp_reg_save
+ i
,
13460 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
13463 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
13467 const char *alloc_rname
;
13469 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
13471 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
13472 gen_rtx_REG (Pmode
,
13473 LINK_REGISTER_REGNUM
));
13474 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
13475 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
13476 alloc_rname
= ggc_strdup (rname
);
13477 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
13478 gen_rtx_SYMBOL_REF (Pmode
,
13480 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
13482 rtx addr
, reg
, mem
;
13483 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
13484 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13485 GEN_INT (info
->fp_save_offset
13486 + sp_offset
+ 8*i
));
13487 mem
= gen_rtx_MEM (DFmode
, addr
);
13488 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13490 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13492 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13493 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13494 NULL_RTX
, NULL_RTX
);
13497 /* Save GPRs. This is done as a PARALLEL if we are using
13498 the store-multiple instructions. */
13499 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
13503 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
13504 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13506 rtx addr
, reg
, mem
;
13507 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13508 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13509 GEN_INT (info
->gp_save_offset
13512 mem
= gen_rtx_MEM (reg_mode
, addr
);
13513 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13515 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
13517 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13518 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13519 NULL_RTX
, NULL_RTX
);
13521 else if (!WORLD_SAVE_P (info
))
13524 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13525 if ((regs_ever_live
[info
->first_gp_reg_save
+i
]
13526 && (! call_used_regs
[info
->first_gp_reg_save
+i
]
13527 || (i
+info
->first_gp_reg_save
13528 == RS6000_PIC_OFFSET_TABLE_REGNUM
13529 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
13530 || (i
+info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
13531 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
13532 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
13534 rtx addr
, reg
, mem
;
13535 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13537 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
13539 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
13542 if (!SPE_CONST_OFFSET_OK (offset
))
13544 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
13545 emit_move_insn (b
, GEN_INT (offset
));
13548 b
= GEN_INT (offset
);
13550 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
13551 mem
= gen_rtx_MEM (V2SImode
, addr
);
13552 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13553 insn
= emit_move_insn (mem
, reg
);
13555 if (GET_CODE (b
) == CONST_INT
)
13556 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13557 NULL_RTX
, NULL_RTX
);
13559 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13560 b
, GEN_INT (offset
));
13564 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13565 GEN_INT (info
->gp_save_offset
13568 mem
= gen_rtx_MEM (reg_mode
, addr
);
13569 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13571 insn
= emit_move_insn (mem
, reg
);
13572 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13573 NULL_RTX
, NULL_RTX
);
13578 /* ??? There's no need to emit actual instructions here, but it's the
13579 easiest way to get the frame unwind information emitted. */
13580 if (!WORLD_SAVE_P (info
) && current_function_calls_eh_return
)
13582 unsigned int i
, regno
;
13584 /* In AIX ABI we need to pretend we save r2 here. */
13587 rtx addr
, reg
, mem
;
13589 reg
= gen_rtx_REG (reg_mode
, 2);
13590 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13591 GEN_INT (sp_offset
+ 5 * reg_size
));
13592 mem
= gen_rtx_MEM (reg_mode
, addr
);
13593 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13595 insn
= emit_move_insn (mem
, reg
);
13596 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13597 NULL_RTX
, NULL_RTX
);
13598 PATTERN (insn
) = gen_blockage ();
13603 regno
= EH_RETURN_DATA_REGNO (i
);
13604 if (regno
== INVALID_REGNUM
)
13607 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
13608 info
->ehrd_offset
+ sp_offset
13609 + reg_size
* (int) i
,
13614 /* Save lr if we used it. */
13615 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
13617 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13618 GEN_INT (info
->lr_save_offset
+ sp_offset
));
13619 rtx reg
= gen_rtx_REG (Pmode
, 0);
13620 rtx mem
= gen_rtx_MEM (Pmode
, addr
);
13621 /* This should not be of rs6000_sr_alias_set, because of
13622 __builtin_return_address. */
13624 insn
= emit_move_insn (mem
, reg
);
13625 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13626 NULL_RTX
, NULL_RTX
);
13629 /* Save CR if we use any that must be preserved. */
13630 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
13632 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13633 GEN_INT (info
->cr_save_offset
+ sp_offset
));
13634 rtx mem
= gen_rtx_MEM (SImode
, addr
);
13635 /* See the large comment above about why CR2_REGNO is used. */
13636 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
13638 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13640 /* If r12 was used to hold the original sp, copy cr into r0 now
13642 if (REGNO (frame_reg_rtx
) == 12)
13646 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
13647 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
13648 RTX_FRAME_RELATED_P (insn
) = 1;
13649 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
13650 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13655 insn
= emit_move_insn (mem
, cr_save_rtx
);
13657 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
13658 NULL_RTX
, NULL_RTX
);
13661 /* Update stack and set back pointer unless this is V.4,
13662 for which it was done previously. */
13663 if (!WORLD_SAVE_P (info
) && info
->push_p
13664 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
13665 rs6000_emit_allocate_stack (info
->total_size
, FALSE
);
13667 /* Set frame pointer, if needed. */
13668 if (frame_pointer_needed
)
13670 insn
= emit_move_insn (gen_rtx_REG (Pmode
, FRAME_POINTER_REGNUM
),
13672 RTX_FRAME_RELATED_P (insn
) = 1;
13675 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
13676 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
13677 || (DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1
13678 && regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
]))
13680 /* If emit_load_toc_table will use the link register, we need to save
13681 it. We use R12 for this purpose because emit_load_toc_table
13682 can use register 0. This allows us to use a plain 'blr' to return
13683 from the procedure more often. */
13684 int save_LR_around_toc_setup
= (TARGET_ELF
13685 && DEFAULT_ABI
!= ABI_AIX
13687 && ! info
->lr_save_p
13688 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
13689 if (save_LR_around_toc_setup
)
13691 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13693 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
13694 rs6000_maybe_dead (insn
);
13695 RTX_FRAME_RELATED_P (insn
) = 1;
13697 rs6000_emit_load_toc_table (TRUE
);
13699 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
13700 rs6000_maybe_dead (insn
);
13701 RTX_FRAME_RELATED_P (insn
) = 1;
13704 rs6000_emit_load_toc_table (TRUE
);
13708 if (DEFAULT_ABI
== ABI_DARWIN
13709 && flag_pic
&& current_function_uses_pic_offset_table
)
13711 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13712 rtx src
= machopic_function_base_sym ();
13714 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr
, src
)));
13716 insn
= emit_move_insn (gen_rtx_REG (Pmode
,
13717 RS6000_PIC_OFFSET_TABLE_REGNUM
),
13719 rs6000_maybe_dead (insn
);
13724 /* Write function prologue. */
13727 rs6000_output_function_prologue (FILE *file
,
13728 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
13730 rs6000_stack_t
*info
= rs6000_stack_info ();
13732 if (TARGET_DEBUG_STACK
)
13733 debug_stack_info (info
);
13735 /* Write .extern for any function we will call to save and restore
13737 if (info
->first_fp_reg_save
< 64
13738 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
13739 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
13740 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
13741 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
13742 RESTORE_FP_SUFFIX
);
13744 /* Write .extern for AIX common mode routines, if needed. */
13745 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
13747 fputs ("\t.extern __mulh\n", file
);
13748 fputs ("\t.extern __mull\n", file
);
13749 fputs ("\t.extern __divss\n", file
);
13750 fputs ("\t.extern __divus\n", file
);
13751 fputs ("\t.extern __quoss\n", file
);
13752 fputs ("\t.extern __quous\n", file
);
13753 common_mode_defined
= 1;
13756 if (! HAVE_prologue
)
13760 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
13761 the "toplevel" insn chain. */
13762 emit_note (NOTE_INSN_DELETED
);
13763 rs6000_emit_prologue ();
13764 emit_note (NOTE_INSN_DELETED
);
13766 /* Expand INSN_ADDRESSES so final() doesn't crash. */
13770 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
13772 INSN_ADDRESSES_NEW (insn
, addr
);
13777 if (TARGET_DEBUG_STACK
)
13778 debug_rtx_list (get_insns (), 100);
13779 final (get_insns (), file
, FALSE
);
13783 rs6000_pic_labelno
++;
13786 /* Emit function epilogue as insns.
13788 At present, dwarf2out_frame_debug_expr doesn't understand
13789 register restores, so we don't bother setting RTX_FRAME_RELATED_P
13790 anywhere in the epilogue. Most of the insns below would in any case
13791 need special notes to explain where r11 is in relation to the stack. */
13794 rs6000_emit_epilogue (int sibcall
)
13796 rs6000_stack_t
*info
;
13797 int restoring_FPRs_inline
;
13798 int using_load_multiple
;
13799 int using_mfcr_multiple
;
13800 int use_backchain_to_restore_sp
;
13802 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
13803 rtx frame_reg_rtx
= sp_reg_rtx
;
13804 enum machine_mode reg_mode
= Pmode
;
13805 int reg_size
= TARGET_32BIT
? 4 : 8;
13808 info
= rs6000_stack_info ();
13810 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
13812 reg_mode
= V2SImode
;
13816 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
13817 && (!TARGET_SPE_ABI
13818 || info
->spe_64bit_regs_used
== 0)
13819 && info
->first_gp_reg_save
< 31);
13820 restoring_FPRs_inline
= (sibcall
13821 || current_function_calls_eh_return
13822 || info
->first_fp_reg_save
== 64
13823 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
13824 use_backchain_to_restore_sp
= (frame_pointer_needed
13825 || current_function_calls_alloca
13826 || info
->total_size
> 32767);
13827 using_mfcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
13828 || rs6000_cpu
== PROCESSOR_PPC603
13829 || rs6000_cpu
== PROCESSOR_PPC750
13832 if (WORLD_SAVE_P (info
))
13836 const char *alloc_rname
;
13839 /* eh_rest_world_r10 will return to the location saved in the LR
13840 stack slot (which is not likely to be our caller.)
13841 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
13842 rest_world is similar, except any R10 parameter is ignored.
13843 The exception-handling stuff that was here in 2.95 is no
13844 longer necessary. */
13848 + 32 - info
->first_gp_reg_save
13849 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
13850 + 63 + 1 - info
->first_fp_reg_save
);
13852 strcpy (rname
, ((current_function_calls_eh_return
) ?
13853 "*eh_rest_world_r10" : "*rest_world"));
13854 alloc_rname
= ggc_strdup (rname
);
13857 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
13858 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
13859 gen_rtx_REG (Pmode
,
13860 LINK_REGISTER_REGNUM
));
13862 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
13863 /* The instruction pattern requires a clobber here;
13864 it is shared with the restVEC helper. */
13866 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
13869 /* CR register traditionally saved as CR2. */
13870 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
13871 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13872 GEN_INT (info
->cr_save_offset
));
13873 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13874 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13876 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13879 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
13881 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
13882 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13883 GEN_INT (info
->gp_save_offset
13885 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
13886 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13888 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13890 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
13892 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
13893 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13894 GEN_INT (info
->altivec_save_offset
13896 rtx mem
= gen_rtx_MEM (V4SImode
, addr
);
13897 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13899 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13901 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
13903 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
13904 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13905 GEN_INT (info
->fp_save_offset
13907 rtx mem
= gen_rtx_MEM (DFmode
, addr
);
13908 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13910 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
13913 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
13915 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
13917 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
13919 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
13921 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
13922 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
13927 /* If we have a frame pointer, a call to alloca, or a large stack
13928 frame, restore the old stack pointer using the backchain. Otherwise,
13929 we know what size to update it with. */
13930 if (use_backchain_to_restore_sp
)
13932 /* Under V.4, don't reset the stack pointer until after we're done
13933 loading the saved registers. */
13934 if (DEFAULT_ABI
== ABI_V4
)
13935 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
13937 emit_move_insn (frame_reg_rtx
,
13938 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
13941 else if (info
->push_p
)
13943 if (DEFAULT_ABI
== ABI_V4
13944 || current_function_calls_eh_return
)
13945 sp_offset
= info
->total_size
;
13948 emit_insn (TARGET_32BIT
13949 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
13950 GEN_INT (info
->total_size
))
13951 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
13952 GEN_INT (info
->total_size
)));
13956 /* Restore AltiVec registers if needed. */
13957 if (TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
13961 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13962 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13964 rtx addr
, areg
, mem
;
13966 areg
= gen_rtx_REG (Pmode
, 0);
13968 (areg
, GEN_INT (info
->altivec_save_offset
13970 + 16 * (i
- info
->first_altivec_reg_save
)));
13972 /* AltiVec addressing mode is [reg+reg]. */
13973 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
13974 mem
= gen_rtx_MEM (V4SImode
, addr
);
13975 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13977 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
13981 /* Restore VRSAVE if needed. */
13982 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
13983 && info
->vrsave_mask
!= 0)
13985 rtx addr
, mem
, reg
;
13987 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
13988 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
13989 mem
= gen_rtx_MEM (SImode
, addr
);
13990 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
13991 reg
= gen_rtx_REG (SImode
, 12);
13992 emit_move_insn (reg
, mem
);
13994 emit_insn (generate_set_vrsave (reg
, info
, 1));
13997 /* Get the old lr if we saved it. */
13998 if (info
->lr_save_p
)
14000 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
14001 info
->lr_save_offset
+ sp_offset
);
14003 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14005 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
14008 /* Get the old cr if we saved it. */
14009 if (info
->cr_save_p
)
14011 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14012 GEN_INT (info
->cr_save_offset
+ sp_offset
));
14013 rtx mem
= gen_rtx_MEM (SImode
, addr
);
14015 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14017 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
14020 /* Set LR here to try to overlap restores below. */
14021 if (info
->lr_save_p
)
14022 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
),
14023 gen_rtx_REG (Pmode
, 0));
14025 /* Load exception handler data registers, if needed. */
14026 if (current_function_calls_eh_return
)
14028 unsigned int i
, regno
;
14032 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14033 GEN_INT (sp_offset
+ 5 * reg_size
));
14034 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14036 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14038 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
14045 regno
= EH_RETURN_DATA_REGNO (i
);
14046 if (regno
== INVALID_REGNUM
)
14049 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
14050 info
->ehrd_offset
+ sp_offset
14051 + reg_size
* (int) i
);
14052 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14054 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
14058 /* Restore GPRs. This is done as a PARALLEL if we are using
14059 the load-multiple instructions. */
14060 if (using_load_multiple
)
14063 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14064 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14066 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14067 GEN_INT (info
->gp_save_offset
14070 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14072 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14075 gen_rtx_SET (VOIDmode
,
14076 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
14079 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14082 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14083 if ((regs_ever_live
[info
->first_gp_reg_save
+i
]
14084 && (! call_used_regs
[info
->first_gp_reg_save
+i
]
14085 || (i
+info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14086 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14087 || (i
+info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14088 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14089 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14091 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14092 GEN_INT (info
->gp_save_offset
14095 rtx mem
= gen_rtx_MEM (reg_mode
, addr
);
14097 /* Restore 64-bit quantities for SPE. */
14098 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14100 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14103 if (!SPE_CONST_OFFSET_OK (offset
))
14105 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14106 emit_move_insn (b
, GEN_INT (offset
));
14109 b
= GEN_INT (offset
);
14111 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
14112 mem
= gen_rtx_MEM (V2SImode
, addr
);
14115 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14117 emit_move_insn (gen_rtx_REG (reg_mode
,
14118 info
->first_gp_reg_save
+ i
), mem
);
14121 /* Restore fpr's if we need to do it without calling a function. */
14122 if (restoring_FPRs_inline
)
14123 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14124 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
14125 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
14128 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14129 GEN_INT (info
->fp_save_offset
14132 mem
= gen_rtx_MEM (DFmode
, addr
);
14133 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14135 emit_move_insn (gen_rtx_REG (DFmode
,
14136 info
->first_fp_reg_save
+ i
),
14140 /* If we saved cr, restore it here. Just those that were used. */
14141 if (info
->cr_save_p
)
14143 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
14146 if (using_mfcr_multiple
)
14148 for (i
= 0; i
< 8; i
++)
14149 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14151 gcc_assert (count
);
14154 if (using_mfcr_multiple
&& count
> 1)
14159 p
= rtvec_alloc (count
);
14162 for (i
= 0; i
< 8; i
++)
14163 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14165 rtvec r
= rtvec_alloc (2);
14166 RTVEC_ELT (r
, 0) = r12_rtx
;
14167 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
14168 RTVEC_ELT (p
, ndx
) =
14169 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
14170 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
14173 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14174 gcc_assert (ndx
== count
);
14177 for (i
= 0; i
< 8; i
++)
14178 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
14180 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
14186 /* If this is V.4, unwind the stack pointer after all of the loads
14187 have been done. We need to emit a block here so that sched
14188 doesn't decide to move the sp change before the register restores
14189 (which may not have any obvious dependency on the stack). This
14190 doesn't hurt performance, because there is no scheduling that can
14191 be done after this point. */
14192 if (DEFAULT_ABI
== ABI_V4
14193 || current_function_calls_eh_return
)
14195 if (frame_reg_rtx
!= sp_reg_rtx
)
14196 rs6000_emit_stack_tie ();
14198 if (use_backchain_to_restore_sp
)
14200 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
14202 else if (sp_offset
!= 0)
14204 emit_insn (TARGET_32BIT
14205 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
14206 GEN_INT (sp_offset
))
14207 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
14208 GEN_INT (sp_offset
)));
14212 if (current_function_calls_eh_return
)
14214 rtx sa
= EH_RETURN_STACKADJ_RTX
;
14215 emit_insn (TARGET_32BIT
14216 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
14217 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
14223 if (! restoring_FPRs_inline
)
14224 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
14226 p
= rtvec_alloc (2);
14228 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
14229 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
14230 gen_rtx_REG (Pmode
,
14231 LINK_REGISTER_REGNUM
));
14233 /* If we have to restore more than two FP registers, branch to the
14234 restore function. It will return to our caller. */
14235 if (! restoring_FPRs_inline
)
14239 const char *alloc_rname
;
14241 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
14242 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
14243 alloc_rname
= ggc_strdup (rname
);
14244 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
14245 gen_rtx_SYMBOL_REF (Pmode
,
14248 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14251 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
14252 GEN_INT (info
->fp_save_offset
+ 8*i
));
14253 mem
= gen_rtx_MEM (DFmode
, addr
);
14254 set_mem_alias_set (mem
, rs6000_sr_alias_set
);
14256 RTVEC_ELT (p
, i
+3) =
14257 gen_rtx_SET (VOIDmode
,
14258 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
14263 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14267 /* Write function epilogue. */
14270 rs6000_output_function_epilogue (FILE *file
,
14271 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
14273 rs6000_stack_t
*info
= rs6000_stack_info ();
14275 if (! HAVE_epilogue
)
14277 rtx insn
= get_last_insn ();
14278 /* If the last insn was a BARRIER, we don't have to write anything except
14279 the trace table. */
14280 if (GET_CODE (insn
) == NOTE
)
14281 insn
= prev_nonnote_insn (insn
);
14282 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
14284 /* This is slightly ugly, but at least we don't have two
14285 copies of the epilogue-emitting code. */
14288 /* A NOTE_INSN_DELETED is supposed to be at the start
14289 and end of the "toplevel" insn chain. */
14290 emit_note (NOTE_INSN_DELETED
);
14291 rs6000_emit_epilogue (FALSE
);
14292 emit_note (NOTE_INSN_DELETED
);
14294 /* Expand INSN_ADDRESSES so final() doesn't crash. */
14298 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
14300 INSN_ADDRESSES_NEW (insn
, addr
);
14305 if (TARGET_DEBUG_STACK
)
14306 debug_rtx_list (get_insns (), 100);
14307 final (get_insns (), file
, FALSE
);
14313 macho_branch_islands ();
14314 /* Mach-O doesn't support labels at the end of objects, so if
14315 it looks like we might want one, insert a NOP. */
14317 rtx insn
= get_last_insn ();
14320 && NOTE_LINE_NUMBER (insn
) != NOTE_INSN_DELETED_LABEL
)
14321 insn
= PREV_INSN (insn
);
14325 && NOTE_LINE_NUMBER (insn
) == NOTE_INSN_DELETED_LABEL
)))
14326 fputs ("\tnop\n", file
);
14330 /* Output a traceback table here. See /usr/include/sys/debug.h for info
14333 We don't output a traceback table if -finhibit-size-directive was
14334 used. The documentation for -finhibit-size-directive reads
14335 ``don't output a @code{.size} assembler directive, or anything
14336 else that would cause trouble if the function is split in the
14337 middle, and the two halves are placed at locations far apart in
14338 memory.'' The traceback table has this property, since it
14339 includes the offset from the start of the function to the
14340 traceback table itself.
14342 System V.4 Powerpc's (and the embedded ABI derived from it) use a
14343 different traceback table. */
14344 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
14345 && rs6000_traceback
!= traceback_none
)
14347 const char *fname
= NULL
;
14348 const char *language_string
= lang_hooks
.name
;
14349 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
14351 int optional_tbtab
;
14353 if (rs6000_traceback
== traceback_full
)
14354 optional_tbtab
= 1;
14355 else if (rs6000_traceback
== traceback_part
)
14356 optional_tbtab
= 0;
14358 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
14360 if (optional_tbtab
)
14362 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
14363 while (*fname
== '.') /* V.4 encodes . in the name */
14366 /* Need label immediately before tbtab, so we can compute
14367 its offset from the function start. */
14368 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
14369 ASM_OUTPUT_LABEL (file
, fname
);
14372 /* The .tbtab pseudo-op can only be used for the first eight
14373 expressions, since it can't handle the possibly variable
14374 length fields that follow. However, if you omit the optional
14375 fields, the assembler outputs zeros for all optional fields
14376 anyways, giving each variable length field is minimum length
14377 (as defined in sys/debug.h). Thus we can not use the .tbtab
14378 pseudo-op at all. */
14380 /* An all-zero word flags the start of the tbtab, for debuggers
14381 that have to find it by searching forward from the entry
14382 point or from the current pc. */
14383 fputs ("\t.long 0\n", file
);
14385 /* Tbtab format type. Use format type 0. */
14386 fputs ("\t.byte 0,", file
);
14388 /* Language type. Unfortunately, there does not seem to be any
14389 official way to discover the language being compiled, so we
14390 use language_string.
14391 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
14392 Java is 13. Objective-C is 14. */
14393 if (! strcmp (language_string
, "GNU C"))
14395 else if (! strcmp (language_string
, "GNU F77")
14396 || ! strcmp (language_string
, "GNU F95"))
14398 else if (! strcmp (language_string
, "GNU Pascal"))
14400 else if (! strcmp (language_string
, "GNU Ada"))
14402 else if (! strcmp (language_string
, "GNU C++"))
14404 else if (! strcmp (language_string
, "GNU Java"))
14406 else if (! strcmp (language_string
, "GNU Objective-C"))
14409 gcc_unreachable ();
14410 fprintf (file
, "%d,", i
);
14412 /* 8 single bit fields: global linkage (not set for C extern linkage,
14413 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
14414 from start of procedure stored in tbtab, internal function, function
14415 has controlled storage, function has no toc, function uses fp,
14416 function logs/aborts fp operations. */
14417 /* Assume that fp operations are used if any fp reg must be saved. */
14418 fprintf (file
, "%d,",
14419 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
14421 /* 6 bitfields: function is interrupt handler, name present in
14422 proc table, function calls alloca, on condition directives
14423 (controls stack walks, 3 bits), saves condition reg, saves
14425 /* The `function calls alloca' bit seems to be set whenever reg 31 is
14426 set up as a frame pointer, even when there is no alloca call. */
14427 fprintf (file
, "%d,",
14428 ((optional_tbtab
<< 6)
14429 | ((optional_tbtab
& frame_pointer_needed
) << 5)
14430 | (info
->cr_save_p
<< 1)
14431 | (info
->lr_save_p
)));
14433 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
14435 fprintf (file
, "%d,",
14436 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
14438 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
14439 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
14441 if (optional_tbtab
)
14443 /* Compute the parameter info from the function decl argument
14446 int next_parm_info_bit
= 31;
14448 for (decl
= DECL_ARGUMENTS (current_function_decl
);
14449 decl
; decl
= TREE_CHAIN (decl
))
14451 rtx parameter
= DECL_INCOMING_RTL (decl
);
14452 enum machine_mode mode
= GET_MODE (parameter
);
14454 if (GET_CODE (parameter
) == REG
)
14456 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
14474 gcc_unreachable ();
14477 /* If only one bit will fit, don't or in this entry. */
14478 if (next_parm_info_bit
> 0)
14479 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
14480 next_parm_info_bit
-= 2;
14484 fixed_parms
+= ((GET_MODE_SIZE (mode
)
14485 + (UNITS_PER_WORD
- 1))
14487 next_parm_info_bit
-= 1;
14493 /* Number of fixed point parameters. */
14494 /* This is actually the number of words of fixed point parameters; thus
14495 an 8 byte struct counts as 2; and thus the maximum value is 8. */
14496 fprintf (file
, "%d,", fixed_parms
);
14498 /* 2 bitfields: number of floating point parameters (7 bits), parameters
14500 /* This is actually the number of fp registers that hold parameters;
14501 and thus the maximum value is 13. */
14502 /* Set parameters on stack bit if parameters are not in their original
14503 registers, regardless of whether they are on the stack? Xlc
14504 seems to set the bit when not optimizing. */
14505 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
14507 if (! optional_tbtab
)
14510 /* Optional fields follow. Some are variable length. */
14512 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
14513 11 double float. */
14514 /* There is an entry for each parameter in a register, in the order that
14515 they occur in the parameter list. Any intervening arguments on the
14516 stack are ignored. If the list overflows a long (max possible length
14517 34 bits) then completely leave off all elements that don't fit. */
14518 /* Only emit this long if there was at least one parameter. */
14519 if (fixed_parms
|| float_parms
)
14520 fprintf (file
, "\t.long %d\n", parm_info
);
14522 /* Offset from start of code to tb table. */
14523 fputs ("\t.long ", file
);
14524 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
14526 RS6000_OUTPUT_BASENAME (file
, fname
);
14528 assemble_name (file
, fname
);
14530 rs6000_output_function_entry (file
, fname
);
14533 /* Interrupt handler mask. */
14534 /* Omit this long, since we never set the interrupt handler bit
14537 /* Number of CTL (controlled storage) anchors. */
14538 /* Omit this long, since the has_ctl bit is never set above. */
14540 /* Displacement into stack of each CTL anchor. */
14541 /* Omit this list of longs, because there are no CTL anchors. */
14543 /* Length of function name. */
14546 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
14548 /* Function name. */
14549 assemble_string (fname
, strlen (fname
));
14551 /* Register for alloca automatic storage; this is always reg 31.
14552 Only emit this if the alloca bit was set above. */
14553 if (frame_pointer_needed
)
14554 fputs ("\t.byte 31\n", file
);
14556 fputs ("\t.align 2\n", file
);
14560 /* A C compound statement that outputs the assembler code for a thunk
14561 function, used to implement C++ virtual function calls with
14562 multiple inheritance. The thunk acts as a wrapper around a virtual
14563 function, adjusting the implicit object parameter before handing
14564 control off to the real function.
14566 First, emit code to add the integer DELTA to the location that
14567 contains the incoming first argument. Assume that this argument
14568 contains a pointer, and is the one used to pass the `this' pointer
14569 in C++. This is the incoming argument *before* the function
14570 prologue, e.g. `%o0' on a sparc. The addition must preserve the
14571 values of all other incoming arguments.
14573 After the addition, emit code to jump to FUNCTION, which is a
14574 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
14575 not touch the return address. Hence returning from FUNCTION will
14576 return to whoever called the current `thunk'.
14578 The effect must be as if FUNCTION had been called directly with the
14579 adjusted first argument. This macro is responsible for emitting
14580 all of the code for a thunk function; output_function_prologue()
14581 and output_function_epilogue() are not invoked.
14583 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
14584 been extracted from it.) It might possibly be useful on some
14585 targets, but probably not.
14587 If you do not define this macro, the target-independent code in the
14588 C++ frontend will generate a less efficient heavyweight thunk that
14589 calls FUNCTION instead of jumping to it. The generic approach does
14590 not support varargs. */
14593 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
14594 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
14597 rtx
this, insn
, funexp
;
14599 reload_completed
= 1;
14600 epilogue_completed
= 1;
14601 no_new_pseudos
= 1;
14602 reset_block_changes ();
14604 /* Mark the end of the (empty) prologue. */
14605 emit_note (NOTE_INSN_PROLOGUE_END
);
14607 /* Find the "this" pointer. If the function returns a structure,
14608 the structure return pointer is in r3. */
14609 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
14610 this = gen_rtx_REG (Pmode
, 4);
14612 this = gen_rtx_REG (Pmode
, 3);
14614 /* Apply the constant offset, if required. */
14617 rtx delta_rtx
= GEN_INT (delta
);
14618 emit_insn (TARGET_32BIT
14619 ? gen_addsi3 (this, this, delta_rtx
)
14620 : gen_adddi3 (this, this, delta_rtx
));
14623 /* Apply the offset from the vtable, if required. */
14626 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
14627 rtx tmp
= gen_rtx_REG (Pmode
, 12);
14629 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
14630 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
14632 emit_insn (TARGET_32BIT
14633 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
14634 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
14635 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
14639 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
14641 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
14643 emit_insn (TARGET_32BIT
14644 ? gen_addsi3 (this, this, tmp
)
14645 : gen_adddi3 (this, this, tmp
));
14648 /* Generate a tail call to the target function. */
14649 if (!TREE_USED (function
))
14651 assemble_external (function
);
14652 TREE_USED (function
) = 1;
14654 funexp
= XEXP (DECL_RTL (function
), 0);
14655 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
14658 if (MACHOPIC_INDIRECT
)
14659 funexp
= machopic_indirect_call_target (funexp
);
14662 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
14663 generate sibcall RTL explicitly. */
14664 insn
= emit_call_insn (
14665 gen_rtx_PARALLEL (VOIDmode
,
14667 gen_rtx_CALL (VOIDmode
,
14668 funexp
, const0_rtx
),
14669 gen_rtx_USE (VOIDmode
, const0_rtx
),
14670 gen_rtx_USE (VOIDmode
,
14671 gen_rtx_REG (SImode
,
14672 LINK_REGISTER_REGNUM
)),
14673 gen_rtx_RETURN (VOIDmode
))));
14674 SIBLING_CALL_P (insn
) = 1;
14677 /* Run just enough of rest_of_compilation to get the insns emitted.
14678 There's not really enough bulk here to make other passes such as
14679 instruction scheduling worth while. Note that use_thunk calls
14680 assemble_start_function and assemble_end_function. */
14681 insn
= get_insns ();
14682 insn_locators_initialize ();
14683 shorten_branches (insn
);
14684 final_start_function (insn
, file
, 1);
14685 final (insn
, file
, 1);
14686 final_end_function ();
14688 reload_completed
= 0;
14689 epilogue_completed
= 0;
14690 no_new_pseudos
= 0;
14693 /* A quick summary of the various types of 'constant-pool tables'
14696 Target Flags Name One table per
14697 AIX (none) AIX TOC object file
14698 AIX -mfull-toc AIX TOC object file
14699 AIX -mminimal-toc AIX minimal TOC translation unit
14700 SVR4/EABI (none) SVR4 SDATA object file
14701 SVR4/EABI -fpic SVR4 pic object file
14702 SVR4/EABI -fPIC SVR4 PIC translation unit
14703 SVR4/EABI -mrelocatable EABI TOC function
14704 SVR4/EABI -maix AIX TOC object file
14705 SVR4/EABI -maix -mminimal-toc
14706 AIX minimal TOC translation unit
14708 Name Reg. Set by entries contains:
14709 made by addrs? fp? sum?
14711 AIX TOC 2 crt0 as Y option option
14712 AIX minimal TOC 30 prolog gcc Y Y option
14713 SVR4 SDATA 13 crt0 gcc N Y N
14714 SVR4 pic 30 prolog ld Y not yet N
14715 SVR4 PIC 30 prolog gcc Y option option
14716 EABI TOC 30 prolog gcc Y option option
14720 /* Hash functions for the hash table. */
14723 rs6000_hash_constant (rtx k
)
14725 enum rtx_code code
= GET_CODE (k
);
14726 enum machine_mode mode
= GET_MODE (k
);
14727 unsigned result
= (code
<< 3) ^ mode
;
14728 const char *format
;
14731 format
= GET_RTX_FORMAT (code
);
14732 flen
= strlen (format
);
14738 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
14741 if (mode
!= VOIDmode
)
14742 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
14754 for (; fidx
< flen
; fidx
++)
14755 switch (format
[fidx
])
14760 const char *str
= XSTR (k
, fidx
);
14761 len
= strlen (str
);
14762 result
= result
* 613 + len
;
14763 for (i
= 0; i
< len
; i
++)
14764 result
= result
* 613 + (unsigned) str
[i
];
14769 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
14773 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
14776 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
14777 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
14781 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
14782 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
14789 gcc_unreachable ();
14796 toc_hash_function (const void *hash_entry
)
14798 const struct toc_hash_struct
*thc
=
14799 (const struct toc_hash_struct
*) hash_entry
;
14800 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
14803 /* Compare H1 and H2 for equivalence. */
14806 toc_hash_eq (const void *h1
, const void *h2
)
14808 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
14809 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
14811 if (((const struct toc_hash_struct
*) h1
)->key_mode
14812 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
14815 return rtx_equal_p (r1
, r2
);
14818 /* These are the names given by the C++ front-end to vtables, and
14819 vtable-like objects. Ideally, this logic should not be here;
14820 instead, there should be some programmatic way of inquiring as
14821 to whether or not an object is a vtable. */
14823 #define VTABLE_NAME_P(NAME) \
14824 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
14825 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
14826 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
14827 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
14828 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
14831 rs6000_output_symbol_ref (FILE *file
, rtx x
)
14833 /* Currently C++ toc references to vtables can be emitted before it
14834 is decided whether the vtable is public or private. If this is
14835 the case, then the linker will eventually complain that there is
14836 a reference to an unknown section. Thus, for vtables only,
14837 we emit the TOC reference to reference the symbol and not the
14839 const char *name
= XSTR (x
, 0);
14841 if (VTABLE_NAME_P (name
))
14843 RS6000_OUTPUT_BASENAME (file
, name
);
14846 assemble_name (file
, name
);
14849 /* Output a TOC entry. We derive the entry name from what is being
14853 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
14856 const char *name
= buf
;
14857 const char *real_name
;
14861 gcc_assert (!TARGET_NO_TOC
);
14863 /* When the linker won't eliminate them, don't output duplicate
14864 TOC entries (this happens on AIX if there is any kind of TOC,
14865 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
14867 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
14869 struct toc_hash_struct
*h
;
14872 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
14873 time because GGC is not initialized at that point. */
14874 if (toc_hash_table
== NULL
)
14875 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
14876 toc_hash_eq
, NULL
);
14878 h
= ggc_alloc (sizeof (*h
));
14880 h
->key_mode
= mode
;
14881 h
->labelno
= labelno
;
14883 found
= htab_find_slot (toc_hash_table
, h
, 1);
14884 if (*found
== NULL
)
14886 else /* This is indeed a duplicate.
14887 Set this label equal to that label. */
14889 fputs ("\t.set ", file
);
14890 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
14891 fprintf (file
, "%d,", labelno
);
14892 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
14893 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
14899 /* If we're going to put a double constant in the TOC, make sure it's
14900 aligned properly when strict alignment is on. */
14901 if (GET_CODE (x
) == CONST_DOUBLE
14902 && STRICT_ALIGNMENT
14903 && GET_MODE_BITSIZE (mode
) >= 64
14904 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
14905 ASM_OUTPUT_ALIGN (file
, 3);
14908 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
14910 /* Handle FP constants specially. Note that if we have a minimal
14911 TOC, things we put here aren't actually in the TOC, so we can allow
14913 if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == TFmode
)
14915 REAL_VALUE_TYPE rv
;
14918 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
14919 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
14923 if (TARGET_MINIMAL_TOC
)
14924 fputs (DOUBLE_INT_ASM_OP
, file
);
14926 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
14927 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14928 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14929 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
14930 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14931 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14936 if (TARGET_MINIMAL_TOC
)
14937 fputs ("\t.long ", file
);
14939 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
14940 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14941 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14942 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
14943 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
14944 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
14948 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == DFmode
)
14950 REAL_VALUE_TYPE rv
;
14953 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
14954 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
14958 if (TARGET_MINIMAL_TOC
)
14959 fputs (DOUBLE_INT_ASM_OP
, file
);
14961 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
14962 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
14963 fprintf (file
, "0x%lx%08lx\n",
14964 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
14969 if (TARGET_MINIMAL_TOC
)
14970 fputs ("\t.long ", file
);
14972 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
14973 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
14974 fprintf (file
, "0x%lx,0x%lx\n",
14975 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
14979 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == SFmode
)
14981 REAL_VALUE_TYPE rv
;
14984 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
14985 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
14989 if (TARGET_MINIMAL_TOC
)
14990 fputs (DOUBLE_INT_ASM_OP
, file
);
14992 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
14993 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
14998 if (TARGET_MINIMAL_TOC
)
14999 fputs ("\t.long ", file
);
15001 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
15002 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
15006 else if (GET_MODE (x
) == VOIDmode
15007 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
15009 unsigned HOST_WIDE_INT low
;
15010 HOST_WIDE_INT high
;
15012 if (GET_CODE (x
) == CONST_DOUBLE
)
15014 low
= CONST_DOUBLE_LOW (x
);
15015 high
= CONST_DOUBLE_HIGH (x
);
15018 #if HOST_BITS_PER_WIDE_INT == 32
15021 high
= (low
& 0x80000000) ? ~0 : 0;
15025 low
= INTVAL (x
) & 0xffffffff;
15026 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
15030 /* TOC entries are always Pmode-sized, but since this
15031 is a bigendian machine then if we're putting smaller
15032 integer constants in the TOC we have to pad them.
15033 (This is still a win over putting the constants in
15034 a separate constant pool, because then we'd have
15035 to have both a TOC entry _and_ the actual constant.)
15037 For a 32-bit target, CONST_INT values are loaded and shifted
15038 entirely within `low' and can be stored in one TOC entry. */
15040 /* It would be easy to make this work, but it doesn't now. */
15041 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
15043 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
15045 #if HOST_BITS_PER_WIDE_INT == 32
15046 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
15047 POINTER_SIZE
, &low
, &high
, 0);
15050 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
15051 high
= (HOST_WIDE_INT
) low
>> 32;
15058 if (TARGET_MINIMAL_TOC
)
15059 fputs (DOUBLE_INT_ASM_OP
, file
);
15061 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15062 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15063 fprintf (file
, "0x%lx%08lx\n",
15064 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15069 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
15071 if (TARGET_MINIMAL_TOC
)
15072 fputs ("\t.long ", file
);
15074 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15075 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15076 fprintf (file
, "0x%lx,0x%lx\n",
15077 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15081 if (TARGET_MINIMAL_TOC
)
15082 fputs ("\t.long ", file
);
15084 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
15085 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
15091 if (GET_CODE (x
) == CONST
)
15093 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
15095 base
= XEXP (XEXP (x
, 0), 0);
15096 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
15099 switch (GET_CODE (base
))
15102 name
= XSTR (base
, 0);
15106 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
15107 CODE_LABEL_NUMBER (XEXP (base
, 0)));
15111 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
15115 gcc_unreachable ();
15118 real_name
= (*targetm
.strip_name_encoding
) (name
);
15119 if (TARGET_MINIMAL_TOC
)
15120 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
15123 fprintf (file
, "\t.tc %s", real_name
);
15126 fprintf (file
, ".N%d", - offset
);
15128 fprintf (file
, ".P%d", offset
);
15130 fputs ("[TC],", file
);
15133 /* Currently C++ toc references to vtables can be emitted before it
15134 is decided whether the vtable is public or private. If this is
15135 the case, then the linker will eventually complain that there is
15136 a TOC reference to an unknown section. Thus, for vtables only,
15137 we emit the TOC reference to reference the symbol and not the
15139 if (VTABLE_NAME_P (name
))
15141 RS6000_OUTPUT_BASENAME (file
, name
);
15143 fprintf (file
, "%d", offset
);
15144 else if (offset
> 0)
15145 fprintf (file
, "+%d", offset
);
15148 output_addr_const (file
, x
);
15152 /* Output an assembler pseudo-op to write an ASCII string of N characters
15153 starting at P to FILE.
15155 On the RS/6000, we have to do this using the .byte operation and
15156 write out special characters outside the quoted string.
15157 Also, the assembler is broken; very long strings are truncated,
15158 so we must artificially break them up early. */
15161 output_ascii (FILE *file
, const char *p
, int n
)
15164 int i
, count_string
;
15165 const char *for_string
= "\t.byte \"";
15166 const char *for_decimal
= "\t.byte ";
15167 const char *to_close
= NULL
;
15170 for (i
= 0; i
< n
; i
++)
15173 if (c
>= ' ' && c
< 0177)
15176 fputs (for_string
, file
);
15179 /* Write two quotes to get one. */
15187 for_decimal
= "\"\n\t.byte ";
15191 if (count_string
>= 512)
15193 fputs (to_close
, file
);
15195 for_string
= "\t.byte \"";
15196 for_decimal
= "\t.byte ";
15204 fputs (for_decimal
, file
);
15205 fprintf (file
, "%d", c
);
15207 for_string
= "\n\t.byte \"";
15208 for_decimal
= ", ";
15214 /* Now close the string if we have written one. Then end the line. */
15216 fputs (to_close
, file
);
15219 /* Generate a unique section name for FILENAME for a section type
15220 represented by SECTION_DESC. Output goes into BUF.
15222 SECTION_DESC can be any string, as long as it is different for each
15223 possible section type.
15225 We name the section in the same manner as xlc. The name begins with an
15226 underscore followed by the filename (after stripping any leading directory
15227 names) with the last period replaced by the string SECTION_DESC. If
15228 FILENAME does not contain a period, SECTION_DESC is appended to the end of
15232 rs6000_gen_section_name (char **buf
, const char *filename
,
15233 const char *section_desc
)
15235 const char *q
, *after_last_slash
, *last_period
= 0;
15239 after_last_slash
= filename
;
15240 for (q
= filename
; *q
; q
++)
15243 after_last_slash
= q
+ 1;
15244 else if (*q
== '.')
15248 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
15249 *buf
= (char *) xmalloc (len
);
15254 for (q
= after_last_slash
; *q
; q
++)
15256 if (q
== last_period
)
15258 strcpy (p
, section_desc
);
15259 p
+= strlen (section_desc
);
15263 else if (ISALNUM (*q
))
15267 if (last_period
== 0)
15268 strcpy (p
, section_desc
);
15273 /* Emit profile function. */
15276 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
15278 /* Non-standard profiling for kernels, which just saves LR then calls
15279 _mcount without worrying about arg saves. The idea is to change
15280 the function prologue as little as possible as it isn't easy to
15281 account for arg save/restore code added just for _mcount. */
15282 if (TARGET_PROFILE_KERNEL
)
15285 if (DEFAULT_ABI
== ABI_AIX
)
15287 #ifndef NO_PROFILE_COUNTERS
15288 # define NO_PROFILE_COUNTERS 0
15290 if (NO_PROFILE_COUNTERS
)
15291 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
15295 const char *label_name
;
15298 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
15299 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
15300 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
15302 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
15306 else if (DEFAULT_ABI
== ABI_DARWIN
)
15308 const char *mcount_name
= RS6000_MCOUNT
;
15309 int caller_addr_regno
= LINK_REGISTER_REGNUM
;
15311 /* Be conservative and always set this, at least for now. */
15312 current_function_uses_pic_offset_table
= 1;
15315 /* For PIC code, set up a stub and collect the caller's address
15316 from r0, which is where the prologue puts it. */
15317 if (MACHOPIC_INDIRECT
15318 && current_function_uses_pic_offset_table
)
15319 caller_addr_regno
= 0;
15321 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
15323 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
15327 /* Write function profiler code. */
15330 output_function_profiler (FILE *file
, int labelno
)
15335 switch (DEFAULT_ABI
)
15338 gcc_unreachable ();
15344 warning (0, "no profiling of 64-bit code for this ABI");
15347 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
15348 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
15351 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
15352 asm_fprintf (file
, "\t{st|stw} %s,%d(%s)\n",
15353 reg_names
[0], save_lr
, reg_names
[1]);
15354 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
15355 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
15356 assemble_name (file
, buf
);
15357 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
15359 else if (flag_pic
> 1)
15361 asm_fprintf (file
, "\t{st|stw} %s,%d(%s)\n",
15362 reg_names
[0], save_lr
, reg_names
[1]);
15363 /* Now, we need to get the address of the label. */
15364 fputs ("\tbl 1f\n\t.long ", file
);
15365 assemble_name (file
, buf
);
15366 fputs ("-.\n1:", file
);
15367 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
15368 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
15369 reg_names
[0], reg_names
[11]);
15370 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
15371 reg_names
[0], reg_names
[0], reg_names
[11]);
15375 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
15376 assemble_name (file
, buf
);
15377 fputs ("@ha\n", file
);
15378 asm_fprintf (file
, "\t{st|stw} %s,%d(%s)\n",
15379 reg_names
[0], save_lr
, reg_names
[1]);
15380 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
15381 assemble_name (file
, buf
);
15382 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
15385 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
15386 fprintf (file
, "\tbl %s%s\n",
15387 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
15392 if (!TARGET_PROFILE_KERNEL
)
15394 /* Don't do anything, done in output_profile_hook (). */
15398 gcc_assert (!TARGET_32BIT
);
15400 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
15401 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
15403 if (cfun
->static_chain_decl
!= NULL
)
15405 asm_fprintf (file
, "\tstd %s,24(%s)\n",
15406 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
15407 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
15408 asm_fprintf (file
, "\tld %s,24(%s)\n",
15409 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
15412 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
15419 /* Power4 load update and store update instructions are cracked into a
15420 load or store and an integer insn which are executed in the same cycle.
15421 Branches have their own dispatch slot which does not count against the
15422 GCC issue rate, but it changes the program flow so there are no other
15423 instructions to issue in this cycle. */
15426 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
15427 int verbose ATTRIBUTE_UNUSED
,
15428 rtx insn
, int more
)
15430 if (GET_CODE (PATTERN (insn
)) == USE
15431 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15434 if (rs6000_sched_groups
)
15436 if (is_microcoded_insn (insn
))
15438 else if (is_cracked_insn (insn
))
15439 return more
> 2 ? more
- 2 : 0;
15445 /* Adjust the cost of a scheduling dependency. Return the new cost of
15446 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
15449 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
15451 if (! recog_memoized (insn
))
15454 if (REG_NOTE_KIND (link
) != 0)
15457 if (REG_NOTE_KIND (link
) == 0)
15459 /* Data dependency; DEP_INSN writes a register that INSN reads
15460 some cycles later. */
15462 /* Separate a load from a narrower, dependent store. */
15463 if (rs6000_sched_groups
15464 && GET_CODE (PATTERN (insn
)) == SET
15465 && GET_CODE (PATTERN (dep_insn
)) == SET
15466 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
15467 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
15468 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
15469 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
15472 switch (get_attr_type (insn
))
15475 /* Tell the first scheduling pass about the latency between
15476 a mtctr and bctr (and mtlr and br/blr). The first
15477 scheduling pass will not know about this latency since
15478 the mtctr instruction, which has the latency associated
15479 to it, will be generated by reload. */
15480 return TARGET_POWER
? 5 : 4;
15482 /* Leave some extra cycles between a compare and its
15483 dependent branch, to inhibit expensive mispredicts. */
15484 if ((rs6000_cpu_attr
== CPU_PPC603
15485 || rs6000_cpu_attr
== CPU_PPC604
15486 || rs6000_cpu_attr
== CPU_PPC604E
15487 || rs6000_cpu_attr
== CPU_PPC620
15488 || rs6000_cpu_attr
== CPU_PPC630
15489 || rs6000_cpu_attr
== CPU_PPC750
15490 || rs6000_cpu_attr
== CPU_PPC7400
15491 || rs6000_cpu_attr
== CPU_PPC7450
15492 || rs6000_cpu_attr
== CPU_POWER4
15493 || rs6000_cpu_attr
== CPU_POWER5
)
15494 && recog_memoized (dep_insn
)
15495 && (INSN_CODE (dep_insn
) >= 0)
15496 && (get_attr_type (dep_insn
) == TYPE_CMP
15497 || get_attr_type (dep_insn
) == TYPE_COMPARE
15498 || get_attr_type (dep_insn
) == TYPE_DELAYED_COMPARE
15499 || get_attr_type (dep_insn
) == TYPE_IMUL_COMPARE
15500 || get_attr_type (dep_insn
) == TYPE_LMUL_COMPARE
15501 || get_attr_type (dep_insn
) == TYPE_FPCOMPARE
15502 || get_attr_type (dep_insn
) == TYPE_CR_LOGICAL
15503 || get_attr_type (dep_insn
) == TYPE_DELAYED_CR
))
15508 /* Fall out to return default cost. */
15514 /* The function returns a true if INSN is microcoded.
15515 Return false otherwise. */
15518 is_microcoded_insn (rtx insn
)
15520 if (!insn
|| !INSN_P (insn
)
15521 || GET_CODE (PATTERN (insn
)) == USE
15522 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15525 if (rs6000_sched_groups
)
15527 enum attr_type type
= get_attr_type (insn
);
15528 if (type
== TYPE_LOAD_EXT_U
15529 || type
== TYPE_LOAD_EXT_UX
15530 || type
== TYPE_LOAD_UX
15531 || type
== TYPE_STORE_UX
15532 || type
== TYPE_MFCR
)
15539 /* The function returns a nonzero value if INSN can be scheduled only
15540 as the first insn in a dispatch group ("dispatch-slot restricted").
15541 In this case, the returned value indicates how many dispatch slots
15542 the insn occupies (at the beginning of the group).
15543 Return 0 otherwise. */
15546 is_dispatch_slot_restricted (rtx insn
)
15548 enum attr_type type
;
15550 if (!rs6000_sched_groups
)
15554 || insn
== NULL_RTX
15555 || GET_CODE (insn
) == NOTE
15556 || GET_CODE (PATTERN (insn
)) == USE
15557 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15560 type
= get_attr_type (insn
);
15567 case TYPE_DELAYED_CR
:
15568 case TYPE_CR_LOGICAL
:
15576 if (rs6000_cpu
== PROCESSOR_POWER5
15577 && is_cracked_insn (insn
))
15583 /* The function returns true if INSN is cracked into 2 instructions
15584 by the processor (and therefore occupies 2 issue slots). */
15587 is_cracked_insn (rtx insn
)
15589 if (!insn
|| !INSN_P (insn
)
15590 || GET_CODE (PATTERN (insn
)) == USE
15591 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15594 if (rs6000_sched_groups
)
15596 enum attr_type type
= get_attr_type (insn
);
15597 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
15598 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
15599 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
15600 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
15601 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
15602 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
15603 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
15604 || type
== TYPE_INSERT_WORD
)
15611 /* The function returns true if INSN can be issued only from
15612 the branch slot. */
15615 is_branch_slot_insn (rtx insn
)
15617 if (!insn
|| !INSN_P (insn
)
15618 || GET_CODE (PATTERN (insn
)) == USE
15619 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
15622 if (rs6000_sched_groups
)
15624 enum attr_type type
= get_attr_type (insn
);
15625 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
15633 /* A C statement (sans semicolon) to update the integer scheduling
15634 priority INSN_PRIORITY (INSN). Increase the priority to execute the
15635 INSN earlier, reduce the priority to execute INSN later. Do not
15636 define this macro if you do not need to adjust the scheduling
15637 priorities of insns. */
15640 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
15642 /* On machines (like the 750) which have asymmetric integer units,
15643 where one integer unit can do multiply and divides and the other
15644 can't, reduce the priority of multiply/divide so it is scheduled
15645 before other integer operations. */
15648 if (! INSN_P (insn
))
15651 if (GET_CODE (PATTERN (insn
)) == USE
)
15654 switch (rs6000_cpu_attr
) {
15656 switch (get_attr_type (insn
))
15663 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
15664 priority
, priority
);
15665 if (priority
>= 0 && priority
< 0x01000000)
15672 if (is_dispatch_slot_restricted (insn
)
15673 && reload_completed
15674 && current_sched_info
->sched_max_insns_priority
15675 && rs6000_sched_restricted_insns_priority
)
15678 /* Prioritize insns that can be dispatched only in the first
15680 if (rs6000_sched_restricted_insns_priority
== 1)
15681 /* Attach highest priority to insn. This means that in
15682 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
15683 precede 'priority' (critical path) considerations. */
15684 return current_sched_info
->sched_max_insns_priority
;
15685 else if (rs6000_sched_restricted_insns_priority
== 2)
15686 /* Increase priority of insn by a minimal amount. This means that in
15687 haifa-sched.c:ready_sort(), only 'priority' (critical path)
15688 considerations precede dispatch-slot restriction considerations. */
15689 return (priority
+ 1);
15695 /* Return how many instructions the machine can issue per cycle. */
15698 rs6000_issue_rate (void)
15700 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
15701 if (!reload_completed
)
15704 switch (rs6000_cpu_attr
) {
15705 case CPU_RIOS1
: /* ? */
15707 case CPU_PPC601
: /* ? */
15730 /* Return how many instructions to look ahead for better insn
15734 rs6000_use_sched_lookahead (void)
15736 if (rs6000_cpu_attr
== CPU_PPC8540
)
15741 /* Determine is PAT refers to memory. */
15744 is_mem_ref (rtx pat
)
15750 if (GET_CODE (pat
) == MEM
)
15753 /* Recursively process the pattern. */
15754 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
15756 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
15759 ret
|= is_mem_ref (XEXP (pat
, i
));
15760 else if (fmt
[i
] == 'E')
15761 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
15762 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
15768 /* Determine if PAT is a PATTERN of a load insn. */
15771 is_load_insn1 (rtx pat
)
15773 if (!pat
|| pat
== NULL_RTX
)
15776 if (GET_CODE (pat
) == SET
)
15777 return is_mem_ref (SET_SRC (pat
));
15779 if (GET_CODE (pat
) == PARALLEL
)
15783 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15784 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
15791 /* Determine if INSN loads from memory. */
15794 is_load_insn (rtx insn
)
15796 if (!insn
|| !INSN_P (insn
))
15799 if (GET_CODE (insn
) == CALL_INSN
)
15802 return is_load_insn1 (PATTERN (insn
));
15805 /* Determine if PAT is a PATTERN of a store insn. */
15808 is_store_insn1 (rtx pat
)
15810 if (!pat
|| pat
== NULL_RTX
)
15813 if (GET_CODE (pat
) == SET
)
15814 return is_mem_ref (SET_DEST (pat
));
15816 if (GET_CODE (pat
) == PARALLEL
)
15820 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
15821 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
15828 /* Determine if INSN stores to memory. */
15831 is_store_insn (rtx insn
)
15833 if (!insn
|| !INSN_P (insn
))
15836 return is_store_insn1 (PATTERN (insn
));
15839 /* Returns whether the dependence between INSN and NEXT is considered
15840 costly by the given target. */
15843 rs6000_is_costly_dependence (rtx insn
, rtx next
, rtx link
, int cost
,
15846 /* If the flag is not enabled - no dependence is considered costly;
15847 allow all dependent insns in the same group.
15848 This is the most aggressive option. */
15849 if (rs6000_sched_costly_dep
== no_dep_costly
)
15852 /* If the flag is set to 1 - a dependence is always considered costly;
15853 do not allow dependent instructions in the same group.
15854 This is the most conservative option. */
15855 if (rs6000_sched_costly_dep
== all_deps_costly
)
15858 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
15859 && is_load_insn (next
)
15860 && is_store_insn (insn
))
15861 /* Prevent load after store in the same group. */
15864 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
15865 && is_load_insn (next
)
15866 && is_store_insn (insn
)
15867 && (!link
|| (int) REG_NOTE_KIND (link
) == 0))
15868 /* Prevent load after store in the same group if it is a true
15872 /* The flag is set to X; dependences with latency >= X are considered costly,
15873 and will not be scheduled in the same group. */
15874 if (rs6000_sched_costly_dep
<= max_dep_latency
15875 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
15881 /* Return the next insn after INSN that is found before TAIL is reached,
15882 skipping any "non-active" insns - insns that will not actually occupy
15883 an issue slot. Return NULL_RTX if such an insn is not found. */
15886 get_next_active_insn (rtx insn
, rtx tail
)
15890 if (!insn
|| insn
== tail
)
15893 next_insn
= NEXT_INSN (insn
);
15896 && next_insn
!= tail
15897 && (GET_CODE (next_insn
) == NOTE
15898 || GET_CODE (PATTERN (next_insn
)) == USE
15899 || GET_CODE (PATTERN (next_insn
)) == CLOBBER
))
15901 next_insn
= NEXT_INSN (next_insn
);
15904 if (!next_insn
|| next_insn
== tail
)
15910 /* Return whether the presence of INSN causes a dispatch group termination
15911 of group WHICH_GROUP.
15913 If WHICH_GROUP == current_group, this function will return true if INSN
15914 causes the termination of the current group (i.e, the dispatch group to
15915 which INSN belongs). This means that INSN will be the last insn in the
15916 group it belongs to.
15918 If WHICH_GROUP == previous_group, this function will return true if INSN
15919 causes the termination of the previous group (i.e, the dispatch group that
15920 precedes the group to which INSN belongs). This means that INSN will be
15921 the first insn in the group it belongs to). */
15924 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
15926 enum attr_type type
;
15931 type
= get_attr_type (insn
);
15933 if (is_microcoded_insn (insn
))
15936 if (which_group
== current_group
)
15938 if (is_branch_slot_insn (insn
))
15942 else if (which_group
== previous_group
)
15944 if (is_dispatch_slot_restricted (insn
))
15952 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
15953 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
15956 is_costly_group (rtx
*group_insns
, rtx next_insn
)
15961 int issue_rate
= rs6000_issue_rate ();
15963 for (i
= 0; i
< issue_rate
; i
++)
15965 rtx insn
= group_insns
[i
];
15968 for (link
= INSN_DEPEND (insn
); link
!= 0; link
= XEXP (link
, 1))
15970 rtx next
= XEXP (link
, 0);
15971 if (next
== next_insn
)
15973 cost
= insn_cost (insn
, link
, next_insn
);
15974 if (rs6000_is_costly_dependence (insn
, next_insn
, link
, cost
, 0))
15983 /* Utility of the function redefine_groups.
15984 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
15985 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
15986 to keep it "far" (in a separate group) from GROUP_INSNS, following
15987 one of the following schemes, depending on the value of the flag
15988 -minsert_sched_nops = X:
15989 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
15990 in order to force NEXT_INSN into a separate group.
15991 (2) X < sched_finish_regroup_exact: insert exactly X nops.
15992 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
15993 insertion (has a group just ended, how many vacant issue slots remain in the
15994 last group, and how many dispatch groups were encountered so far). */
15997 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
15998 rtx next_insn
, bool *group_end
, int can_issue_more
,
16003 int issue_rate
= rs6000_issue_rate ();
16004 bool end
= *group_end
;
16007 if (next_insn
== NULL_RTX
)
16008 return can_issue_more
;
16010 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
16011 return can_issue_more
;
16013 force
= is_costly_group (group_insns
, next_insn
);
16015 return can_issue_more
;
16017 if (sched_verbose
> 6)
16018 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
16019 *group_count
,can_issue_more
);
16021 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
16024 can_issue_more
= 0;
16026 /* Since only a branch can be issued in the last issue_slot, it is
16027 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
16028 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
16029 in this case the last nop will start a new group and the branch
16030 will be forced to the new group. */
16031 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
16034 while (can_issue_more
> 0)
16037 emit_insn_before (nop
, next_insn
);
16045 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
16047 int n_nops
= rs6000_sched_insert_nops
;
16049 /* Nops can't be issued from the branch slot, so the effective
16050 issue_rate for nops is 'issue_rate - 1'. */
16051 if (can_issue_more
== 0)
16052 can_issue_more
= issue_rate
;
16054 if (can_issue_more
== 0)
16056 can_issue_more
= issue_rate
- 1;
16059 for (i
= 0; i
< issue_rate
; i
++)
16061 group_insns
[i
] = 0;
16068 emit_insn_before (nop
, next_insn
);
16069 if (can_issue_more
== issue_rate
- 1) /* new group begins */
16072 if (can_issue_more
== 0)
16074 can_issue_more
= issue_rate
- 1;
16077 for (i
= 0; i
< issue_rate
; i
++)
16079 group_insns
[i
] = 0;
16085 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
16088 /* Is next_insn going to start a new group? */
16091 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
16092 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
16093 || (can_issue_more
< issue_rate
&&
16094 insn_terminates_group_p (next_insn
, previous_group
)));
16095 if (*group_end
&& end
)
16098 if (sched_verbose
> 6)
16099 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
16100 *group_count
, can_issue_more
);
16101 return can_issue_more
;
16104 return can_issue_more
;
16107 /* This function tries to synch the dispatch groups that the compiler "sees"
16108 with the dispatch groups that the processor dispatcher is expected to
16109 form in practice. It tries to achieve this synchronization by forcing the
16110 estimated processor grouping on the compiler (as opposed to the function
16111 'pad_goups' which tries to force the scheduler's grouping on the processor).
16113 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
16114 examines the (estimated) dispatch groups that will be formed by the processor
16115 dispatcher. It marks these group boundaries to reflect the estimated
16116 processor grouping, overriding the grouping that the scheduler had marked.
16117 Depending on the value of the flag '-minsert-sched-nops' this function can
16118 force certain insns into separate groups or force a certain distance between
16119 them by inserting nops, for example, if there exists a "costly dependence"
16122 The function estimates the group boundaries that the processor will form as
16123 folllows: It keeps track of how many vacant issue slots are available after
16124 each insn. A subsequent insn will start a new group if one of the following
16126 - no more vacant issue slots remain in the current dispatch group.
16127 - only the last issue slot, which is the branch slot, is vacant, but the next
16128 insn is not a branch.
16129 - only the last 2 or less issue slots, including the branch slot, are vacant,
16130 which means that a cracked insn (which occupies two issue slots) can't be
16131 issued in this group.
16132 - less than 'issue_rate' slots are vacant, and the next insn always needs to
16133 start a new group. */
16136 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
16138 rtx insn
, next_insn
;
16140 int can_issue_more
;
16143 int group_count
= 0;
16147 issue_rate
= rs6000_issue_rate ();
16148 group_insns
= alloca (issue_rate
* sizeof (rtx
));
16149 for (i
= 0; i
< issue_rate
; i
++)
16151 group_insns
[i
] = 0;
16153 can_issue_more
= issue_rate
;
16155 insn
= get_next_active_insn (prev_head_insn
, tail
);
16158 while (insn
!= NULL_RTX
)
16160 slot
= (issue_rate
- can_issue_more
);
16161 group_insns
[slot
] = insn
;
16163 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
16164 if (insn_terminates_group_p (insn
, current_group
))
16165 can_issue_more
= 0;
16167 next_insn
= get_next_active_insn (insn
, tail
);
16168 if (next_insn
== NULL_RTX
)
16169 return group_count
+ 1;
16171 /* Is next_insn going to start a new group? */
16173 = (can_issue_more
== 0
16174 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
16175 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
16176 || (can_issue_more
< issue_rate
&&
16177 insn_terminates_group_p (next_insn
, previous_group
)));
16179 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
16180 next_insn
, &group_end
, can_issue_more
,
16186 can_issue_more
= 0;
16187 for (i
= 0; i
< issue_rate
; i
++)
16189 group_insns
[i
] = 0;
16193 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
16194 PUT_MODE (next_insn
, VOIDmode
);
16195 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
16196 PUT_MODE (next_insn
, TImode
);
16199 if (can_issue_more
== 0)
16200 can_issue_more
= issue_rate
;
16203 return group_count
;
16206 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
16207 dispatch group boundaries that the scheduler had marked. Pad with nops
16208 any dispatch groups which have vacant issue slots, in order to force the
16209 scheduler's grouping on the processor dispatcher. The function
16210 returns the number of dispatch groups found. */
16213 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
16215 rtx insn
, next_insn
;
16218 int can_issue_more
;
16220 int group_count
= 0;
16222 /* Initialize issue_rate. */
16223 issue_rate
= rs6000_issue_rate ();
16224 can_issue_more
= issue_rate
;
16226 insn
= get_next_active_insn (prev_head_insn
, tail
);
16227 next_insn
= get_next_active_insn (insn
, tail
);
16229 while (insn
!= NULL_RTX
)
16232 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
16234 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
16236 if (next_insn
== NULL_RTX
)
16241 /* If the scheduler had marked group termination at this location
16242 (between insn and next_indn), and neither insn nor next_insn will
16243 force group termination, pad the group with nops to force group
16246 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
16247 && !insn_terminates_group_p (insn
, current_group
)
16248 && !insn_terminates_group_p (next_insn
, previous_group
))
16250 if (!is_branch_slot_insn (next_insn
))
16253 while (can_issue_more
)
16256 emit_insn_before (nop
, next_insn
);
16261 can_issue_more
= issue_rate
;
16266 next_insn
= get_next_active_insn (insn
, tail
);
16269 return group_count
;
16272 /* The following function is called at the end of scheduling BB.
16273 After reload, it inserts nops at insn group bundling. */
16276 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
16281 fprintf (dump
, "=== Finishing schedule.\n");
16283 if (reload_completed
&& rs6000_sched_groups
)
16285 if (rs6000_sched_insert_nops
== sched_finish_none
)
16288 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
16289 n_groups
= pad_groups (dump
, sched_verbose
,
16290 current_sched_info
->prev_head
,
16291 current_sched_info
->next_tail
);
16293 n_groups
= redefine_groups (dump
, sched_verbose
,
16294 current_sched_info
->prev_head
,
16295 current_sched_info
->next_tail
);
16297 if (sched_verbose
>= 6)
16299 fprintf (dump
, "ngroups = %d\n", n_groups
);
16300 print_rtl (dump
, current_sched_info
->prev_head
);
16301 fprintf (dump
, "Done finish_sched\n");
16306 /* Length in units of the trampoline for entering a nested function. */
16309 rs6000_trampoline_size (void)
16313 switch (DEFAULT_ABI
)
16316 gcc_unreachable ();
16319 ret
= (TARGET_32BIT
) ? 12 : 24;
16324 ret
= (TARGET_32BIT
) ? 40 : 48;
16331 /* Emit RTL insns to initialize the variable parts of a trampoline.
16332 FNADDR is an RTX for the address of the function's pure code.
16333 CXT is an RTX for the static chain value for the function. */
16336 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
16338 enum machine_mode pmode
= Pmode
;
16339 int regsize
= (TARGET_32BIT
) ? 4 : 8;
16340 rtx ctx_reg
= force_reg (pmode
, cxt
);
16342 switch (DEFAULT_ABI
)
16345 gcc_unreachable ();
16347 /* Macros to shorten the code expansions below. */
16348 #define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
16349 #define MEM_PLUS(addr,offset) \
16350 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
16352 /* Under AIX, just build the 3 word function descriptor */
16355 rtx fn_reg
= gen_reg_rtx (pmode
);
16356 rtx toc_reg
= gen_reg_rtx (pmode
);
16357 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
16358 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
16359 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
16360 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
16361 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
16365 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
16368 emit_library_call (gen_rtx_SYMBOL_REF (SImode
, "__trampoline_setup"),
16369 FALSE
, VOIDmode
, 4,
16371 GEN_INT (rs6000_trampoline_size ()), SImode
,
16381 /* Table of valid machine attributes. */
16383 const struct attribute_spec rs6000_attribute_table
[] =
16385 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
16386 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
16387 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
16388 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
16389 #ifdef SUBTARGET_ATTRIBUTE_TABLE
16390 SUBTARGET_ATTRIBUTE_TABLE
,
16392 { NULL
, 0, 0, false, false, false, NULL
}
16395 /* Handle the "altivec" attribute. The attribute may have
16396 arguments as follows:
16398 __attribute__((altivec(vector__)))
16399 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
16400 __attribute__((altivec(bool__))) (always followed by 'unsigned')
16402 and may appear more than once (e.g., 'vector bool char') in a
16403 given declaration. */
16406 rs6000_handle_altivec_attribute (tree
*node
,
16407 tree name ATTRIBUTE_UNUSED
,
16409 int flags ATTRIBUTE_UNUSED
,
16410 bool *no_add_attrs
)
16412 tree type
= *node
, result
= NULL_TREE
;
16413 enum machine_mode mode
;
16416 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
16417 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
16418 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
16421 while (POINTER_TYPE_P (type
)
16422 || TREE_CODE (type
) == FUNCTION_TYPE
16423 || TREE_CODE (type
) == METHOD_TYPE
16424 || TREE_CODE (type
) == ARRAY_TYPE
)
16425 type
= TREE_TYPE (type
);
16427 mode
= TYPE_MODE (type
);
16429 /* Check for invalid AltiVec type qualifiers. */
16430 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
16433 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
16434 else if (rs6000_warn_altivec_long
)
16435 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
16437 else if (type
== long_long_unsigned_type_node
16438 || type
== long_long_integer_type_node
)
16439 error ("use of %<long long%> in AltiVec types is invalid");
16440 else if (type
== double_type_node
)
16441 error ("use of %<double%> in AltiVec types is invalid");
16442 else if (type
== long_double_type_node
)
16443 error ("use of %<long double%> in AltiVec types is invalid");
16444 else if (type
== boolean_type_node
)
16445 error ("use of boolean types in AltiVec types is invalid");
16446 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
16447 error ("use of %<complex%> in AltiVec types is invalid");
16449 switch (altivec_type
)
16452 unsigned_p
= TYPE_UNSIGNED (type
);
16456 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
16459 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
16462 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
16464 case SFmode
: result
= V4SF_type_node
; break;
16465 /* If the user says 'vector int bool', we may be handed the 'bool'
16466 attribute _before_ the 'vector' attribute, and so select the
16467 proper type in the 'b' case below. */
16468 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
16476 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
16477 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
16478 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
16485 case V8HImode
: result
= pixel_V8HI_type_node
;
16491 if (result
&& result
!= type
&& TYPE_READONLY (type
))
16492 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
16494 *no_add_attrs
= true; /* No need to hang on to the attribute. */
16497 *node
= reconstruct_complex_type (*node
, result
);
16502 /* AltiVec defines four built-in scalar types that serve as vector
16503 elements; we must teach the compiler how to mangle them. */
16505 static const char *
16506 rs6000_mangle_fundamental_type (tree type
)
16508 if (type
== bool_char_type_node
) return "U6__boolc";
16509 if (type
== bool_short_type_node
) return "U6__bools";
16510 if (type
== pixel_type_node
) return "u7__pixel";
16511 if (type
== bool_int_type_node
) return "U6__booli";
16513 /* For all other types, use normal C++ mangling. */
16517 /* Handle a "longcall" or "shortcall" attribute; arguments as in
16518 struct attribute_spec.handler. */
16521 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
16522 tree args ATTRIBUTE_UNUSED
,
16523 int flags ATTRIBUTE_UNUSED
,
16524 bool *no_add_attrs
)
16526 if (TREE_CODE (*node
) != FUNCTION_TYPE
16527 && TREE_CODE (*node
) != FIELD_DECL
16528 && TREE_CODE (*node
) != TYPE_DECL
)
16530 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
16531 IDENTIFIER_POINTER (name
));
16532 *no_add_attrs
= true;
16538 /* Set longcall attributes on all functions declared when
16539 rs6000_default_long_calls is true. */
16541 rs6000_set_default_type_attributes (tree type
)
16543 if (rs6000_default_long_calls
16544 && (TREE_CODE (type
) == FUNCTION_TYPE
16545 || TREE_CODE (type
) == METHOD_TYPE
))
16546 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
16548 TYPE_ATTRIBUTES (type
));
16551 /* Return a reference suitable for calling a function with the
16552 longcall attribute. */
16555 rs6000_longcall_ref (rtx call_ref
)
16557 const char *call_name
;
16560 if (GET_CODE (call_ref
) != SYMBOL_REF
)
16563 /* System V adds '.' to the internal name, so skip them. */
16564 call_name
= XSTR (call_ref
, 0);
16565 if (*call_name
== '.')
16567 while (*call_name
== '.')
16570 node
= get_identifier (call_name
);
16571 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
16574 return force_reg (Pmode
, call_ref
);
16577 #ifdef USING_ELFOS_H
16579 /* A C statement or statements to switch to the appropriate section
16580 for output of RTX in mode MODE. You can assume that RTX is some
16581 kind of constant in RTL. The argument MODE is redundant except in
16582 the case of a `const_int' rtx. Select the section by calling
16583 `text_section' or one of the alternatives for other sections.
16585 Do not define this macro if you put all constants in the read-only
16589 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
16590 unsigned HOST_WIDE_INT align
)
16592 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
16595 default_elf_select_rtx_section (mode
, x
, align
);
16598 /* A C statement or statements to switch to the appropriate
16599 section for output of DECL. DECL is either a `VAR_DECL' node
16600 or a constant of some sort. RELOC indicates whether forming
16601 the initial value of DECL requires link-time relocations. */
16604 rs6000_elf_select_section (tree decl
, int reloc
,
16605 unsigned HOST_WIDE_INT align
)
16607 /* Pretend that we're always building for a shared library when
16608 ABI_AIX, because otherwise we end up with dynamic relocations
16609 in read-only sections. This happens for function pointers,
16610 references to vtables in typeinfo, and probably other cases. */
16611 default_elf_select_section_1 (decl
, reloc
, align
,
16612 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
16615 /* A C statement to build up a unique section name, expressed as a
16616 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
16617 RELOC indicates whether the initial value of EXP requires
16618 link-time relocations. If you do not define this macro, GCC will use
16619 the symbol name prefixed by `.' as the section name. Note - this
16620 macro can now be called for uninitialized data items as well as
16621 initialized data and functions. */
16624 rs6000_elf_unique_section (tree decl
, int reloc
)
16626 /* As above, pretend that we're always building for a shared library
16627 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
16628 default_unique_section_1 (decl
, reloc
,
16629 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
16632 /* For a SYMBOL_REF, set generic flags and then perform some
16633 target-specific processing.
16635 When the AIX ABI is requested on a non-AIX system, replace the
16636 function name with the real name (with a leading .) rather than the
16637 function descriptor name. This saves a lot of overriding code to
16638 read the prefixes. */
16641 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
16643 default_encode_section_info (decl
, rtl
, first
);
16646 && TREE_CODE (decl
) == FUNCTION_DECL
16648 && DEFAULT_ABI
== ABI_AIX
)
16650 rtx sym_ref
= XEXP (rtl
, 0);
16651 size_t len
= strlen (XSTR (sym_ref
, 0));
16652 char *str
= alloca (len
+ 2);
16654 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
16655 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
16660 rs6000_elf_in_small_data_p (tree decl
)
16662 if (rs6000_sdata
== SDATA_NONE
)
16665 /* We want to merge strings, so we never consider them small data. */
16666 if (TREE_CODE (decl
) == STRING_CST
)
16669 /* Functions are never in the small data area. */
16670 if (TREE_CODE (decl
) == FUNCTION_DECL
)
16673 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
16675 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
16676 if (strcmp (section
, ".sdata") == 0
16677 || strcmp (section
, ".sdata2") == 0
16678 || strcmp (section
, ".sbss") == 0
16679 || strcmp (section
, ".sbss2") == 0
16680 || strcmp (section
, ".PPC.EMB.sdata0") == 0
16681 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
16686 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
16689 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
16690 /* If it's not public, and we're not going to reference it there,
16691 there's no need to put it in the small data section. */
16692 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
16699 #endif /* USING_ELFOS_H */
16702 /* Return a REG that occurs in ADDR with coefficient 1.
16703 ADDR can be effectively incremented by incrementing REG.
16705 r0 is special and we must not select it as an address
16706 register by this routine since our caller will try to
16707 increment the returned register via an "la" instruction. */
16710 find_addr_reg (rtx addr
)
16712 while (GET_CODE (addr
) == PLUS
)
16714 if (GET_CODE (XEXP (addr
, 0)) == REG
16715 && REGNO (XEXP (addr
, 0)) != 0)
16716 addr
= XEXP (addr
, 0);
16717 else if (GET_CODE (XEXP (addr
, 1)) == REG
16718 && REGNO (XEXP (addr
, 1)) != 0)
16719 addr
= XEXP (addr
, 1);
16720 else if (CONSTANT_P (XEXP (addr
, 0)))
16721 addr
= XEXP (addr
, 1);
16722 else if (CONSTANT_P (XEXP (addr
, 1)))
16723 addr
= XEXP (addr
, 0);
16725 gcc_unreachable ();
16727 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
16732 rs6000_fatal_bad_address (rtx op
)
16734 fatal_insn ("bad address", op
);
16739 static tree branch_island_list
= 0;
16741 /* Remember to generate a branch island for far calls to the given
16745 add_compiler_branch_island (tree label_name
, tree function_name
,
16748 tree branch_island
= build_tree_list (function_name
, label_name
);
16749 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
16750 TREE_CHAIN (branch_island
) = branch_island_list
;
16751 branch_island_list
= branch_island
;
16754 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
16755 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
16756 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
16757 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
16759 /* Generate far-jump branch islands for everything on the
16760 branch_island_list. Invoked immediately after the last instruction
16761 of the epilogue has been emitted; the branch-islands must be
16762 appended to, and contiguous with, the function body. Mach-O stubs
16763 are generated in machopic_output_stub(). */
16766 macho_branch_islands (void)
16769 tree branch_island
;
16771 for (branch_island
= branch_island_list
;
16773 branch_island
= TREE_CHAIN (branch_island
))
16775 const char *label
=
16776 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
16778 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
16779 char name_buf
[512];
16780 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
16781 if (name
[0] == '*' || name
[0] == '&')
16782 strcpy (name_buf
, name
+1);
16786 strcpy (name_buf
+1, name
);
16788 strcpy (tmp_buf
, "\n");
16789 strcat (tmp_buf
, label
);
16790 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
16791 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
16792 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
16793 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
16796 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
16797 strcat (tmp_buf
, label
);
16798 strcat (tmp_buf
, "_pic\n");
16799 strcat (tmp_buf
, label
);
16800 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
16802 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
16803 strcat (tmp_buf
, name_buf
);
16804 strcat (tmp_buf
, " - ");
16805 strcat (tmp_buf
, label
);
16806 strcat (tmp_buf
, "_pic)\n");
16808 strcat (tmp_buf
, "\tmtlr r0\n");
16810 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
16811 strcat (tmp_buf
, name_buf
);
16812 strcat (tmp_buf
, " - ");
16813 strcat (tmp_buf
, label
);
16814 strcat (tmp_buf
, "_pic)\n");
16816 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
16820 strcat (tmp_buf
, ":\nlis r12,hi16(");
16821 strcat (tmp_buf
, name_buf
);
16822 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
16823 strcat (tmp_buf
, name_buf
);
16824 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
16826 output_asm_insn (tmp_buf
, 0);
16827 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
16828 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
16829 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
16830 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
16833 branch_island_list
= 0;
16836 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
16837 already there or not. */
16840 no_previous_def (tree function_name
)
16842 tree branch_island
;
16843 for (branch_island
= branch_island_list
;
16845 branch_island
= TREE_CHAIN (branch_island
))
16846 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
16851 /* GET_PREV_LABEL gets the label name from the previous definition of
16855 get_prev_label (tree function_name
)
16857 tree branch_island
;
16858 for (branch_island
= branch_island_list
;
16860 branch_island
= TREE_CHAIN (branch_island
))
16861 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
16862 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
16866 /* INSN is either a function call or a millicode call. It may have an
16867 unconditional jump in its delay slot.
16869 CALL_DEST is the routine we are calling. */
16872 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
16873 int cookie_operand_number
)
16875 static char buf
[256];
16876 if (GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
16877 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
16880 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
16882 if (no_previous_def (funname
))
16884 int line_number
= 0;
16885 rtx label_rtx
= gen_label_rtx ();
16886 char *label_buf
, temp_buf
[256];
16887 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
16888 CODE_LABEL_NUMBER (label_rtx
));
16889 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
16890 labelname
= get_identifier (label_buf
);
16891 for (; insn
&& GET_CODE (insn
) != NOTE
; insn
= PREV_INSN (insn
));
16893 line_number
= NOTE_LINE_NUMBER (insn
);
16894 add_compiler_branch_island (labelname
, funname
, line_number
);
16897 labelname
= get_prev_label (funname
);
16899 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
16900 instruction will reach 'foo', otherwise link as 'bl L42'".
16901 "L42" should be a 'branch island', that will do a far jump to
16902 'foo'. Branch islands are generated in
16903 macho_branch_islands(). */
16904 sprintf (buf
, "jbsr %%z%d,%.246s",
16905 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
16908 sprintf (buf
, "bl %%z%d", dest_operand_number
);
16912 /* Generate PIC and indirect symbol stubs. */
16915 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
16917 unsigned int length
;
16918 char *symbol_name
, *lazy_ptr_name
;
16919 char *local_label_0
;
16920 static int label
= 0;
16922 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
16923 symb
= (*targetm
.strip_name_encoding
) (symb
);
16926 length
= strlen (symb
);
16927 symbol_name
= alloca (length
+ 32);
16928 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
16930 lazy_ptr_name
= alloca (length
+ 32);
16931 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
16934 machopic_picsymbol_stub1_section ();
16936 machopic_symbol_stub1_section ();
16940 fprintf (file
, "\t.align 5\n");
16942 fprintf (file
, "%s:\n", stub
);
16943 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
16946 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
16947 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
16949 fprintf (file
, "\tmflr r0\n");
16950 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
16951 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
16952 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
16953 lazy_ptr_name
, local_label_0
);
16954 fprintf (file
, "\tmtlr r0\n");
16955 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
16956 (TARGET_64BIT
? "ldu" : "lwzu"),
16957 lazy_ptr_name
, local_label_0
);
16958 fprintf (file
, "\tmtctr r12\n");
16959 fprintf (file
, "\tbctr\n");
16963 fprintf (file
, "\t.align 4\n");
16965 fprintf (file
, "%s:\n", stub
);
16966 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
16968 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
16969 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
16970 (TARGET_64BIT
? "ldu" : "lwzu"),
16972 fprintf (file
, "\tmtctr r12\n");
16973 fprintf (file
, "\tbctr\n");
16976 machopic_lazy_symbol_ptr_section ();
16977 fprintf (file
, "%s:\n", lazy_ptr_name
);
16978 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
16979 fprintf (file
, "%sdyld_stub_binding_helper\n",
16980 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
16983 /* Legitimize PIC addresses. If the address is already
16984 position-independent, we return ORIG. Newly generated
16985 position-independent addresses go into a reg. This is REG if non
16986 zero, otherwise we allocate register(s) as necessary. */
16988 #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x8000) < 0x10000)
16991 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
16996 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
16997 reg
= gen_reg_rtx (Pmode
);
16999 if (GET_CODE (orig
) == CONST
)
17003 if (GET_CODE (XEXP (orig
, 0)) == PLUS
17004 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
17007 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
17009 /* Use a different reg for the intermediate value, as
17010 it will be marked UNCHANGING. */
17011 reg_temp
= no_new_pseudos
? reg
: gen_reg_rtx (Pmode
);
17012 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
17015 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
17018 if (GET_CODE (offset
) == CONST_INT
)
17020 if (SMALL_INT (offset
))
17021 return plus_constant (base
, INTVAL (offset
));
17022 else if (! reload_in_progress
&& ! reload_completed
)
17023 offset
= force_reg (Pmode
, offset
);
17026 rtx mem
= force_const_mem (Pmode
, orig
);
17027 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
17030 return gen_rtx_PLUS (Pmode
, base
, offset
);
17033 /* Fall back on generic machopic code. */
17034 return machopic_legitimize_pic_address (orig
, mode
, reg
);
17037 /* This is just a placeholder to make linking work without having to
17038 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
17039 ever needed for Darwin (not too likely!) this would have to get a
17040 real definition. */
17047 /* Output a .machine directive for the Darwin assembler, and call
17048 the generic start_file routine. */
17051 rs6000_darwin_file_start (void)
17053 static const struct
17059 { "ppc64", "ppc64", MASK_64BIT
},
17060 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
17061 { "power4", "ppc970", 0 },
17062 { "G5", "ppc970", 0 },
17063 { "7450", "ppc7450", 0 },
17064 { "7400", "ppc7400", MASK_ALTIVEC
},
17065 { "G4", "ppc7400", 0 },
17066 { "750", "ppc750", 0 },
17067 { "740", "ppc750", 0 },
17068 { "G3", "ppc750", 0 },
17069 { "604e", "ppc604e", 0 },
17070 { "604", "ppc604", 0 },
17071 { "603e", "ppc603", 0 },
17072 { "603", "ppc603", 0 },
17073 { "601", "ppc601", 0 },
17074 { NULL
, "ppc", 0 } };
17075 const char *cpu_id
= "";
17078 rs6000_file_start ();
17080 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
17081 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
17082 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
17083 && rs6000_select
[i
].string
[0] != '\0')
17084 cpu_id
= rs6000_select
[i
].string
;
17086 /* Look through the mapping array. Pick the first name that either
17087 matches the argument, has a bit set in IF_SET that is also set
17088 in the target flags, or has a NULL name. */
17091 while (mapping
[i
].arg
!= NULL
17092 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
17093 && (mapping
[i
].if_set
& target_flags
) == 0)
17096 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
17099 #endif /* TARGET_MACHO */
17102 static unsigned int
17103 rs6000_elf_section_type_flags (tree decl
, const char *name
, int reloc
)
17105 return default_section_type_flags_1 (decl
, name
, reloc
,
17106 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
17109 /* Record an element in the table of global constructors. SYMBOL is
17110 a SYMBOL_REF of the function to be called; PRIORITY is a number
17111 between 0 and MAX_INIT_PRIORITY.
17113 This differs from default_named_section_asm_out_constructor in
17114 that we have special handling for -mrelocatable. */
17117 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
17119 const char *section
= ".ctors";
17122 if (priority
!= DEFAULT_INIT_PRIORITY
)
17124 sprintf (buf
, ".ctors.%.5u",
17125 /* Invert the numbering so the linker puts us in the proper
17126 order; constructors are run from right to left, and the
17127 linker sorts in increasing order. */
17128 MAX_INIT_PRIORITY
- priority
);
17132 named_section_flags (section
, SECTION_WRITE
);
17133 assemble_align (POINTER_SIZE
);
17135 if (TARGET_RELOCATABLE
)
17137 fputs ("\t.long (", asm_out_file
);
17138 output_addr_const (asm_out_file
, symbol
);
17139 fputs (")@fixup\n", asm_out_file
);
17142 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
17146 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
17148 const char *section
= ".dtors";
17151 if (priority
!= DEFAULT_INIT_PRIORITY
)
17153 sprintf (buf
, ".dtors.%.5u",
17154 /* Invert the numbering so the linker puts us in the proper
17155 order; constructors are run from right to left, and the
17156 linker sorts in increasing order. */
17157 MAX_INIT_PRIORITY
- priority
);
17161 named_section_flags (section
, SECTION_WRITE
);
17162 assemble_align (POINTER_SIZE
);
17164 if (TARGET_RELOCATABLE
)
17166 fputs ("\t.long (", asm_out_file
);
17167 output_addr_const (asm_out_file
, symbol
);
17168 fputs (")@fixup\n", asm_out_file
);
17171 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
17175 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
17179 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
17180 ASM_OUTPUT_LABEL (file
, name
);
17181 fputs (DOUBLE_INT_ASM_OP
, file
);
17182 rs6000_output_function_entry (file
, name
);
17183 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
17186 fputs ("\t.size\t", file
);
17187 assemble_name (file
, name
);
17188 fputs (",24\n\t.type\t.", file
);
17189 assemble_name (file
, name
);
17190 fputs (",@function\n", file
);
17191 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
17193 fputs ("\t.globl\t.", file
);
17194 assemble_name (file
, name
);
17199 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
17200 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
17201 rs6000_output_function_entry (file
, name
);
17202 fputs (":\n", file
);
17206 if (TARGET_RELOCATABLE
17207 && (get_pool_size () != 0 || current_function_profile
)
17212 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
17214 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
17215 fprintf (file
, "\t.long ");
17216 assemble_name (file
, buf
);
17218 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
17219 assemble_name (file
, buf
);
17223 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
17224 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
17226 if (DEFAULT_ABI
== ABI_AIX
)
17228 const char *desc_name
, *orig_name
;
17230 orig_name
= (*targetm
.strip_name_encoding
) (name
);
17231 desc_name
= orig_name
;
17232 while (*desc_name
== '.')
17235 if (TREE_PUBLIC (decl
))
17236 fprintf (file
, "\t.globl %s\n", desc_name
);
17238 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
17239 fprintf (file
, "%s:\n", desc_name
);
17240 fprintf (file
, "\t.long %s\n", orig_name
);
17241 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
17242 if (DEFAULT_ABI
== ABI_AIX
)
17243 fputs ("\t.long 0\n", file
);
17244 fprintf (file
, "\t.previous\n");
17246 ASM_OUTPUT_LABEL (file
, name
);
17250 rs6000_elf_end_indicate_exec_stack (void)
17253 file_end_indicate_exec_stack ();
17259 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
17261 fputs (GLOBAL_ASM_OP
, stream
);
17262 RS6000_OUTPUT_BASENAME (stream
, name
);
17263 putc ('\n', stream
);
17267 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
17268 tree decl ATTRIBUTE_UNUSED
)
17271 static const char * const suffix
[3] = { "PR", "RO", "RW" };
17273 if (flags
& SECTION_CODE
)
17275 else if (flags
& SECTION_WRITE
)
17280 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
17281 (flags
& SECTION_CODE
) ? "." : "",
17282 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
17286 rs6000_xcoff_select_section (tree decl
, int reloc
,
17287 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
17289 if (decl_readonly_section_1 (decl
, reloc
, 1))
17291 if (TREE_PUBLIC (decl
))
17292 read_only_data_section ();
17294 read_only_private_data_section ();
17298 if (TREE_PUBLIC (decl
))
17301 private_data_section ();
17306 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
17310 /* Use select_section for private and uninitialized data. */
17311 if (!TREE_PUBLIC (decl
)
17312 || DECL_COMMON (decl
)
17313 || DECL_INITIAL (decl
) == NULL_TREE
17314 || DECL_INITIAL (decl
) == error_mark_node
17315 || (flag_zero_initialized_in_bss
17316 && initializer_zerop (DECL_INITIAL (decl
))))
17319 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
17320 name
= (*targetm
.strip_name_encoding
) (name
);
17321 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
17324 /* Select section for constant in constant pool.
17326 On RS/6000, all constants are in the private read-only data area.
17327 However, if this is being placed in the TOC it must be output as a
17331 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
17332 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
17334 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
17337 read_only_private_data_section ();
17340 /* Remove any trailing [DS] or the like from the symbol name. */
17342 static const char *
17343 rs6000_xcoff_strip_name_encoding (const char *name
)
17348 len
= strlen (name
);
17349 if (name
[len
- 1] == ']')
17350 return ggc_alloc_string (name
, len
- 4);
17355 /* Section attributes. AIX is always PIC. */
17357 static unsigned int
17358 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
17360 unsigned int align
;
17361 unsigned int flags
= default_section_type_flags_1 (decl
, name
, reloc
, 1);
17363 /* Align to at least UNIT size. */
17364 if (flags
& SECTION_CODE
)
17365 align
= MIN_UNITS_PER_WORD
;
17367 /* Increase alignment of large objects if not already stricter. */
17368 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
17369 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
17370 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
17372 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
17375 /* Output at beginning of assembler file.
17377 Initialize the section names for the RS/6000 at this point.
17379 Specify filename, including full path, to assembler.
17381 We want to go into the TOC section so at least one .toc will be emitted.
17382 Also, in order to output proper .bs/.es pairs, we need at least one static
17383 [RW] section emitted.
17385 Finally, declare mcount when profiling to make the assembler happy. */
17388 rs6000_xcoff_file_start (void)
17390 rs6000_gen_section_name (&xcoff_bss_section_name
,
17391 main_input_filename
, ".bss_");
17392 rs6000_gen_section_name (&xcoff_private_data_section_name
,
17393 main_input_filename
, ".rw_");
17394 rs6000_gen_section_name (&xcoff_read_only_section_name
,
17395 main_input_filename
, ".ro_");
17397 fputs ("\t.file\t", asm_out_file
);
17398 output_quoted_string (asm_out_file
, main_input_filename
);
17399 fputc ('\n', asm_out_file
);
17400 if (write_symbols
!= NO_DEBUG
)
17401 private_data_section ();
17404 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
17405 rs6000_file_start ();
17408 /* Output at end of assembler file.
17409 On the RS/6000, referencing data should automatically pull in text. */
17412 rs6000_xcoff_file_end (void)
17415 fputs ("_section_.text:\n", asm_out_file
);
17417 fputs (TARGET_32BIT
17418 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
17421 #endif /* TARGET_XCOFF */
17424 /* Cross-module name binding. Darwin does not support overriding
17425 functions at dynamic-link time. */
17428 rs6000_binds_local_p (tree decl
)
17430 return default_binds_local_p_1 (decl
, 0);
17434 /* Compute a (partial) cost for rtx X. Return true if the complete
17435 cost has been computed, and false if subexpressions should be
17436 scanned. In either case, *TOTAL contains the cost result. */
17439 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
17441 enum machine_mode mode
= GET_MODE (x
);
17445 /* On the RS/6000, if it is valid in the insn, it is free. */
17447 if (((outer_code
== SET
17448 || outer_code
== PLUS
17449 || outer_code
== MINUS
)
17450 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
17451 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')))
17452 || (outer_code
== AND
17453 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17454 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
17455 mode
== SImode
? 'L' : 'J'))
17456 || mask_operand (x
, VOIDmode
)))
17457 || ((outer_code
== IOR
|| outer_code
== XOR
)
17458 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17459 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
17460 mode
== SImode
? 'L' : 'J'))))
17461 || outer_code
== ASHIFT
17462 || outer_code
== ASHIFTRT
17463 || outer_code
== LSHIFTRT
17464 || outer_code
== ROTATE
17465 || outer_code
== ROTATERT
17466 || outer_code
== ZERO_EXTRACT
17467 || (outer_code
== MULT
17468 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
17469 || ((outer_code
== DIV
|| outer_code
== UDIV
17470 || outer_code
== MOD
|| outer_code
== UMOD
)
17471 && exact_log2 (INTVAL (x
)) >= 0)
17472 || (outer_code
== COMPARE
17473 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
17474 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')))
17475 || (outer_code
== EQ
17476 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
17477 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17478 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
17479 mode
== SImode
? 'L' : 'J'))))
17480 || (outer_code
== GTU
17481 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
17482 || (outer_code
== LTU
17483 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'P')))
17488 else if ((outer_code
== PLUS
17489 && reg_or_add_cint64_operand (x
, VOIDmode
))
17490 || (outer_code
== MINUS
17491 && reg_or_sub_cint64_operand (x
, VOIDmode
))
17492 || ((outer_code
== SET
17493 || outer_code
== IOR
17494 || outer_code
== XOR
)
17496 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
17498 *total
= COSTS_N_INSNS (1);
17505 && ((outer_code
== AND
17506 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
17507 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')
17508 || mask64_operand (x
, DImode
)))
17509 || ((outer_code
== IOR
|| outer_code
== XOR
)
17510 && CONST_DOUBLE_HIGH (x
) == 0
17511 && (CONST_DOUBLE_LOW (x
)
17512 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)))
17517 else if (mode
== DImode
17518 && (outer_code
== SET
17519 || outer_code
== IOR
17520 || outer_code
== XOR
)
17521 && CONST_DOUBLE_HIGH (x
) == 0)
17523 *total
= COSTS_N_INSNS (1);
17532 /* When optimizing for size, MEM should be slightly more expensive
17533 than generating address, e.g., (plus (reg) (const)).
17534 L1 cache latency is about two instructions. */
17535 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
17543 if (mode
== DFmode
)
17545 if (GET_CODE (XEXP (x
, 0)) == MULT
)
17547 /* FNMA accounted in outer NEG. */
17548 if (outer_code
== NEG
)
17549 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
17551 *total
= rs6000_cost
->dmul
;
17554 *total
= rs6000_cost
->fp
;
17556 else if (mode
== SFmode
)
17558 /* FNMA accounted in outer NEG. */
17559 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
17562 *total
= rs6000_cost
->fp
;
17564 else if (GET_CODE (XEXP (x
, 0)) == MULT
)
17566 /* The rs6000 doesn't have shift-and-add instructions. */
17567 rs6000_rtx_costs (XEXP (x
, 0), MULT
, PLUS
, total
);
17568 *total
+= COSTS_N_INSNS (1);
17571 *total
= COSTS_N_INSNS (1);
17575 if (mode
== DFmode
)
17577 if (GET_CODE (XEXP (x
, 0)) == MULT
)
17579 /* FNMA accounted in outer NEG. */
17580 if (outer_code
== NEG
)
17583 *total
= rs6000_cost
->dmul
;
17586 *total
= rs6000_cost
->fp
;
17588 else if (mode
== SFmode
)
17590 /* FNMA accounted in outer NEG. */
17591 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
17594 *total
= rs6000_cost
->fp
;
17596 else if (GET_CODE (XEXP (x
, 0)) == MULT
)
17598 /* The rs6000 doesn't have shift-and-sub instructions. */
17599 rs6000_rtx_costs (XEXP (x
, 0), MULT
, MINUS
, total
);
17600 *total
+= COSTS_N_INSNS (1);
17603 *total
= COSTS_N_INSNS (1);
17607 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
17608 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x
, 1)), 'I'))
17610 if (INTVAL (XEXP (x
, 1)) >= -256
17611 && INTVAL (XEXP (x
, 1)) <= 255)
17612 *total
= rs6000_cost
->mulsi_const9
;
17614 *total
= rs6000_cost
->mulsi_const
;
17616 /* FMA accounted in outer PLUS/MINUS. */
17617 else if ((mode
== DFmode
|| mode
== SFmode
)
17618 && (outer_code
== PLUS
|| outer_code
== MINUS
))
17620 else if (mode
== DFmode
)
17621 *total
= rs6000_cost
->dmul
;
17622 else if (mode
== SFmode
)
17623 *total
= rs6000_cost
->fp
;
17624 else if (mode
== DImode
)
17625 *total
= rs6000_cost
->muldi
;
17627 *total
= rs6000_cost
->mulsi
;
17632 if (FLOAT_MODE_P (mode
))
17634 *total
= mode
== DFmode
? rs6000_cost
->ddiv
17635 : rs6000_cost
->sdiv
;
17642 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
17643 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
17645 if (code
== DIV
|| code
== MOD
)
17647 *total
= COSTS_N_INSNS (2);
17650 *total
= COSTS_N_INSNS (1);
17654 if (GET_MODE (XEXP (x
, 1)) == DImode
)
17655 *total
= rs6000_cost
->divdi
;
17657 *total
= rs6000_cost
->divsi
;
17659 /* Add in shift and subtract for MOD. */
17660 if (code
== MOD
|| code
== UMOD
)
17661 *total
+= COSTS_N_INSNS (2);
17665 *total
= COSTS_N_INSNS (4);
17669 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
17680 *total
= COSTS_N_INSNS (1);
17688 /* Handle mul_highpart. */
17689 if (outer_code
== TRUNCATE
17690 && GET_CODE (XEXP (x
, 0)) == MULT
)
17692 if (mode
== DImode
)
17693 *total
= rs6000_cost
->muldi
;
17695 *total
= rs6000_cost
->mulsi
;
17698 else if (outer_code
== AND
)
17701 *total
= COSTS_N_INSNS (1);
17706 if (GET_CODE (XEXP (x
, 0)) == MEM
)
17709 *total
= COSTS_N_INSNS (1);
17715 if (!FLOAT_MODE_P (mode
))
17717 *total
= COSTS_N_INSNS (1);
17723 case UNSIGNED_FLOAT
:
17727 case FLOAT_TRUNCATE
:
17728 *total
= rs6000_cost
->fp
;
17732 switch (XINT (x
, 1))
17735 *total
= rs6000_cost
->fp
;
17747 *total
= COSTS_N_INSNS (1);
17750 else if (FLOAT_MODE_P (mode
)
17751 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
17753 *total
= rs6000_cost
->fp
;
17761 /* Carry bit requires mode == Pmode.
17762 NEG or PLUS already counted so only add one. */
17764 && (outer_code
== NEG
|| outer_code
== PLUS
))
17766 *total
= COSTS_N_INSNS (1);
17769 if (outer_code
== SET
)
17771 if (XEXP (x
, 1) == const0_rtx
)
17773 *total
= COSTS_N_INSNS (2);
17776 else if (mode
== Pmode
)
17778 *total
= COSTS_N_INSNS (3);
17787 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
17789 *total
= COSTS_N_INSNS (2);
17793 if (outer_code
== COMPARE
)
17807 /* A C expression returning the cost of moving data from a register of class
17808 CLASS1 to one of CLASS2. */
17811 rs6000_register_move_cost (enum machine_mode mode
,
17812 enum reg_class from
, enum reg_class to
)
17814 /* Moves from/to GENERAL_REGS. */
17815 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
17816 || reg_classes_intersect_p (from
, GENERAL_REGS
))
17818 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
17821 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
17822 return (rs6000_memory_move_cost (mode
, from
, 0)
17823 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
17825 /* It's more expensive to move CR_REGS than CR0_REGS because of the
17827 else if (from
== CR_REGS
)
17831 /* A move will cost one instruction per GPR moved. */
17832 return 2 * HARD_REGNO_NREGS (0, mode
);
17835 /* Moving between two similar registers is just one instruction. */
17836 else if (reg_classes_intersect_p (to
, from
))
17837 return mode
== TFmode
? 4 : 2;
17839 /* Everything else has to go through GENERAL_REGS. */
17841 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
17842 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
17845 /* A C expressions returning the cost of moving data of MODE from a register to
17849 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
17850 int in ATTRIBUTE_UNUSED
)
17852 if (reg_classes_intersect_p (class, GENERAL_REGS
))
17853 return 4 * HARD_REGNO_NREGS (0, mode
);
17854 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
17855 return 4 * HARD_REGNO_NREGS (32, mode
);
17856 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
17857 return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO
, mode
);
17859 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
17862 /* Return an RTX representing where to find the function value of a
17863 function returning MODE. */
17865 rs6000_complex_function_value (enum machine_mode mode
)
17867 unsigned int regno
;
17869 enum machine_mode inner
= GET_MODE_INNER (mode
);
17870 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
17872 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
17873 regno
= FP_ARG_RETURN
;
17876 regno
= GP_ARG_RETURN
;
17878 /* 32-bit is OK since it'll go in r3/r4. */
17879 if (TARGET_32BIT
&& inner_bytes
>= 4)
17880 return gen_rtx_REG (mode
, regno
);
17883 if (inner_bytes
>= 8)
17884 return gen_rtx_REG (mode
, regno
);
17886 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
17888 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
17889 GEN_INT (inner_bytes
));
17890 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
17893 /* Define how to find the value returned by a function.
17894 VALTYPE is the data type of the value (as a tree).
17895 If the precise function being called is known, FUNC is its FUNCTION_DECL;
17896 otherwise, FUNC is 0.
17898 On the SPE, both FPs and vectors are returned in r3.
17900 On RS/6000 an integer value is in r3 and a floating-point value is in
17901 fp1, unless -msoft-float. */
17904 rs6000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
17906 enum machine_mode mode
;
17907 unsigned int regno
;
17909 /* Special handling for structs in darwin64. */
17910 if (rs6000_darwin64_abi
17911 && TYPE_MODE (valtype
) == BLKmode
17912 && TREE_CODE (valtype
) == RECORD_TYPE
17913 && int_size_in_bytes (valtype
) > 0)
17915 CUMULATIVE_ARGS valcum
;
17919 valcum
.fregno
= FP_ARG_MIN_REG
;
17920 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
17921 /* Do a trial code generation as if this were going to be passed as
17922 an argument; if any part goes in memory, we return NULL. */
17923 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
17926 /* Otherwise fall through to standard ABI rules. */
17929 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
17931 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
17932 return gen_rtx_PARALLEL (DImode
,
17934 gen_rtx_EXPR_LIST (VOIDmode
,
17935 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
17937 gen_rtx_EXPR_LIST (VOIDmode
,
17938 gen_rtx_REG (SImode
,
17939 GP_ARG_RETURN
+ 1),
17943 if ((INTEGRAL_TYPE_P (valtype
)
17944 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
17945 || POINTER_TYPE_P (valtype
))
17946 mode
= TARGET_32BIT
? SImode
: DImode
;
17948 mode
= TYPE_MODE (valtype
);
17950 if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
17951 regno
= FP_ARG_RETURN
;
17952 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
17953 && targetm
.calls
.split_complex_arg
)
17954 return rs6000_complex_function_value (mode
);
17955 else if (TREE_CODE (valtype
) == VECTOR_TYPE
17956 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
17957 && ALTIVEC_VECTOR_MODE (mode
))
17958 regno
= ALTIVEC_ARG_RETURN
;
17959 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
17960 && (mode
== DFmode
|| mode
== DCmode
))
17961 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
17963 regno
= GP_ARG_RETURN
;
17965 return gen_rtx_REG (mode
, regno
);
17968 /* Define how to find the value returned by a library function
17969 assuming the value has mode MODE. */
17971 rs6000_libcall_value (enum machine_mode mode
)
17973 unsigned int regno
;
17975 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
17977 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
17978 return gen_rtx_PARALLEL (DImode
,
17980 gen_rtx_EXPR_LIST (VOIDmode
,
17981 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
17983 gen_rtx_EXPR_LIST (VOIDmode
,
17984 gen_rtx_REG (SImode
,
17985 GP_ARG_RETURN
+ 1),
17989 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
17990 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
17991 regno
= FP_ARG_RETURN
;
17992 else if (ALTIVEC_VECTOR_MODE (mode
)
17993 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
17994 regno
= ALTIVEC_ARG_RETURN
;
17995 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
17996 return rs6000_complex_function_value (mode
);
17997 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
17998 && (mode
== DFmode
|| mode
== DCmode
))
17999 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
18001 regno
= GP_ARG_RETURN
;
18003 return gen_rtx_REG (mode
, regno
);
18006 /* Define the offset between two registers, FROM to be eliminated and its
18007 replacement TO, at the start of a routine. */
18009 rs6000_initial_elimination_offset (int from
, int to
)
18011 rs6000_stack_t
*info
= rs6000_stack_info ();
18012 HOST_WIDE_INT offset
;
18014 if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
18015 offset
= info
->push_p
? 0 : -info
->total_size
;
18016 else if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
18017 offset
= info
->total_size
;
18018 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
18019 offset
= info
->push_p
? info
->total_size
: 0;
18020 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
18023 gcc_unreachable ();
18028 /* Return true if TYPE is a SPE or AltiVec opaque type. */
18031 rs6000_is_opaque_type (tree type
)
18033 return (type
== opaque_V2SI_type_node
18034 || type
== opaque_V2SF_type_node
18035 || type
== opaque_p_V2SI_type_node
18036 || type
== opaque_V4SI_type_node
);
18040 rs6000_dwarf_register_span (rtx reg
)
18045 && (SPE_VECTOR_MODE (GET_MODE (reg
))
18046 || (TARGET_E500_DOUBLE
&& GET_MODE (reg
) == DFmode
)))
18051 regno
= REGNO (reg
);
18053 /* The duality of the SPE register size wreaks all kinds of havoc.
18054 This is a way of distinguishing r0 in 32-bits from r0 in
18057 gen_rtx_PARALLEL (VOIDmode
,
18060 gen_rtx_REG (SImode
, regno
+ 1200),
18061 gen_rtx_REG (SImode
, regno
))
18063 gen_rtx_REG (SImode
, regno
),
18064 gen_rtx_REG (SImode
, regno
+ 1200)));
18067 /* Map internal gcc register numbers to DWARF2 register numbers. */
18070 rs6000_dbx_register_number (unsigned int regno
)
18072 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
18074 if (regno
== MQ_REGNO
)
18076 if (regno
== LINK_REGISTER_REGNUM
)
18078 if (regno
== COUNT_REGISTER_REGNUM
)
18080 if (CR_REGNO_P (regno
))
18081 return regno
- CR0_REGNO
+ 86;
18082 if (regno
== XER_REGNO
)
18084 if (ALTIVEC_REGNO_P (regno
))
18085 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
18086 if (regno
== VRSAVE_REGNO
)
18088 if (regno
== VSCR_REGNO
)
18090 if (regno
== SPE_ACC_REGNO
)
18092 if (regno
== SPEFSCR_REGNO
)
18094 /* SPE high reg number. We get these values of regno from
18095 rs6000_dwarf_register_span. */
18096 gcc_assert (regno
>= 1200 && regno
< 1232);
18100 /* target hook eh_return_filter_mode */
18101 static enum machine_mode
18102 rs6000_eh_return_filter_mode (void)
18104 return TARGET_32BIT
? SImode
: word_mode
;
18107 /* Target hook for vector_mode_supported_p. */
18109 rs6000_vector_mode_supported_p (enum machine_mode mode
)
18112 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
18115 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
18122 /* Target hook for invalid_arg_for_unprototyped_fn. */
18123 static const char *
18124 invalid_arg_for_unprototyped_fn (tree typelist
, tree funcdecl
, tree val
)
18126 return (!rs6000_darwin64_abi
18128 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
18129 && (funcdecl
== NULL_TREE
18130 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
18131 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
18132 ? N_("AltiVec argument passed to unprototyped function")
18136 #include "gt-rs6000.h"