1 /* Subroutines used for code generation on IBM RS/6000.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 2, or (at your
12 option) any later version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING. If not, write to the
21 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
22 MA 02110-1301, USA. */
26 #include "coretypes.h"
30 #include "hard-reg-set.h"
32 #include "insn-config.h"
33 #include "conditions.h"
34 #include "insn-attr.h"
44 #include "basic-block.h"
45 #include "integrate.h"
51 #include "target-def.h"
52 #include "langhooks.h"
54 #include "cfglayout.h"
55 #include "sched-int.h"
56 #include "tree-gimple.h"
60 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
63 #include "gstab.h" /* for N_SLINE */
66 #ifndef TARGET_NO_PROTOTYPE
67 #define TARGET_NO_PROTOTYPE 0
70 #define min(A,B) ((A) < (B) ? (A) : (B))
71 #define max(A,B) ((A) > (B) ? (A) : (B))
73 /* Structure used to define the rs6000 stack */
74 typedef struct rs6000_stack
{
75 int first_gp_reg_save
; /* first callee saved GP register used */
76 int first_fp_reg_save
; /* first callee saved FP register used */
77 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
78 int lr_save_p
; /* true if the link reg needs to be saved */
79 int cr_save_p
; /* true if the CR reg needs to be saved */
80 unsigned int vrsave_mask
; /* mask of vec registers to save */
81 int push_p
; /* true if we need to allocate stack space */
82 int calls_p
; /* true if the function makes any calls */
83 int world_save_p
; /* true if we're saving *everything*:
84 r13-r31, cr, f14-f31, vrsave, v20-v31 */
85 enum rs6000_abi abi
; /* which ABI to use */
86 int gp_save_offset
; /* offset to save GP regs from initial SP */
87 int fp_save_offset
; /* offset to save FP regs from initial SP */
88 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
89 int lr_save_offset
; /* offset to save LR from initial SP */
90 int cr_save_offset
; /* offset to save CR from initial SP */
91 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
92 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
93 int varargs_save_offset
; /* offset to save the varargs registers */
94 int ehrd_offset
; /* offset to EH return data */
95 int reg_size
; /* register size (4 or 8) */
96 HOST_WIDE_INT vars_size
; /* variable save area size */
97 int parm_size
; /* outgoing parameter size */
98 int save_size
; /* save area size */
99 int fixed_size
; /* fixed size of stack frame */
100 int gp_size
; /* size of saved GP registers */
101 int fp_size
; /* size of saved FP registers */
102 int altivec_size
; /* size of saved AltiVec registers */
103 int cr_size
; /* size to hold CR if not in save_size */
104 int vrsave_size
; /* size to hold VRSAVE if not in save_size */
105 int altivec_padding_size
; /* size of altivec alignment padding if
107 int spe_gp_size
; /* size of 64-bit GPR save size for SPE */
108 int spe_padding_size
;
109 HOST_WIDE_INT total_size
; /* total bytes allocated for stack */
110 int spe_64bit_regs_used
;
113 /* A C structure for machine-specific, per-function data.
114 This is added to the cfun structure. */
115 typedef struct machine_function
GTY(())
117 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
118 int ra_needs_full_frame
;
119 /* Some local-dynamic symbol. */
120 const char *some_ld_name
;
121 /* Whether the instruction chain has been scanned already. */
122 int insn_chain_scanned_p
;
123 /* Flags if __builtin_return_address (0) was used. */
125 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
126 varargs save area. */
127 HOST_WIDE_INT varargs_save_offset
;
130 /* Target cpu type */
132 enum processor_type rs6000_cpu
;
133 struct rs6000_cpu_select rs6000_select
[3] =
135 /* switch name, tune arch */
136 { (const char *)0, "--with-cpu=", 1, 1 },
137 { (const char *)0, "-mcpu=", 1, 1 },
138 { (const char *)0, "-mtune=", 1, 0 },
141 /* Always emit branch hint bits. */
142 static GTY(()) bool rs6000_always_hint
;
144 /* Schedule instructions for group formation. */
145 static GTY(()) bool rs6000_sched_groups
;
147 /* Support for -msched-costly-dep option. */
148 const char *rs6000_sched_costly_dep_str
;
149 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
151 /* Support for -minsert-sched-nops option. */
152 const char *rs6000_sched_insert_nops_str
;
153 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
155 /* Support targetm.vectorize.builtin_mask_for_load. */
156 static GTY(()) tree altivec_builtin_mask_for_load
;
158 /* Size of long double. */
159 int rs6000_long_double_type_size
;
161 /* IEEE quad extended precision long double. */
164 /* Whether -mabi=altivec has appeared. */
165 int rs6000_altivec_abi
;
167 /* Nonzero if we want SPE ABI extensions. */
170 /* Nonzero if floating point operations are done in the GPRs. */
171 int rs6000_float_gprs
= 0;
173 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
174 int rs6000_darwin64_abi
;
176 /* Set to nonzero once AIX common-mode calls have been defined. */
177 static GTY(()) int common_mode_defined
;
179 /* Save information from a "cmpxx" operation until the branch or scc is
181 rtx rs6000_compare_op0
, rs6000_compare_op1
;
182 int rs6000_compare_fp_p
;
184 /* Label number of label created for -mrelocatable, to call to so we can
185 get the address of the GOT section */
186 int rs6000_pic_labelno
;
189 /* Which abi to adhere to */
190 const char *rs6000_abi_name
;
192 /* Semantics of the small data area */
193 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
195 /* Which small data model to use */
196 const char *rs6000_sdata_name
= (char *)0;
198 /* Counter for labels which are to be placed in .fixup. */
199 int fixuplabelno
= 0;
202 /* Bit size of immediate TLS offsets and string from which it is decoded. */
203 int rs6000_tls_size
= 32;
204 const char *rs6000_tls_size_string
;
206 /* ABI enumeration available for subtarget to use. */
207 enum rs6000_abi rs6000_current_abi
;
209 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
213 const char *rs6000_debug_name
;
214 int rs6000_debug_stack
; /* debug stack applications */
215 int rs6000_debug_arg
; /* debug argument handling */
217 /* Value is TRUE if register/mode pair is acceptable. */
218 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
220 /* Built in types. */
222 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
223 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
225 const char *rs6000_traceback_name
;
227 traceback_default
= 0,
233 /* Flag to say the TOC is initialized */
235 char toc_label_name
[10];
237 static GTY(()) section
*read_only_data_section
;
238 static GTY(()) section
*private_data_section
;
239 static GTY(()) section
*read_only_private_data_section
;
240 static GTY(()) section
*sdata2_section
;
241 static GTY(()) section
*toc_section
;
243 /* Control alignment for fields within structures. */
244 /* String from -malign-XXXXX. */
245 int rs6000_alignment_flags
;
247 /* True for any options that were explicitly set. */
249 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
250 bool alignment
; /* True if -malign- was used. */
251 bool abi
; /* True if -mabi= was used. */
252 bool spe
; /* True if -mspe= was used. */
253 bool float_gprs
; /* True if -mfloat-gprs= was used. */
254 bool isel
; /* True if -misel was used. */
255 bool long_double
; /* True if -mlong-double- was used. */
256 } rs6000_explicit_options
;
258 struct builtin_description
260 /* mask is not const because we're going to alter it below. This
261 nonsense will go away when we rewrite the -march infrastructure
262 to give us more target flag bits. */
264 const enum insn_code icode
;
265 const char *const name
;
266 const enum rs6000_builtins code
;
269 /* Target cpu costs. */
271 struct processor_costs
{
272 const int mulsi
; /* cost of SImode multiplication. */
273 const int mulsi_const
; /* cost of SImode multiplication by constant. */
274 const int mulsi_const9
; /* cost of SImode mult by short constant. */
275 const int muldi
; /* cost of DImode multiplication. */
276 const int divsi
; /* cost of SImode division. */
277 const int divdi
; /* cost of DImode division. */
278 const int fp
; /* cost of simple SFmode and DFmode insns. */
279 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
280 const int sdiv
; /* cost of SFmode division (fdivs). */
281 const int ddiv
; /* cost of DFmode division (fdiv). */
284 const struct processor_costs
*rs6000_cost
;
286 /* Processor costs (relative to an add) */
288 /* Instruction size costs on 32bit processors. */
290 struct processor_costs size32_cost
= {
291 COSTS_N_INSNS (1), /* mulsi */
292 COSTS_N_INSNS (1), /* mulsi_const */
293 COSTS_N_INSNS (1), /* mulsi_const9 */
294 COSTS_N_INSNS (1), /* muldi */
295 COSTS_N_INSNS (1), /* divsi */
296 COSTS_N_INSNS (1), /* divdi */
297 COSTS_N_INSNS (1), /* fp */
298 COSTS_N_INSNS (1), /* dmul */
299 COSTS_N_INSNS (1), /* sdiv */
300 COSTS_N_INSNS (1), /* ddiv */
303 /* Instruction size costs on 64bit processors. */
305 struct processor_costs size64_cost
= {
306 COSTS_N_INSNS (1), /* mulsi */
307 COSTS_N_INSNS (1), /* mulsi_const */
308 COSTS_N_INSNS (1), /* mulsi_const9 */
309 COSTS_N_INSNS (1), /* muldi */
310 COSTS_N_INSNS (1), /* divsi */
311 COSTS_N_INSNS (1), /* divdi */
312 COSTS_N_INSNS (1), /* fp */
313 COSTS_N_INSNS (1), /* dmul */
314 COSTS_N_INSNS (1), /* sdiv */
315 COSTS_N_INSNS (1), /* ddiv */
318 /* Instruction costs on RIOS1 processors. */
320 struct processor_costs rios1_cost
= {
321 COSTS_N_INSNS (5), /* mulsi */
322 COSTS_N_INSNS (4), /* mulsi_const */
323 COSTS_N_INSNS (3), /* mulsi_const9 */
324 COSTS_N_INSNS (5), /* muldi */
325 COSTS_N_INSNS (19), /* divsi */
326 COSTS_N_INSNS (19), /* divdi */
327 COSTS_N_INSNS (2), /* fp */
328 COSTS_N_INSNS (2), /* dmul */
329 COSTS_N_INSNS (19), /* sdiv */
330 COSTS_N_INSNS (19), /* ddiv */
333 /* Instruction costs on RIOS2 processors. */
335 struct processor_costs rios2_cost
= {
336 COSTS_N_INSNS (2), /* mulsi */
337 COSTS_N_INSNS (2), /* mulsi_const */
338 COSTS_N_INSNS (2), /* mulsi_const9 */
339 COSTS_N_INSNS (2), /* muldi */
340 COSTS_N_INSNS (13), /* divsi */
341 COSTS_N_INSNS (13), /* divdi */
342 COSTS_N_INSNS (2), /* fp */
343 COSTS_N_INSNS (2), /* dmul */
344 COSTS_N_INSNS (17), /* sdiv */
345 COSTS_N_INSNS (17), /* ddiv */
348 /* Instruction costs on RS64A processors. */
350 struct processor_costs rs64a_cost
= {
351 COSTS_N_INSNS (20), /* mulsi */
352 COSTS_N_INSNS (12), /* mulsi_const */
353 COSTS_N_INSNS (8), /* mulsi_const9 */
354 COSTS_N_INSNS (34), /* muldi */
355 COSTS_N_INSNS (65), /* divsi */
356 COSTS_N_INSNS (67), /* divdi */
357 COSTS_N_INSNS (4), /* fp */
358 COSTS_N_INSNS (4), /* dmul */
359 COSTS_N_INSNS (31), /* sdiv */
360 COSTS_N_INSNS (31), /* ddiv */
363 /* Instruction costs on MPCCORE processors. */
365 struct processor_costs mpccore_cost
= {
366 COSTS_N_INSNS (2), /* mulsi */
367 COSTS_N_INSNS (2), /* mulsi_const */
368 COSTS_N_INSNS (2), /* mulsi_const9 */
369 COSTS_N_INSNS (2), /* muldi */
370 COSTS_N_INSNS (6), /* divsi */
371 COSTS_N_INSNS (6), /* divdi */
372 COSTS_N_INSNS (4), /* fp */
373 COSTS_N_INSNS (5), /* dmul */
374 COSTS_N_INSNS (10), /* sdiv */
375 COSTS_N_INSNS (17), /* ddiv */
378 /* Instruction costs on PPC403 processors. */
380 struct processor_costs ppc403_cost
= {
381 COSTS_N_INSNS (4), /* mulsi */
382 COSTS_N_INSNS (4), /* mulsi_const */
383 COSTS_N_INSNS (4), /* mulsi_const9 */
384 COSTS_N_INSNS (4), /* muldi */
385 COSTS_N_INSNS (33), /* divsi */
386 COSTS_N_INSNS (33), /* divdi */
387 COSTS_N_INSNS (11), /* fp */
388 COSTS_N_INSNS (11), /* dmul */
389 COSTS_N_INSNS (11), /* sdiv */
390 COSTS_N_INSNS (11), /* ddiv */
393 /* Instruction costs on PPC405 processors. */
395 struct processor_costs ppc405_cost
= {
396 COSTS_N_INSNS (5), /* mulsi */
397 COSTS_N_INSNS (4), /* mulsi_const */
398 COSTS_N_INSNS (3), /* mulsi_const9 */
399 COSTS_N_INSNS (5), /* muldi */
400 COSTS_N_INSNS (35), /* divsi */
401 COSTS_N_INSNS (35), /* divdi */
402 COSTS_N_INSNS (11), /* fp */
403 COSTS_N_INSNS (11), /* dmul */
404 COSTS_N_INSNS (11), /* sdiv */
405 COSTS_N_INSNS (11), /* ddiv */
408 /* Instruction costs on PPC440 processors. */
410 struct processor_costs ppc440_cost
= {
411 COSTS_N_INSNS (3), /* mulsi */
412 COSTS_N_INSNS (2), /* mulsi_const */
413 COSTS_N_INSNS (2), /* mulsi_const9 */
414 COSTS_N_INSNS (3), /* muldi */
415 COSTS_N_INSNS (34), /* divsi */
416 COSTS_N_INSNS (34), /* divdi */
417 COSTS_N_INSNS (5), /* fp */
418 COSTS_N_INSNS (5), /* dmul */
419 COSTS_N_INSNS (19), /* sdiv */
420 COSTS_N_INSNS (33), /* ddiv */
423 /* Instruction costs on PPC601 processors. */
425 struct processor_costs ppc601_cost
= {
426 COSTS_N_INSNS (5), /* mulsi */
427 COSTS_N_INSNS (5), /* mulsi_const */
428 COSTS_N_INSNS (5), /* mulsi_const9 */
429 COSTS_N_INSNS (5), /* muldi */
430 COSTS_N_INSNS (36), /* divsi */
431 COSTS_N_INSNS (36), /* divdi */
432 COSTS_N_INSNS (4), /* fp */
433 COSTS_N_INSNS (5), /* dmul */
434 COSTS_N_INSNS (17), /* sdiv */
435 COSTS_N_INSNS (31), /* ddiv */
438 /* Instruction costs on PPC603 processors. */
440 struct processor_costs ppc603_cost
= {
441 COSTS_N_INSNS (5), /* mulsi */
442 COSTS_N_INSNS (3), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (5), /* muldi */
445 COSTS_N_INSNS (37), /* divsi */
446 COSTS_N_INSNS (37), /* divdi */
447 COSTS_N_INSNS (3), /* fp */
448 COSTS_N_INSNS (4), /* dmul */
449 COSTS_N_INSNS (18), /* sdiv */
450 COSTS_N_INSNS (33), /* ddiv */
453 /* Instruction costs on PPC604 processors. */
455 struct processor_costs ppc604_cost
= {
456 COSTS_N_INSNS (4), /* mulsi */
457 COSTS_N_INSNS (4), /* mulsi_const */
458 COSTS_N_INSNS (4), /* mulsi_const9 */
459 COSTS_N_INSNS (4), /* muldi */
460 COSTS_N_INSNS (20), /* divsi */
461 COSTS_N_INSNS (20), /* divdi */
462 COSTS_N_INSNS (3), /* fp */
463 COSTS_N_INSNS (3), /* dmul */
464 COSTS_N_INSNS (18), /* sdiv */
465 COSTS_N_INSNS (32), /* ddiv */
468 /* Instruction costs on PPC604e processors. */
470 struct processor_costs ppc604e_cost
= {
471 COSTS_N_INSNS (2), /* mulsi */
472 COSTS_N_INSNS (2), /* mulsi_const */
473 COSTS_N_INSNS (2), /* mulsi_const9 */
474 COSTS_N_INSNS (2), /* muldi */
475 COSTS_N_INSNS (20), /* divsi */
476 COSTS_N_INSNS (20), /* divdi */
477 COSTS_N_INSNS (3), /* fp */
478 COSTS_N_INSNS (3), /* dmul */
479 COSTS_N_INSNS (18), /* sdiv */
480 COSTS_N_INSNS (32), /* ddiv */
483 /* Instruction costs on PPC620 processors. */
485 struct processor_costs ppc620_cost
= {
486 COSTS_N_INSNS (5), /* mulsi */
487 COSTS_N_INSNS (4), /* mulsi_const */
488 COSTS_N_INSNS (3), /* mulsi_const9 */
489 COSTS_N_INSNS (7), /* muldi */
490 COSTS_N_INSNS (21), /* divsi */
491 COSTS_N_INSNS (37), /* divdi */
492 COSTS_N_INSNS (3), /* fp */
493 COSTS_N_INSNS (3), /* dmul */
494 COSTS_N_INSNS (18), /* sdiv */
495 COSTS_N_INSNS (32), /* ddiv */
498 /* Instruction costs on PPC630 processors. */
500 struct processor_costs ppc630_cost
= {
501 COSTS_N_INSNS (5), /* mulsi */
502 COSTS_N_INSNS (4), /* mulsi_const */
503 COSTS_N_INSNS (3), /* mulsi_const9 */
504 COSTS_N_INSNS (7), /* muldi */
505 COSTS_N_INSNS (21), /* divsi */
506 COSTS_N_INSNS (37), /* divdi */
507 COSTS_N_INSNS (3), /* fp */
508 COSTS_N_INSNS (3), /* dmul */
509 COSTS_N_INSNS (17), /* sdiv */
510 COSTS_N_INSNS (21), /* ddiv */
513 /* Instruction costs on PPC750 and PPC7400 processors. */
515 struct processor_costs ppc750_cost
= {
516 COSTS_N_INSNS (5), /* mulsi */
517 COSTS_N_INSNS (3), /* mulsi_const */
518 COSTS_N_INSNS (2), /* mulsi_const9 */
519 COSTS_N_INSNS (5), /* muldi */
520 COSTS_N_INSNS (17), /* divsi */
521 COSTS_N_INSNS (17), /* divdi */
522 COSTS_N_INSNS (3), /* fp */
523 COSTS_N_INSNS (3), /* dmul */
524 COSTS_N_INSNS (17), /* sdiv */
525 COSTS_N_INSNS (31), /* ddiv */
528 /* Instruction costs on PPC7450 processors. */
530 struct processor_costs ppc7450_cost
= {
531 COSTS_N_INSNS (4), /* mulsi */
532 COSTS_N_INSNS (3), /* mulsi_const */
533 COSTS_N_INSNS (3), /* mulsi_const9 */
534 COSTS_N_INSNS (4), /* muldi */
535 COSTS_N_INSNS (23), /* divsi */
536 COSTS_N_INSNS (23), /* divdi */
537 COSTS_N_INSNS (5), /* fp */
538 COSTS_N_INSNS (5), /* dmul */
539 COSTS_N_INSNS (21), /* sdiv */
540 COSTS_N_INSNS (35), /* ddiv */
543 /* Instruction costs on PPC8540 processors. */
545 struct processor_costs ppc8540_cost
= {
546 COSTS_N_INSNS (4), /* mulsi */
547 COSTS_N_INSNS (4), /* mulsi_const */
548 COSTS_N_INSNS (4), /* mulsi_const9 */
549 COSTS_N_INSNS (4), /* muldi */
550 COSTS_N_INSNS (19), /* divsi */
551 COSTS_N_INSNS (19), /* divdi */
552 COSTS_N_INSNS (4), /* fp */
553 COSTS_N_INSNS (4), /* dmul */
554 COSTS_N_INSNS (29), /* sdiv */
555 COSTS_N_INSNS (29), /* ddiv */
558 /* Instruction costs on POWER4 and POWER5 processors. */
560 struct processor_costs power4_cost
= {
561 COSTS_N_INSNS (3), /* mulsi */
562 COSTS_N_INSNS (2), /* mulsi_const */
563 COSTS_N_INSNS (2), /* mulsi_const9 */
564 COSTS_N_INSNS (4), /* muldi */
565 COSTS_N_INSNS (18), /* divsi */
566 COSTS_N_INSNS (34), /* divdi */
567 COSTS_N_INSNS (3), /* fp */
568 COSTS_N_INSNS (3), /* dmul */
569 COSTS_N_INSNS (17), /* sdiv */
570 COSTS_N_INSNS (17), /* ddiv */
574 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
575 static const char *rs6000_invalid_within_doloop (rtx
);
576 static rtx
rs6000_generate_compare (enum rtx_code
);
577 static void rs6000_maybe_dead (rtx
);
578 static void rs6000_emit_stack_tie (void);
579 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
580 static rtx
spe_synthesize_frame_save (rtx
);
581 static bool spe_func_has_64bit_regs_p (void);
582 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
584 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
585 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int);
586 static unsigned rs6000_hash_constant (rtx
);
587 static unsigned toc_hash_function (const void *);
588 static int toc_hash_eq (const void *, const void *);
589 static int constant_pool_expr_1 (rtx
, int *, int *);
590 static bool constant_pool_expr_p (rtx
);
591 static bool legitimate_indexed_address_p (rtx
, int);
592 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
593 static struct machine_function
* rs6000_init_machine_status (void);
594 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
595 static bool no_global_regs_above (int);
596 #ifdef HAVE_GAS_HIDDEN
597 static void rs6000_assemble_visibility (tree
, int);
599 static int rs6000_ra_ever_killed (void);
600 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
601 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
602 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
603 static const char *rs6000_mangle_fundamental_type (tree
);
604 extern const struct attribute_spec rs6000_attribute_table
[];
605 static void rs6000_set_default_type_attributes (tree
);
606 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
607 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
608 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
610 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
611 static bool rs6000_return_in_memory (tree
, tree
);
612 static void rs6000_file_start (void);
614 static unsigned int rs6000_elf_section_type_flags (tree
, const char *, int);
615 static void rs6000_elf_asm_out_constructor (rtx
, int);
616 static void rs6000_elf_asm_out_destructor (rtx
, int);
617 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
618 static void rs6000_elf_asm_init_sections (void);
619 static section
*rs6000_elf_select_section (tree
, int, unsigned HOST_WIDE_INT
);
620 static void rs6000_elf_unique_section (tree
, int);
621 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
622 unsigned HOST_WIDE_INT
);
623 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
627 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
628 static void rs6000_xcoff_asm_init_sections (void);
629 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
630 static section
*rs6000_xcoff_select_section (tree
, int,
631 unsigned HOST_WIDE_INT
);
632 static void rs6000_xcoff_unique_section (tree
, int);
633 static section
*rs6000_xcoff_select_rtx_section
634 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
635 static const char * rs6000_xcoff_strip_name_encoding (const char *);
636 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
637 static void rs6000_xcoff_file_start (void);
638 static void rs6000_xcoff_file_end (void);
640 static int rs6000_variable_issue (FILE *, int, rtx
, int);
641 static bool rs6000_rtx_costs (rtx
, int, int, int *);
642 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
643 static bool is_microcoded_insn (rtx
);
644 static int is_dispatch_slot_restricted (rtx
);
645 static bool is_cracked_insn (rtx
);
646 static bool is_branch_slot_insn (rtx
);
647 static int rs6000_adjust_priority (rtx
, int);
648 static int rs6000_issue_rate (void);
649 static bool rs6000_is_costly_dependence (rtx
, rtx
, rtx
, int, int);
650 static rtx
get_next_active_insn (rtx
, rtx
);
651 static bool insn_terminates_group_p (rtx
, enum group_termination
);
652 static bool is_costly_group (rtx
*, rtx
);
653 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
654 static int redefine_groups (FILE *, int, rtx
, rtx
);
655 static int pad_groups (FILE *, int, rtx
, rtx
);
656 static void rs6000_sched_finish (FILE *, int);
657 static int rs6000_use_sched_lookahead (void);
658 static tree
rs6000_builtin_mask_for_load (void);
660 static void def_builtin (int, const char *, tree
, int);
661 static void rs6000_init_builtins (void);
662 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
663 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
664 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
665 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
666 static void altivec_init_builtins (void);
667 static void rs6000_common_init_builtins (void);
668 static void rs6000_init_libfuncs (void);
670 static void enable_mask_for_builtins (struct builtin_description
*, int,
671 enum rs6000_builtins
,
672 enum rs6000_builtins
);
673 static tree
build_opaque_vector_type (tree
, int);
674 static void spe_init_builtins (void);
675 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
676 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
677 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
678 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
679 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
680 static rs6000_stack_t
*rs6000_stack_info (void);
681 static void debug_stack_info (rs6000_stack_t
*);
683 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
684 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
685 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
686 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
687 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
688 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
689 const char *, tree
, rtx
);
690 static rtx
altivec_expand_lv_builtin (enum insn_code
, tree
, rtx
);
691 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
692 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
693 static rtx
altivec_expand_vec_set_builtin (tree
);
694 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
695 static int get_element_number (tree
, tree
);
696 static bool rs6000_handle_option (size_t, const char *, int);
697 static void rs6000_parse_tls_size_option (void);
698 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
699 static int first_altivec_reg_to_save (void);
700 static unsigned int compute_vrsave_mask (void);
701 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
702 static void is_altivec_return_reg (rtx
, void *);
703 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
704 int easy_vector_constant (rtx
, enum machine_mode
);
705 static bool rs6000_is_opaque_type (tree
);
706 static rtx
rs6000_dwarf_register_span (rtx
);
707 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
708 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
709 static rtx
rs6000_tls_get_addr (void);
710 static rtx
rs6000_got_sym (void);
711 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
712 static const char *rs6000_get_some_local_dynamic_name (void);
713 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
714 static rtx
rs6000_complex_function_value (enum machine_mode
);
715 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
716 enum machine_mode
, tree
);
717 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
719 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
720 tree
, HOST_WIDE_INT
);
721 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
724 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
727 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, tree
, int, bool);
728 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
729 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
730 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
731 enum machine_mode
, tree
,
733 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
735 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
737 static const char *invalid_arg_for_unprototyped_fn (tree
, tree
, tree
);
739 static void macho_branch_islands (void);
740 static void add_compiler_branch_island (tree
, tree
, int);
741 static int no_previous_def (tree function_name
);
742 static tree
get_prev_label (tree function_name
);
743 static void rs6000_darwin_file_start (void);
746 static tree
rs6000_build_builtin_va_list (void);
747 static tree
rs6000_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
748 static bool rs6000_must_pass_in_stack (enum machine_mode
, tree
);
749 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
750 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
751 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
753 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
755 static int get_vsel_insn (enum machine_mode
);
756 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
757 static tree
rs6000_stack_protect_fail (void);
759 const int INSN_NOT_AVAILABLE
= -1;
760 static enum machine_mode
rs6000_eh_return_filter_mode (void);
762 /* Hash table stuff for keeping track of TOC entries. */
764 struct toc_hash_struct
GTY(())
766 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
767 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
769 enum machine_mode key_mode
;
773 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
775 /* Default register names. */
776 char rs6000_reg_names
[][8] =
778 "0", "1", "2", "3", "4", "5", "6", "7",
779 "8", "9", "10", "11", "12", "13", "14", "15",
780 "16", "17", "18", "19", "20", "21", "22", "23",
781 "24", "25", "26", "27", "28", "29", "30", "31",
782 "0", "1", "2", "3", "4", "5", "6", "7",
783 "8", "9", "10", "11", "12", "13", "14", "15",
784 "16", "17", "18", "19", "20", "21", "22", "23",
785 "24", "25", "26", "27", "28", "29", "30", "31",
786 "mq", "lr", "ctr","ap",
787 "0", "1", "2", "3", "4", "5", "6", "7",
789 /* AltiVec registers. */
790 "0", "1", "2", "3", "4", "5", "6", "7",
791 "8", "9", "10", "11", "12", "13", "14", "15",
792 "16", "17", "18", "19", "20", "21", "22", "23",
793 "24", "25", "26", "27", "28", "29", "30", "31",
796 "spe_acc", "spefscr",
797 /* Soft frame pointer. */
801 #ifdef TARGET_REGNAMES
802 static const char alt_reg_names
[][8] =
804 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
805 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
806 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
807 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
808 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
809 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
810 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
811 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
812 "mq", "lr", "ctr", "ap",
813 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
815 /* AltiVec registers. */
816 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
817 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
818 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
819 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
822 "spe_acc", "spefscr",
823 /* Soft frame pointer. */
828 #ifndef MASK_STRICT_ALIGN
829 #define MASK_STRICT_ALIGN 0
831 #ifndef TARGET_PROFILE_KERNEL
832 #define TARGET_PROFILE_KERNEL 0
835 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
836 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
838 /* Initialize the GCC target structure. */
839 #undef TARGET_ATTRIBUTE_TABLE
840 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
841 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
842 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
844 #undef TARGET_ASM_ALIGNED_DI_OP
845 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
847 /* Default unaligned ops are only provided for ELF. Find the ops needed
848 for non-ELF systems. */
849 #ifndef OBJECT_FORMAT_ELF
851 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
853 #undef TARGET_ASM_UNALIGNED_HI_OP
854 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
855 #undef TARGET_ASM_UNALIGNED_SI_OP
856 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
857 #undef TARGET_ASM_UNALIGNED_DI_OP
858 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
861 #undef TARGET_ASM_UNALIGNED_HI_OP
862 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
863 #undef TARGET_ASM_UNALIGNED_SI_OP
864 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
865 #undef TARGET_ASM_UNALIGNED_DI_OP
866 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
867 #undef TARGET_ASM_ALIGNED_DI_OP
868 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
872 /* This hook deals with fixups for relocatable code and DI-mode objects
874 #undef TARGET_ASM_INTEGER
875 #define TARGET_ASM_INTEGER rs6000_assemble_integer
877 #ifdef HAVE_GAS_HIDDEN
878 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
879 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
882 #undef TARGET_HAVE_TLS
883 #define TARGET_HAVE_TLS HAVE_AS_TLS
885 #undef TARGET_CANNOT_FORCE_CONST_MEM
886 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
888 #undef TARGET_ASM_FUNCTION_PROLOGUE
889 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
890 #undef TARGET_ASM_FUNCTION_EPILOGUE
891 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
893 #undef TARGET_SCHED_VARIABLE_ISSUE
894 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
896 #undef TARGET_SCHED_ISSUE_RATE
897 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
898 #undef TARGET_SCHED_ADJUST_COST
899 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
900 #undef TARGET_SCHED_ADJUST_PRIORITY
901 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
902 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
903 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
904 #undef TARGET_SCHED_FINISH
905 #define TARGET_SCHED_FINISH rs6000_sched_finish
907 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
908 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
910 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
911 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
913 #undef TARGET_INIT_BUILTINS
914 #define TARGET_INIT_BUILTINS rs6000_init_builtins
916 #undef TARGET_EXPAND_BUILTIN
917 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
919 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
920 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
922 #undef TARGET_INIT_LIBFUNCS
923 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
926 #undef TARGET_BINDS_LOCAL_P
927 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
930 #undef TARGET_ASM_OUTPUT_MI_THUNK
931 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
933 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
934 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
936 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
937 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
939 #undef TARGET_INVALID_WITHIN_DOLOOP
940 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
942 #undef TARGET_RTX_COSTS
943 #define TARGET_RTX_COSTS rs6000_rtx_costs
944 #undef TARGET_ADDRESS_COST
945 #define TARGET_ADDRESS_COST hook_int_rtx_0
947 #undef TARGET_VECTOR_OPAQUE_P
948 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
950 #undef TARGET_DWARF_REGISTER_SPAN
951 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
953 /* On rs6000, function arguments are promoted, as are function return
955 #undef TARGET_PROMOTE_FUNCTION_ARGS
956 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
957 #undef TARGET_PROMOTE_FUNCTION_RETURN
958 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
960 #undef TARGET_RETURN_IN_MEMORY
961 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
963 #undef TARGET_SETUP_INCOMING_VARARGS
964 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
966 /* Always strict argument naming on rs6000. */
967 #undef TARGET_STRICT_ARGUMENT_NAMING
968 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
969 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
970 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
971 #undef TARGET_SPLIT_COMPLEX_ARG
972 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
973 #undef TARGET_MUST_PASS_IN_STACK
974 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
975 #undef TARGET_PASS_BY_REFERENCE
976 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
977 #undef TARGET_ARG_PARTIAL_BYTES
978 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
980 #undef TARGET_BUILD_BUILTIN_VA_LIST
981 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
983 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
984 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
986 #undef TARGET_EH_RETURN_FILTER_MODE
987 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
989 #undef TARGET_SCALAR_MODE_SUPPORTED_P
990 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
992 #undef TARGET_VECTOR_MODE_SUPPORTED_P
993 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
995 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
996 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
998 #undef TARGET_HANDLE_OPTION
999 #define TARGET_HANDLE_OPTION rs6000_handle_option
1001 #undef TARGET_DEFAULT_TARGET_FLAGS
1002 #define TARGET_DEFAULT_TARGET_FLAGS \
1003 (TARGET_DEFAULT | MASK_SCHED_PROLOG)
1005 #undef TARGET_STACK_PROTECT_FAIL
1006 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1008 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1009 The PowerPC architecture requires only weak consistency among
1010 processors--that is, memory accesses between processors need not be
1011 sequentially consistent and memory accesses among processors can occur
1012 in any order. The ability to order memory accesses weakly provides
1013 opportunities for more efficient use of the system bus. Unless a
1014 dependency exists, the 604e allows read operations to precede store
1016 #undef TARGET_RELAXED_ORDERING
1017 #define TARGET_RELAXED_ORDERING true
1020 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1021 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1024 struct gcc_target targetm
= TARGET_INITIALIZER
;
1027 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1030 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1032 /* The GPRs can hold any mode, but values bigger than one register
1033 cannot go past R31. */
1034 if (INT_REGNO_P (regno
))
1035 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1037 /* The float registers can only hold floating modes and DImode.
1038 This also excludes decimal float modes. */
1039 if (FP_REGNO_P (regno
))
1041 (SCALAR_FLOAT_MODE_P (mode
)
1042 && !DECIMAL_FLOAT_MODE_P (mode
)
1043 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1044 || (GET_MODE_CLASS (mode
) == MODE_INT
1045 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
);
1047 /* The CR register can only hold CC modes. */
1048 if (CR_REGNO_P (regno
))
1049 return GET_MODE_CLASS (mode
) == MODE_CC
;
1051 if (XER_REGNO_P (regno
))
1052 return mode
== PSImode
;
1054 /* AltiVec only in AldyVec registers. */
1055 if (ALTIVEC_REGNO_P (regno
))
1056 return ALTIVEC_VECTOR_MODE (mode
);
1058 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1059 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1062 /* We cannot put TImode anywhere except general register and it must be
1063 able to fit within the register set. */
1065 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1068 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1070 rs6000_init_hard_regno_mode_ok (void)
1074 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1075 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1076 if (rs6000_hard_regno_mode_ok (r
, m
))
1077 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1080 /* If not otherwise specified by a target, make 'long double' equivalent to
1083 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1084 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1087 /* Override command line options. Mostly we process the processor
1088 type and sometimes adjust other TARGET_ options. */
1091 rs6000_override_options (const char *default_cpu
)
1094 struct rs6000_cpu_select
*ptr
;
1097 /* Simplifications for entries below. */
1100 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1101 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1104 /* This table occasionally claims that a processor does not support
1105 a particular feature even though it does, but the feature is slower
1106 than the alternative. Thus, it shouldn't be relied on as a
1107 complete description of the processor's support.
1109 Please keep this list in order, and don't forget to update the
1110 documentation in invoke.texi when adding a new processor or
1114 const char *const name
; /* Canonical processor name. */
1115 const enum processor_type processor
; /* Processor type enum value. */
1116 const int target_enable
; /* Target flags to enable. */
1117 } const processor_target_table
[]
1118 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1119 {"403", PROCESSOR_PPC403
,
1120 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1121 {"405", PROCESSOR_PPC405
,
1122 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
},
1123 {"405fp", PROCESSOR_PPC405
, POWERPC_BASE_MASK
| MASK_MULHW
},
1124 {"440", PROCESSOR_PPC440
,
1125 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
},
1126 {"440fp", PROCESSOR_PPC440
, POWERPC_BASE_MASK
| MASK_MULHW
},
1127 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1128 {"601", PROCESSOR_PPC601
,
1129 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1130 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1131 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1132 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1133 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1134 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1135 {"620", PROCESSOR_PPC620
,
1136 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1137 {"630", PROCESSOR_PPC630
,
1138 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1139 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1140 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1141 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1142 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1143 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1144 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1145 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1146 {"8540", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1147 /* 8548 has a dummy entry for now. */
1148 {"8548", PROCESSOR_PPC8540
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1149 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1150 {"970", PROCESSOR_POWER4
,
1151 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1152 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1153 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1154 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1155 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1156 {"G5", PROCESSOR_POWER4
,
1157 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1158 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1159 {"power2", PROCESSOR_POWER
,
1160 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1161 {"power3", PROCESSOR_PPC630
,
1162 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1163 {"power4", PROCESSOR_POWER4
,
1164 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1165 {"power5", PROCESSOR_POWER5
,
1166 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1167 | MASK_MFCRF
| MASK_POPCNTB
},
1168 {"power5+", PROCESSOR_POWER5
,
1169 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1170 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1171 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1172 {"powerpc64", PROCESSOR_POWERPC64
,
1173 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1174 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1175 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1176 {"rios2", PROCESSOR_RIOS2
,
1177 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1178 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1179 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1180 {"rs64", PROCESSOR_RS64A
,
1181 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1184 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1186 /* Some OSs don't support saving the high part of 64-bit registers on
1187 context switch. Other OSs don't support saving Altivec registers.
1188 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1189 settings; if the user wants either, the user must explicitly specify
1190 them and we won't interfere with the user's specification. */
1193 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1194 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
1195 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1196 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
)
1199 rs6000_init_hard_regno_mode_ok ();
1201 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1202 #ifdef OS_MISSING_POWERPC64
1203 if (OS_MISSING_POWERPC64
)
1204 set_masks
&= ~MASK_POWERPC64
;
1206 #ifdef OS_MISSING_ALTIVEC
1207 if (OS_MISSING_ALTIVEC
)
1208 set_masks
&= ~MASK_ALTIVEC
;
1211 /* Don't override by the processor default if given explicitly. */
1212 set_masks
&= ~target_flags_explicit
;
1214 /* Identify the processor type. */
1215 rs6000_select
[0].string
= default_cpu
;
1216 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1218 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1220 ptr
= &rs6000_select
[i
];
1221 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1223 for (j
= 0; j
< ptt_size
; j
++)
1224 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1226 if (ptr
->set_tune_p
)
1227 rs6000_cpu
= processor_target_table
[j
].processor
;
1229 if (ptr
->set_arch_p
)
1231 target_flags
&= ~set_masks
;
1232 target_flags
|= (processor_target_table
[j
].target_enable
1239 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1246 /* If we are optimizing big endian systems for space, use the load/store
1247 multiple and string instructions. */
1248 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1249 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1251 /* Don't allow -mmultiple or -mstring on little endian systems
1252 unless the cpu is a 750, because the hardware doesn't support the
1253 instructions used in little endian mode, and causes an alignment
1254 trap. The 750 does not cause an alignment trap (except when the
1255 target is unaligned). */
1257 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1259 if (TARGET_MULTIPLE
)
1261 target_flags
&= ~MASK_MULTIPLE
;
1262 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1263 warning (0, "-mmultiple is not supported on little endian systems");
1268 target_flags
&= ~MASK_STRING
;
1269 if ((target_flags_explicit
& MASK_STRING
) != 0)
1270 warning (0, "-mstring is not supported on little endian systems");
1274 /* Set debug flags */
1275 if (rs6000_debug_name
)
1277 if (! strcmp (rs6000_debug_name
, "all"))
1278 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1279 else if (! strcmp (rs6000_debug_name
, "stack"))
1280 rs6000_debug_stack
= 1;
1281 else if (! strcmp (rs6000_debug_name
, "arg"))
1282 rs6000_debug_arg
= 1;
1284 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1287 if (rs6000_traceback_name
)
1289 if (! strncmp (rs6000_traceback_name
, "full", 4))
1290 rs6000_traceback
= traceback_full
;
1291 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1292 rs6000_traceback
= traceback_part
;
1293 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1294 rs6000_traceback
= traceback_none
;
1296 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1297 rs6000_traceback_name
);
1300 if (!rs6000_explicit_options
.long_double
)
1301 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1303 #ifndef POWERPC_LINUX
1304 if (!rs6000_explicit_options
.abi
)
1305 rs6000_ieeequad
= 1;
1308 /* Set Altivec ABI as default for powerpc64 linux. */
1309 if (TARGET_ELF
&& TARGET_64BIT
)
1311 rs6000_altivec_abi
= 1;
1312 TARGET_ALTIVEC_VRSAVE
= 1;
1315 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1316 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1318 rs6000_darwin64_abi
= 1;
1320 darwin_one_byte_bool
= 1;
1322 /* Default to natural alignment, for better performance. */
1323 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1326 /* Handle -mtls-size option. */
1327 rs6000_parse_tls_size_option ();
1329 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1330 SUBTARGET_OVERRIDE_OPTIONS
;
1332 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1333 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1335 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1336 SUB3TARGET_OVERRIDE_OPTIONS
;
1342 error ("AltiVec and E500 instructions cannot coexist");
1344 /* The e500 does not have string instructions, and we set
1345 MASK_STRING above when optimizing for size. */
1346 if ((target_flags
& MASK_STRING
) != 0)
1347 target_flags
= target_flags
& ~MASK_STRING
;
1349 else if (rs6000_select
[1].string
!= NULL
)
1351 /* For the powerpc-eabispe configuration, we set all these by
1352 default, so let's unset them if we manually set another
1353 CPU that is not the E500. */
1354 if (!rs6000_explicit_options
.abi
)
1356 if (!rs6000_explicit_options
.spe
)
1358 if (!rs6000_explicit_options
.float_gprs
)
1359 rs6000_float_gprs
= 0;
1360 if (!rs6000_explicit_options
.isel
)
1362 if (!rs6000_explicit_options
.long_double
)
1363 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1366 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1367 && rs6000_cpu
!= PROCESSOR_POWER5
);
1368 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1369 || rs6000_cpu
== PROCESSOR_POWER5
);
1371 rs6000_sched_restricted_insns_priority
1372 = (rs6000_sched_groups
? 1 : 0);
1374 /* Handle -msched-costly-dep option. */
1375 rs6000_sched_costly_dep
1376 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1378 if (rs6000_sched_costly_dep_str
)
1380 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1381 rs6000_sched_costly_dep
= no_dep_costly
;
1382 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1383 rs6000_sched_costly_dep
= all_deps_costly
;
1384 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1385 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1386 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1387 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1389 rs6000_sched_costly_dep
= atoi (rs6000_sched_costly_dep_str
);
1392 /* Handle -minsert-sched-nops option. */
1393 rs6000_sched_insert_nops
1394 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1396 if (rs6000_sched_insert_nops_str
)
1398 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1399 rs6000_sched_insert_nops
= sched_finish_none
;
1400 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1401 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1402 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1403 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1405 rs6000_sched_insert_nops
= atoi (rs6000_sched_insert_nops_str
);
1408 #ifdef TARGET_REGNAMES
1409 /* If the user desires alternate register names, copy in the
1410 alternate names now. */
1411 if (TARGET_REGNAMES
)
1412 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1415 /* Set aix_struct_return last, after the ABI is determined.
1416 If -maix-struct-return or -msvr4-struct-return was explicitly
1417 used, don't override with the ABI default. */
1418 if (!rs6000_explicit_options
.aix_struct_ret
)
1419 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1421 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1422 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1425 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1427 /* We can only guarantee the availability of DI pseudo-ops when
1428 assembling for 64-bit targets. */
1431 targetm
.asm_out
.aligned_op
.di
= NULL
;
1432 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1435 /* Set branch target alignment, if not optimizing for size. */
1438 if (rs6000_sched_groups
)
1440 if (align_functions
<= 0)
1441 align_functions
= 16;
1442 if (align_jumps
<= 0)
1444 if (align_loops
<= 0)
1447 if (align_jumps_max_skip
<= 0)
1448 align_jumps_max_skip
= 15;
1449 if (align_loops_max_skip
<= 0)
1450 align_loops_max_skip
= 15;
1453 /* Arrange to save and restore machine status around nested functions. */
1454 init_machine_status
= rs6000_init_machine_status
;
1456 /* We should always be splitting complex arguments, but we can't break
1457 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1458 if (DEFAULT_ABI
!= ABI_AIX
)
1459 targetm
.calls
.split_complex_arg
= NULL
;
1461 /* Initialize rs6000_cost with the appropriate target costs. */
1463 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1467 case PROCESSOR_RIOS1
:
1468 rs6000_cost
= &rios1_cost
;
1471 case PROCESSOR_RIOS2
:
1472 rs6000_cost
= &rios2_cost
;
1475 case PROCESSOR_RS64A
:
1476 rs6000_cost
= &rs64a_cost
;
1479 case PROCESSOR_MPCCORE
:
1480 rs6000_cost
= &mpccore_cost
;
1483 case PROCESSOR_PPC403
:
1484 rs6000_cost
= &ppc403_cost
;
1487 case PROCESSOR_PPC405
:
1488 rs6000_cost
= &ppc405_cost
;
1491 case PROCESSOR_PPC440
:
1492 rs6000_cost
= &ppc440_cost
;
1495 case PROCESSOR_PPC601
:
1496 rs6000_cost
= &ppc601_cost
;
1499 case PROCESSOR_PPC603
:
1500 rs6000_cost
= &ppc603_cost
;
1503 case PROCESSOR_PPC604
:
1504 rs6000_cost
= &ppc604_cost
;
1507 case PROCESSOR_PPC604e
:
1508 rs6000_cost
= &ppc604e_cost
;
1511 case PROCESSOR_PPC620
:
1512 rs6000_cost
= &ppc620_cost
;
1515 case PROCESSOR_PPC630
:
1516 rs6000_cost
= &ppc630_cost
;
1519 case PROCESSOR_PPC750
:
1520 case PROCESSOR_PPC7400
:
1521 rs6000_cost
= &ppc750_cost
;
1524 case PROCESSOR_PPC7450
:
1525 rs6000_cost
= &ppc7450_cost
;
1528 case PROCESSOR_PPC8540
:
1529 rs6000_cost
= &ppc8540_cost
;
1532 case PROCESSOR_POWER4
:
1533 case PROCESSOR_POWER5
:
1534 rs6000_cost
= &power4_cost
;
1542 /* Implement targetm.vectorize.builtin_mask_for_load. */
1544 rs6000_builtin_mask_for_load (void)
1547 return altivec_builtin_mask_for_load
;
1552 /* Handle generic options of the form -mfoo=yes/no.
1553 NAME is the option name.
1554 VALUE is the option value.
1555 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1556 whether the option value is 'yes' or 'no' respectively. */
1558 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
1562 else if (!strcmp (value
, "yes"))
1564 else if (!strcmp (value
, "no"))
1567 error ("unknown -m%s= option specified: '%s'", name
, value
);
1570 /* Validate and record the size specified with the -mtls-size option. */
1573 rs6000_parse_tls_size_option (void)
1575 if (rs6000_tls_size_string
== 0)
1577 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
1578 rs6000_tls_size
= 16;
1579 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
1580 rs6000_tls_size
= 32;
1581 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
1582 rs6000_tls_size
= 64;
1584 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
1588 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1590 if (DEFAULT_ABI
== ABI_DARWIN
)
1591 /* The Darwin libraries never set errno, so we might as well
1592 avoid calling them when that's the only reason we would. */
1593 flag_errno_math
= 0;
1595 /* Double growth factor to counter reduced min jump length. */
1596 set_param_value ("max-grow-copy-bb-insns", 16);
1599 /* Implement TARGET_HANDLE_OPTION. */
1602 rs6000_handle_option (size_t code
, const char *arg
, int value
)
1607 target_flags
&= ~(MASK_POWER
| MASK_POWER2
1608 | MASK_MULTIPLE
| MASK_STRING
);
1609 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
1610 | MASK_MULTIPLE
| MASK_STRING
);
1612 case OPT_mno_powerpc
:
1613 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
1614 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1615 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
1616 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1619 target_flags
&= ~(MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
1620 | MASK_NO_SUM_IN_TOC
);
1621 target_flags_explicit
|= (MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
1622 | MASK_NO_SUM_IN_TOC
);
1623 #ifdef TARGET_USES_SYSV4_OPT
1624 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1625 just the same as -mminimal-toc. */
1626 target_flags
|= MASK_MINIMAL_TOC
;
1627 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1631 #ifdef TARGET_USES_SYSV4_OPT
1633 /* Make -mtoc behave like -mminimal-toc. */
1634 target_flags
|= MASK_MINIMAL_TOC
;
1635 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1639 #ifdef TARGET_USES_AIX64_OPT
1644 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
1645 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
1646 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
1649 #ifdef TARGET_USES_AIX64_OPT
1654 target_flags
&= ~MASK_POWERPC64
;
1655 target_flags_explicit
|= MASK_POWERPC64
;
1658 case OPT_minsert_sched_nops_
:
1659 rs6000_sched_insert_nops_str
= arg
;
1662 case OPT_mminimal_toc
:
1665 target_flags
&= ~(MASK_NO_FP_IN_TOC
| MASK_NO_SUM_IN_TOC
);
1666 target_flags_explicit
|= (MASK_NO_FP_IN_TOC
| MASK_NO_SUM_IN_TOC
);
1673 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
1674 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
1681 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1682 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1686 case OPT_mpowerpc_gpopt
:
1687 case OPT_mpowerpc_gfxopt
:
1690 target_flags
|= MASK_POWERPC
;
1691 target_flags_explicit
|= MASK_POWERPC
;
1695 case OPT_maix_struct_return
:
1696 case OPT_msvr4_struct_return
:
1697 rs6000_explicit_options
.aix_struct_ret
= true;
1701 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
1705 rs6000_explicit_options
.isel
= true;
1706 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
1710 rs6000_explicit_options
.spe
= true;
1711 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
1712 /* No SPE means 64-bit long doubles, even if an E500. */
1714 rs6000_long_double_type_size
= 64;
1718 rs6000_debug_name
= arg
;
1721 #ifdef TARGET_USES_SYSV4_OPT
1723 rs6000_abi_name
= arg
;
1727 rs6000_sdata_name
= arg
;
1730 case OPT_mtls_size_
:
1731 rs6000_tls_size_string
= arg
;
1734 case OPT_mrelocatable
:
1737 target_flags
|= MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
;
1738 target_flags_explicit
|= MASK_MINIMAL_TOC
| MASK_NO_FP_IN_TOC
;
1742 case OPT_mrelocatable_lib
:
1745 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
1746 | MASK_NO_FP_IN_TOC
;
1747 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
1748 | MASK_NO_FP_IN_TOC
;
1752 target_flags
&= ~MASK_RELOCATABLE
;
1753 target_flags_explicit
|= MASK_RELOCATABLE
;
1759 rs6000_explicit_options
.abi
= true;
1760 if (!strcmp (arg
, "altivec"))
1762 rs6000_altivec_abi
= 1;
1765 else if (! strcmp (arg
, "no-altivec"))
1766 rs6000_altivec_abi
= 0;
1767 else if (! strcmp (arg
, "spe"))
1770 rs6000_altivec_abi
= 0;
1771 if (!TARGET_SPE_ABI
)
1772 error ("not configured for ABI: '%s'", arg
);
1774 else if (! strcmp (arg
, "no-spe"))
1777 /* These are here for testing during development only, do not
1778 document in the manual please. */
1779 else if (! strcmp (arg
, "d64"))
1781 rs6000_darwin64_abi
= 1;
1782 warning (0, "Using darwin64 ABI");
1784 else if (! strcmp (arg
, "d32"))
1786 rs6000_darwin64_abi
= 0;
1787 warning (0, "Using old darwin ABI");
1790 else if (! strcmp (arg
, "ibmlongdouble"))
1792 rs6000_ieeequad
= 0;
1793 warning (0, "Using IBM extended precision long double");
1795 else if (! strcmp (arg
, "ieeelongdouble"))
1797 rs6000_ieeequad
= 1;
1798 warning (0, "Using IEEE extended precision long double");
1803 error ("unknown ABI specified: '%s'", arg
);
1809 rs6000_select
[1].string
= arg
;
1813 rs6000_select
[2].string
= arg
;
1816 case OPT_mtraceback_
:
1817 rs6000_traceback_name
= arg
;
1820 case OPT_mfloat_gprs_
:
1821 rs6000_explicit_options
.float_gprs
= true;
1822 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
1823 rs6000_float_gprs
= 1;
1824 else if (! strcmp (arg
, "double"))
1825 rs6000_float_gprs
= 2;
1826 else if (! strcmp (arg
, "no"))
1827 rs6000_float_gprs
= 0;
1830 error ("invalid option for -mfloat-gprs: '%s'", arg
);
1835 case OPT_mlong_double_
:
1836 rs6000_explicit_options
.long_double
= true;
1837 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1838 if (value
!= 64 && value
!= 128)
1840 error ("Unknown switch -mlong-double-%s", arg
);
1841 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1845 rs6000_long_double_type_size
= value
;
1848 case OPT_msched_costly_dep_
:
1849 rs6000_sched_costly_dep_str
= arg
;
1853 rs6000_explicit_options
.alignment
= true;
1854 if (! strcmp (arg
, "power"))
1856 /* On 64-bit Darwin, power alignment is ABI-incompatible with
1857 some C library functions, so warn about it. The flag may be
1858 useful for performance studies from time to time though, so
1859 don't disable it entirely. */
1860 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1861 warning (0, "-malign-power is not supported for 64-bit Darwin;"
1862 " it is incompatible with the installed C and C++ libraries");
1863 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
1865 else if (! strcmp (arg
, "natural"))
1866 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1869 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
1877 /* Do anything needed at the start of the asm file. */
1880 rs6000_file_start (void)
1884 const char *start
= buffer
;
1885 struct rs6000_cpu_select
*ptr
;
1886 const char *default_cpu
= TARGET_CPU_DEFAULT
;
1887 FILE *file
= asm_out_file
;
1889 default_file_start ();
1891 #ifdef TARGET_BI_ARCH
1892 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
1896 if (flag_verbose_asm
)
1898 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
1899 rs6000_select
[0].string
= default_cpu
;
1901 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1903 ptr
= &rs6000_select
[i
];
1904 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1906 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
1911 if (PPC405_ERRATUM77
)
1913 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
1917 #ifdef USING_ELFOS_H
1918 switch (rs6000_sdata
)
1920 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
1921 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
1922 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
1923 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
1926 if (rs6000_sdata
&& g_switch_value
)
1928 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
1938 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
1940 switch_to_section (toc_section
);
1941 switch_to_section (text_section
);
1946 /* Return nonzero if this function is known to have a null epilogue. */
1949 direct_return (void)
1951 if (reload_completed
)
1953 rs6000_stack_t
*info
= rs6000_stack_info ();
1955 if (info
->first_gp_reg_save
== 32
1956 && info
->first_fp_reg_save
== 64
1957 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
1958 && ! info
->lr_save_p
1959 && ! info
->cr_save_p
1960 && info
->vrsave_mask
== 0
1968 /* Return the number of instructions it takes to form a constant in an
1969 integer register. */
1972 num_insns_constant_wide (HOST_WIDE_INT value
)
1974 /* signed constant loadable with {cal|addi} */
1975 if (CONST_OK_FOR_LETTER_P (value
, 'I'))
1978 /* constant loadable with {cau|addis} */
1979 else if (CONST_OK_FOR_LETTER_P (value
, 'L'))
1982 #if HOST_BITS_PER_WIDE_INT == 64
1983 else if (TARGET_POWERPC64
)
1985 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
1986 HOST_WIDE_INT high
= value
>> 31;
1988 if (high
== 0 || high
== -1)
1994 return num_insns_constant_wide (high
) + 1;
1996 return (num_insns_constant_wide (high
)
1997 + num_insns_constant_wide (low
) + 1);
2006 num_insns_constant (rtx op
, enum machine_mode mode
)
2008 HOST_WIDE_INT low
, high
;
2010 switch (GET_CODE (op
))
2013 #if HOST_BITS_PER_WIDE_INT == 64
2014 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2015 && mask64_operand (op
, mode
))
2019 return num_insns_constant_wide (INTVAL (op
));
2027 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2028 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2029 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2032 if (mode
== VOIDmode
|| mode
== DImode
)
2034 high
= CONST_DOUBLE_HIGH (op
);
2035 low
= CONST_DOUBLE_LOW (op
);
2042 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2043 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2044 high
= l
[WORDS_BIG_ENDIAN
== 0];
2045 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2049 return (num_insns_constant_wide (low
)
2050 + num_insns_constant_wide (high
));
2053 if ((high
== 0 && low
>= 0)
2054 || (high
== -1 && low
< 0))
2055 return num_insns_constant_wide (low
);
2057 else if (mask64_operand (op
, mode
))
2061 return num_insns_constant_wide (high
) + 1;
2064 return (num_insns_constant_wide (high
)
2065 + num_insns_constant_wide (low
) + 1);
2074 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2075 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2076 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2077 all items are set to the same value and contain COPIES replicas of the
2078 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2079 operand and the others are set to the value of the operand's msb. */
2082 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2084 enum machine_mode mode
= GET_MODE (op
);
2085 enum machine_mode inner
= GET_MODE_INNER (mode
);
2088 unsigned nunits
= GET_MODE_NUNITS (mode
);
2089 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2090 unsigned mask
= GET_MODE_MASK (inner
);
2092 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2093 HOST_WIDE_INT val
= INTVAL (last
);
2094 HOST_WIDE_INT splat_val
= val
;
2095 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2097 /* Construct the value to be splatted, if possible. If not, return 0. */
2098 for (i
= 2; i
<= copies
; i
*= 2)
2100 HOST_WIDE_INT small_val
;
2102 small_val
= splat_val
>> bitsize
;
2104 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2106 splat_val
= small_val
;
2109 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2110 if (EASY_VECTOR_15 (splat_val
))
2113 /* Also check if we can splat, and then add the result to itself. Do so if
2114 the value is positive, of if the splat instruction is using OP's mode;
2115 for splat_val < 0, the splat and the add should use the same mode. */
2116 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2117 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2123 /* Check if VAL is present in every STEP-th element, and the
2124 other elements are filled with its most significant bit. */
2125 for (i
= 0; i
< nunits
- 1; ++i
)
2127 HOST_WIDE_INT desired_val
;
2128 if (((i
+ 1) & (step
- 1)) == 0)
2131 desired_val
= msb_val
;
2133 if (desired_val
!= INTVAL (CONST_VECTOR_ELT (op
, i
)))
2141 /* Return true if OP is of the given MODE and can be synthesized
2142 with a vspltisb, vspltish or vspltisw. */
2145 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2147 unsigned step
, copies
;
2149 if (mode
== VOIDmode
)
2150 mode
= GET_MODE (op
);
2151 else if (mode
!= GET_MODE (op
))
2154 /* Start with a vspltisw. */
2155 step
= GET_MODE_NUNITS (mode
) / 4;
2158 if (vspltis_constant (op
, step
, copies
))
2161 /* Then try with a vspltish. */
2167 if (vspltis_constant (op
, step
, copies
))
2170 /* And finally a vspltisb. */
2176 if (vspltis_constant (op
, step
, copies
))
2182 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2183 result is OP. Abort if it is not possible. */
2186 gen_easy_altivec_constant (rtx op
)
2188 enum machine_mode mode
= GET_MODE (op
);
2189 int nunits
= GET_MODE_NUNITS (mode
);
2190 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2191 unsigned step
= nunits
/ 4;
2192 unsigned copies
= 1;
2194 /* Start with a vspltisw. */
2195 if (vspltis_constant (op
, step
, copies
))
2196 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2198 /* Then try with a vspltish. */
2204 if (vspltis_constant (op
, step
, copies
))
2205 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2207 /* And finally a vspltisb. */
2213 if (vspltis_constant (op
, step
, copies
))
2214 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2220 output_vec_const_move (rtx
*operands
)
2223 enum machine_mode mode
;
2228 mode
= GET_MODE (dest
);
2233 if (zero_constant (vec
, mode
))
2234 return "vxor %0,%0,%0";
2236 splat_vec
= gen_easy_altivec_constant (vec
);
2237 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2238 operands
[1] = XEXP (splat_vec
, 0);
2239 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2242 switch (GET_MODE (splat_vec
))
2245 return "vspltisw %0,%1";
2248 return "vspltish %0,%1";
2251 return "vspltisb %0,%1";
2258 gcc_assert (TARGET_SPE
);
2260 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2261 pattern of V1DI, V4HI, and V2SF.
2263 FIXME: We should probably return # and add post reload
2264 splitters for these, but this way is so easy ;-). */
2265 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2266 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2267 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
2268 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
2270 return "li %0,%1\n\tevmergelo %0,%0,%0";
2272 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2275 /* Initialize vector TARGET to VALS. */
2278 rs6000_expand_vector_init (rtx target
, rtx vals
)
2280 enum machine_mode mode
= GET_MODE (target
);
2281 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2282 int n_elts
= GET_MODE_NUNITS (mode
);
2283 int n_var
= 0, one_var
= -1;
2284 bool all_same
= true, all_const_zero
= true;
2288 for (i
= 0; i
< n_elts
; ++i
)
2290 x
= XVECEXP (vals
, 0, i
);
2291 if (!CONSTANT_P (x
))
2292 ++n_var
, one_var
= i
;
2293 else if (x
!= CONST0_RTX (inner_mode
))
2294 all_const_zero
= false;
2296 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
2302 if (mode
!= V4SFmode
&& all_const_zero
)
2304 /* Zero register. */
2305 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2306 gen_rtx_XOR (mode
, target
, target
)));
2309 else if (mode
!= V4SFmode
&& easy_vector_constant (vals
, mode
))
2311 /* Splat immediate. */
2312 emit_insn (gen_rtx_SET (VOIDmode
, target
, vals
));
2316 ; /* Splat vector element. */
2319 /* Load from constant pool. */
2320 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
2325 /* Store value to stack temp. Load vector element. Splat. */
2328 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2329 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
2330 XVECEXP (vals
, 0, 0));
2331 x
= gen_rtx_UNSPEC (VOIDmode
,
2332 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2333 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2335 gen_rtx_SET (VOIDmode
,
2338 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
2339 gen_rtx_PARALLEL (VOIDmode
,
2340 gen_rtvec (1, const0_rtx
)));
2341 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2342 gen_rtx_VEC_DUPLICATE (mode
, x
)));
2346 /* One field is non-constant. Load constant then overwrite
2350 rtx copy
= copy_rtx (vals
);
2352 /* Load constant part of vector, substitute neighboring value for
2354 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
2355 rs6000_expand_vector_init (target
, copy
);
2357 /* Insert variable. */
2358 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
2362 /* Construct the vector in memory one field at a time
2363 and load the whole vector. */
2364 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2365 for (i
= 0; i
< n_elts
; i
++)
2366 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
2367 i
* GET_MODE_SIZE (inner_mode
)),
2368 XVECEXP (vals
, 0, i
));
2369 emit_move_insn (target
, mem
);
2372 /* Set field ELT of TARGET to VAL. */
2375 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
2377 enum machine_mode mode
= GET_MODE (target
);
2378 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2379 rtx reg
= gen_reg_rtx (mode
);
2381 int width
= GET_MODE_SIZE (inner_mode
);
2384 /* Load single variable value. */
2385 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2386 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
2387 x
= gen_rtx_UNSPEC (VOIDmode
,
2388 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2389 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2391 gen_rtx_SET (VOIDmode
,
2395 /* Linear sequence. */
2396 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
2397 for (i
= 0; i
< 16; ++i
)
2398 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
2400 /* Set permute mask to insert element into target. */
2401 for (i
= 0; i
< width
; ++i
)
2402 XVECEXP (mask
, 0, elt
*width
+ i
)
2403 = GEN_INT (i
+ 0x10);
2404 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
2405 x
= gen_rtx_UNSPEC (mode
,
2406 gen_rtvec (3, target
, reg
,
2407 force_reg (V16QImode
, x
)),
2409 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
2412 /* Extract field ELT from VEC into TARGET. */
2415 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
2417 enum machine_mode mode
= GET_MODE (vec
);
2418 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2421 /* Allocate mode-sized buffer. */
2422 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2424 /* Add offset to field within buffer matching vector element. */
2425 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
2427 /* Store single field into mode-sized buffer. */
2428 x
= gen_rtx_UNSPEC (VOIDmode
,
2429 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
2430 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2432 gen_rtx_SET (VOIDmode
,
2435 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
2438 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2439 implement ANDing by the mask IN. */
2441 build_mask64_2_operands (rtx in
, rtx
*out
)
2443 #if HOST_BITS_PER_WIDE_INT >= 64
2444 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
2447 gcc_assert (GET_CODE (in
) == CONST_INT
);
2452 /* Assume c initially something like 0x00fff000000fffff. The idea
2453 is to rotate the word so that the middle ^^^^^^ group of zeros
2454 is at the MS end and can be cleared with an rldicl mask. We then
2455 rotate back and clear off the MS ^^ group of zeros with a
2457 c
= ~c
; /* c == 0xff000ffffff00000 */
2458 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
2459 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
2460 c
= ~c
; /* c == 0x00fff000000fffff */
2461 c
&= -lsb
; /* c == 0x00fff00000000000 */
2462 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2463 c
= ~c
; /* c == 0xff000fffffffffff */
2464 c
&= -lsb
; /* c == 0xff00000000000000 */
2466 while ((lsb
>>= 1) != 0)
2467 shift
++; /* shift == 44 on exit from loop */
2468 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
2469 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
2470 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
2474 /* Assume c initially something like 0xff000f0000000000. The idea
2475 is to rotate the word so that the ^^^ middle group of zeros
2476 is at the LS end and can be cleared with an rldicr mask. We then
2477 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2479 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
2480 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
2481 c
= ~c
; /* c == 0x00fff0ffffffffff */
2482 c
&= -lsb
; /* c == 0x00fff00000000000 */
2483 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2484 c
= ~c
; /* c == 0xff000fffffffffff */
2485 c
&= -lsb
; /* c == 0xff00000000000000 */
2487 while ((lsb
>>= 1) != 0)
2488 shift
++; /* shift == 44 on exit from loop */
2489 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
2490 m1
>>= shift
; /* m1 == 0x0000000000000fff */
2491 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
2494 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2495 masks will be all 1's. We are guaranteed more than one transition. */
2496 out
[0] = GEN_INT (64 - shift
);
2497 out
[1] = GEN_INT (m1
);
2498 out
[2] = GEN_INT (shift
);
2499 out
[3] = GEN_INT (m2
);
2507 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2510 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
2512 /* Reject (subreg:SI (reg:DF)). */
2513 if (GET_CODE (op
) == SUBREG
2515 && REG_P (SUBREG_REG (op
))
2516 && GET_MODE (SUBREG_REG (op
)) == DFmode
)
2519 /* Reject (subreg:DF (reg:DI)). */
2520 if (GET_CODE (op
) == SUBREG
2522 && REG_P (SUBREG_REG (op
))
2523 && GET_MODE (SUBREG_REG (op
)) == DImode
)
2529 /* Darwin, AIX increases natural record alignment to doubleword if the first
2530 field is an FP double while the FP fields remain word aligned. */
2533 rs6000_special_round_type_align (tree type
, unsigned int computed
,
2534 unsigned int specified
)
2536 unsigned int align
= MAX (computed
, specified
);
2537 tree field
= TYPE_FIELDS (type
);
2539 /* Skip all non field decls */
2540 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
2541 field
= TREE_CHAIN (field
);
2543 if (field
!= NULL
&& field
!= type
)
2545 type
= TREE_TYPE (field
);
2546 while (TREE_CODE (type
) == ARRAY_TYPE
)
2547 type
= TREE_TYPE (type
);
2549 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
2550 align
= MAX (align
, 64);
2556 /* Return 1 for an operand in small memory on V.4/eabi. */
2559 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
2560 enum machine_mode mode ATTRIBUTE_UNUSED
)
2565 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
2568 if (DEFAULT_ABI
!= ABI_V4
)
2571 if (GET_CODE (op
) == SYMBOL_REF
)
2574 else if (GET_CODE (op
) != CONST
2575 || GET_CODE (XEXP (op
, 0)) != PLUS
2576 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
2577 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
2582 rtx sum
= XEXP (op
, 0);
2583 HOST_WIDE_INT summand
;
2585 /* We have to be careful here, because it is the referenced address
2586 that must be 32k from _SDA_BASE_, not just the symbol. */
2587 summand
= INTVAL (XEXP (sum
, 1));
2588 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
2591 sym_ref
= XEXP (sum
, 0);
2594 return SYMBOL_REF_SMALL_P (sym_ref
);
2600 /* Return true if either operand is a general purpose register. */
2603 gpr_or_gpr_p (rtx op0
, rtx op1
)
2605 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
2606 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
2610 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2613 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
2615 switch (GET_CODE (op
))
2618 if (RS6000_SYMBOL_REF_TLS_P (op
))
2620 else if (CONSTANT_POOL_ADDRESS_P (op
))
2622 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
2630 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
2639 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
2640 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
2642 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
2651 constant_pool_expr_p (rtx op
)
2655 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
2659 toc_relative_expr_p (rtx op
)
2663 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
2667 legitimate_constant_pool_address_p (rtx x
)
2670 && GET_CODE (x
) == PLUS
2671 && GET_CODE (XEXP (x
, 0)) == REG
2672 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
2673 && constant_pool_expr_p (XEXP (x
, 1)));
2677 rs6000_legitimate_small_data_p (enum machine_mode mode
, rtx x
)
2679 return (DEFAULT_ABI
== ABI_V4
2680 && !flag_pic
&& !TARGET_TOC
2681 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
2682 && small_data_operand (x
, mode
));
2685 /* SPE offset addressing is limited to 5-bits worth of double words. */
2686 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2689 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
2691 unsigned HOST_WIDE_INT offset
, extra
;
2693 if (GET_CODE (x
) != PLUS
)
2695 if (GET_CODE (XEXP (x
, 0)) != REG
)
2697 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
2699 if (legitimate_constant_pool_address_p (x
))
2701 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
2704 offset
= INTVAL (XEXP (x
, 1));
2712 /* AltiVec vector modes. Only reg+reg addressing is valid and
2713 constant offset zero should not occur due to canonicalization.
2714 Allow any offset when not strict before reload. */
2721 /* SPE vector modes. */
2722 return SPE_CONST_OFFSET_OK (offset
);
2725 if (TARGET_E500_DOUBLE
)
2726 return SPE_CONST_OFFSET_OK (offset
);
2729 /* On e500v2, we may have:
2731 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2733 Which gets addressed with evldd instructions. */
2734 if (TARGET_E500_DOUBLE
)
2735 return SPE_CONST_OFFSET_OK (offset
);
2737 if (mode
== DFmode
|| !TARGET_POWERPC64
)
2739 else if (offset
& 3)
2745 if (mode
== TFmode
|| !TARGET_POWERPC64
)
2747 else if (offset
& 3)
2758 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
2762 legitimate_indexed_address_p (rtx x
, int strict
)
2766 if (GET_CODE (x
) != PLUS
)
2772 /* Recognize the rtl generated by reload which we know will later be
2773 replaced with proper base and index regs. */
2775 && reload_in_progress
2776 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
2780 return (REG_P (op0
) && REG_P (op1
)
2781 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
2782 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
2783 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
2784 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
2788 legitimate_indirect_address_p (rtx x
, int strict
)
2790 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
2794 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
2796 if (!TARGET_MACHO
|| !flag_pic
2797 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
2801 if (GET_CODE (x
) != LO_SUM
)
2803 if (GET_CODE (XEXP (x
, 0)) != REG
)
2805 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
2809 return CONSTANT_P (x
);
2813 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
2815 if (GET_CODE (x
) != LO_SUM
)
2817 if (GET_CODE (XEXP (x
, 0)) != REG
)
2819 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
2821 /* Restrict addressing for DI because of our SUBREG hackery. */
2822 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DImode
))
2826 if (TARGET_ELF
|| TARGET_MACHO
)
2828 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
2832 if (GET_MODE_NUNITS (mode
) != 1)
2834 if (GET_MODE_BITSIZE (mode
) > 64
2835 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
2836 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& mode
== DFmode
)))
2839 return CONSTANT_P (x
);
2846 /* Try machine-dependent ways of modifying an illegitimate address
2847 to be legitimate. If we find one, return the new, valid address.
2848 This is used from only one place: `memory_address' in explow.c.
2850 OLDX is the address as it was before break_out_memory_refs was
2851 called. In some cases it is useful to look at this to decide what
2854 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
2856 It is always safe for this function to do nothing. It exists to
2857 recognize opportunities to optimize the output.
2859 On RS/6000, first check for the sum of a register with a constant
2860 integer that is out of range. If so, generate code to add the
2861 constant with the low-order 16 bits masked to the register and force
2862 this result into another register (this can be done with `cau').
2863 Then generate an address of REG+(CONST&0xffff), allowing for the
2864 possibility of bit 16 being a one.
2866 Then check for the sum of a register and something not constant, try to
2867 load the other things into a register and return the sum. */
2870 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
2871 enum machine_mode mode
)
2873 if (GET_CODE (x
) == SYMBOL_REF
)
2875 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
2877 return rs6000_legitimize_tls_address (x
, model
);
2880 if (GET_CODE (x
) == PLUS
2881 && GET_CODE (XEXP (x
, 0)) == REG
2882 && GET_CODE (XEXP (x
, 1)) == CONST_INT
2883 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000)
2885 HOST_WIDE_INT high_int
, low_int
;
2887 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2888 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
2889 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
2890 GEN_INT (high_int
)), 0);
2891 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
2893 else if (GET_CODE (x
) == PLUS
2894 && GET_CODE (XEXP (x
, 0)) == REG
2895 && GET_CODE (XEXP (x
, 1)) != CONST_INT
2896 && GET_MODE_NUNITS (mode
) == 1
2897 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
2899 || (((mode
!= DImode
&& mode
!= DFmode
) || TARGET_E500_DOUBLE
)
2901 && (TARGET_POWERPC64
|| mode
!= DImode
)
2904 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
2905 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
2907 else if (ALTIVEC_VECTOR_MODE (mode
))
2911 /* Make sure both operands are registers. */
2912 if (GET_CODE (x
) == PLUS
)
2913 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
2914 force_reg (Pmode
, XEXP (x
, 1)));
2916 reg
= force_reg (Pmode
, x
);
2919 else if (SPE_VECTOR_MODE (mode
)
2920 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
2921 || mode
== DImode
)))
2925 /* We accept [reg + reg] and [reg + OFFSET]. */
2927 if (GET_CODE (x
) == PLUS
)
2929 rtx op1
= XEXP (x
, 0);
2930 rtx op2
= XEXP (x
, 1);
2932 op1
= force_reg (Pmode
, op1
);
2934 if (GET_CODE (op2
) != REG
2935 && (GET_CODE (op2
) != CONST_INT
2936 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))))
2937 op2
= force_reg (Pmode
, op2
);
2939 return gen_rtx_PLUS (Pmode
, op1
, op2
);
2942 return force_reg (Pmode
, x
);
2948 && GET_CODE (x
) != CONST_INT
2949 && GET_CODE (x
) != CONST_DOUBLE
2951 && GET_MODE_NUNITS (mode
) == 1
2952 && (GET_MODE_BITSIZE (mode
) <= 32
2953 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) && mode
== DFmode
)))
2955 rtx reg
= gen_reg_rtx (Pmode
);
2956 emit_insn (gen_elf_high (reg
, x
));
2957 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
2959 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
2962 && ! MACHO_DYNAMIC_NO_PIC_P
2964 && GET_CODE (x
) != CONST_INT
2965 && GET_CODE (x
) != CONST_DOUBLE
2967 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) || mode
!= DFmode
)
2971 rtx reg
= gen_reg_rtx (Pmode
);
2972 emit_insn (gen_macho_high (reg
, x
));
2973 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
2976 && constant_pool_expr_p (x
)
2977 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
2979 return create_TOC_reference (x
);
2985 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
2986 We need to emit DTP-relative relocations. */
2989 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
2994 fputs ("\t.long\t", file
);
2997 fputs (DOUBLE_INT_ASM_OP
, file
);
3002 output_addr_const (file
, x
);
3003 fputs ("@dtprel+0x8000", file
);
3006 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3008 static GTY(()) rtx rs6000_tls_symbol
;
3010 rs6000_tls_get_addr (void)
3012 if (!rs6000_tls_symbol
)
3013 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3015 return rs6000_tls_symbol
;
3018 /* Construct the SYMBOL_REF for TLS GOT references. */
3020 static GTY(()) rtx rs6000_got_symbol
;
3022 rs6000_got_sym (void)
3024 if (!rs6000_got_symbol
)
3026 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
3027 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
3028 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
3031 return rs6000_got_symbol
;
3034 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3035 this (thread-local) address. */
3038 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
3042 dest
= gen_reg_rtx (Pmode
);
3043 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
3049 tlsreg
= gen_rtx_REG (Pmode
, 13);
3050 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
3054 tlsreg
= gen_rtx_REG (Pmode
, 2);
3055 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
3059 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
3063 tmp
= gen_reg_rtx (Pmode
);
3066 tlsreg
= gen_rtx_REG (Pmode
, 13);
3067 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
3071 tlsreg
= gen_rtx_REG (Pmode
, 2);
3072 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
3076 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
3078 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
3083 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
3085 /* We currently use relocations like @got@tlsgd for tls, which
3086 means the linker will handle allocation of tls entries, placing
3087 them in the .got section. So use a pointer to the .got section,
3088 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3089 or to secondary GOT sections used by 32-bit -fPIC. */
3091 got
= gen_rtx_REG (Pmode
, 2);
3095 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
3098 rtx gsym
= rs6000_got_sym ();
3099 got
= gen_reg_rtx (Pmode
);
3101 rs6000_emit_move (got
, gsym
, Pmode
);
3104 rtx tempLR
, tmp3
, mem
;
3107 tempLR
= gen_reg_rtx (Pmode
);
3108 tmp1
= gen_reg_rtx (Pmode
);
3109 tmp2
= gen_reg_rtx (Pmode
);
3110 tmp3
= gen_reg_rtx (Pmode
);
3111 mem
= gen_const_mem (Pmode
, tmp1
);
3113 first
= emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, gsym
));
3114 emit_move_insn (tmp1
, tempLR
);
3115 emit_move_insn (tmp2
, mem
);
3116 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
3117 last
= emit_move_insn (got
, tmp3
);
3118 REG_NOTES (last
) = gen_rtx_EXPR_LIST (REG_EQUAL
, gsym
,
3120 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
3122 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
,
3128 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
3130 r3
= gen_rtx_REG (Pmode
, 3);
3132 insn
= gen_tls_gd_64 (r3
, got
, addr
);
3134 insn
= gen_tls_gd_32 (r3
, got
, addr
);
3137 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3138 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3139 insn
= emit_call_insn (insn
);
3140 CONST_OR_PURE_CALL_P (insn
) = 1;
3141 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3142 insn
= get_insns ();
3144 emit_libcall_block (insn
, dest
, r3
, addr
);
3146 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
3148 r3
= gen_rtx_REG (Pmode
, 3);
3150 insn
= gen_tls_ld_64 (r3
, got
);
3152 insn
= gen_tls_ld_32 (r3
, got
);
3155 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3156 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3157 insn
= emit_call_insn (insn
);
3158 CONST_OR_PURE_CALL_P (insn
) = 1;
3159 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3160 insn
= get_insns ();
3162 tmp1
= gen_reg_rtx (Pmode
);
3163 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3165 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
3166 if (rs6000_tls_size
== 16)
3169 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
3171 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
3173 else if (rs6000_tls_size
== 32)
3175 tmp2
= gen_reg_rtx (Pmode
);
3177 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
3179 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
3182 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
3184 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
3188 tmp2
= gen_reg_rtx (Pmode
);
3190 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
3192 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
3194 insn
= gen_rtx_SET (Pmode
, dest
,
3195 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
3201 /* IE, or 64 bit offset LE. */
3202 tmp2
= gen_reg_rtx (Pmode
);
3204 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
3206 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
3209 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
3211 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
3219 /* Return 1 if X contains a thread-local symbol. */
3222 rs6000_tls_referenced_p (rtx x
)
3224 if (! TARGET_HAVE_TLS
)
3227 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
3230 /* Return 1 if *X is a thread-local symbol. This is the same as
3231 rs6000_tls_symbol_ref except for the type of the unused argument. */
3234 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
3236 return RS6000_SYMBOL_REF_TLS_P (*x
);
3239 /* The convention appears to be to define this wherever it is used.
3240 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3241 is now used here. */
3242 #ifndef REG_MODE_OK_FOR_BASE_P
3243 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3246 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3247 replace the input X, or the original X if no replacement is called for.
3248 The output parameter *WIN is 1 if the calling macro should goto WIN,
3251 For RS/6000, we wish to handle large displacements off a base
3252 register by splitting the addend across an addiu/addis and the mem insn.
3253 This cuts number of extra insns needed from 3 to 1.
3255 On Darwin, we use this to generate code for floating point constants.
3256 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3257 The Darwin code is inside #if TARGET_MACHO because only then is
3258 machopic_function_base_name() defined. */
3260 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
3261 int opnum
, int type
,
3262 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
3264 /* We must recognize output that we have already generated ourselves. */
3265 if (GET_CODE (x
) == PLUS
3266 && GET_CODE (XEXP (x
, 0)) == PLUS
3267 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3268 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3269 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3271 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3272 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3273 opnum
, (enum reload_type
)type
);
3279 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
3280 && GET_CODE (x
) == LO_SUM
3281 && GET_CODE (XEXP (x
, 0)) == PLUS
3282 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
3283 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
3284 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
3285 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
3286 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
3287 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
3288 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
3290 /* Result of previous invocation of this function on Darwin
3291 floating point constant. */
3292 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3293 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3294 opnum
, (enum reload_type
)type
);
3300 /* Force ld/std non-word aligned offset into base register by wrapping
3302 if (GET_CODE (x
) == PLUS
3303 && GET_CODE (XEXP (x
, 0)) == REG
3304 && REGNO (XEXP (x
, 0)) < 32
3305 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3306 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3307 && (INTVAL (XEXP (x
, 1)) & 3) != 0
3308 && !ALTIVEC_VECTOR_MODE (mode
)
3309 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
3310 && TARGET_POWERPC64
)
3312 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
3313 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3314 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3315 opnum
, (enum reload_type
) type
);
3320 if (GET_CODE (x
) == PLUS
3321 && GET_CODE (XEXP (x
, 0)) == REG
3322 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
3323 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3324 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3325 && !SPE_VECTOR_MODE (mode
)
3326 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
3328 && !ALTIVEC_VECTOR_MODE (mode
))
3330 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
3331 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
3333 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3335 /* Check for 32-bit overflow. */
3336 if (high
+ low
!= val
)
3342 /* Reload the high part into a base reg; leave the low part
3343 in the mem directly. */
3345 x
= gen_rtx_PLUS (GET_MODE (x
),
3346 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
3350 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3351 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3352 opnum
, (enum reload_type
)type
);
3357 if (GET_CODE (x
) == SYMBOL_REF
3358 && !ALTIVEC_VECTOR_MODE (mode
)
3360 && DEFAULT_ABI
== ABI_DARWIN
3361 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
3363 && DEFAULT_ABI
== ABI_V4
3366 /* Don't do this for TFmode, since the result isn't offsettable.
3367 The same goes for DImode without 64-bit gprs. */
3369 && (mode
!= DImode
|| TARGET_POWERPC64
))
3374 rtx offset
= gen_rtx_CONST (Pmode
,
3375 gen_rtx_MINUS (Pmode
, x
,
3376 machopic_function_base_sym ()));
3377 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3378 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
3379 gen_rtx_HIGH (Pmode
, offset
)), offset
);
3383 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3384 gen_rtx_HIGH (Pmode
, x
), x
);
3386 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3387 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3388 opnum
, (enum reload_type
)type
);
3393 /* Reload an offset address wrapped by an AND that represents the
3394 masking of the lower bits. Strip the outer AND and let reload
3395 convert the offset address into an indirect address. */
3397 && ALTIVEC_VECTOR_MODE (mode
)
3398 && GET_CODE (x
) == AND
3399 && GET_CODE (XEXP (x
, 0)) == PLUS
3400 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3401 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3402 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3403 && INTVAL (XEXP (x
, 1)) == -16)
3411 && constant_pool_expr_p (x
)
3412 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
3414 (x
) = create_TOC_reference (x
);
3422 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3423 that is a valid memory address for an instruction.
3424 The MODE argument is the machine mode for the MEM expression
3425 that wants to use this address.
3427 On the RS/6000, there are four valid address: a SYMBOL_REF that
3428 refers to a constant pool entry of an address (or the sum of it
3429 plus a constant), a short (16-bit signed) constant plus a register,
3430 the sum of two registers, or a register indirect, possibly with an
3431 auto-increment. For DFmode and DImode with a constant plus register,
3432 we must ensure that both words are addressable or PowerPC64 with offset
3435 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3436 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3437 adjacent memory cells are accessed by adding word-sized offsets
3438 during assembly output. */
3440 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
3442 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3444 && ALTIVEC_VECTOR_MODE (mode
)
3445 && GET_CODE (x
) == AND
3446 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3447 && INTVAL (XEXP (x
, 1)) == -16)
3450 if (RS6000_SYMBOL_REF_TLS_P (x
))
3452 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
3454 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
3455 && !ALTIVEC_VECTOR_MODE (mode
)
3456 && !SPE_VECTOR_MODE (mode
)
3457 /* Restrict addressing for DI because of our SUBREG hackery. */
3458 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DImode
))
3460 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
3462 if (rs6000_legitimate_small_data_p (mode
, x
))
3464 if (legitimate_constant_pool_address_p (x
))
3466 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3468 && GET_CODE (x
) == PLUS
3469 && GET_CODE (XEXP (x
, 0)) == REG
3470 && (XEXP (x
, 0) == virtual_stack_vars_rtx
3471 || XEXP (x
, 0) == arg_pointer_rtx
)
3472 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3474 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
3478 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3480 || ((mode
!= DFmode
|| TARGET_E500_DOUBLE
) && mode
!= TFmode
))
3481 && (TARGET_POWERPC64
|| mode
!= DImode
)
3482 && legitimate_indexed_address_p (x
, reg_ok_strict
))
3484 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
3489 /* Go to LABEL if ADDR (a legitimate address expression)
3490 has an effect that depends on the machine mode it is used for.
3492 On the RS/6000 this is true of all integral offsets (since AltiVec
3493 modes don't allow them) or is a pre-increment or decrement.
3495 ??? Except that due to conceptual problems in offsettable_address_p
3496 we can't really report the problems of integral offsets. So leave
3497 this assuming that the adjustable offset must be valid for the
3498 sub-words of a TFmode operand, which is what we had before. */
3501 rs6000_mode_dependent_address (rtx addr
)
3503 switch (GET_CODE (addr
))
3506 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
3508 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
3509 return val
+ 12 + 0x8000 >= 0x10000;
3518 return TARGET_UPDATE
;
3527 /* Return number of consecutive hard regs needed starting at reg REGNO
3528 to hold something of mode MODE.
3529 This is ordinarily the length in words of a value of mode MODE
3530 but can be less for certain modes in special long registers.
3532 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3533 scalar instructions. The upper 32 bits are only available to the
3536 POWER and PowerPC GPRs hold 32 bits worth;
3537 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3540 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
3542 if (FP_REGNO_P (regno
))
3543 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
3545 if (TARGET_E500_DOUBLE
&& mode
== DFmode
)
3548 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
3549 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
3551 if (ALTIVEC_REGNO_P (regno
))
3553 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
3555 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3558 /* Change register usage conditional on target flags. */
3560 rs6000_conditional_register_usage (void)
3564 /* Set MQ register fixed (already call_used) if not POWER
3565 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3570 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3572 fixed_regs
[13] = call_used_regs
[13]
3573 = call_really_used_regs
[13] = 1;
3575 /* Conditionally disable FPRs. */
3576 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
3577 for (i
= 32; i
< 64; i
++)
3578 fixed_regs
[i
] = call_used_regs
[i
]
3579 = call_really_used_regs
[i
] = 1;
3581 /* The TOC register is not killed across calls in a way that is
3582 visible to the compiler. */
3583 if (DEFAULT_ABI
== ABI_AIX
)
3584 call_really_used_regs
[2] = 0;
3586 if (DEFAULT_ABI
== ABI_V4
3587 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3589 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3591 if (DEFAULT_ABI
== ABI_V4
3592 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3594 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3595 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3596 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3598 if (DEFAULT_ABI
== ABI_DARWIN
3599 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
3600 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3601 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3602 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3604 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
3605 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3606 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3609 global_regs
[VSCR_REGNO
] = 1;
3613 global_regs
[SPEFSCR_REGNO
] = 1;
3614 fixed_regs
[FIXED_SCRATCH
]
3615 = call_used_regs
[FIXED_SCRATCH
]
3616 = call_really_used_regs
[FIXED_SCRATCH
] = 1;
3619 if (! TARGET_ALTIVEC
)
3621 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
3622 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3623 call_really_used_regs
[VRSAVE_REGNO
] = 1;
3626 if (TARGET_ALTIVEC_ABI
)
3627 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
3628 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3631 /* Try to output insns to set TARGET equal to the constant C if it can
3632 be done in less than N insns. Do all computations in MODE.
3633 Returns the place where the output has been placed if it can be
3634 done and the insns have been emitted. If it would take more than N
3635 insns, zero is returned and no insns and emitted. */
3638 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
3639 rtx source
, int n ATTRIBUTE_UNUSED
)
3641 rtx result
, insn
, set
;
3642 HOST_WIDE_INT c0
, c1
;
3649 dest
= gen_reg_rtx (mode
);
3650 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
3654 result
= no_new_pseudos
? dest
: gen_reg_rtx (SImode
);
3656 emit_insn (gen_rtx_SET (VOIDmode
, result
,
3657 GEN_INT (INTVAL (source
)
3658 & (~ (HOST_WIDE_INT
) 0xffff))));
3659 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
3660 gen_rtx_IOR (SImode
, result
,
3661 GEN_INT (INTVAL (source
) & 0xffff))));
3666 switch (GET_CODE (source
))
3669 c0
= INTVAL (source
);
3674 #if HOST_BITS_PER_WIDE_INT >= 64
3675 c0
= CONST_DOUBLE_LOW (source
);
3678 c0
= CONST_DOUBLE_LOW (source
);
3679 c1
= CONST_DOUBLE_HIGH (source
);
3687 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
3694 insn
= get_last_insn ();
3695 set
= single_set (insn
);
3696 if (! CONSTANT_P (SET_SRC (set
)))
3697 set_unique_reg_note (insn
, REG_EQUAL
, source
);
3702 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3703 fall back to a straight forward decomposition. We do this to avoid
3704 exponential run times encountered when looking for longer sequences
3705 with rs6000_emit_set_const. */
3707 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
3709 if (!TARGET_POWERPC64
)
3711 rtx operand1
, operand2
;
3713 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
3715 operand2
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
!= 0,
3717 emit_move_insn (operand1
, GEN_INT (c1
));
3718 emit_move_insn (operand2
, GEN_INT (c2
));
3722 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
3725 ud2
= (c1
& 0xffff0000) >> 16;
3726 #if HOST_BITS_PER_WIDE_INT >= 64
3730 ud4
= (c2
& 0xffff0000) >> 16;
3732 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
3733 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
3736 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
3738 emit_move_insn (dest
, GEN_INT (ud1
));
3741 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
3742 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
3745 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
3748 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
3750 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3752 else if ((ud4
== 0xffff && (ud3
& 0x8000))
3753 || (ud4
== 0 && ! (ud3
& 0x8000)))
3756 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
3759 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
3762 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud2
)));
3763 emit_move_insn (dest
, gen_rtx_ASHIFT (DImode
, dest
, GEN_INT (16)));
3765 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3770 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
3773 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
3776 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud3
)));
3778 emit_move_insn (dest
, gen_rtx_ASHIFT (DImode
, dest
, GEN_INT (32)));
3780 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
,
3781 GEN_INT (ud2
<< 16)));
3783 emit_move_insn (dest
, gen_rtx_IOR (DImode
, dest
, GEN_INT (ud1
)));
3789 /* Helper for the following. Get rid of [r+r] memory refs
3790 in cases where it won't work (TImode, TFmode). */
3793 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
3795 if (GET_CODE (operands
[0]) == MEM
3796 && GET_CODE (XEXP (operands
[0], 0)) != REG
3797 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
3798 && ! reload_in_progress
)
3800 = replace_equiv_address (operands
[0],
3801 copy_addr_to_reg (XEXP (operands
[0], 0)));
3803 if (GET_CODE (operands
[1]) == MEM
3804 && GET_CODE (XEXP (operands
[1], 0)) != REG
3805 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
3806 && ! reload_in_progress
)
3808 = replace_equiv_address (operands
[1],
3809 copy_addr_to_reg (XEXP (operands
[1], 0)));
3812 /* Emit a move from SOURCE to DEST in mode MODE. */
3814 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
3818 operands
[1] = source
;
3820 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
3821 if (GET_CODE (operands
[1]) == CONST_DOUBLE
3822 && ! FLOAT_MODE_P (mode
)
3823 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
3825 /* FIXME. This should never happen. */
3826 /* Since it seems that it does, do the safe thing and convert
3828 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
3830 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
3831 || FLOAT_MODE_P (mode
)
3832 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
3833 || CONST_DOUBLE_LOW (operands
[1]) < 0)
3834 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
3835 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
3837 /* Check if GCC is setting up a block move that will end up using FP
3838 registers as temporaries. We must make sure this is acceptable. */
3839 if (GET_CODE (operands
[0]) == MEM
3840 && GET_CODE (operands
[1]) == MEM
3842 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
3843 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
3844 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
3845 ? 32 : MEM_ALIGN (operands
[0])))
3846 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
3848 : MEM_ALIGN (operands
[1]))))
3849 && ! MEM_VOLATILE_P (operands
[0])
3850 && ! MEM_VOLATILE_P (operands
[1]))
3852 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
3853 adjust_address (operands
[1], SImode
, 0));
3854 emit_move_insn (adjust_address (operands
[0], SImode
, 4),
3855 adjust_address (operands
[1], SImode
, 4));
3859 if (!no_new_pseudos
&& GET_CODE (operands
[0]) == MEM
3860 && !gpc_reg_operand (operands
[1], mode
))
3861 operands
[1] = force_reg (mode
, operands
[1]);
3863 if (mode
== SFmode
&& ! TARGET_POWERPC
3864 && TARGET_HARD_FLOAT
&& TARGET_FPRS
3865 && GET_CODE (operands
[0]) == MEM
)
3869 if (reload_in_progress
|| reload_completed
)
3870 regnum
= true_regnum (operands
[1]);
3871 else if (GET_CODE (operands
[1]) == REG
)
3872 regnum
= REGNO (operands
[1]);
3876 /* If operands[1] is a register, on POWER it may have
3877 double-precision data in it, so truncate it to single
3879 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
3882 newreg
= (no_new_pseudos
? operands
[1] : gen_reg_rtx (mode
));
3883 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
3884 operands
[1] = newreg
;
3888 /* Recognize the case where operand[1] is a reference to thread-local
3889 data and load its address to a register. */
3890 if (rs6000_tls_referenced_p (operands
[1]))
3892 enum tls_model model
;
3893 rtx tmp
= operands
[1];
3896 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
3898 addend
= XEXP (XEXP (tmp
, 0), 1);
3899 tmp
= XEXP (XEXP (tmp
, 0), 0);
3902 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
3903 model
= SYMBOL_REF_TLS_MODEL (tmp
);
3904 gcc_assert (model
!= 0);
3906 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
3909 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
3910 tmp
= force_operand (tmp
, operands
[0]);
3915 /* Handle the case where reload calls us with an invalid address. */
3916 if (reload_in_progress
&& mode
== Pmode
3917 && (! general_operand (operands
[1], mode
)
3918 || ! nonimmediate_operand (operands
[0], mode
)))
3921 /* 128-bit constant floating-point values on Darwin should really be
3922 loaded as two parts. */
3923 if (!TARGET_IEEEQUAD
3924 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
3925 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
3927 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
3928 know how to get a DFmode SUBREG of a TFmode. */
3929 rs6000_emit_move (simplify_gen_subreg (DImode
, operands
[0], mode
, 0),
3930 simplify_gen_subreg (DImode
, operands
[1], mode
, 0),
3932 rs6000_emit_move (simplify_gen_subreg (DImode
, operands
[0], mode
,
3933 GET_MODE_SIZE (DImode
)),
3934 simplify_gen_subreg (DImode
, operands
[1], mode
,
3935 GET_MODE_SIZE (DImode
)),
3940 /* FIXME: In the long term, this switch statement should go away
3941 and be replaced by a sequence of tests based on things like
3947 if (CONSTANT_P (operands
[1])
3948 && GET_CODE (operands
[1]) != CONST_INT
)
3949 operands
[1] = force_const_mem (mode
, operands
[1]);
3953 rs6000_eliminate_indexed_memrefs (operands
);
3958 if (CONSTANT_P (operands
[1])
3959 && ! easy_fp_constant (operands
[1], mode
))
3960 operands
[1] = force_const_mem (mode
, operands
[1]);
3971 if (CONSTANT_P (operands
[1])
3972 && !easy_vector_constant (operands
[1], mode
))
3973 operands
[1] = force_const_mem (mode
, operands
[1]);
3978 /* Use default pattern for address of ELF small data */
3981 && DEFAULT_ABI
== ABI_V4
3982 && (GET_CODE (operands
[1]) == SYMBOL_REF
3983 || GET_CODE (operands
[1]) == CONST
)
3984 && small_data_operand (operands
[1], mode
))
3986 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
3990 if (DEFAULT_ABI
== ABI_V4
3991 && mode
== Pmode
&& mode
== SImode
3992 && flag_pic
== 1 && got_operand (operands
[1], mode
))
3994 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
3998 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
4002 && CONSTANT_P (operands
[1])
4003 && GET_CODE (operands
[1]) != HIGH
4004 && GET_CODE (operands
[1]) != CONST_INT
)
4006 rtx target
= (no_new_pseudos
? operands
[0] : gen_reg_rtx (mode
));
4008 /* If this is a function address on -mcall-aixdesc,
4009 convert it to the address of the descriptor. */
4010 if (DEFAULT_ABI
== ABI_AIX
4011 && GET_CODE (operands
[1]) == SYMBOL_REF
4012 && XSTR (operands
[1], 0)[0] == '.')
4014 const char *name
= XSTR (operands
[1], 0);
4016 while (*name
== '.')
4018 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
4019 CONSTANT_POOL_ADDRESS_P (new_ref
)
4020 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
4021 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
4022 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
4023 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
4024 operands
[1] = new_ref
;
4027 if (DEFAULT_ABI
== ABI_DARWIN
)
4030 if (MACHO_DYNAMIC_NO_PIC_P
)
4032 /* Take care of any required data indirection. */
4033 operands
[1] = rs6000_machopic_legitimize_pic_address (
4034 operands
[1], mode
, operands
[0]);
4035 if (operands
[0] != operands
[1])
4036 emit_insn (gen_rtx_SET (VOIDmode
,
4037 operands
[0], operands
[1]));
4041 emit_insn (gen_macho_high (target
, operands
[1]));
4042 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
4046 emit_insn (gen_elf_high (target
, operands
[1]));
4047 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
4051 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4052 and we have put it in the TOC, we just need to make a TOC-relative
4055 && GET_CODE (operands
[1]) == SYMBOL_REF
4056 && constant_pool_expr_p (operands
[1])
4057 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
4058 get_pool_mode (operands
[1])))
4060 operands
[1] = create_TOC_reference (operands
[1]);
4062 else if (mode
== Pmode
4063 && CONSTANT_P (operands
[1])
4064 && ((GET_CODE (operands
[1]) != CONST_INT
4065 && ! easy_fp_constant (operands
[1], mode
))
4066 || (GET_CODE (operands
[1]) == CONST_INT
4067 && num_insns_constant (operands
[1], mode
) > 2)
4068 || (GET_CODE (operands
[0]) == REG
4069 && FP_REGNO_P (REGNO (operands
[0]))))
4070 && GET_CODE (operands
[1]) != HIGH
4071 && ! legitimate_constant_pool_address_p (operands
[1])
4072 && ! toc_relative_expr_p (operands
[1]))
4074 /* Emit a USE operation so that the constant isn't deleted if
4075 expensive optimizations are turned on because nobody
4076 references it. This should only be done for operands that
4077 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4078 This should not be done for operands that contain LABEL_REFs.
4079 For now, we just handle the obvious case. */
4080 if (GET_CODE (operands
[1]) != LABEL_REF
)
4081 emit_insn (gen_rtx_USE (VOIDmode
, operands
[1]));
4084 /* Darwin uses a special PIC legitimizer. */
4085 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
4088 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
4090 if (operands
[0] != operands
[1])
4091 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4096 /* If we are to limit the number of things we put in the TOC and
4097 this is a symbol plus a constant we can add in one insn,
4098 just put the symbol in the TOC and add the constant. Don't do
4099 this if reload is in progress. */
4100 if (GET_CODE (operands
[1]) == CONST
4101 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
4102 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
4103 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
4104 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
4105 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
4106 && ! side_effects_p (operands
[0]))
4109 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
4110 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
4112 sym
= force_reg (mode
, sym
);
4114 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
4116 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
4120 operands
[1] = force_const_mem (mode
, operands
[1]);
4123 && constant_pool_expr_p (XEXP (operands
[1], 0))
4124 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4125 get_pool_constant (XEXP (operands
[1], 0)),
4126 get_pool_mode (XEXP (operands
[1], 0))))
4129 = gen_const_mem (mode
,
4130 create_TOC_reference (XEXP (operands
[1], 0)));
4131 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
4137 rs6000_eliminate_indexed_memrefs (operands
);
4141 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4143 gen_rtx_SET (VOIDmode
,
4144 operands
[0], operands
[1]),
4145 gen_rtx_CLOBBER (VOIDmode
,
4146 gen_rtx_SCRATCH (SImode
)))));
4155 /* Above, we may have called force_const_mem which may have returned
4156 an invalid address. If we can, fix this up; otherwise, reload will
4157 have to deal with it. */
4158 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
4159 operands
[1] = validize_mem (operands
[1]);
4162 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4165 /* Nonzero if we can use a floating-point register to pass this arg. */
4166 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4167 (SCALAR_FLOAT_MODE_P (MODE) \
4168 && !DECIMAL_FLOAT_MODE_P (MODE) \
4169 && (CUM)->fregno <= FP_ARG_MAX_REG \
4170 && TARGET_HARD_FLOAT && TARGET_FPRS)
4172 /* Nonzero if we can use an AltiVec register to pass this arg. */
4173 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4174 (ALTIVEC_VECTOR_MODE (MODE) \
4175 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4176 && TARGET_ALTIVEC_ABI \
4179 /* Return a nonzero value to say to return the function value in
4180 memory, just as large structures are always returned. TYPE will be
4181 the data type of the value, and FNTYPE will be the type of the
4182 function doing the returning, or @code{NULL} for libcalls.
4184 The AIX ABI for the RS/6000 specifies that all structures are
4185 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4186 specifies that structures <= 8 bytes are returned in r3/r4, but a
4187 draft put them in memory, and GCC used to implement the draft
4188 instead of the final standard. Therefore, aix_struct_return
4189 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4190 compatibility can change DRAFT_V4_STRUCT_RET to override the
4191 default, and -m switches get the final word. See
4192 rs6000_override_options for more details.
4194 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4195 long double support is enabled. These values are returned in memory.
4197 int_size_in_bytes returns -1 for variable size objects, which go in
4198 memory always. The cast to unsigned makes -1 > 8. */
4201 rs6000_return_in_memory (tree type
, tree fntype ATTRIBUTE_UNUSED
)
4203 /* In the darwin64 abi, try to use registers for larger structs
4205 if (rs6000_darwin64_abi
4206 && TREE_CODE (type
) == RECORD_TYPE
4207 && int_size_in_bytes (type
) > 0)
4209 CUMULATIVE_ARGS valcum
;
4213 valcum
.fregno
= FP_ARG_MIN_REG
;
4214 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
4215 /* Do a trial code generation as if this were going to be passed
4216 as an argument; if any part goes in memory, we return NULL. */
4217 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
4220 /* Otherwise fall through to more conventional ABI rules. */
4223 if (AGGREGATE_TYPE_P (type
)
4224 && (aix_struct_return
4225 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
4228 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4229 modes only exist for GCC vector types if -maltivec. */
4230 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
4231 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
4234 /* Return synthetic vectors in memory. */
4235 if (TREE_CODE (type
) == VECTOR_TYPE
4236 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
4238 static bool warned_for_return_big_vectors
= false;
4239 if (!warned_for_return_big_vectors
)
4241 warning (0, "GCC vector returned by reference: "
4242 "non-standard ABI extension with no compatibility guarantee");
4243 warned_for_return_big_vectors
= true;
4248 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
4254 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4255 for a call to a function whose data type is FNTYPE.
4256 For a library call, FNTYPE is 0.
4258 For incoming args we set the number of arguments in the prototype large
4259 so we never return a PARALLEL. */
4262 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
4263 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
4264 int libcall
, int n_named_args
)
4266 static CUMULATIVE_ARGS zero_cumulative
;
4268 *cum
= zero_cumulative
;
4270 cum
->fregno
= FP_ARG_MIN_REG
;
4271 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
4272 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
4273 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
4274 ? CALL_LIBCALL
: CALL_NORMAL
);
4275 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
4276 cum
->stdarg
= fntype
4277 && (TYPE_ARG_TYPES (fntype
) != 0
4278 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
4279 != void_type_node
));
4281 cum
->nargs_prototype
= 0;
4282 if (incoming
|| cum
->prototype
)
4283 cum
->nargs_prototype
= n_named_args
;
4285 /* Check for a longcall attribute. */
4286 if ((!fntype
&& rs6000_default_long_calls
)
4288 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
4289 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
4290 cum
->call_cookie
|= CALL_LONG
;
4292 if (TARGET_DEBUG_ARG
)
4294 fprintf (stderr
, "\ninit_cumulative_args:");
4297 tree ret_type
= TREE_TYPE (fntype
);
4298 fprintf (stderr
, " ret code = %s,",
4299 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
4302 if (cum
->call_cookie
& CALL_LONG
)
4303 fprintf (stderr
, " longcall,");
4305 fprintf (stderr
, " proto = %d, nargs = %d\n",
4306 cum
->prototype
, cum
->nargs_prototype
);
4311 && TARGET_ALTIVEC_ABI
4312 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
4314 error ("cannot return value in vector register because"
4315 " altivec instructions are disabled, use -maltivec"
4320 /* Return true if TYPE must be passed on the stack and not in registers. */
4323 rs6000_must_pass_in_stack (enum machine_mode mode
, tree type
)
4325 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
4326 return must_pass_in_stack_var_size (mode
, type
);
4328 return must_pass_in_stack_var_size_or_pad (mode
, type
);
4331 /* If defined, a C expression which determines whether, and in which
4332 direction, to pad out an argument with extra space. The value
4333 should be of type `enum direction': either `upward' to pad above
4334 the argument, `downward' to pad below, or `none' to inhibit
4337 For the AIX ABI structs are always stored left shifted in their
4341 function_arg_padding (enum machine_mode mode
, tree type
)
4343 #ifndef AGGREGATE_PADDING_FIXED
4344 #define AGGREGATE_PADDING_FIXED 0
4346 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4347 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4350 if (!AGGREGATE_PADDING_FIXED
)
4352 /* GCC used to pass structures of the same size as integer types as
4353 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4354 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4355 passed padded downward, except that -mstrict-align further
4356 muddied the water in that multi-component structures of 2 and 4
4357 bytes in size were passed padded upward.
4359 The following arranges for best compatibility with previous
4360 versions of gcc, but removes the -mstrict-align dependency. */
4361 if (BYTES_BIG_ENDIAN
)
4363 HOST_WIDE_INT size
= 0;
4365 if (mode
== BLKmode
)
4367 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
4368 size
= int_size_in_bytes (type
);
4371 size
= GET_MODE_SIZE (mode
);
4373 if (size
== 1 || size
== 2 || size
== 4)
4379 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
4381 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
4385 /* Fall back to the default. */
4386 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
4389 /* If defined, a C expression that gives the alignment boundary, in bits,
4390 of an argument with the specified mode and type. If it is not defined,
4391 PARM_BOUNDARY is used for all arguments.
4393 V.4 wants long longs to be double word aligned.
4394 Doubleword align SPE vectors.
4395 Quadword align Altivec vectors.
4396 Quadword align large synthetic vector types. */
4399 function_arg_boundary (enum machine_mode mode
, tree type
)
4401 if (DEFAULT_ABI
== ABI_V4
&& GET_MODE_SIZE (mode
) == 8)
4403 else if (SPE_VECTOR_MODE (mode
)
4404 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4405 && int_size_in_bytes (type
) >= 8
4406 && int_size_in_bytes (type
) < 16))
4408 else if (ALTIVEC_VECTOR_MODE (mode
)
4409 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4410 && int_size_in_bytes (type
) >= 16))
4412 else if (rs6000_darwin64_abi
&& mode
== BLKmode
4413 && type
&& TYPE_ALIGN (type
) > 64)
4416 return PARM_BOUNDARY
;
4419 /* For a function parm of MODE and TYPE, return the starting word in
4420 the parameter area. NWORDS of the parameter area are already used. */
4423 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
4426 unsigned int parm_offset
;
4428 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
4429 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
4430 return nwords
+ (-(parm_offset
+ nwords
) & align
);
4433 /* Compute the size (in words) of a function argument. */
4435 static unsigned long
4436 rs6000_arg_size (enum machine_mode mode
, tree type
)
4440 if (mode
!= BLKmode
)
4441 size
= GET_MODE_SIZE (mode
);
4443 size
= int_size_in_bytes (type
);
4446 return (size
+ 3) >> 2;
4448 return (size
+ 7) >> 3;
4451 /* Use this to flush pending int fields. */
4454 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
4455 HOST_WIDE_INT bitpos
)
4457 unsigned int startbit
, endbit
;
4458 int intregs
, intoffset
;
4459 enum machine_mode mode
;
4461 if (cum
->intoffset
== -1)
4464 intoffset
= cum
->intoffset
;
4465 cum
->intoffset
= -1;
4467 if (intoffset
% BITS_PER_WORD
!= 0)
4469 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4471 if (mode
== BLKmode
)
4473 /* We couldn't find an appropriate mode, which happens,
4474 e.g., in packed structs when there are 3 bytes to load.
4475 Back intoffset back to the beginning of the word in this
4477 intoffset
= intoffset
& -BITS_PER_WORD
;
4481 startbit
= intoffset
& -BITS_PER_WORD
;
4482 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4483 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4484 cum
->words
+= intregs
;
4487 /* The darwin64 ABI calls for us to recurse down through structs,
4488 looking for elements passed in registers. Unfortunately, we have
4489 to track int register count here also because of misalignments
4490 in powerpc alignment mode. */
4493 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
4495 HOST_WIDE_INT startbitpos
)
4499 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4500 if (TREE_CODE (f
) == FIELD_DECL
)
4502 HOST_WIDE_INT bitpos
= startbitpos
;
4503 tree ftype
= TREE_TYPE (f
);
4504 enum machine_mode mode
= TYPE_MODE (ftype
);
4506 if (DECL_SIZE (f
) != 0
4507 && host_integerp (bit_position (f
), 1))
4508 bitpos
+= int_bit_position (f
);
4510 /* ??? FIXME: else assume zero offset. */
4512 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4513 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
4514 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4516 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4517 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4518 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4520 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
4522 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4526 else if (cum
->intoffset
== -1)
4527 cum
->intoffset
= bitpos
;
4531 /* Update the data in CUM to advance over an argument
4532 of mode MODE and data type TYPE.
4533 (TYPE is null for libcalls where that information may not be available.)
4535 Note that for args passed by reference, function_arg will be called
4536 with MODE and TYPE set to that of the pointer to the arg, not the arg
4540 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4541 tree type
, int named
, int depth
)
4545 /* Only tick off an argument if we're not recursing. */
4547 cum
->nargs_prototype
--;
4549 if (TARGET_ALTIVEC_ABI
4550 && (ALTIVEC_VECTOR_MODE (mode
)
4551 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4552 && int_size_in_bytes (type
) == 16)))
4556 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
4559 if (!TARGET_ALTIVEC
)
4560 error ("cannot pass argument in vector register because"
4561 " altivec instructions are disabled, use -maltivec"
4564 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4565 even if it is going to be passed in a vector register.
4566 Darwin does the same for variable-argument functions. */
4567 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4568 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
4578 /* Vector parameters must be 16-byte aligned. This places
4579 them at 2 mod 4 in terms of words in 32-bit mode, since
4580 the parameter save area starts at offset 24 from the
4581 stack. In 64-bit mode, they just have to start on an
4582 even word, since the parameter save area is 16-byte
4583 aligned. Space for GPRs is reserved even if the argument
4584 will be passed in memory. */
4586 align
= (2 - cum
->words
) & 3;
4588 align
= cum
->words
& 1;
4589 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
4591 if (TARGET_DEBUG_ARG
)
4593 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
4595 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
4596 cum
->nargs_prototype
, cum
->prototype
,
4597 GET_MODE_NAME (mode
));
4601 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
4603 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
4606 else if (rs6000_darwin64_abi
4608 && TREE_CODE (type
) == RECORD_TYPE
4609 && (size
= int_size_in_bytes (type
)) > 0)
4611 /* Variable sized types have size == -1 and are
4612 treated as if consisting entirely of ints.
4613 Pad to 16 byte boundary if needed. */
4614 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
4615 && (cum
->words
% 2) != 0)
4617 /* For varargs, we can just go up by the size of the struct. */
4619 cum
->words
+= (size
+ 7) / 8;
4622 /* It is tempting to say int register count just goes up by
4623 sizeof(type)/8, but this is wrong in a case such as
4624 { int; double; int; } [powerpc alignment]. We have to
4625 grovel through the fields for these too. */
4627 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
4628 rs6000_darwin64_record_arg_advance_flush (cum
,
4629 size
* BITS_PER_UNIT
);
4632 else if (DEFAULT_ABI
== ABI_V4
)
4634 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
4635 && (mode
== SFmode
|| mode
== DFmode
4636 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
4638 if (cum
->fregno
+ (mode
== TFmode
? 1 : 0) <= FP_ARG_V4_MAX_REG
)
4639 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4642 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
4643 if (mode
== DFmode
|| mode
== TFmode
)
4644 cum
->words
+= cum
->words
& 1;
4645 cum
->words
+= rs6000_arg_size (mode
, type
);
4650 int n_words
= rs6000_arg_size (mode
, type
);
4651 int gregno
= cum
->sysv_gregno
;
4653 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4654 (r7,r8) or (r9,r10). As does any other 2 word item such
4655 as complex int due to a historical mistake. */
4657 gregno
+= (1 - gregno
) & 1;
4659 /* Multi-reg args are not split between registers and stack. */
4660 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
4662 /* Long long and SPE vectors are aligned on the stack.
4663 So are other 2 word items such as complex int due to
4664 a historical mistake. */
4666 cum
->words
+= cum
->words
& 1;
4667 cum
->words
+= n_words
;
4670 /* Note: continuing to accumulate gregno past when we've started
4671 spilling to the stack indicates the fact that we've started
4672 spilling to the stack to expand_builtin_saveregs. */
4673 cum
->sysv_gregno
= gregno
+ n_words
;
4676 if (TARGET_DEBUG_ARG
)
4678 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
4679 cum
->words
, cum
->fregno
);
4680 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
4681 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
4682 fprintf (stderr
, "mode = %4s, named = %d\n",
4683 GET_MODE_NAME (mode
), named
);
4688 int n_words
= rs6000_arg_size (mode
, type
);
4689 int start_words
= cum
->words
;
4690 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
4692 cum
->words
= align_words
+ n_words
;
4694 if (SCALAR_FLOAT_MODE_P (mode
)
4695 && !DECIMAL_FLOAT_MODE_P (mode
)
4696 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
4697 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4699 if (TARGET_DEBUG_ARG
)
4701 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
4702 cum
->words
, cum
->fregno
);
4703 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
4704 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
4705 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
4706 named
, align_words
- start_words
, depth
);
4712 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
4719 r1
= gen_rtx_REG (DImode
, gregno
);
4720 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
4721 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
4724 r1
= gen_rtx_REG (DImode
, gregno
);
4725 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
4726 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
4727 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
4728 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
4735 /* Determine where to put a SIMD argument on the SPE. */
4737 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4740 int gregno
= cum
->sysv_gregno
;
4742 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
4743 are passed and returned in a pair of GPRs for ABI compatibility. */
4744 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DCmode
))
4746 int n_words
= rs6000_arg_size (mode
, type
);
4748 /* Doubles go in an odd/even register pair (r5/r6, etc). */
4750 gregno
+= (1 - gregno
) & 1;
4752 /* Multi-reg args are not split between registers and stack. */
4753 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
4756 return spe_build_register_parallel (mode
, gregno
);
4760 int n_words
= rs6000_arg_size (mode
, type
);
4762 /* SPE vectors are put in odd registers. */
4763 if (n_words
== 2 && (gregno
& 1) == 0)
4766 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
4769 enum machine_mode m
= SImode
;
4771 r1
= gen_rtx_REG (m
, gregno
);
4772 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
4773 r2
= gen_rtx_REG (m
, gregno
+ 1);
4774 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
4775 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
4782 if (gregno
<= GP_ARG_MAX_REG
)
4783 return gen_rtx_REG (mode
, gregno
);
4789 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
4790 structure between cum->intoffset and bitpos to integer registers. */
4793 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
4794 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
4796 enum machine_mode mode
;
4798 unsigned int startbit
, endbit
;
4799 int this_regno
, intregs
, intoffset
;
4802 if (cum
->intoffset
== -1)
4805 intoffset
= cum
->intoffset
;
4806 cum
->intoffset
= -1;
4808 /* If this is the trailing part of a word, try to only load that
4809 much into the register. Otherwise load the whole register. Note
4810 that in the latter case we may pick up unwanted bits. It's not a
4811 problem at the moment but may wish to revisit. */
4813 if (intoffset
% BITS_PER_WORD
!= 0)
4815 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4817 if (mode
== BLKmode
)
4819 /* We couldn't find an appropriate mode, which happens,
4820 e.g., in packed structs when there are 3 bytes to load.
4821 Back intoffset back to the beginning of the word in this
4823 intoffset
= intoffset
& -BITS_PER_WORD
;
4830 startbit
= intoffset
& -BITS_PER_WORD
;
4831 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4832 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4833 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
4835 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
4838 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
4842 intoffset
/= BITS_PER_UNIT
;
4845 regno
= GP_ARG_MIN_REG
+ this_regno
;
4846 reg
= gen_rtx_REG (mode
, regno
);
4848 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
4851 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
4855 while (intregs
> 0);
4858 /* Recursive workhorse for the following. */
4861 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, tree type
,
4862 HOST_WIDE_INT startbitpos
, rtx rvec
[],
4867 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4868 if (TREE_CODE (f
) == FIELD_DECL
)
4870 HOST_WIDE_INT bitpos
= startbitpos
;
4871 tree ftype
= TREE_TYPE (f
);
4872 enum machine_mode mode
= TYPE_MODE (ftype
);
4874 if (DECL_SIZE (f
) != 0
4875 && host_integerp (bit_position (f
), 1))
4876 bitpos
+= int_bit_position (f
);
4878 /* ??? FIXME: else assume zero offset. */
4880 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4881 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
4882 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4887 case SCmode
: mode
= SFmode
; break;
4888 case DCmode
: mode
= DFmode
; break;
4889 case TCmode
: mode
= TFmode
; break;
4893 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
4895 = gen_rtx_EXPR_LIST (VOIDmode
,
4896 gen_rtx_REG (mode
, cum
->fregno
++),
4897 GEN_INT (bitpos
/ BITS_PER_UNIT
));
4901 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
4903 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
4905 = gen_rtx_EXPR_LIST (VOIDmode
,
4906 gen_rtx_REG (mode
, cum
->vregno
++),
4907 GEN_INT (bitpos
/ BITS_PER_UNIT
));
4909 else if (cum
->intoffset
== -1)
4910 cum
->intoffset
= bitpos
;
4914 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
4915 the register(s) to be used for each field and subfield of a struct
4916 being passed by value, along with the offset of where the
4917 register's value may be found in the block. FP fields go in FP
4918 register, vector fields go in vector registers, and everything
4919 else goes in int registers, packed as in memory.
4921 This code is also used for function return values. RETVAL indicates
4922 whether this is the case.
4924 Much of this is taken from the SPARC V9 port, which has a similar
4925 calling convention. */
4928 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, tree type
,
4929 int named
, bool retval
)
4931 rtx rvec
[FIRST_PSEUDO_REGISTER
];
4932 int k
= 1, kbase
= 1;
4933 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
4934 /* This is a copy; modifications are not visible to our caller. */
4935 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
4936 CUMULATIVE_ARGS
*cum
= ©_cum
;
4938 /* Pad to 16 byte boundary if needed. */
4939 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
4940 && (cum
->words
% 2) != 0)
4947 /* Put entries into rvec[] for individual FP and vector fields, and
4948 for the chunks of memory that go in int regs. Note we start at
4949 element 1; 0 is reserved for an indication of using memory, and
4950 may or may not be filled in below. */
4951 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
4952 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
4954 /* If any part of the struct went on the stack put all of it there.
4955 This hack is because the generic code for
4956 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
4957 parts of the struct are not at the beginning. */
4961 return NULL_RTX
; /* doesn't go in registers at all */
4963 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
4965 if (k
> 1 || cum
->use_stack
)
4966 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
4971 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
4974 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
4978 rtx rvec
[GP_ARG_NUM_REG
+ 1];
4980 if (align_words
>= GP_ARG_NUM_REG
)
4983 n_units
= rs6000_arg_size (mode
, type
);
4985 /* Optimize the simple case where the arg fits in one gpr, except in
4986 the case of BLKmode due to assign_parms assuming that registers are
4987 BITS_PER_WORD wide. */
4989 || (n_units
== 1 && mode
!= BLKmode
))
4990 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
4993 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
4994 /* Not all of the arg fits in gprs. Say that it goes in memory too,
4995 using a magic NULL_RTX component.
4996 FIXME: This is not strictly correct. Only some of the arg
4997 belongs in memory, not all of it. However, there isn't any way
4998 to do this currently, apart from building rtx descriptions for
4999 the pieces of memory we want stored. Due to bugs in the generic
5000 code we can't use the normal function_arg_partial_nregs scheme
5001 with the PARALLEL arg description we emit here.
5002 In any case, the code to store the whole arg to memory is often
5003 more efficient than code to store pieces, and we know that space
5004 is available in the right place for the whole arg. */
5005 /* FIXME: This should be fixed since the conversion to
5006 TARGET_ARG_PARTIAL_BYTES. */
5007 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5012 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
5013 rtx off
= GEN_INT (i
++ * 4);
5014 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5016 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
5018 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5021 /* Determine where to put an argument to a function.
5022 Value is zero to push the argument on the stack,
5023 or a hard register in which to store the argument.
5025 MODE is the argument's machine mode.
5026 TYPE is the data type of the argument (as a tree).
5027 This is null for libcalls where that information may
5029 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5030 the preceding args and about the function being called. It is
5031 not modified in this routine.
5032 NAMED is nonzero if this argument is a named parameter
5033 (otherwise it is an extra parameter matching an ellipsis).
5035 On RS/6000 the first eight words of non-FP are normally in registers
5036 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5037 Under V.4, the first 8 FP args are in registers.
5039 If this is floating-point and no prototype is specified, we use
5040 both an FP and integer register (or possibly FP reg and stack). Library
5041 functions (when CALL_LIBCALL is set) always have the proper types for args,
5042 so we can pass the FP value just in one register. emit_library_function
5043 doesn't support PARALLEL anyway.
5045 Note that for args passed by reference, function_arg will be called
5046 with MODE and TYPE set to that of the pointer to the arg, not the arg
5050 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5051 tree type
, int named
)
5053 enum rs6000_abi abi
= DEFAULT_ABI
;
5055 /* Return a marker to indicate whether CR1 needs to set or clear the
5056 bit that V.4 uses to say fp args were passed in registers.
5057 Assume that we don't need the marker for software floating point,
5058 or compiler generated library calls. */
5059 if (mode
== VOIDmode
)
5062 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
5064 || (cum
->nargs_prototype
< 0
5065 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
5067 /* For the SPE, we need to crxor CR6 always. */
5069 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
5070 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5071 return GEN_INT (cum
->call_cookie
5072 | ((cum
->fregno
== FP_ARG_MIN_REG
)
5073 ? CALL_V4_SET_FP_ARGS
5074 : CALL_V4_CLEAR_FP_ARGS
));
5077 return GEN_INT (cum
->call_cookie
);
5080 if (rs6000_darwin64_abi
&& mode
== BLKmode
5081 && TREE_CODE (type
) == RECORD_TYPE
)
5083 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
5084 if (rslt
!= NULL_RTX
)
5086 /* Else fall through to usual handling. */
5089 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5090 if (TARGET_64BIT
&& ! cum
->prototype
)
5092 /* Vector parameters get passed in vector register
5093 and also in GPRs or memory, in absence of prototype. */
5096 align_words
= (cum
->words
+ 1) & ~1;
5098 if (align_words
>= GP_ARG_NUM_REG
)
5104 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5106 return gen_rtx_PARALLEL (mode
,
5108 gen_rtx_EXPR_LIST (VOIDmode
,
5110 gen_rtx_EXPR_LIST (VOIDmode
,
5111 gen_rtx_REG (mode
, cum
->vregno
),
5115 return gen_rtx_REG (mode
, cum
->vregno
);
5116 else if (TARGET_ALTIVEC_ABI
5117 && (ALTIVEC_VECTOR_MODE (mode
)
5118 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5119 && int_size_in_bytes (type
) == 16)))
5121 if (named
|| abi
== ABI_V4
)
5125 /* Vector parameters to varargs functions under AIX or Darwin
5126 get passed in memory and possibly also in GPRs. */
5127 int align
, align_words
, n_words
;
5128 enum machine_mode part_mode
;
5130 /* Vector parameters must be 16-byte aligned. This places them at
5131 2 mod 4 in terms of words in 32-bit mode, since the parameter
5132 save area starts at offset 24 from the stack. In 64-bit mode,
5133 they just have to start on an even word, since the parameter
5134 save area is 16-byte aligned. */
5136 align
= (2 - cum
->words
) & 3;
5138 align
= cum
->words
& 1;
5139 align_words
= cum
->words
+ align
;
5141 /* Out of registers? Memory, then. */
5142 if (align_words
>= GP_ARG_NUM_REG
)
5145 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5146 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5148 /* The vector value goes in GPRs. Only the part of the
5149 value in GPRs is reported here. */
5151 n_words
= rs6000_arg_size (mode
, type
);
5152 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
5153 /* Fortunately, there are only two possibilities, the value
5154 is either wholly in GPRs or half in GPRs and half not. */
5157 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
5160 else if (TARGET_SPE_ABI
&& TARGET_SPE
5161 && (SPE_VECTOR_MODE (mode
)
5162 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
5163 || mode
== DCmode
))))
5164 return rs6000_spe_function_arg (cum
, mode
, type
);
5166 else if (abi
== ABI_V4
)
5168 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5169 && (mode
== SFmode
|| mode
== DFmode
5170 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
5172 if (cum
->fregno
+ (mode
== TFmode
? 1 : 0) <= FP_ARG_V4_MAX_REG
)
5173 return gen_rtx_REG (mode
, cum
->fregno
);
5179 int n_words
= rs6000_arg_size (mode
, type
);
5180 int gregno
= cum
->sysv_gregno
;
5182 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5183 (r7,r8) or (r9,r10). As does any other 2 word item such
5184 as complex int due to a historical mistake. */
5186 gregno
+= (1 - gregno
) & 1;
5188 /* Multi-reg args are not split between registers and stack. */
5189 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5192 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5193 return rs6000_mixed_function_arg (mode
, type
,
5194 gregno
- GP_ARG_MIN_REG
);
5195 return gen_rtx_REG (mode
, gregno
);
5200 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5202 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
5204 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5208 enum machine_mode fmode
= mode
;
5209 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
5211 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
5213 /* Currently, we only ever need one reg here because complex
5214 doubles are split. */
5215 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
&& fmode
== TFmode
);
5217 /* Long double split over regs and memory. */
5221 /* Do we also need to pass this arg in the parameter save
5224 && (cum
->nargs_prototype
<= 0
5225 || (DEFAULT_ABI
== ABI_AIX
5227 && align_words
>= GP_ARG_NUM_REG
)));
5229 if (!needs_psave
&& mode
== fmode
)
5230 return gen_rtx_REG (fmode
, cum
->fregno
);
5235 /* Describe the part that goes in gprs or the stack.
5236 This piece must come first, before the fprs. */
5237 if (align_words
< GP_ARG_NUM_REG
)
5239 unsigned long n_words
= rs6000_arg_size (mode
, type
);
5241 if (align_words
+ n_words
> GP_ARG_NUM_REG
5242 || (TARGET_32BIT
&& TARGET_POWERPC64
))
5244 /* If this is partially on the stack, then we only
5245 include the portion actually in registers here. */
5246 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
5249 if (align_words
+ n_words
> GP_ARG_NUM_REG
5250 && (TARGET_32BIT
&& TARGET_POWERPC64
))
5251 /* Not all of the arg fits in gprs. Say that it
5252 goes in memory too, using a magic NULL_RTX
5253 component. Also see comment in
5254 rs6000_mixed_function_arg for why the normal
5255 function_arg_partial_nregs scheme doesn't work
5257 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
5261 r
= gen_rtx_REG (rmode
,
5262 GP_ARG_MIN_REG
+ align_words
);
5263 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
5264 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5266 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
5270 /* The whole arg fits in gprs. */
5271 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5272 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5276 /* It's entirely in memory. */
5277 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5280 /* Describe where this piece goes in the fprs. */
5281 r
= gen_rtx_REG (fmode
, cum
->fregno
);
5282 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5284 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5286 else if (align_words
< GP_ARG_NUM_REG
)
5288 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5289 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5291 if (mode
== BLKmode
)
5294 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5301 /* For an arg passed partly in registers and partly in memory, this is
5302 the number of bytes passed in registers. For args passed entirely in
5303 registers or entirely in memory, zero. When an arg is described by a
5304 PARALLEL, perhaps using more than one register type, this function
5305 returns the number of bytes used by the first element of the PARALLEL. */
5308 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5309 tree type
, bool named
)
5314 if (DEFAULT_ABI
== ABI_V4
)
5317 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
5318 && cum
->nargs_prototype
>= 0)
5321 /* In this complicated case we just disable the partial_nregs code. */
5322 if (rs6000_darwin64_abi
&& mode
== BLKmode
5323 && TREE_CODE (type
) == RECORD_TYPE
5324 && int_size_in_bytes (type
) > 0)
5327 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5329 if (USE_FP_FOR_ARG_P (cum
, mode
, type
)
5330 /* If we are passing this arg in the fixed parameter save area
5331 (gprs or memory) as well as fprs, then this function should
5332 return the number of bytes passed in the parameter save area
5333 rather than bytes passed in fprs. */
5335 && (cum
->nargs_prototype
<= 0
5336 || (DEFAULT_ABI
== ABI_AIX
5338 && align_words
>= GP_ARG_NUM_REG
))))
5340 if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3) > FP_ARG_MAX_REG
+ 1)
5341 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
5342 else if (cum
->nargs_prototype
>= 0)
5346 if (align_words
< GP_ARG_NUM_REG
5347 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
5348 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
5350 if (ret
!= 0 && TARGET_DEBUG_ARG
)
5351 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
5356 /* A C expression that indicates when an argument must be passed by
5357 reference. If nonzero for an argument, a copy of that argument is
5358 made in memory and a pointer to the argument is passed instead of
5359 the argument itself. The pointer is passed in whatever way is
5360 appropriate for passing a pointer to that type.
5362 Under V.4, aggregates and long double are passed by reference.
5364 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5365 reference unless the AltiVec vector extension ABI is in force.
5367 As an extension to all ABIs, variable sized types are passed by
5371 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
5372 enum machine_mode mode
, tree type
,
5373 bool named ATTRIBUTE_UNUSED
)
5375 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
5377 if (TARGET_DEBUG_ARG
)
5378 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
5385 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
5387 if (TARGET_DEBUG_ARG
)
5388 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
5392 if (int_size_in_bytes (type
) < 0)
5394 if (TARGET_DEBUG_ARG
)
5395 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
5399 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5400 modes only exist for GCC vector types if -maltivec. */
5401 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
5403 if (TARGET_DEBUG_ARG
)
5404 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
5408 /* Pass synthetic vectors in memory. */
5409 if (TREE_CODE (type
) == VECTOR_TYPE
5410 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5412 static bool warned_for_pass_big_vectors
= false;
5413 if (TARGET_DEBUG_ARG
)
5414 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
5415 if (!warned_for_pass_big_vectors
)
5417 warning (0, "GCC vector passed by reference: "
5418 "non-standard ABI extension with no compatibility guarantee");
5419 warned_for_pass_big_vectors
= true;
5428 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
5431 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
5436 for (i
= 0; i
< nregs
; i
++)
5438 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
5439 if (reload_completed
)
5441 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
5444 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
5445 i
* GET_MODE_SIZE (reg_mode
));
5448 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
5452 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
5456 /* Perform any needed actions needed for a function that is receiving a
5457 variable number of arguments.
5461 MODE and TYPE are the mode and type of the current parameter.
5463 PRETEND_SIZE is a variable that should be set to the amount of stack
5464 that must be pushed by the prolog to pretend that our caller pushed
5467 Normally, this macro will push all remaining incoming registers on the
5468 stack and set PRETEND_SIZE to the length of the registers pushed. */
5471 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5472 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
5475 CUMULATIVE_ARGS next_cum
;
5476 int reg_size
= TARGET_32BIT
? 4 : 8;
5477 rtx save_area
= NULL_RTX
, mem
;
5478 int first_reg_offset
, set
;
5480 /* Skip the last named argument. */
5482 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
5484 if (DEFAULT_ABI
== ABI_V4
)
5486 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
5490 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
5491 HOST_WIDE_INT offset
= 0;
5493 /* Try to optimize the size of the varargs save area.
5494 The ABI requires that ap.reg_save_area is doubleword
5495 aligned, but we don't need to allocate space for all
5496 the bytes, only those to which we actually will save
5498 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
5499 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
5500 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5501 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5502 && cfun
->va_list_fpr_size
)
5505 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
5506 * UNITS_PER_FP_WORD
;
5507 if (cfun
->va_list_fpr_size
5508 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5509 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
5511 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5512 * UNITS_PER_FP_WORD
;
5516 offset
= -((first_reg_offset
* reg_size
) & ~7);
5517 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
5519 gpr_reg_num
= cfun
->va_list_gpr_size
;
5520 if (reg_size
== 4 && (first_reg_offset
& 1))
5523 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
5526 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
5528 - (int) (GP_ARG_NUM_REG
* reg_size
);
5530 if (gpr_size
+ fpr_size
)
5533 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
5534 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
5535 reg_save_area
= XEXP (reg_save_area
, 0);
5536 if (GET_CODE (reg_save_area
) == PLUS
)
5538 gcc_assert (XEXP (reg_save_area
, 0)
5539 == virtual_stack_vars_rtx
);
5540 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
5541 offset
+= INTVAL (XEXP (reg_save_area
, 1));
5544 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
5547 cfun
->machine
->varargs_save_offset
= offset
;
5548 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
5553 first_reg_offset
= next_cum
.words
;
5554 save_area
= virtual_incoming_args_rtx
;
5556 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
5557 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
5560 set
= get_varargs_alias_set ();
5561 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
5562 && cfun
->va_list_gpr_size
)
5564 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
5566 if (va_list_gpr_counter_field
)
5568 /* V4 va_list_gpr_size counts number of registers needed. */
5569 if (nregs
> cfun
->va_list_gpr_size
)
5570 nregs
= cfun
->va_list_gpr_size
;
5574 /* char * va_list instead counts number of bytes needed. */
5575 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
5576 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
5579 mem
= gen_rtx_MEM (BLKmode
,
5580 plus_constant (save_area
,
5581 first_reg_offset
* reg_size
));
5582 MEM_NOTRAP_P (mem
) = 1;
5583 set_mem_alias_set (mem
, set
);
5584 set_mem_align (mem
, BITS_PER_WORD
);
5586 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
5590 /* Save FP registers if needed. */
5591 if (DEFAULT_ABI
== ABI_V4
5592 && TARGET_HARD_FLOAT
&& TARGET_FPRS
5594 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5595 && cfun
->va_list_fpr_size
)
5597 int fregno
= next_cum
.fregno
, nregs
;
5598 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
5599 rtx lab
= gen_label_rtx ();
5600 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
5601 * UNITS_PER_FP_WORD
);
5604 (gen_rtx_SET (VOIDmode
,
5606 gen_rtx_IF_THEN_ELSE (VOIDmode
,
5607 gen_rtx_NE (VOIDmode
, cr1
,
5609 gen_rtx_LABEL_REF (VOIDmode
, lab
),
5613 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
5614 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
5616 mem
= gen_rtx_MEM (DFmode
, plus_constant (save_area
, off
));
5617 MEM_NOTRAP_P (mem
) = 1;
5618 set_mem_alias_set (mem
, set
);
5619 set_mem_align (mem
, GET_MODE_ALIGNMENT (DFmode
));
5620 emit_move_insn (mem
, gen_rtx_REG (DFmode
, fregno
));
5627 /* Create the va_list data type. */
5630 rs6000_build_builtin_va_list (void)
5632 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
5634 /* For AIX, prefer 'char *' because that's what the system
5635 header files like. */
5636 if (DEFAULT_ABI
!= ABI_V4
)
5637 return build_pointer_type (char_type_node
);
5639 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
5640 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
5642 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
5643 unsigned_char_type_node
);
5644 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
5645 unsigned_char_type_node
);
5646 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5648 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
5649 short_unsigned_type_node
);
5650 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
5652 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
5655 va_list_gpr_counter_field
= f_gpr
;
5656 va_list_fpr_counter_field
= f_fpr
;
5658 DECL_FIELD_CONTEXT (f_gpr
) = record
;
5659 DECL_FIELD_CONTEXT (f_fpr
) = record
;
5660 DECL_FIELD_CONTEXT (f_res
) = record
;
5661 DECL_FIELD_CONTEXT (f_ovf
) = record
;
5662 DECL_FIELD_CONTEXT (f_sav
) = record
;
5664 TREE_CHAIN (record
) = type_decl
;
5665 TYPE_NAME (record
) = type_decl
;
5666 TYPE_FIELDS (record
) = f_gpr
;
5667 TREE_CHAIN (f_gpr
) = f_fpr
;
5668 TREE_CHAIN (f_fpr
) = f_res
;
5669 TREE_CHAIN (f_res
) = f_ovf
;
5670 TREE_CHAIN (f_ovf
) = f_sav
;
5672 layout_type (record
);
5674 /* The correct type is an array type of one element. */
5675 return build_array_type (record
, build_index_type (size_zero_node
));
5678 /* Implement va_start. */
5681 rs6000_va_start (tree valist
, rtx nextarg
)
5683 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
5684 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
5685 tree gpr
, fpr
, ovf
, sav
, t
;
5687 /* Only SVR4 needs something special. */
5688 if (DEFAULT_ABI
!= ABI_V4
)
5690 std_expand_builtin_va_start (valist
, nextarg
);
5694 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
5695 f_fpr
= TREE_CHAIN (f_gpr
);
5696 f_res
= TREE_CHAIN (f_fpr
);
5697 f_ovf
= TREE_CHAIN (f_res
);
5698 f_sav
= TREE_CHAIN (f_ovf
);
5700 valist
= build_va_arg_indirect_ref (valist
);
5701 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
5702 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
5703 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
5704 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
5706 /* Count number of gp and fp argument registers used. */
5707 words
= current_function_args_info
.words
;
5708 n_gpr
= MIN (current_function_args_info
.sysv_gregno
- GP_ARG_MIN_REG
,
5710 n_fpr
= MIN (current_function_args_info
.fregno
- FP_ARG_MIN_REG
,
5713 if (TARGET_DEBUG_ARG
)
5714 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
5715 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
5716 words
, n_gpr
, n_fpr
);
5718 if (cfun
->va_list_gpr_size
)
5720 t
= build2 (MODIFY_EXPR
, TREE_TYPE (gpr
), gpr
,
5721 build_int_cst (NULL_TREE
, n_gpr
));
5722 TREE_SIDE_EFFECTS (t
) = 1;
5723 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5726 if (cfun
->va_list_fpr_size
)
5728 t
= build2 (MODIFY_EXPR
, TREE_TYPE (fpr
), fpr
,
5729 build_int_cst (NULL_TREE
, n_fpr
));
5730 TREE_SIDE_EFFECTS (t
) = 1;
5731 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5734 /* Find the overflow area. */
5735 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
5737 t
= build2 (PLUS_EXPR
, TREE_TYPE (ovf
), t
,
5738 build_int_cst (NULL_TREE
, words
* UNITS_PER_WORD
));
5739 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
5740 TREE_SIDE_EFFECTS (t
) = 1;
5741 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5743 /* If there were no va_arg invocations, don't set up the register
5745 if (!cfun
->va_list_gpr_size
5746 && !cfun
->va_list_fpr_size
5747 && n_gpr
< GP_ARG_NUM_REG
5748 && n_fpr
< FP_ARG_V4_MAX_REG
)
5751 /* Find the register save area. */
5752 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
5753 if (cfun
->machine
->varargs_save_offset
)
5754 t
= build2 (PLUS_EXPR
, TREE_TYPE (sav
), t
,
5755 build_int_cst (NULL_TREE
, cfun
->machine
->varargs_save_offset
));
5756 t
= build2 (MODIFY_EXPR
, TREE_TYPE (sav
), sav
, t
);
5757 TREE_SIDE_EFFECTS (t
) = 1;
5758 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
5761 /* Implement va_arg. */
5764 rs6000_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
5766 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
5767 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
5768 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
5769 tree lab_false
, lab_over
, addr
;
5771 tree ptrtype
= build_pointer_type (type
);
5773 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
5775 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
5776 return build_va_arg_indirect_ref (t
);
5779 if (DEFAULT_ABI
!= ABI_V4
)
5781 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
5783 tree elem_type
= TREE_TYPE (type
);
5784 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
5785 int elem_size
= GET_MODE_SIZE (elem_mode
);
5787 if (elem_size
< UNITS_PER_WORD
)
5789 tree real_part
, imag_part
;
5790 tree post
= NULL_TREE
;
5792 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
5794 /* Copy the value into a temporary, lest the formal temporary
5795 be reused out from under us. */
5796 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
5797 append_to_statement_list (post
, pre_p
);
5799 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
5802 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
5806 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
5809 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
5810 f_fpr
= TREE_CHAIN (f_gpr
);
5811 f_res
= TREE_CHAIN (f_fpr
);
5812 f_ovf
= TREE_CHAIN (f_res
);
5813 f_sav
= TREE_CHAIN (f_ovf
);
5815 valist
= build_va_arg_indirect_ref (valist
);
5816 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
5817 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
5818 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
5819 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
5821 size
= int_size_in_bytes (type
);
5822 rsize
= (size
+ 3) / 4;
5825 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5826 && (TYPE_MODE (type
) == SFmode
5827 || TYPE_MODE (type
) == DFmode
5828 || TYPE_MODE (type
) == TFmode
))
5830 /* FP args go in FP registers, if present. */
5832 n_reg
= (size
+ 7) / 8;
5835 if (TYPE_MODE (type
) != SFmode
)
5840 /* Otherwise into GP registers. */
5849 /* Pull the value out of the saved registers.... */
5852 addr
= create_tmp_var (ptr_type_node
, "addr");
5853 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
5855 /* AltiVec vectors never go in registers when -mabi=altivec. */
5856 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
5860 lab_false
= create_artificial_label ();
5861 lab_over
= create_artificial_label ();
5863 /* Long long and SPE vectors are aligned in the registers.
5864 As are any other 2 gpr item such as complex int due to a
5865 historical mistake. */
5867 if (n_reg
== 2 && reg
== gpr
)
5869 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), reg
,
5870 size_int (n_reg
- 1));
5871 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, u
);
5874 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
5875 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
5876 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
5877 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
5878 gimplify_and_add (t
, pre_p
);
5882 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
5884 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, size_int (n_reg
));
5885 u
= build1 (CONVERT_EXPR
, integer_type_node
, u
);
5886 u
= build2 (MULT_EXPR
, integer_type_node
, u
, size_int (sav_scale
));
5887 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, u
);
5889 t
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
5890 gimplify_and_add (t
, pre_p
);
5892 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
5893 gimplify_and_add (t
, pre_p
);
5895 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
5896 append_to_statement_list (t
, pre_p
);
5900 /* Ensure that we don't find any more args in regs.
5901 Alignment has taken care of the n_reg == 2 case. */
5902 t
= build2 (MODIFY_EXPR
, TREE_TYPE (reg
), reg
, size_int (8));
5903 gimplify_and_add (t
, pre_p
);
5907 /* ... otherwise out of the overflow area. */
5909 /* Care for on-stack alignment if needed. */
5913 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
5914 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
5915 build_int_cst (NULL_TREE
, -align
));
5917 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
5919 u
= build2 (MODIFY_EXPR
, void_type_node
, addr
, t
);
5920 gimplify_and_add (u
, pre_p
);
5922 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
5923 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ovf
), ovf
, t
);
5924 gimplify_and_add (t
, pre_p
);
5928 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
5929 append_to_statement_list (t
, pre_p
);
5932 addr
= fold_convert (ptrtype
, addr
);
5933 return build_va_arg_indirect_ref (addr
);
5939 def_builtin (int mask
, const char *name
, tree type
, int code
)
5941 if (mask
& target_flags
)
5943 if (rs6000_builtin_decls
[code
])
5946 rs6000_builtin_decls
[code
] =
5947 lang_hooks
.builtin_function (name
, type
, code
, BUILT_IN_MD
,
5952 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
5954 static const struct builtin_description bdesc_3arg
[] =
5956 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
5957 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
5958 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
5959 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
5960 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
5961 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
5962 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
5963 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
5964 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
5965 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
5966 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
5967 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
5968 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
5969 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
5970 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
5971 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
5972 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
5973 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
5974 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
5975 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
5976 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
5977 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
5978 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
5980 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
5981 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
5982 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
5983 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
5984 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
5985 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
5986 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
5987 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
5988 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
5989 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
5990 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
5991 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
5992 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
5993 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
5994 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
5997 /* DST operations: void foo (void *, const int, const char). */
5999 static const struct builtin_description bdesc_dst
[] =
6001 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
6002 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
6003 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
6004 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
6006 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
6007 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
6008 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
6009 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
6012 /* Simple binary operations: VECc = foo (VECa, VECb). */
6014 static struct builtin_description bdesc_2arg
[] =
6016 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
6017 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
6018 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
6019 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
6020 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
6021 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
6022 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
6023 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
6024 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
6025 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
6026 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
6027 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
6028 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
6029 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
6030 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
6031 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
6032 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
6033 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
6034 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
6035 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
6036 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
6037 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
6038 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
6039 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
6040 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
6041 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
6042 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
6043 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
6044 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
6045 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
6046 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
6047 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
6048 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
6049 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
6050 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
6051 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
6052 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
6053 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
6054 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
6055 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
6056 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
6057 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
6058 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
6059 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
6060 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
6061 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
6062 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
6063 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
6064 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
6065 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
6066 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
6067 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
6068 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
6069 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
6070 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
6071 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
6072 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
6073 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
6074 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
6075 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
6076 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
6077 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
6078 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
6079 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
6080 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
6081 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
6082 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
6083 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
6084 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
6085 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
6086 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
6087 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
6088 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
6089 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
6090 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
6091 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
6092 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
6093 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
6094 { MASK_ALTIVEC
, CODE_FOR_altivec_vslb
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
6095 { MASK_ALTIVEC
, CODE_FOR_altivec_vslh
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
6096 { MASK_ALTIVEC
, CODE_FOR_altivec_vslw
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
6097 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
6098 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
6099 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
6100 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
6101 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
6102 { MASK_ALTIVEC
, CODE_FOR_lshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
6103 { MASK_ALTIVEC
, CODE_FOR_lshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
6104 { MASK_ALTIVEC
, CODE_FOR_lshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
6105 { MASK_ALTIVEC
, CODE_FOR_ashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
6106 { MASK_ALTIVEC
, CODE_FOR_ashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
6107 { MASK_ALTIVEC
, CODE_FOR_ashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
6108 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
6109 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
6110 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
6111 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
6112 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
6113 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
6114 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
6115 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
6116 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
6117 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
6118 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
6119 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
6120 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
6121 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
6122 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
6123 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
6124 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
6125 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
6126 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
6128 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
6129 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
6130 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
6131 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
6132 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
6133 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
6134 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
6135 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
6136 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
6137 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
6138 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
6139 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
6140 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
6141 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
6142 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
6143 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
6144 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
6145 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
6146 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
6147 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
6148 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
6149 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
6150 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
6151 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
6152 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
6153 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
6154 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
6155 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
6156 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
6157 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
6158 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
6159 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
6160 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
6161 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
6162 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
6163 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
6164 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
6165 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
6166 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
6167 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
6168 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
6169 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
6170 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
6171 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
6172 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
6173 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
6174 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
6175 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
6176 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
6177 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
6178 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
6179 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
6180 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
6181 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
6182 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
6183 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
6184 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
6185 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
6186 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
6187 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
6188 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
6189 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
6190 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
6191 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
6192 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
6193 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
6194 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
6195 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
6196 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
6197 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
6198 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
6199 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
6200 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
6201 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
6202 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
6203 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
6204 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
6205 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
6206 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
6207 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
6208 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
6209 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
6210 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
6211 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
6212 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
6213 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
6214 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
6215 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
6216 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
6217 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
6218 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
6219 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
6220 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
6221 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
6222 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
6223 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
6224 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
6225 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
6226 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
6227 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
6228 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
6229 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
6230 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
6231 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
6232 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
6233 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
6234 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
6235 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
6236 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
6237 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
6238 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
6239 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
6240 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
6241 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
6242 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
6243 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
6244 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
6245 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
6246 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
6247 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
6248 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
6249 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
6250 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
6251 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
6252 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
6253 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
6254 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
6256 /* Place holder, leave as first spe builtin. */
6257 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
6258 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
6259 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
6260 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
6261 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
6262 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
6263 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
6264 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
6265 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
6266 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
6267 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
6268 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
6269 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
6270 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
6271 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
6272 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
6273 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
6274 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
6275 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
6276 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
6277 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
6278 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
6279 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
6280 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
6281 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
6282 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
6283 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
6284 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
6285 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
6286 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
6287 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
6288 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
6289 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
6290 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
6291 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
6292 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
6293 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
6294 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
6295 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
6296 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
6297 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
6298 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
6299 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
6300 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
6301 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
6302 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
6303 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
6304 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
6305 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
6306 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
6307 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
6308 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
6309 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
6310 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
6311 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
6312 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
6313 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
6314 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
6315 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
6316 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
6317 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
6318 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
6319 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
6320 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
6321 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
6322 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
6323 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
6324 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
6325 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
6326 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
6327 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
6328 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
6329 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
6330 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
6331 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
6332 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
6333 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
6334 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
6335 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
6336 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
6337 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
6338 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
6339 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
6340 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
6341 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
6342 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
6343 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
6344 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
6345 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
6346 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
6347 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
6348 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
6349 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
6350 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
6351 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
6352 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
6353 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
6354 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
6355 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
6356 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
6357 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
6358 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
6359 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
6360 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
6361 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
6362 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
6363 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
6364 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
6365 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
6367 /* SPE binary operations expecting a 5-bit unsigned literal. */
6368 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
6370 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
6371 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
6372 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
6373 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
6374 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
6375 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
6376 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
6377 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
6378 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
6379 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
6380 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
6381 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
6382 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
6383 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
6384 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
6385 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
6386 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
6387 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
6388 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
6389 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
6390 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
6391 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
6392 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
6393 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
6394 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
6395 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
6397 /* Place-holder. Leave as last binary SPE builtin. */
6398 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
6401 /* AltiVec predicates. */
6403 struct builtin_description_predicates
6405 const unsigned int mask
;
6406 const enum insn_code icode
;
6408 const char *const name
;
6409 const enum rs6000_builtins code
;
6412 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
6414 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
6415 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
6416 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
6417 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
6418 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
6419 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
6420 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
6421 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
6422 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
6423 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
6424 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
6425 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
6426 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
6428 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
6429 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
6430 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
6433 /* SPE predicates. */
6434 static struct builtin_description bdesc_spe_predicates
[] =
6436 /* Place-holder. Leave as first. */
6437 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
6438 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
6439 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
6440 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
6441 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
6442 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
6443 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
6444 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
6445 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
6446 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
6447 /* Place-holder. Leave as last. */
6448 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
6451 /* SPE evsel predicates. */
6452 static struct builtin_description bdesc_spe_evsel
[] =
6454 /* Place-holder. Leave as first. */
6455 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
6456 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
6457 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
6458 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
6459 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
6460 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
6461 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
6462 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
6463 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
6464 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
6465 /* Place-holder. Leave as last. */
6466 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
6469 /* ABS* operations. */
6471 static const struct builtin_description bdesc_abs
[] =
6473 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
6474 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
6475 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
6476 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
6477 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
6478 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
6479 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
6482 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6485 static struct builtin_description bdesc_1arg
[] =
6487 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
6488 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
6489 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
6490 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
6491 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
6492 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
6493 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
6494 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
6495 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
6496 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
6497 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
6498 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
6499 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
6500 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
6501 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
6502 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
6503 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
6505 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
6506 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
6507 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
6508 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
6509 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
6510 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
6511 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
6512 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
6513 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
6514 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
6515 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
6516 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
6517 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
6518 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
6519 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
6520 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
6521 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
6522 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
6523 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
6525 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6526 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6527 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
6528 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
6529 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
6530 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
6531 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
6532 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
6533 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
6534 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
6535 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
6536 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
6537 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
6538 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
6539 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
6540 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
6541 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
6542 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
6543 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
6544 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
6545 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
6546 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
6547 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
6548 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
6549 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
6550 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
6551 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
6552 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
6553 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
6554 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
6556 /* Place-holder. Leave as last unary SPE builtin. */
6557 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
}
6561 rs6000_expand_unop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6564 tree arg0
= TREE_VALUE (arglist
);
6565 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6566 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6567 enum machine_mode mode0
= insn_data
[icode
].operand
[1].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
)
6577 if (icode
== CODE_FOR_altivec_vspltisb
6578 || icode
== CODE_FOR_altivec_vspltish
6579 || icode
== CODE_FOR_altivec_vspltisw
6580 || icode
== CODE_FOR_spe_evsplatfi
6581 || icode
== CODE_FOR_spe_evsplati
)
6583 /* Only allow 5-bit *signed* literals. */
6584 if (GET_CODE (op0
) != CONST_INT
6585 || INTVAL (op0
) > 15
6586 || INTVAL (op0
) < -16)
6588 error ("argument 1 must be a 5-bit signed literal");
6594 || GET_MODE (target
) != tmode
6595 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6596 target
= gen_reg_rtx (tmode
);
6598 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6599 op0
= copy_to_mode_reg (mode0
, op0
);
6601 pat
= GEN_FCN (icode
) (target
, op0
);
6610 altivec_expand_abs_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6612 rtx pat
, scratch1
, scratch2
;
6613 tree arg0
= TREE_VALUE (arglist
);
6614 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6615 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6616 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6618 /* If we have invalid arguments, bail out before generating bad rtl. */
6619 if (arg0
== error_mark_node
)
6623 || GET_MODE (target
) != tmode
6624 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6625 target
= gen_reg_rtx (tmode
);
6627 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6628 op0
= copy_to_mode_reg (mode0
, op0
);
6630 scratch1
= gen_reg_rtx (mode0
);
6631 scratch2
= gen_reg_rtx (mode0
);
6633 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
6642 rs6000_expand_binop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6645 tree arg0
= TREE_VALUE (arglist
);
6646 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6647 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6648 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6649 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6650 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6651 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6653 if (icode
== CODE_FOR_nothing
)
6654 /* Builtin not supported on this processor. */
6657 /* If we got invalid arguments bail out before generating bad rtl. */
6658 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6661 if (icode
== CODE_FOR_altivec_vcfux
6662 || icode
== CODE_FOR_altivec_vcfsx
6663 || icode
== CODE_FOR_altivec_vctsxs
6664 || icode
== CODE_FOR_altivec_vctuxs
6665 || icode
== CODE_FOR_altivec_vspltb
6666 || icode
== CODE_FOR_altivec_vsplth
6667 || icode
== CODE_FOR_altivec_vspltw
6668 || icode
== CODE_FOR_spe_evaddiw
6669 || icode
== CODE_FOR_spe_evldd
6670 || icode
== CODE_FOR_spe_evldh
6671 || icode
== CODE_FOR_spe_evldw
6672 || icode
== CODE_FOR_spe_evlhhesplat
6673 || icode
== CODE_FOR_spe_evlhhossplat
6674 || icode
== CODE_FOR_spe_evlhhousplat
6675 || icode
== CODE_FOR_spe_evlwhe
6676 || icode
== CODE_FOR_spe_evlwhos
6677 || icode
== CODE_FOR_spe_evlwhou
6678 || icode
== CODE_FOR_spe_evlwhsplat
6679 || icode
== CODE_FOR_spe_evlwwsplat
6680 || icode
== CODE_FOR_spe_evrlwi
6681 || icode
== CODE_FOR_spe_evslwi
6682 || icode
== CODE_FOR_spe_evsrwis
6683 || icode
== CODE_FOR_spe_evsubifw
6684 || icode
== CODE_FOR_spe_evsrwiu
)
6686 /* Only allow 5-bit unsigned literals. */
6688 if (TREE_CODE (arg1
) != INTEGER_CST
6689 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
6691 error ("argument 2 must be a 5-bit unsigned literal");
6697 || GET_MODE (target
) != tmode
6698 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6699 target
= gen_reg_rtx (tmode
);
6701 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6702 op0
= copy_to_mode_reg (mode0
, op0
);
6703 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6704 op1
= copy_to_mode_reg (mode1
, op1
);
6706 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6715 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
6716 tree arglist
, rtx target
)
6719 tree cr6_form
= TREE_VALUE (arglist
);
6720 tree arg0
= TREE_VALUE (TREE_CHAIN (arglist
));
6721 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6722 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6723 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6724 enum machine_mode tmode
= SImode
;
6725 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6726 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6729 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
6731 error ("argument 1 of __builtin_altivec_predicate must be a constant");
6735 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
6737 gcc_assert (mode0
== mode1
);
6739 /* If we have invalid arguments, bail out before generating bad rtl. */
6740 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6744 || GET_MODE (target
) != tmode
6745 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6746 target
= gen_reg_rtx (tmode
);
6748 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6749 op0
= copy_to_mode_reg (mode0
, op0
);
6750 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6751 op1
= copy_to_mode_reg (mode1
, op1
);
6753 scratch
= gen_reg_rtx (mode0
);
6755 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
6756 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
6761 /* The vec_any* and vec_all* predicates use the same opcodes for two
6762 different operations, but the bits in CR6 will be different
6763 depending on what information we want. So we have to play tricks
6764 with CR6 to get the right bits out.
6766 If you think this is disgusting, look at the specs for the
6767 AltiVec predicates. */
6769 switch (cr6_form_int
)
6772 emit_insn (gen_cr6_test_for_zero (target
));
6775 emit_insn (gen_cr6_test_for_zero_reverse (target
));
6778 emit_insn (gen_cr6_test_for_lt (target
));
6781 emit_insn (gen_cr6_test_for_lt_reverse (target
));
6784 error ("argument 1 of __builtin_altivec_predicate is out of range");
6792 altivec_expand_lv_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6795 tree arg0
= TREE_VALUE (arglist
);
6796 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6797 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6798 enum machine_mode mode0
= Pmode
;
6799 enum machine_mode mode1
= Pmode
;
6800 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6801 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6803 if (icode
== CODE_FOR_nothing
)
6804 /* Builtin not supported on this processor. */
6807 /* If we got invalid arguments bail out before generating bad rtl. */
6808 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
6812 || GET_MODE (target
) != tmode
6813 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6814 target
= gen_reg_rtx (tmode
);
6816 op1
= copy_to_mode_reg (mode1
, op1
);
6818 if (op0
== const0_rtx
)
6820 addr
= gen_rtx_MEM (tmode
, op1
);
6824 op0
= copy_to_mode_reg (mode0
, op0
);
6825 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
6828 pat
= GEN_FCN (icode
) (target
, addr
);
6838 spe_expand_stv_builtin (enum insn_code icode
, tree arglist
)
6840 tree arg0
= TREE_VALUE (arglist
);
6841 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6842 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6843 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6844 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6845 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6847 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
6848 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
6849 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
6851 /* Invalid arguments. Bail before doing anything stoopid! */
6852 if (arg0
== error_mark_node
6853 || arg1
== error_mark_node
6854 || arg2
== error_mark_node
)
6857 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
6858 op0
= copy_to_mode_reg (mode2
, op0
);
6859 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
6860 op1
= copy_to_mode_reg (mode0
, op1
);
6861 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
6862 op2
= copy_to_mode_reg (mode1
, op2
);
6864 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
6871 altivec_expand_stv_builtin (enum insn_code icode
, tree arglist
)
6873 tree arg0
= TREE_VALUE (arglist
);
6874 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6875 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6876 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6877 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6878 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6880 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6881 enum machine_mode mode1
= Pmode
;
6882 enum machine_mode mode2
= Pmode
;
6884 /* Invalid arguments. Bail before doing anything stoopid! */
6885 if (arg0
== error_mark_node
6886 || arg1
== error_mark_node
6887 || arg2
== error_mark_node
)
6890 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
6891 op0
= copy_to_mode_reg (tmode
, op0
);
6893 op2
= copy_to_mode_reg (mode2
, op2
);
6895 if (op1
== const0_rtx
)
6897 addr
= gen_rtx_MEM (tmode
, op2
);
6901 op1
= copy_to_mode_reg (mode1
, op1
);
6902 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
6905 pat
= GEN_FCN (icode
) (addr
, op0
);
6912 rs6000_expand_ternop_builtin (enum insn_code icode
, tree arglist
, rtx target
)
6915 tree arg0
= TREE_VALUE (arglist
);
6916 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
6917 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
6918 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
6919 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
6920 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
6921 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6922 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6923 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
6924 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
6926 if (icode
== CODE_FOR_nothing
)
6927 /* Builtin not supported on this processor. */
6930 /* If we got invalid arguments bail out before generating bad rtl. */
6931 if (arg0
== error_mark_node
6932 || arg1
== error_mark_node
6933 || arg2
== error_mark_node
)
6936 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
6937 || icode
== CODE_FOR_altivec_vsldoi_v4si
6938 || icode
== CODE_FOR_altivec_vsldoi_v8hi
6939 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
6941 /* Only allow 4-bit unsigned literals. */
6943 if (TREE_CODE (arg2
) != INTEGER_CST
6944 || TREE_INT_CST_LOW (arg2
) & ~0xf)
6946 error ("argument 3 must be a 4-bit unsigned literal");
6952 || GET_MODE (target
) != tmode
6953 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6954 target
= gen_reg_rtx (tmode
);
6956 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6957 op0
= copy_to_mode_reg (mode0
, op0
);
6958 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
6959 op1
= copy_to_mode_reg (mode1
, op1
);
6960 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
6961 op2
= copy_to_mode_reg (mode2
, op2
);
6963 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6971 /* Expand the lvx builtins. */
6973 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
6975 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
6976 tree arglist
= TREE_OPERAND (exp
, 1);
6977 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
6979 enum machine_mode tmode
, mode0
;
6981 enum insn_code icode
;
6985 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
6986 icode
= CODE_FOR_altivec_lvx_v16qi
;
6988 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
6989 icode
= CODE_FOR_altivec_lvx_v8hi
;
6991 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
6992 icode
= CODE_FOR_altivec_lvx_v4si
;
6994 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
6995 icode
= CODE_FOR_altivec_lvx_v4sf
;
7004 arg0
= TREE_VALUE (arglist
);
7005 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7006 tmode
= insn_data
[icode
].operand
[0].mode
;
7007 mode0
= insn_data
[icode
].operand
[1].mode
;
7010 || GET_MODE (target
) != tmode
7011 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7012 target
= gen_reg_rtx (tmode
);
7014 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7015 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
7017 pat
= GEN_FCN (icode
) (target
, op0
);
7024 /* Expand the stvx builtins. */
7026 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
7029 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7030 tree arglist
= TREE_OPERAND (exp
, 1);
7031 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7033 enum machine_mode mode0
, mode1
;
7035 enum insn_code icode
;
7039 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
7040 icode
= CODE_FOR_altivec_stvx_v16qi
;
7042 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
7043 icode
= CODE_FOR_altivec_stvx_v8hi
;
7045 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
7046 icode
= CODE_FOR_altivec_stvx_v4si
;
7048 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
7049 icode
= CODE_FOR_altivec_stvx_v4sf
;
7056 arg0
= TREE_VALUE (arglist
);
7057 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7058 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7059 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7060 mode0
= insn_data
[icode
].operand
[0].mode
;
7061 mode1
= insn_data
[icode
].operand
[1].mode
;
7063 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7064 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
7065 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
7066 op1
= copy_to_mode_reg (mode1
, op1
);
7068 pat
= GEN_FCN (icode
) (op0
, op1
);
7076 /* Expand the dst builtins. */
7078 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
7081 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7082 tree arglist
= TREE_OPERAND (exp
, 1);
7083 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7084 tree arg0
, arg1
, arg2
;
7085 enum machine_mode mode0
, mode1
, mode2
;
7086 rtx pat
, op0
, op1
, op2
;
7087 struct builtin_description
*d
;
7092 /* Handle DST variants. */
7093 d
= (struct builtin_description
*) bdesc_dst
;
7094 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
7095 if (d
->code
== fcode
)
7097 arg0
= TREE_VALUE (arglist
);
7098 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7099 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7100 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7101 op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7102 op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
7103 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
7104 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
7105 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
7107 /* Invalid arguments, bail out before generating bad rtl. */
7108 if (arg0
== error_mark_node
7109 || arg1
== error_mark_node
7110 || arg2
== error_mark_node
)
7115 if (TREE_CODE (arg2
) != INTEGER_CST
7116 || TREE_INT_CST_LOW (arg2
) & ~0x3)
7118 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
7122 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
7123 op0
= copy_to_mode_reg (Pmode
, op0
);
7124 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
7125 op1
= copy_to_mode_reg (mode1
, op1
);
7127 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
7137 /* Expand vec_init builtin. */
7139 altivec_expand_vec_init_builtin (tree type
, tree arglist
, rtx target
)
7141 enum machine_mode tmode
= TYPE_MODE (type
);
7142 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
7143 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
7144 rtvec v
= rtvec_alloc (n_elt
);
7146 gcc_assert (VECTOR_MODE_P (tmode
));
7148 for (i
= 0; i
< n_elt
; ++i
, arglist
= TREE_CHAIN (arglist
))
7150 rtx x
= expand_expr (TREE_VALUE (arglist
), NULL_RTX
, VOIDmode
, 0);
7151 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
7154 gcc_assert (arglist
== NULL
);
7156 if (!target
|| !register_operand (target
, tmode
))
7157 target
= gen_reg_rtx (tmode
);
7159 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
7163 /* Return the integer constant in ARG. Constrain it to be in the range
7164 of the subparts of VEC_TYPE; issue an error if not. */
7167 get_element_number (tree vec_type
, tree arg
)
7169 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
7171 if (!host_integerp (arg
, 1)
7172 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
7174 error ("selector must be an integer constant in the range 0..%wi", max
);
7181 /* Expand vec_set builtin. */
7183 altivec_expand_vec_set_builtin (tree arglist
)
7185 enum machine_mode tmode
, mode1
;
7186 tree arg0
, arg1
, arg2
;
7190 arg0
= TREE_VALUE (arglist
);
7191 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7192 arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7194 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
7195 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7196 gcc_assert (VECTOR_MODE_P (tmode
));
7198 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, 0);
7199 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, 0);
7200 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
7202 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
7203 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
7205 op0
= force_reg (tmode
, op0
);
7206 op1
= force_reg (mode1
, op1
);
7208 rs6000_expand_vector_set (op0
, op1
, elt
);
7213 /* Expand vec_ext builtin. */
7215 altivec_expand_vec_ext_builtin (tree arglist
, rtx target
)
7217 enum machine_mode tmode
, mode0
;
7222 arg0
= TREE_VALUE (arglist
);
7223 arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7225 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7226 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
7228 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7229 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
7230 gcc_assert (VECTOR_MODE_P (mode0
));
7232 op0
= force_reg (mode0
, op0
);
7234 if (optimize
|| !target
|| !register_operand (target
, tmode
))
7235 target
= gen_reg_rtx (tmode
);
7237 rs6000_expand_vector_extract (target
, op0
, elt
);
7242 /* Expand the builtin in EXP and store the result in TARGET. Store
7243 true in *EXPANDEDP if we found a builtin to expand. */
7245 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7247 struct builtin_description
*d
;
7248 struct builtin_description_predicates
*dp
;
7250 enum insn_code icode
;
7251 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7252 tree arglist
= TREE_OPERAND (exp
, 1);
7255 enum machine_mode tmode
, mode0
;
7256 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7258 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7259 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
7262 error ("unresolved overload for Altivec builtin %qF", fndecl
);
7266 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
7270 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
7274 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
7282 case ALTIVEC_BUILTIN_STVX
:
7283 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, arglist
);
7284 case ALTIVEC_BUILTIN_STVEBX
:
7285 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, arglist
);
7286 case ALTIVEC_BUILTIN_STVEHX
:
7287 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, arglist
);
7288 case ALTIVEC_BUILTIN_STVEWX
:
7289 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, arglist
);
7290 case ALTIVEC_BUILTIN_STVXL
:
7291 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, arglist
);
7293 case ALTIVEC_BUILTIN_MFVSCR
:
7294 icode
= CODE_FOR_altivec_mfvscr
;
7295 tmode
= insn_data
[icode
].operand
[0].mode
;
7298 || GET_MODE (target
) != tmode
7299 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7300 target
= gen_reg_rtx (tmode
);
7302 pat
= GEN_FCN (icode
) (target
);
7308 case ALTIVEC_BUILTIN_MTVSCR
:
7309 icode
= CODE_FOR_altivec_mtvscr
;
7310 arg0
= TREE_VALUE (arglist
);
7311 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7312 mode0
= insn_data
[icode
].operand
[0].mode
;
7314 /* If we got invalid arguments bail out before generating bad rtl. */
7315 if (arg0
== error_mark_node
)
7318 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7319 op0
= copy_to_mode_reg (mode0
, op0
);
7321 pat
= GEN_FCN (icode
) (op0
);
7326 case ALTIVEC_BUILTIN_DSSALL
:
7327 emit_insn (gen_altivec_dssall ());
7330 case ALTIVEC_BUILTIN_DSS
:
7331 icode
= CODE_FOR_altivec_dss
;
7332 arg0
= TREE_VALUE (arglist
);
7334 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7335 mode0
= insn_data
[icode
].operand
[0].mode
;
7337 /* If we got invalid arguments bail out before generating bad rtl. */
7338 if (arg0
== error_mark_node
)
7341 if (TREE_CODE (arg0
) != INTEGER_CST
7342 || TREE_INT_CST_LOW (arg0
) & ~0x3)
7344 error ("argument to dss must be a 2-bit unsigned literal");
7348 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7349 op0
= copy_to_mode_reg (mode0
, op0
);
7351 emit_insn (gen_altivec_dss (op0
));
7354 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
7355 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
7356 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
7357 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
7358 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), arglist
, target
);
7360 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
7361 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
7362 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
7363 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
7364 return altivec_expand_vec_set_builtin (arglist
);
7366 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
7367 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
7368 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
7369 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
7370 return altivec_expand_vec_ext_builtin (arglist
, target
);
7377 /* Expand abs* operations. */
7378 d
= (struct builtin_description
*) bdesc_abs
;
7379 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
7380 if (d
->code
== fcode
)
7381 return altivec_expand_abs_builtin (d
->icode
, arglist
, target
);
7383 /* Expand the AltiVec predicates. */
7384 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
7385 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
7386 if (dp
->code
== fcode
)
7387 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
7390 /* LV* are funky. We initialized them differently. */
7393 case ALTIVEC_BUILTIN_LVSL
:
7394 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
7396 case ALTIVEC_BUILTIN_LVSR
:
7397 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
7399 case ALTIVEC_BUILTIN_LVEBX
:
7400 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
7402 case ALTIVEC_BUILTIN_LVEHX
:
7403 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
7405 case ALTIVEC_BUILTIN_LVEWX
:
7406 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
7408 case ALTIVEC_BUILTIN_LVXL
:
7409 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
7411 case ALTIVEC_BUILTIN_LVX
:
7412 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
7423 /* Binops that need to be initialized manually, but can be expanded
7424 automagically by rs6000_expand_binop_builtin. */
7425 static struct builtin_description bdesc_2arg_spe
[] =
7427 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
7428 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
7429 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
7430 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
7431 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
7432 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
7433 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
7434 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
7435 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
7436 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
7437 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
7438 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
7439 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
7440 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
7441 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
7442 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
7443 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
7444 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
7445 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
7446 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
7447 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
7448 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
7451 /* Expand the builtin in EXP and store the result in TARGET. Store
7452 true in *EXPANDEDP if we found a builtin to expand.
7454 This expands the SPE builtins that are not simple unary and binary
7457 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7459 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7460 tree arglist
= TREE_OPERAND (exp
, 1);
7462 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7463 enum insn_code icode
;
7464 enum machine_mode tmode
, mode0
;
7466 struct builtin_description
*d
;
7471 /* Syntax check for a 5-bit unsigned immediate. */
7474 case SPE_BUILTIN_EVSTDD
:
7475 case SPE_BUILTIN_EVSTDH
:
7476 case SPE_BUILTIN_EVSTDW
:
7477 case SPE_BUILTIN_EVSTWHE
:
7478 case SPE_BUILTIN_EVSTWHO
:
7479 case SPE_BUILTIN_EVSTWWE
:
7480 case SPE_BUILTIN_EVSTWWO
:
7481 arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7482 if (TREE_CODE (arg1
) != INTEGER_CST
7483 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7485 error ("argument 2 must be a 5-bit unsigned literal");
7493 /* The evsplat*i instructions are not quite generic. */
7496 case SPE_BUILTIN_EVSPLATFI
:
7497 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
7499 case SPE_BUILTIN_EVSPLATI
:
7500 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
7506 d
= (struct builtin_description
*) bdesc_2arg_spe
;
7507 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
7508 if (d
->code
== fcode
)
7509 return rs6000_expand_binop_builtin (d
->icode
, arglist
, target
);
7511 d
= (struct builtin_description
*) bdesc_spe_predicates
;
7512 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
7513 if (d
->code
== fcode
)
7514 return spe_expand_predicate_builtin (d
->icode
, arglist
, target
);
7516 d
= (struct builtin_description
*) bdesc_spe_evsel
;
7517 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
7518 if (d
->code
== fcode
)
7519 return spe_expand_evsel_builtin (d
->icode
, arglist
, target
);
7523 case SPE_BUILTIN_EVSTDDX
:
7524 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, arglist
);
7525 case SPE_BUILTIN_EVSTDHX
:
7526 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, arglist
);
7527 case SPE_BUILTIN_EVSTDWX
:
7528 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, arglist
);
7529 case SPE_BUILTIN_EVSTWHEX
:
7530 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, arglist
);
7531 case SPE_BUILTIN_EVSTWHOX
:
7532 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, arglist
);
7533 case SPE_BUILTIN_EVSTWWEX
:
7534 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, arglist
);
7535 case SPE_BUILTIN_EVSTWWOX
:
7536 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, arglist
);
7537 case SPE_BUILTIN_EVSTDD
:
7538 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, arglist
);
7539 case SPE_BUILTIN_EVSTDH
:
7540 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, arglist
);
7541 case SPE_BUILTIN_EVSTDW
:
7542 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, arglist
);
7543 case SPE_BUILTIN_EVSTWHE
:
7544 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, arglist
);
7545 case SPE_BUILTIN_EVSTWHO
:
7546 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, arglist
);
7547 case SPE_BUILTIN_EVSTWWE
:
7548 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, arglist
);
7549 case SPE_BUILTIN_EVSTWWO
:
7550 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, arglist
);
7551 case SPE_BUILTIN_MFSPEFSCR
:
7552 icode
= CODE_FOR_spe_mfspefscr
;
7553 tmode
= insn_data
[icode
].operand
[0].mode
;
7556 || GET_MODE (target
) != tmode
7557 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7558 target
= gen_reg_rtx (tmode
);
7560 pat
= GEN_FCN (icode
) (target
);
7565 case SPE_BUILTIN_MTSPEFSCR
:
7566 icode
= CODE_FOR_spe_mtspefscr
;
7567 arg0
= TREE_VALUE (arglist
);
7568 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7569 mode0
= insn_data
[icode
].operand
[0].mode
;
7571 if (arg0
== error_mark_node
)
7574 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7575 op0
= copy_to_mode_reg (mode0
, op0
);
7577 pat
= GEN_FCN (icode
) (op0
);
7590 spe_expand_predicate_builtin (enum insn_code icode
, tree arglist
, rtx target
)
7592 rtx pat
, scratch
, tmp
;
7593 tree form
= TREE_VALUE (arglist
);
7594 tree arg0
= TREE_VALUE (TREE_CHAIN (arglist
));
7595 tree arg1
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7596 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7597 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7598 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7599 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7603 if (TREE_CODE (form
) != INTEGER_CST
)
7605 error ("argument 1 of __builtin_spe_predicate must be a constant");
7609 form_int
= TREE_INT_CST_LOW (form
);
7611 gcc_assert (mode0
== mode1
);
7613 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7617 || GET_MODE (target
) != SImode
7618 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
7619 target
= gen_reg_rtx (SImode
);
7621 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7622 op0
= copy_to_mode_reg (mode0
, op0
);
7623 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7624 op1
= copy_to_mode_reg (mode1
, op1
);
7626 scratch
= gen_reg_rtx (CCmode
);
7628 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
7633 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7634 _lower_. We use one compare, but look in different bits of the
7635 CR for each variant.
7637 There are 2 elements in each SPE simd type (upper/lower). The CR
7638 bits are set as follows:
7640 BIT0 | BIT 1 | BIT 2 | BIT 3
7641 U | L | (U | L) | (U & L)
7643 So, for an "all" relationship, BIT 3 would be set.
7644 For an "any" relationship, BIT 2 would be set. Etc.
7646 Following traditional nomenclature, these bits map to:
7648 BIT0 | BIT 1 | BIT 2 | BIT 3
7651 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
7656 /* All variant. OV bit. */
7658 /* We need to get to the OV bit, which is the ORDERED bit. We
7659 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
7660 that's ugly and will make validate_condition_mode die.
7661 So let's just use another pattern. */
7662 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
7664 /* Any variant. EQ bit. */
7668 /* Upper variant. LT bit. */
7672 /* Lower variant. GT bit. */
7677 error ("argument 1 of __builtin_spe_predicate is out of range");
7681 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
7682 emit_move_insn (target
, tmp
);
7687 /* The evsel builtins look like this:
7689 e = __builtin_spe_evsel_OP (a, b, c, d);
7693 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
7694 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
7698 spe_expand_evsel_builtin (enum insn_code icode
, tree arglist
, rtx target
)
7701 tree arg0
= TREE_VALUE (arglist
);
7702 tree arg1
= TREE_VALUE (TREE_CHAIN (arglist
));
7703 tree arg2
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist
)));
7704 tree arg3
= TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist
))));
7705 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, 0);
7706 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, 0);
7707 rtx op2
= expand_expr (arg2
, NULL_RTX
, VOIDmode
, 0);
7708 rtx op3
= expand_expr (arg3
, NULL_RTX
, VOIDmode
, 0);
7709 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7710 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7712 gcc_assert (mode0
== mode1
);
7714 if (arg0
== error_mark_node
|| arg1
== error_mark_node
7715 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
7719 || GET_MODE (target
) != mode0
7720 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
7721 target
= gen_reg_rtx (mode0
);
7723 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7724 op0
= copy_to_mode_reg (mode0
, op0
);
7725 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
7726 op1
= copy_to_mode_reg (mode0
, op1
);
7727 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
7728 op2
= copy_to_mode_reg (mode0
, op2
);
7729 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
7730 op3
= copy_to_mode_reg (mode0
, op3
);
7732 /* Generate the compare. */
7733 scratch
= gen_reg_rtx (CCmode
);
7734 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
7739 if (mode0
== V2SImode
)
7740 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
7742 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
7747 /* Expand an expression EXP that calls a built-in function,
7748 with result going to TARGET if that's convenient
7749 (and in mode MODE if that's convenient).
7750 SUBTARGET may be used as the target for computing one of EXP's operands.
7751 IGNORE is nonzero if the value is to be ignored. */
7754 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
7755 enum machine_mode mode ATTRIBUTE_UNUSED
,
7756 int ignore ATTRIBUTE_UNUSED
)
7758 tree fndecl
= TREE_OPERAND (TREE_OPERAND (exp
, 0), 0);
7759 tree arglist
= TREE_OPERAND (exp
, 1);
7760 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7761 struct builtin_description
*d
;
7766 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
7767 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
7769 int icode
= (int) CODE_FOR_altivec_lvsr
;
7770 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7771 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
7775 gcc_assert (TARGET_ALTIVEC
);
7777 arg
= TREE_VALUE (arglist
);
7778 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
7779 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
7780 addr
= memory_address (mode
, op
);
7781 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
7785 /* For the load case need to negate the address. */
7786 op
= gen_reg_rtx (GET_MODE (addr
));
7787 emit_insn (gen_rtx_SET (VOIDmode
, op
,
7788 gen_rtx_NEG (GET_MODE (addr
), addr
)));
7790 op
= gen_rtx_MEM (mode
, op
);
7793 || GET_MODE (target
) != tmode
7794 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7795 target
= gen_reg_rtx (tmode
);
7797 /*pat = gen_altivec_lvsr (target, op);*/
7798 pat
= GEN_FCN (icode
) (target
, op
);
7808 ret
= altivec_expand_builtin (exp
, target
, &success
);
7815 ret
= spe_expand_builtin (exp
, target
, &success
);
7821 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
);
7823 /* Handle simple unary operations. */
7824 d
= (struct builtin_description
*) bdesc_1arg
;
7825 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
7826 if (d
->code
== fcode
)
7827 return rs6000_expand_unop_builtin (d
->icode
, arglist
, target
);
7829 /* Handle simple binary operations. */
7830 d
= (struct builtin_description
*) bdesc_2arg
;
7831 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
7832 if (d
->code
== fcode
)
7833 return rs6000_expand_binop_builtin (d
->icode
, arglist
, target
);
7835 /* Handle simple ternary operations. */
7836 d
= (struct builtin_description
*) bdesc_3arg
;
7837 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
7838 if (d
->code
== fcode
)
7839 return rs6000_expand_ternop_builtin (d
->icode
, arglist
, target
);
7845 build_opaque_vector_type (tree node
, int nunits
)
7847 node
= copy_node (node
);
7848 TYPE_MAIN_VARIANT (node
) = node
;
7849 return build_vector_type (node
, nunits
);
7853 rs6000_init_builtins (void)
7855 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
7856 V2SF_type_node
= build_vector_type (float_type_node
, 2);
7857 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
7858 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
7859 V4SF_type_node
= build_vector_type (float_type_node
, 4);
7860 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
7861 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
7863 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
7864 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
7865 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
7867 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
7868 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
7869 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
7870 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
7872 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
7873 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
7874 'vector unsigned short'. */
7876 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
7877 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
7878 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
7879 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
7881 long_integer_type_internal_node
= long_integer_type_node
;
7882 long_unsigned_type_internal_node
= long_unsigned_type_node
;
7883 intQI_type_internal_node
= intQI_type_node
;
7884 uintQI_type_internal_node
= unsigned_intQI_type_node
;
7885 intHI_type_internal_node
= intHI_type_node
;
7886 uintHI_type_internal_node
= unsigned_intHI_type_node
;
7887 intSI_type_internal_node
= intSI_type_node
;
7888 uintSI_type_internal_node
= unsigned_intSI_type_node
;
7889 float_type_internal_node
= float_type_node
;
7890 void_type_internal_node
= void_type_node
;
7892 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7893 get_identifier ("__bool char"),
7894 bool_char_type_node
));
7895 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7896 get_identifier ("__bool short"),
7897 bool_short_type_node
));
7898 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7899 get_identifier ("__bool int"),
7900 bool_int_type_node
));
7901 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7902 get_identifier ("__pixel"),
7905 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
7906 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
7907 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
7908 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
7910 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7911 get_identifier ("__vector unsigned char"),
7912 unsigned_V16QI_type_node
));
7913 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7914 get_identifier ("__vector signed char"),
7916 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7917 get_identifier ("__vector __bool char"),
7918 bool_V16QI_type_node
));
7920 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7921 get_identifier ("__vector unsigned short"),
7922 unsigned_V8HI_type_node
));
7923 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7924 get_identifier ("__vector signed short"),
7926 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7927 get_identifier ("__vector __bool short"),
7928 bool_V8HI_type_node
));
7930 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7931 get_identifier ("__vector unsigned int"),
7932 unsigned_V4SI_type_node
));
7933 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7934 get_identifier ("__vector signed int"),
7936 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7937 get_identifier ("__vector __bool int"),
7938 bool_V4SI_type_node
));
7940 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7941 get_identifier ("__vector float"),
7943 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
7944 get_identifier ("__vector __pixel"),
7945 pixel_V8HI_type_node
));
7948 spe_init_builtins ();
7950 altivec_init_builtins ();
7951 if (TARGET_ALTIVEC
|| TARGET_SPE
)
7952 rs6000_common_init_builtins ();
7955 /* Search through a set of builtins and enable the mask bits.
7956 DESC is an array of builtins.
7957 SIZE is the total number of builtins.
7958 START is the builtin enum at which to start.
7959 END is the builtin enum at which to end. */
7961 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
7962 enum rs6000_builtins start
,
7963 enum rs6000_builtins end
)
7967 for (i
= 0; i
< size
; ++i
)
7968 if (desc
[i
].code
== start
)
7974 for (; i
< size
; ++i
)
7976 /* Flip all the bits on. */
7977 desc
[i
].mask
= target_flags
;
7978 if (desc
[i
].code
== end
)
7984 spe_init_builtins (void)
7986 tree endlink
= void_list_node
;
7987 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
7988 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
7989 struct builtin_description
*d
;
7992 tree v2si_ftype_4_v2si
7993 = build_function_type
7994 (opaque_V2SI_type_node
,
7995 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7996 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7997 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
7998 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8001 tree v2sf_ftype_4_v2sf
8002 = build_function_type
8003 (opaque_V2SF_type_node
,
8004 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8005 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8006 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8007 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8010 tree int_ftype_int_v2si_v2si
8011 = build_function_type
8013 tree_cons (NULL_TREE
, integer_type_node
,
8014 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8015 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8018 tree int_ftype_int_v2sf_v2sf
8019 = build_function_type
8021 tree_cons (NULL_TREE
, integer_type_node
,
8022 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8023 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8026 tree void_ftype_v2si_puint_int
8027 = build_function_type (void_type_node
,
8028 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8029 tree_cons (NULL_TREE
, puint_type_node
,
8030 tree_cons (NULL_TREE
,
8034 tree void_ftype_v2si_puint_char
8035 = build_function_type (void_type_node
,
8036 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8037 tree_cons (NULL_TREE
, puint_type_node
,
8038 tree_cons (NULL_TREE
,
8042 tree void_ftype_v2si_pv2si_int
8043 = build_function_type (void_type_node
,
8044 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8045 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8046 tree_cons (NULL_TREE
,
8050 tree void_ftype_v2si_pv2si_char
8051 = build_function_type (void_type_node
,
8052 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8053 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8054 tree_cons (NULL_TREE
,
8059 = build_function_type (void_type_node
,
8060 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
8063 = build_function_type (integer_type_node
, endlink
);
8065 tree v2si_ftype_pv2si_int
8066 = build_function_type (opaque_V2SI_type_node
,
8067 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8068 tree_cons (NULL_TREE
, integer_type_node
,
8071 tree v2si_ftype_puint_int
8072 = build_function_type (opaque_V2SI_type_node
,
8073 tree_cons (NULL_TREE
, puint_type_node
,
8074 tree_cons (NULL_TREE
, integer_type_node
,
8077 tree v2si_ftype_pushort_int
8078 = build_function_type (opaque_V2SI_type_node
,
8079 tree_cons (NULL_TREE
, pushort_type_node
,
8080 tree_cons (NULL_TREE
, integer_type_node
,
8083 tree v2si_ftype_signed_char
8084 = build_function_type (opaque_V2SI_type_node
,
8085 tree_cons (NULL_TREE
, signed_char_type_node
,
8088 /* The initialization of the simple binary and unary builtins is
8089 done in rs6000_common_init_builtins, but we have to enable the
8090 mask bits here manually because we have run out of `target_flags'
8091 bits. We really need to redesign this mask business. */
8093 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
8094 ARRAY_SIZE (bdesc_2arg
),
8097 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
8098 ARRAY_SIZE (bdesc_1arg
),
8100 SPE_BUILTIN_EVSUBFUSIAAW
);
8101 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
8102 ARRAY_SIZE (bdesc_spe_predicates
),
8103 SPE_BUILTIN_EVCMPEQ
,
8104 SPE_BUILTIN_EVFSTSTLT
);
8105 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
8106 ARRAY_SIZE (bdesc_spe_evsel
),
8107 SPE_BUILTIN_EVSEL_CMPGTS
,
8108 SPE_BUILTIN_EVSEL_FSTSTEQ
);
8110 (*lang_hooks
.decls
.pushdecl
)
8111 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
8112 opaque_V2SI_type_node
));
8114 /* Initialize irregular SPE builtins. */
8116 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
8117 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
8118 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
8119 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
8120 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
8121 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
8122 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
8123 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
8124 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
8125 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
8126 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
8127 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
8128 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
8129 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
8130 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
8131 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
8132 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
8133 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
8136 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
8137 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
8138 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
8139 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
8140 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
8141 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
8142 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
8143 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
8144 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
8145 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
8146 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
8147 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
8148 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
8149 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
8150 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
8151 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
8152 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
8153 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
8154 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
8155 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
8156 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
8157 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
8160 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8161 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
8165 switch (insn_data
[d
->icode
].operand
[1].mode
)
8168 type
= int_ftype_int_v2si_v2si
;
8171 type
= int_ftype_int_v2sf_v2sf
;
8177 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8180 /* Evsel predicates. */
8181 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8182 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
8186 switch (insn_data
[d
->icode
].operand
[1].mode
)
8189 type
= v2si_ftype_4_v2si
;
8192 type
= v2sf_ftype_4_v2sf
;
8198 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8203 altivec_init_builtins (void)
8205 struct builtin_description
*d
;
8206 struct builtin_description_predicates
*dp
;
8210 tree pfloat_type_node
= build_pointer_type (float_type_node
);
8211 tree pint_type_node
= build_pointer_type (integer_type_node
);
8212 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
8213 tree pchar_type_node
= build_pointer_type (char_type_node
);
8215 tree pvoid_type_node
= build_pointer_type (void_type_node
);
8217 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
8218 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
8219 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
8220 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
8222 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
8224 tree int_ftype_opaque
8225 = build_function_type_list (integer_type_node
,
8226 opaque_V4SI_type_node
, NULL_TREE
);
8228 tree opaque_ftype_opaque_int
8229 = build_function_type_list (opaque_V4SI_type_node
,
8230 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
8231 tree opaque_ftype_opaque_opaque_int
8232 = build_function_type_list (opaque_V4SI_type_node
,
8233 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
8234 integer_type_node
, NULL_TREE
);
8235 tree int_ftype_int_opaque_opaque
8236 = build_function_type_list (integer_type_node
,
8237 integer_type_node
, opaque_V4SI_type_node
,
8238 opaque_V4SI_type_node
, NULL_TREE
);
8239 tree int_ftype_int_v4si_v4si
8240 = build_function_type_list (integer_type_node
,
8241 integer_type_node
, V4SI_type_node
,
8242 V4SI_type_node
, NULL_TREE
);
8243 tree v4sf_ftype_pcfloat
8244 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
8245 tree void_ftype_pfloat_v4sf
8246 = build_function_type_list (void_type_node
,
8247 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
8248 tree v4si_ftype_pcint
8249 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
8250 tree void_ftype_pint_v4si
8251 = build_function_type_list (void_type_node
,
8252 pint_type_node
, V4SI_type_node
, NULL_TREE
);
8253 tree v8hi_ftype_pcshort
8254 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
8255 tree void_ftype_pshort_v8hi
8256 = build_function_type_list (void_type_node
,
8257 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
8258 tree v16qi_ftype_pcchar
8259 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
8260 tree void_ftype_pchar_v16qi
8261 = build_function_type_list (void_type_node
,
8262 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
8263 tree void_ftype_v4si
8264 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
8265 tree v8hi_ftype_void
8266 = build_function_type (V8HI_type_node
, void_list_node
);
8267 tree void_ftype_void
8268 = build_function_type (void_type_node
, void_list_node
);
8270 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
8272 tree opaque_ftype_long_pcvoid
8273 = build_function_type_list (opaque_V4SI_type_node
,
8274 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8275 tree v16qi_ftype_long_pcvoid
8276 = build_function_type_list (V16QI_type_node
,
8277 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8278 tree v8hi_ftype_long_pcvoid
8279 = build_function_type_list (V8HI_type_node
,
8280 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8281 tree v4si_ftype_long_pcvoid
8282 = build_function_type_list (V4SI_type_node
,
8283 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8285 tree void_ftype_opaque_long_pvoid
8286 = build_function_type_list (void_type_node
,
8287 opaque_V4SI_type_node
, long_integer_type_node
,
8288 pvoid_type_node
, NULL_TREE
);
8289 tree void_ftype_v4si_long_pvoid
8290 = build_function_type_list (void_type_node
,
8291 V4SI_type_node
, long_integer_type_node
,
8292 pvoid_type_node
, NULL_TREE
);
8293 tree void_ftype_v16qi_long_pvoid
8294 = build_function_type_list (void_type_node
,
8295 V16QI_type_node
, long_integer_type_node
,
8296 pvoid_type_node
, NULL_TREE
);
8297 tree void_ftype_v8hi_long_pvoid
8298 = build_function_type_list (void_type_node
,
8299 V8HI_type_node
, long_integer_type_node
,
8300 pvoid_type_node
, NULL_TREE
);
8301 tree int_ftype_int_v8hi_v8hi
8302 = build_function_type_list (integer_type_node
,
8303 integer_type_node
, V8HI_type_node
,
8304 V8HI_type_node
, NULL_TREE
);
8305 tree int_ftype_int_v16qi_v16qi
8306 = build_function_type_list (integer_type_node
,
8307 integer_type_node
, V16QI_type_node
,
8308 V16QI_type_node
, NULL_TREE
);
8309 tree int_ftype_int_v4sf_v4sf
8310 = build_function_type_list (integer_type_node
,
8311 integer_type_node
, V4SF_type_node
,
8312 V4SF_type_node
, NULL_TREE
);
8313 tree v4si_ftype_v4si
8314 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8315 tree v8hi_ftype_v8hi
8316 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8317 tree v16qi_ftype_v16qi
8318 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8319 tree v4sf_ftype_v4sf
8320 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8321 tree void_ftype_pcvoid_int_int
8322 = build_function_type_list (void_type_node
,
8323 pcvoid_type_node
, integer_type_node
,
8324 integer_type_node
, NULL_TREE
);
8326 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
8327 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
8328 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
8329 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
8330 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
8331 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
8332 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
8333 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
8334 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
8335 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
8336 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
8337 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
8338 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
8339 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
8340 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
8341 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
8342 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
8343 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
8344 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
8345 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
8346 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
8347 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
8348 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
8349 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
8350 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
8351 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
8352 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
8353 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
8354 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
8355 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
8356 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
8357 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
8358 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
8359 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
8360 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
8361 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
8362 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
8363 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
8364 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
8365 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
8366 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
8367 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
8368 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
8369 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
8370 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
8371 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
8373 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
8375 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
8376 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
8377 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
8378 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
8379 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
8380 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
8381 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
8382 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
8383 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
8384 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
8386 /* Add the DST variants. */
8387 d
= (struct builtin_description
*) bdesc_dst
;
8388 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8389 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
8391 /* Initialize the predicates. */
8392 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
8393 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8395 enum machine_mode mode1
;
8397 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8398 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8403 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
8408 type
= int_ftype_int_opaque_opaque
;
8411 type
= int_ftype_int_v4si_v4si
;
8414 type
= int_ftype_int_v8hi_v8hi
;
8417 type
= int_ftype_int_v16qi_v16qi
;
8420 type
= int_ftype_int_v4sf_v4sf
;
8426 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
8429 /* Initialize the abs* operators. */
8430 d
= (struct builtin_description
*) bdesc_abs
;
8431 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8433 enum machine_mode mode0
;
8436 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8441 type
= v4si_ftype_v4si
;
8444 type
= v8hi_ftype_v8hi
;
8447 type
= v16qi_ftype_v16qi
;
8450 type
= v4sf_ftype_v4sf
;
8456 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8463 /* Initialize target builtin that implements
8464 targetm.vectorize.builtin_mask_for_load. */
8466 decl
= lang_hooks
.builtin_function ("__builtin_altivec_mask_for_load",
8467 v16qi_ftype_long_pcvoid
,
8468 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
8470 tree_cons (get_identifier ("const"),
8471 NULL_TREE
, NULL_TREE
));
8472 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8473 altivec_builtin_mask_for_load
= decl
;
8476 /* Access to the vec_init patterns. */
8477 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
8478 integer_type_node
, integer_type_node
,
8479 integer_type_node
, NULL_TREE
);
8480 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
8481 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
8483 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
8484 short_integer_type_node
,
8485 short_integer_type_node
,
8486 short_integer_type_node
,
8487 short_integer_type_node
,
8488 short_integer_type_node
,
8489 short_integer_type_node
,
8490 short_integer_type_node
, NULL_TREE
);
8491 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
8492 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
8494 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
8495 char_type_node
, char_type_node
,
8496 char_type_node
, char_type_node
,
8497 char_type_node
, char_type_node
,
8498 char_type_node
, char_type_node
,
8499 char_type_node
, char_type_node
,
8500 char_type_node
, char_type_node
,
8501 char_type_node
, char_type_node
,
8502 char_type_node
, NULL_TREE
);
8503 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
8504 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
8506 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
8507 float_type_node
, float_type_node
,
8508 float_type_node
, NULL_TREE
);
8509 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
8510 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
8512 /* Access to the vec_set patterns. */
8513 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
8515 integer_type_node
, NULL_TREE
);
8516 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
8517 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
8519 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
8521 integer_type_node
, NULL_TREE
);
8522 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
8523 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
8525 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
8527 integer_type_node
, NULL_TREE
);
8528 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
8529 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
8531 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
8533 integer_type_node
, NULL_TREE
);
8534 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
8535 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
8537 /* Access to the vec_extract patterns. */
8538 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
8539 integer_type_node
, NULL_TREE
);
8540 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
8541 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
8543 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
8544 integer_type_node
, NULL_TREE
);
8545 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
8546 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
8548 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
8549 integer_type_node
, NULL_TREE
);
8550 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
8551 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
8553 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
8554 integer_type_node
, NULL_TREE
);
8555 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
8556 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
8560 rs6000_common_init_builtins (void)
8562 struct builtin_description
*d
;
8565 tree v4sf_ftype_v4sf_v4sf_v16qi
8566 = build_function_type_list (V4SF_type_node
,
8567 V4SF_type_node
, V4SF_type_node
,
8568 V16QI_type_node
, NULL_TREE
);
8569 tree v4si_ftype_v4si_v4si_v16qi
8570 = build_function_type_list (V4SI_type_node
,
8571 V4SI_type_node
, V4SI_type_node
,
8572 V16QI_type_node
, NULL_TREE
);
8573 tree v8hi_ftype_v8hi_v8hi_v16qi
8574 = build_function_type_list (V8HI_type_node
,
8575 V8HI_type_node
, V8HI_type_node
,
8576 V16QI_type_node
, NULL_TREE
);
8577 tree v16qi_ftype_v16qi_v16qi_v16qi
8578 = build_function_type_list (V16QI_type_node
,
8579 V16QI_type_node
, V16QI_type_node
,
8580 V16QI_type_node
, NULL_TREE
);
8582 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
8584 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
8585 tree v16qi_ftype_int
8586 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
8587 tree v8hi_ftype_v16qi
8588 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
8589 tree v4sf_ftype_v4sf
8590 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8592 tree v2si_ftype_v2si_v2si
8593 = build_function_type_list (opaque_V2SI_type_node
,
8594 opaque_V2SI_type_node
,
8595 opaque_V2SI_type_node
, NULL_TREE
);
8597 tree v2sf_ftype_v2sf_v2sf
8598 = build_function_type_list (opaque_V2SF_type_node
,
8599 opaque_V2SF_type_node
,
8600 opaque_V2SF_type_node
, NULL_TREE
);
8602 tree v2si_ftype_int_int
8603 = build_function_type_list (opaque_V2SI_type_node
,
8604 integer_type_node
, integer_type_node
,
8607 tree opaque_ftype_opaque
8608 = build_function_type_list (opaque_V4SI_type_node
,
8609 opaque_V4SI_type_node
, NULL_TREE
);
8611 tree v2si_ftype_v2si
8612 = build_function_type_list (opaque_V2SI_type_node
,
8613 opaque_V2SI_type_node
, NULL_TREE
);
8615 tree v2sf_ftype_v2sf
8616 = build_function_type_list (opaque_V2SF_type_node
,
8617 opaque_V2SF_type_node
, NULL_TREE
);
8619 tree v2sf_ftype_v2si
8620 = build_function_type_list (opaque_V2SF_type_node
,
8621 opaque_V2SI_type_node
, NULL_TREE
);
8623 tree v2si_ftype_v2sf
8624 = build_function_type_list (opaque_V2SI_type_node
,
8625 opaque_V2SF_type_node
, NULL_TREE
);
8627 tree v2si_ftype_v2si_char
8628 = build_function_type_list (opaque_V2SI_type_node
,
8629 opaque_V2SI_type_node
,
8630 char_type_node
, NULL_TREE
);
8632 tree v2si_ftype_int_char
8633 = build_function_type_list (opaque_V2SI_type_node
,
8634 integer_type_node
, char_type_node
, NULL_TREE
);
8636 tree v2si_ftype_char
8637 = build_function_type_list (opaque_V2SI_type_node
,
8638 char_type_node
, NULL_TREE
);
8640 tree int_ftype_int_int
8641 = build_function_type_list (integer_type_node
,
8642 integer_type_node
, integer_type_node
,
8645 tree opaque_ftype_opaque_opaque
8646 = build_function_type_list (opaque_V4SI_type_node
,
8647 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
8648 tree v4si_ftype_v4si_v4si
8649 = build_function_type_list (V4SI_type_node
,
8650 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8651 tree v4sf_ftype_v4si_int
8652 = build_function_type_list (V4SF_type_node
,
8653 V4SI_type_node
, integer_type_node
, NULL_TREE
);
8654 tree v4si_ftype_v4sf_int
8655 = build_function_type_list (V4SI_type_node
,
8656 V4SF_type_node
, integer_type_node
, NULL_TREE
);
8657 tree v4si_ftype_v4si_int
8658 = build_function_type_list (V4SI_type_node
,
8659 V4SI_type_node
, integer_type_node
, NULL_TREE
);
8660 tree v8hi_ftype_v8hi_int
8661 = build_function_type_list (V8HI_type_node
,
8662 V8HI_type_node
, integer_type_node
, NULL_TREE
);
8663 tree v16qi_ftype_v16qi_int
8664 = build_function_type_list (V16QI_type_node
,
8665 V16QI_type_node
, integer_type_node
, NULL_TREE
);
8666 tree v16qi_ftype_v16qi_v16qi_int
8667 = build_function_type_list (V16QI_type_node
,
8668 V16QI_type_node
, V16QI_type_node
,
8669 integer_type_node
, NULL_TREE
);
8670 tree v8hi_ftype_v8hi_v8hi_int
8671 = build_function_type_list (V8HI_type_node
,
8672 V8HI_type_node
, V8HI_type_node
,
8673 integer_type_node
, NULL_TREE
);
8674 tree v4si_ftype_v4si_v4si_int
8675 = build_function_type_list (V4SI_type_node
,
8676 V4SI_type_node
, V4SI_type_node
,
8677 integer_type_node
, NULL_TREE
);
8678 tree v4sf_ftype_v4sf_v4sf_int
8679 = build_function_type_list (V4SF_type_node
,
8680 V4SF_type_node
, V4SF_type_node
,
8681 integer_type_node
, NULL_TREE
);
8682 tree v4sf_ftype_v4sf_v4sf
8683 = build_function_type_list (V4SF_type_node
,
8684 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8685 tree opaque_ftype_opaque_opaque_opaque
8686 = build_function_type_list (opaque_V4SI_type_node
,
8687 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
8688 opaque_V4SI_type_node
, NULL_TREE
);
8689 tree v4sf_ftype_v4sf_v4sf_v4si
8690 = build_function_type_list (V4SF_type_node
,
8691 V4SF_type_node
, V4SF_type_node
,
8692 V4SI_type_node
, NULL_TREE
);
8693 tree v4sf_ftype_v4sf_v4sf_v4sf
8694 = build_function_type_list (V4SF_type_node
,
8695 V4SF_type_node
, V4SF_type_node
,
8696 V4SF_type_node
, NULL_TREE
);
8697 tree v4si_ftype_v4si_v4si_v4si
8698 = build_function_type_list (V4SI_type_node
,
8699 V4SI_type_node
, V4SI_type_node
,
8700 V4SI_type_node
, NULL_TREE
);
8701 tree v8hi_ftype_v8hi_v8hi
8702 = build_function_type_list (V8HI_type_node
,
8703 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8704 tree v8hi_ftype_v8hi_v8hi_v8hi
8705 = build_function_type_list (V8HI_type_node
,
8706 V8HI_type_node
, V8HI_type_node
,
8707 V8HI_type_node
, NULL_TREE
);
8708 tree v4si_ftype_v8hi_v8hi_v4si
8709 = build_function_type_list (V4SI_type_node
,
8710 V8HI_type_node
, V8HI_type_node
,
8711 V4SI_type_node
, NULL_TREE
);
8712 tree v4si_ftype_v16qi_v16qi_v4si
8713 = build_function_type_list (V4SI_type_node
,
8714 V16QI_type_node
, V16QI_type_node
,
8715 V4SI_type_node
, NULL_TREE
);
8716 tree v16qi_ftype_v16qi_v16qi
8717 = build_function_type_list (V16QI_type_node
,
8718 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8719 tree v4si_ftype_v4sf_v4sf
8720 = build_function_type_list (V4SI_type_node
,
8721 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8722 tree v8hi_ftype_v16qi_v16qi
8723 = build_function_type_list (V8HI_type_node
,
8724 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8725 tree v4si_ftype_v8hi_v8hi
8726 = build_function_type_list (V4SI_type_node
,
8727 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8728 tree v8hi_ftype_v4si_v4si
8729 = build_function_type_list (V8HI_type_node
,
8730 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8731 tree v16qi_ftype_v8hi_v8hi
8732 = build_function_type_list (V16QI_type_node
,
8733 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8734 tree v4si_ftype_v16qi_v4si
8735 = build_function_type_list (V4SI_type_node
,
8736 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
8737 tree v4si_ftype_v16qi_v16qi
8738 = build_function_type_list (V4SI_type_node
,
8739 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8740 tree v4si_ftype_v8hi_v4si
8741 = build_function_type_list (V4SI_type_node
,
8742 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
8743 tree v4si_ftype_v8hi
8744 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
8745 tree int_ftype_v4si_v4si
8746 = build_function_type_list (integer_type_node
,
8747 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8748 tree int_ftype_v4sf_v4sf
8749 = build_function_type_list (integer_type_node
,
8750 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8751 tree int_ftype_v16qi_v16qi
8752 = build_function_type_list (integer_type_node
,
8753 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8754 tree int_ftype_v8hi_v8hi
8755 = build_function_type_list (integer_type_node
,
8756 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8758 /* Add the simple ternary operators. */
8759 d
= (struct builtin_description
*) bdesc_3arg
;
8760 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
8762 enum machine_mode mode0
, mode1
, mode2
, mode3
;
8764 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8765 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8776 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8779 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8780 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8781 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8782 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
8785 /* When all four are of the same mode. */
8786 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
8791 type
= opaque_ftype_opaque_opaque_opaque
;
8794 type
= v4si_ftype_v4si_v4si_v4si
;
8797 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
8800 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
8803 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
8809 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
8814 type
= v4si_ftype_v4si_v4si_v16qi
;
8817 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
8820 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
8823 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
8829 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
8830 && mode3
== V4SImode
)
8831 type
= v4si_ftype_v16qi_v16qi_v4si
;
8832 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
8833 && mode3
== V4SImode
)
8834 type
= v4si_ftype_v8hi_v8hi_v4si
;
8835 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
8836 && mode3
== V4SImode
)
8837 type
= v4sf_ftype_v4sf_v4sf_v4si
;
8839 /* vchar, vchar, vchar, 4 bit literal. */
8840 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
8842 type
= v16qi_ftype_v16qi_v16qi_int
;
8844 /* vshort, vshort, vshort, 4 bit literal. */
8845 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
8847 type
= v8hi_ftype_v8hi_v8hi_int
;
8849 /* vint, vint, vint, 4 bit literal. */
8850 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
8852 type
= v4si_ftype_v4si_v4si_int
;
8854 /* vfloat, vfloat, vfloat, 4 bit literal. */
8855 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
8857 type
= v4sf_ftype_v4sf_v4sf_int
;
8862 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8865 /* Add the simple binary operators. */
8866 d
= (struct builtin_description
*) bdesc_2arg
;
8867 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
8869 enum machine_mode mode0
, mode1
, mode2
;
8871 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8872 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8882 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
8885 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8886 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
8887 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
8890 /* When all three operands are of the same mode. */
8891 if (mode0
== mode1
&& mode1
== mode2
)
8896 type
= opaque_ftype_opaque_opaque
;
8899 type
= v4sf_ftype_v4sf_v4sf
;
8902 type
= v4si_ftype_v4si_v4si
;
8905 type
= v16qi_ftype_v16qi_v16qi
;
8908 type
= v8hi_ftype_v8hi_v8hi
;
8911 type
= v2si_ftype_v2si_v2si
;
8914 type
= v2sf_ftype_v2sf_v2sf
;
8917 type
= int_ftype_int_int
;
8924 /* A few other combos we really don't want to do manually. */
8926 /* vint, vfloat, vfloat. */
8927 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
8928 type
= v4si_ftype_v4sf_v4sf
;
8930 /* vshort, vchar, vchar. */
8931 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
8932 type
= v8hi_ftype_v16qi_v16qi
;
8934 /* vint, vshort, vshort. */
8935 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
8936 type
= v4si_ftype_v8hi_v8hi
;
8938 /* vshort, vint, vint. */
8939 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
8940 type
= v8hi_ftype_v4si_v4si
;
8942 /* vchar, vshort, vshort. */
8943 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
8944 type
= v16qi_ftype_v8hi_v8hi
;
8946 /* vint, vchar, vint. */
8947 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
8948 type
= v4si_ftype_v16qi_v4si
;
8950 /* vint, vchar, vchar. */
8951 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
8952 type
= v4si_ftype_v16qi_v16qi
;
8954 /* vint, vshort, vint. */
8955 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
8956 type
= v4si_ftype_v8hi_v4si
;
8958 /* vint, vint, 5 bit literal. */
8959 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
8960 type
= v4si_ftype_v4si_int
;
8962 /* vshort, vshort, 5 bit literal. */
8963 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
8964 type
= v8hi_ftype_v8hi_int
;
8966 /* vchar, vchar, 5 bit literal. */
8967 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
8968 type
= v16qi_ftype_v16qi_int
;
8970 /* vfloat, vint, 5 bit literal. */
8971 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
8972 type
= v4sf_ftype_v4si_int
;
8974 /* vint, vfloat, 5 bit literal. */
8975 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
8976 type
= v4si_ftype_v4sf_int
;
8978 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
8979 type
= v2si_ftype_int_int
;
8981 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
8982 type
= v2si_ftype_v2si_char
;
8984 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
8985 type
= v2si_ftype_int_char
;
8990 gcc_assert (mode0
== SImode
);
8994 type
= int_ftype_v4si_v4si
;
8997 type
= int_ftype_v4sf_v4sf
;
9000 type
= int_ftype_v16qi_v16qi
;
9003 type
= int_ftype_v8hi_v8hi
;
9010 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9013 /* Add the simple unary operators. */
9014 d
= (struct builtin_description
*) bdesc_1arg
;
9015 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9017 enum machine_mode mode0
, mode1
;
9019 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9020 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9029 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
9032 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9033 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
9036 if (mode0
== V4SImode
&& mode1
== QImode
)
9037 type
= v4si_ftype_int
;
9038 else if (mode0
== V8HImode
&& mode1
== QImode
)
9039 type
= v8hi_ftype_int
;
9040 else if (mode0
== V16QImode
&& mode1
== QImode
)
9041 type
= v16qi_ftype_int
;
9042 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
9043 type
= opaque_ftype_opaque
;
9044 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
9045 type
= v4sf_ftype_v4sf
;
9046 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
9047 type
= v8hi_ftype_v16qi
;
9048 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
9049 type
= v4si_ftype_v8hi
;
9050 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
9051 type
= v2si_ftype_v2si
;
9052 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
9053 type
= v2sf_ftype_v2sf
;
9054 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
9055 type
= v2sf_ftype_v2si
;
9056 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
9057 type
= v2si_ftype_v2sf
;
9058 else if (mode0
== V2SImode
&& mode1
== QImode
)
9059 type
= v2si_ftype_char
;
9063 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9068 rs6000_init_libfuncs (void)
9070 if (!TARGET_HARD_FLOAT
)
9073 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
9074 && !TARGET_POWER2
&& !TARGET_POWERPC
)
9076 /* AIX library routines for float->int conversion. */
9077 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
9078 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
9079 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
9080 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
9083 if (!TARGET_IEEEQUAD
)
9084 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9085 if (!TARGET_XL_COMPAT
)
9087 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
9088 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
9089 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
9090 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
9094 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
9095 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
9096 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
9097 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
9101 /* 32-bit SVR4 quad floating point routines. */
9103 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
9104 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
9105 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
9106 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
9107 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
9108 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
9109 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
9111 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
9112 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
9113 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
9114 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
9115 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
9116 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
9118 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
9119 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
9120 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
9121 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
9122 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
9123 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
9124 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
9125 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
9130 /* Expand a block clear operation, and return 1 if successful. Return 0
9131 if we should let the compiler generate normal code.
9133 operands[0] is the destination
9134 operands[1] is the length
9135 operands[3] is the alignment */
9138 expand_block_clear (rtx operands
[])
9140 rtx orig_dest
= operands
[0];
9141 rtx bytes_rtx
= operands
[1];
9142 rtx align_rtx
= operands
[3];
9143 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9144 HOST_WIDE_INT align
;
9145 HOST_WIDE_INT bytes
;
9150 /* If this is not a fixed size move, just call memcpy */
9154 /* This must be a fixed size alignment */
9155 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9156 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9158 /* Anything to clear? */
9159 bytes
= INTVAL (bytes_rtx
);
9163 /* Use the builtin memset after a point, to avoid huge code bloat.
9164 When optimize_size, avoid any significant code bloat; calling
9165 memset is about 4 instructions, so allow for one instruction to
9166 load zero and three to do clearing. */
9167 if (TARGET_ALTIVEC
&& align
>= 128)
9169 else if (TARGET_POWERPC64
&& align
>= 32)
9174 if (optimize_size
&& bytes
> 3 * clear_step
)
9176 if (! optimize_size
&& bytes
> 8 * clear_step
)
9179 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
9181 enum machine_mode mode
= BLKmode
;
9184 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
9189 else if (bytes
>= 8 && TARGET_POWERPC64
9190 /* 64-bit loads and stores require word-aligned
9192 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9197 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9198 { /* move 4 bytes */
9202 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9203 { /* move 2 bytes */
9207 else /* move 1 byte at a time */
9213 dest
= adjust_address (orig_dest
, mode
, offset
);
9215 emit_move_insn (dest
, CONST0_RTX (mode
));
9222 /* Expand a block move operation, and return 1 if successful. Return 0
9223 if we should let the compiler generate normal code.
9225 operands[0] is the destination
9226 operands[1] is the source
9227 operands[2] is the length
9228 operands[3] is the alignment */
9230 #define MAX_MOVE_REG 4
9233 expand_block_move (rtx operands
[])
9235 rtx orig_dest
= operands
[0];
9236 rtx orig_src
= operands
[1];
9237 rtx bytes_rtx
= operands
[2];
9238 rtx align_rtx
= operands
[3];
9239 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9244 rtx stores
[MAX_MOVE_REG
];
9247 /* If this is not a fixed size move, just call memcpy */
9251 /* This must be a fixed size alignment */
9252 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9253 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9255 /* Anything to move? */
9256 bytes
= INTVAL (bytes_rtx
);
9260 /* store_one_arg depends on expand_block_move to handle at least the size of
9261 reg_parm_stack_space. */
9262 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
9265 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
9268 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
9269 rtx (*mov
) (rtx
, rtx
);
9271 enum machine_mode mode
= BLKmode
;
9274 /* Altivec first, since it will be faster than a string move
9275 when it applies, and usually not significantly larger. */
9276 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
9280 gen_func
.mov
= gen_movv4si
;
9282 else if (TARGET_STRING
9283 && bytes
> 24 /* move up to 32 bytes at a time */
9291 && ! fixed_regs
[12])
9293 move_bytes
= (bytes
> 32) ? 32 : bytes
;
9294 gen_func
.movmemsi
= gen_movmemsi_8reg
;
9296 else if (TARGET_STRING
9297 && bytes
> 16 /* move up to 24 bytes at a time */
9303 && ! fixed_regs
[10])
9305 move_bytes
= (bytes
> 24) ? 24 : bytes
;
9306 gen_func
.movmemsi
= gen_movmemsi_6reg
;
9308 else if (TARGET_STRING
9309 && bytes
> 8 /* move up to 16 bytes at a time */
9315 move_bytes
= (bytes
> 16) ? 16 : bytes
;
9316 gen_func
.movmemsi
= gen_movmemsi_4reg
;
9318 else if (bytes
>= 8 && TARGET_POWERPC64
9319 /* 64-bit loads and stores require word-aligned
9321 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9325 gen_func
.mov
= gen_movdi
;
9327 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
9328 { /* move up to 8 bytes at a time */
9329 move_bytes
= (bytes
> 8) ? 8 : bytes
;
9330 gen_func
.movmemsi
= gen_movmemsi_2reg
;
9332 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9333 { /* move 4 bytes */
9336 gen_func
.mov
= gen_movsi
;
9338 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9339 { /* move 2 bytes */
9342 gen_func
.mov
= gen_movhi
;
9344 else if (TARGET_STRING
&& bytes
> 1)
9345 { /* move up to 4 bytes at a time */
9346 move_bytes
= (bytes
> 4) ? 4 : bytes
;
9347 gen_func
.movmemsi
= gen_movmemsi_1reg
;
9349 else /* move 1 byte at a time */
9353 gen_func
.mov
= gen_movqi
;
9356 src
= adjust_address (orig_src
, mode
, offset
);
9357 dest
= adjust_address (orig_dest
, mode
, offset
);
9359 if (mode
!= BLKmode
)
9361 rtx tmp_reg
= gen_reg_rtx (mode
);
9363 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
9364 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
9367 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
9370 for (i
= 0; i
< num_reg
; i
++)
9371 emit_insn (stores
[i
]);
9375 if (mode
== BLKmode
)
9377 /* Move the address into scratch registers. The movmemsi
9378 patterns require zero offset. */
9379 if (!REG_P (XEXP (src
, 0)))
9381 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
9382 src
= replace_equiv_address (src
, src_reg
);
9384 set_mem_size (src
, GEN_INT (move_bytes
));
9386 if (!REG_P (XEXP (dest
, 0)))
9388 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
9389 dest
= replace_equiv_address (dest
, dest_reg
);
9391 set_mem_size (dest
, GEN_INT (move_bytes
));
9393 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
9394 GEN_INT (move_bytes
& 31),
9403 /* Return a string to perform a load_multiple operation.
9404 operands[0] is the vector.
9405 operands[1] is the source address.
9406 operands[2] is the first destination register. */
9409 rs6000_output_load_multiple (rtx operands
[3])
9411 /* We have to handle the case where the pseudo used to contain the address
9412 is assigned to one of the output registers. */
9414 int words
= XVECLEN (operands
[0], 0);
9417 if (XVECLEN (operands
[0], 0) == 1)
9418 return "{l|lwz} %2,0(%1)";
9420 for (i
= 0; i
< words
; i
++)
9421 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
9422 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
9426 xop
[0] = GEN_INT (4 * (words
-1));
9427 xop
[1] = operands
[1];
9428 xop
[2] = operands
[2];
9429 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
9434 xop
[0] = GEN_INT (4 * (words
-1));
9435 xop
[1] = operands
[1];
9436 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
9437 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
);
9442 for (j
= 0; j
< words
; j
++)
9445 xop
[0] = GEN_INT (j
* 4);
9446 xop
[1] = operands
[1];
9447 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
9448 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
9450 xop
[0] = GEN_INT (i
* 4);
9451 xop
[1] = operands
[1];
9452 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
9457 return "{lsi|lswi} %2,%1,%N0";
9461 /* A validation routine: say whether CODE, a condition code, and MODE
9462 match. The other alternatives either don't make sense or should
9463 never be generated. */
9466 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
9468 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
9469 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
9470 && GET_MODE_CLASS (mode
) == MODE_CC
);
9472 /* These don't make sense. */
9473 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
9474 || mode
!= CCUNSmode
);
9476 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
9477 || mode
== CCUNSmode
);
9479 gcc_assert (mode
== CCFPmode
9480 || (code
!= ORDERED
&& code
!= UNORDERED
9481 && code
!= UNEQ
&& code
!= LTGT
9482 && code
!= UNGT
&& code
!= UNLT
9483 && code
!= UNGE
&& code
!= UNLE
));
9485 /* These should never be generated except for
9486 flag_finite_math_only. */
9487 gcc_assert (mode
!= CCFPmode
9488 || flag_finite_math_only
9489 || (code
!= LE
&& code
!= GE
9490 && code
!= UNEQ
&& code
!= LTGT
9491 && code
!= UNGT
&& code
!= UNLT
));
9493 /* These are invalid; the information is not there. */
9494 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
9498 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9499 mask required to convert the result of a rotate insn into a shift
9500 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9503 includes_lshift_p (rtx shiftop
, rtx andop
)
9505 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
9507 shift_mask
<<= INTVAL (shiftop
);
9509 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
9512 /* Similar, but for right shift. */
9515 includes_rshift_p (rtx shiftop
, rtx andop
)
9517 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
9519 shift_mask
>>= INTVAL (shiftop
);
9521 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
9524 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9525 to perform a left shift. It must have exactly SHIFTOP least
9526 significant 0's, then one or more 1's, then zero or more 0's. */
9529 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
9531 if (GET_CODE (andop
) == CONST_INT
)
9533 HOST_WIDE_INT c
, lsb
, shift_mask
;
9536 if (c
== 0 || c
== ~0)
9540 shift_mask
<<= INTVAL (shiftop
);
9542 /* Find the least significant one bit. */
9545 /* It must coincide with the LSB of the shift mask. */
9546 if (-lsb
!= shift_mask
)
9549 /* Invert to look for the next transition (if any). */
9552 /* Remove the low group of ones (originally low group of zeros). */
9555 /* Again find the lsb, and check we have all 1's above. */
9559 else if (GET_CODE (andop
) == CONST_DOUBLE
9560 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
9562 HOST_WIDE_INT low
, high
, lsb
;
9563 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
9565 low
= CONST_DOUBLE_LOW (andop
);
9566 if (HOST_BITS_PER_WIDE_INT
< 64)
9567 high
= CONST_DOUBLE_HIGH (andop
);
9569 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
9570 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
9573 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
9575 shift_mask_high
= ~0;
9576 if (INTVAL (shiftop
) > 32)
9577 shift_mask_high
<<= INTVAL (shiftop
) - 32;
9581 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
9588 return high
== -lsb
;
9591 shift_mask_low
= ~0;
9592 shift_mask_low
<<= INTVAL (shiftop
);
9596 if (-lsb
!= shift_mask_low
)
9599 if (HOST_BITS_PER_WIDE_INT
< 64)
9604 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
9607 return high
== -lsb
;
9611 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
9617 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9618 to perform a left shift. It must have SHIFTOP or more least
9619 significant 0's, with the remainder of the word 1's. */
9622 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
9624 if (GET_CODE (andop
) == CONST_INT
)
9626 HOST_WIDE_INT c
, lsb
, shift_mask
;
9629 shift_mask
<<= INTVAL (shiftop
);
9632 /* Find the least significant one bit. */
9635 /* It must be covered by the shift mask.
9636 This test also rejects c == 0. */
9637 if ((lsb
& shift_mask
) == 0)
9640 /* Check we have all 1's above the transition, and reject all 1's. */
9641 return c
== -lsb
&& lsb
!= 1;
9643 else if (GET_CODE (andop
) == CONST_DOUBLE
9644 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
9646 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
9648 low
= CONST_DOUBLE_LOW (andop
);
9650 if (HOST_BITS_PER_WIDE_INT
< 64)
9652 HOST_WIDE_INT high
, shift_mask_high
;
9654 high
= CONST_DOUBLE_HIGH (andop
);
9658 shift_mask_high
= ~0;
9659 if (INTVAL (shiftop
) > 32)
9660 shift_mask_high
<<= INTVAL (shiftop
) - 32;
9664 if ((lsb
& shift_mask_high
) == 0)
9667 return high
== -lsb
;
9673 shift_mask_low
= ~0;
9674 shift_mask_low
<<= INTVAL (shiftop
);
9678 if ((lsb
& shift_mask_low
) == 0)
9681 return low
== -lsb
&& lsb
!= 1;
9687 /* Return 1 if operands will generate a valid arguments to rlwimi
9688 instruction for insert with right shift in 64-bit mode. The mask may
9689 not start on the first bit or stop on the last bit because wrap-around
9690 effects of instruction do not correspond to semantics of RTL insn. */
9693 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
9695 if (INTVAL (startop
) < 64
9696 && INTVAL (startop
) > 32
9697 && (INTVAL (sizeop
) + INTVAL (startop
) < 64)
9698 && (INTVAL (sizeop
) + INTVAL (startop
) > 33)
9699 && (INTVAL (sizeop
) + INTVAL (startop
) + INTVAL (shiftop
) < 96)
9700 && (INTVAL (sizeop
) + INTVAL (startop
) + INTVAL (shiftop
) >= 64)
9701 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
9707 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
9708 for lfq and stfq insns iff the registers are hard registers. */
9711 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
9713 /* We might have been passed a SUBREG. */
9714 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
9717 /* We might have been passed non floating point registers. */
9718 if (!FP_REGNO_P (REGNO (reg1
))
9719 || !FP_REGNO_P (REGNO (reg2
)))
9722 return (REGNO (reg1
) == REGNO (reg2
) - 1);
9725 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
9726 addr1 and addr2 must be in consecutive memory locations
9727 (addr2 == addr1 + 8). */
9730 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
9733 unsigned int reg1
, reg2
;
9734 int offset1
, offset2
;
9736 /* The mems cannot be volatile. */
9737 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
9740 addr1
= XEXP (mem1
, 0);
9741 addr2
= XEXP (mem2
, 0);
9743 /* Extract an offset (if used) from the first addr. */
9744 if (GET_CODE (addr1
) == PLUS
)
9746 /* If not a REG, return zero. */
9747 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
9751 reg1
= REGNO (XEXP (addr1
, 0));
9752 /* The offset must be constant! */
9753 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
9755 offset1
= INTVAL (XEXP (addr1
, 1));
9758 else if (GET_CODE (addr1
) != REG
)
9762 reg1
= REGNO (addr1
);
9763 /* This was a simple (mem (reg)) expression. Offset is 0. */
9767 /* And now for the second addr. */
9768 if (GET_CODE (addr2
) == PLUS
)
9770 /* If not a REG, return zero. */
9771 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
9775 reg2
= REGNO (XEXP (addr2
, 0));
9776 /* The offset must be constant. */
9777 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
9779 offset2
= INTVAL (XEXP (addr2
, 1));
9782 else if (GET_CODE (addr2
) != REG
)
9786 reg2
= REGNO (addr2
);
9787 /* This was a simple (mem (reg)) expression. Offset is 0. */
9791 /* Both of these must have the same base register. */
9795 /* The offset for the second addr must be 8 more than the first addr. */
9796 if (offset2
!= offset1
+ 8)
9799 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
9804 /* Return the register class of a scratch register needed to copy IN into
9805 or out of a register in CLASS in MODE. If it can be done directly,
9806 NO_REGS is returned. */
9809 rs6000_secondary_reload_class (enum reg_class
class,
9810 enum machine_mode mode ATTRIBUTE_UNUSED
,
9815 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
9817 && MACHOPIC_INDIRECT
9821 /* We cannot copy a symbolic operand directly into anything
9822 other than BASE_REGS for TARGET_ELF. So indicate that a
9823 register from BASE_REGS is needed as an intermediate
9826 On Darwin, pic addresses require a load from memory, which
9827 needs a base register. */
9828 if (class != BASE_REGS
9829 && (GET_CODE (in
) == SYMBOL_REF
9830 || GET_CODE (in
) == HIGH
9831 || GET_CODE (in
) == LABEL_REF
9832 || GET_CODE (in
) == CONST
))
9836 if (GET_CODE (in
) == REG
)
9839 if (regno
>= FIRST_PSEUDO_REGISTER
)
9841 regno
= true_regnum (in
);
9842 if (regno
>= FIRST_PSEUDO_REGISTER
)
9846 else if (GET_CODE (in
) == SUBREG
)
9848 regno
= true_regnum (in
);
9849 if (regno
>= FIRST_PSEUDO_REGISTER
)
9855 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
9857 if (class == GENERAL_REGS
|| class == BASE_REGS
9858 || (regno
>= 0 && INT_REGNO_P (regno
)))
9861 /* Constants, memory, and FP registers can go into FP registers. */
9862 if ((regno
== -1 || FP_REGNO_P (regno
))
9863 && (class == FLOAT_REGS
|| class == NON_SPECIAL_REGS
))
9866 /* Memory, and AltiVec registers can go into AltiVec registers. */
9867 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
9868 && class == ALTIVEC_REGS
)
9871 /* We can copy among the CR registers. */
9872 if ((class == CR_REGS
|| class == CR0_REGS
)
9873 && regno
>= 0 && CR_REGNO_P (regno
))
9876 /* Otherwise, we need GENERAL_REGS. */
9877 return GENERAL_REGS
;
9880 /* Given a comparison operation, return the bit number in CCR to test. We
9881 know this is a valid comparison.
9883 SCC_P is 1 if this is for an scc. That means that %D will have been
9884 used instead of %C, so the bits will be in different places.
9886 Return -1 if OP isn't a valid comparison for some reason. */
9889 ccr_bit (rtx op
, int scc_p
)
9891 enum rtx_code code
= GET_CODE (op
);
9892 enum machine_mode cc_mode
;
9897 if (!COMPARISON_P (op
))
9902 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
9904 cc_mode
= GET_MODE (reg
);
9905 cc_regnum
= REGNO (reg
);
9906 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
9908 validate_condition_mode (code
, cc_mode
);
9910 /* When generating a sCOND operation, only positive conditions are
9913 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
9914 || code
== GTU
|| code
== LTU
);
9919 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
9921 return base_bit
+ 2;
9922 case GT
: case GTU
: case UNLE
:
9923 return base_bit
+ 1;
9924 case LT
: case LTU
: case UNGE
:
9926 case ORDERED
: case UNORDERED
:
9927 return base_bit
+ 3;
9930 /* If scc, we will have done a cror to put the bit in the
9931 unordered position. So test that bit. For integer, this is ! LT
9932 unless this is an scc insn. */
9933 return scc_p
? base_bit
+ 3 : base_bit
;
9936 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
9943 /* Return the GOT register. */
9946 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
9948 /* The second flow pass currently (June 1999) can't update
9949 regs_ever_live without disturbing other parts of the compiler, so
9950 update it here to make the prolog/epilogue code happy. */
9951 if (no_new_pseudos
&& ! regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
])
9952 regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
9954 current_function_uses_pic_offset_table
= 1;
9956 return pic_offset_table_rtx
;
9959 /* Function to init struct machine_function.
9960 This will be called, via a pointer variable,
9961 from push_function_context. */
9963 static struct machine_function
*
9964 rs6000_init_machine_status (void)
9966 return ggc_alloc_cleared (sizeof (machine_function
));
9969 /* These macros test for integers and extract the low-order bits. */
9971 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
9972 && GET_MODE (X) == VOIDmode)
9974 #define INT_LOWPART(X) \
9975 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
9981 unsigned long val
= INT_LOWPART (op
);
9983 /* If the high bit is zero, the value is the first 1 bit we find
9985 if ((val
& 0x80000000) == 0)
9987 gcc_assert (val
& 0xffffffff);
9990 while (((val
<<= 1) & 0x80000000) == 0)
9995 /* If the high bit is set and the low bit is not, or the mask is all
9996 1's, the value is zero. */
9997 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
10000 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10003 while (((val
>>= 1) & 1) != 0)
10010 extract_ME (rtx op
)
10013 unsigned long val
= INT_LOWPART (op
);
10015 /* If the low bit is zero, the value is the first 1 bit we find from
10017 if ((val
& 1) == 0)
10019 gcc_assert (val
& 0xffffffff);
10022 while (((val
>>= 1) & 1) == 0)
10028 /* If the low bit is set and the high bit is not, or the mask is all
10029 1's, the value is 31. */
10030 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
10033 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10036 while (((val
<<= 1) & 0x80000000) != 0)
10042 /* Locate some local-dynamic symbol still in use by this function
10043 so that we can print its name in some tls_ld pattern. */
10045 static const char *
10046 rs6000_get_some_local_dynamic_name (void)
10050 if (cfun
->machine
->some_ld_name
)
10051 return cfun
->machine
->some_ld_name
;
10053 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10055 && for_each_rtx (&PATTERN (insn
),
10056 rs6000_get_some_local_dynamic_name_1
, 0))
10057 return cfun
->machine
->some_ld_name
;
10059 gcc_unreachable ();
10062 /* Helper function for rs6000_get_some_local_dynamic_name. */
10065 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
10069 if (GET_CODE (x
) == SYMBOL_REF
)
10071 const char *str
= XSTR (x
, 0);
10072 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
10074 cfun
->machine
->some_ld_name
= str
;
10082 /* Write out a function code label. */
10085 rs6000_output_function_entry (FILE *file
, const char *fname
)
10087 if (fname
[0] != '.')
10089 switch (DEFAULT_ABI
)
10092 gcc_unreachable ();
10098 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
10107 RS6000_OUTPUT_BASENAME (file
, fname
);
10109 assemble_name (file
, fname
);
10112 /* Print an operand. Recognize special options, documented below. */
10115 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10116 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10118 #define SMALL_DATA_RELOC "sda21"
10119 #define SMALL_DATA_REG 0
10123 print_operand (FILE *file
, rtx x
, int code
)
10127 unsigned HOST_WIDE_INT uval
;
10132 /* Write out an instruction after the call which may be replaced
10133 with glue code by the loader. This depends on the AIX version. */
10134 asm_fprintf (file
, RS6000_CALL_GLUE
);
10137 /* %a is output_address. */
10140 /* If X is a constant integer whose low-order 5 bits are zero,
10141 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10142 in the AIX assembler where "sri" with a zero shift count
10143 writes a trash instruction. */
10144 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
10151 /* If constant, low-order 16 bits of constant, unsigned.
10152 Otherwise, write normally. */
10154 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
10156 print_operand (file
, x
, 0);
10160 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10161 for 64-bit mask direction. */
10162 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
10165 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10169 /* X is a CR register. Print the number of the GT bit of the CR. */
10170 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10171 output_operand_lossage ("invalid %%E value");
10173 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
10177 /* Like 'J' but get to the EQ bit. */
10178 gcc_assert (GET_CODE (x
) == REG
);
10180 /* Bit 1 is EQ bit. */
10181 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 2;
10183 fprintf (file
, "%d", i
);
10187 /* X is a CR register. Print the number of the EQ bit of the CR */
10188 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10189 output_operand_lossage ("invalid %%E value");
10191 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
10195 /* X is a CR register. Print the shift count needed to move it
10196 to the high-order four bits. */
10197 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10198 output_operand_lossage ("invalid %%f value");
10200 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
10204 /* Similar, but print the count for the rotate in the opposite
10206 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10207 output_operand_lossage ("invalid %%F value");
10209 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
10213 /* X is a constant integer. If it is negative, print "m",
10214 otherwise print "z". This is to make an aze or ame insn. */
10215 if (GET_CODE (x
) != CONST_INT
)
10216 output_operand_lossage ("invalid %%G value");
10217 else if (INTVAL (x
) >= 0)
10224 /* If constant, output low-order five bits. Otherwise, write
10227 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
10229 print_operand (file
, x
, 0);
10233 /* If constant, output low-order six bits. Otherwise, write
10236 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
10238 print_operand (file
, x
, 0);
10242 /* Print `i' if this is a constant, else nothing. */
10248 /* Write the bit number in CCR for jump. */
10249 i
= ccr_bit (x
, 0);
10251 output_operand_lossage ("invalid %%j code");
10253 fprintf (file
, "%d", i
);
10257 /* Similar, but add one for shift count in rlinm for scc and pass
10258 scc flag to `ccr_bit'. */
10259 i
= ccr_bit (x
, 1);
10261 output_operand_lossage ("invalid %%J code");
10263 /* If we want bit 31, write a shift count of zero, not 32. */
10264 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10268 /* X must be a constant. Write the 1's complement of the
10271 output_operand_lossage ("invalid %%k value");
10273 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
10277 /* X must be a symbolic constant on ELF. Write an
10278 expression suitable for an 'addi' that adds in the low 16
10279 bits of the MEM. */
10280 if (GET_CODE (x
) != CONST
)
10282 print_operand_address (file
, x
);
10283 fputs ("@l", file
);
10287 if (GET_CODE (XEXP (x
, 0)) != PLUS
10288 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
10289 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
10290 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
10291 output_operand_lossage ("invalid %%K value");
10292 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
10293 fputs ("@l", file
);
10294 /* For GNU as, there must be a non-alphanumeric character
10295 between 'l' and the number. The '-' is added by
10296 print_operand() already. */
10297 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
10299 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
10303 /* %l is output_asm_label. */
10306 /* Write second word of DImode or DFmode reference. Works on register
10307 or non-indexed memory only. */
10308 if (GET_CODE (x
) == REG
)
10309 fputs (reg_names
[REGNO (x
) + 1], file
);
10310 else if (GET_CODE (x
) == MEM
)
10312 /* Handle possible auto-increment. Since it is pre-increment and
10313 we have already done it, we can just use an offset of word. */
10314 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10315 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10316 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
10319 output_address (XEXP (adjust_address_nv (x
, SImode
,
10323 if (small_data_operand (x
, GET_MODE (x
)))
10324 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10325 reg_names
[SMALL_DATA_REG
]);
10330 /* MB value for a mask operand. */
10331 if (! mask_operand (x
, SImode
))
10332 output_operand_lossage ("invalid %%m value");
10334 fprintf (file
, "%d", extract_MB (x
));
10338 /* ME value for a mask operand. */
10339 if (! mask_operand (x
, SImode
))
10340 output_operand_lossage ("invalid %%M value");
10342 fprintf (file
, "%d", extract_ME (x
));
10345 /* %n outputs the negative of its operand. */
10348 /* Write the number of elements in the vector times 4. */
10349 if (GET_CODE (x
) != PARALLEL
)
10350 output_operand_lossage ("invalid %%N value");
10352 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
10356 /* Similar, but subtract 1 first. */
10357 if (GET_CODE (x
) != PARALLEL
)
10358 output_operand_lossage ("invalid %%O value");
10360 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
10364 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10366 || INT_LOWPART (x
) < 0
10367 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
10368 output_operand_lossage ("invalid %%p value");
10370 fprintf (file
, "%d", i
);
10374 /* The operand must be an indirect memory reference. The result
10375 is the register name. */
10376 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
10377 || REGNO (XEXP (x
, 0)) >= 32)
10378 output_operand_lossage ("invalid %%P value");
10380 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
10384 /* This outputs the logical code corresponding to a boolean
10385 expression. The expression may have one or both operands
10386 negated (if one, only the first one). For condition register
10387 logical operations, it will also treat the negated
10388 CR codes as NOTs, but not handle NOTs of them. */
10390 const char *const *t
= 0;
10392 enum rtx_code code
= GET_CODE (x
);
10393 static const char * const tbl
[3][3] = {
10394 { "and", "andc", "nor" },
10395 { "or", "orc", "nand" },
10396 { "xor", "eqv", "xor" } };
10400 else if (code
== IOR
)
10402 else if (code
== XOR
)
10405 output_operand_lossage ("invalid %%q value");
10407 if (GET_CODE (XEXP (x
, 0)) != NOT
)
10411 if (GET_CODE (XEXP (x
, 1)) == NOT
)
10429 /* X is a CR register. Print the mask for `mtcrf'. */
10430 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10431 output_operand_lossage ("invalid %%R value");
10433 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
10437 /* Low 5 bits of 32 - value */
10439 output_operand_lossage ("invalid %%s value");
10441 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
10445 /* PowerPC64 mask position. All 0's is excluded.
10446 CONST_INT 32-bit mask is considered sign-extended so any
10447 transition must occur within the CONST_INT, not on the boundary. */
10448 if (! mask64_operand (x
, DImode
))
10449 output_operand_lossage ("invalid %%S value");
10451 uval
= INT_LOWPART (x
);
10453 if (uval
& 1) /* Clear Left */
10455 #if HOST_BITS_PER_WIDE_INT > 64
10456 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10460 else /* Clear Right */
10463 #if HOST_BITS_PER_WIDE_INT > 64
10464 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10470 gcc_assert (i
>= 0);
10471 fprintf (file
, "%d", i
);
10475 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10476 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
10478 /* Bit 3 is OV bit. */
10479 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
10481 /* If we want bit 31, write a shift count of zero, not 32. */
10482 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10486 /* Print the symbolic name of a branch target register. */
10487 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LINK_REGISTER_REGNUM
10488 && REGNO (x
) != COUNT_REGISTER_REGNUM
))
10489 output_operand_lossage ("invalid %%T value");
10490 else if (REGNO (x
) == LINK_REGISTER_REGNUM
)
10491 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
10493 fputs ("ctr", file
);
10497 /* High-order 16 bits of constant for use in unsigned operand. */
10499 output_operand_lossage ("invalid %%u value");
10501 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
10502 (INT_LOWPART (x
) >> 16) & 0xffff);
10506 /* High-order 16 bits of constant for use in signed operand. */
10508 output_operand_lossage ("invalid %%v value");
10510 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
10511 (INT_LOWPART (x
) >> 16) & 0xffff);
10515 /* Print `u' if this has an auto-increment or auto-decrement. */
10516 if (GET_CODE (x
) == MEM
10517 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
10518 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
))
10523 /* Print the trap code for this operand. */
10524 switch (GET_CODE (x
))
10527 fputs ("eq", file
); /* 4 */
10530 fputs ("ne", file
); /* 24 */
10533 fputs ("lt", file
); /* 16 */
10536 fputs ("le", file
); /* 20 */
10539 fputs ("gt", file
); /* 8 */
10542 fputs ("ge", file
); /* 12 */
10545 fputs ("llt", file
); /* 2 */
10548 fputs ("lle", file
); /* 6 */
10551 fputs ("lgt", file
); /* 1 */
10554 fputs ("lge", file
); /* 5 */
10557 gcc_unreachable ();
10562 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10565 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
10566 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
10568 print_operand (file
, x
, 0);
10572 /* MB value for a PowerPC64 rldic operand. */
10573 val
= (GET_CODE (x
) == CONST_INT
10574 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
10579 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
10580 if ((val
<<= 1) < 0)
10583 #if HOST_BITS_PER_WIDE_INT == 32
10584 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
10585 i
+= 32; /* zero-extend high-part was all 0's */
10586 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
10588 val
= CONST_DOUBLE_LOW (x
);
10594 for ( ; i
< 64; i
++)
10595 if ((val
<<= 1) < 0)
10600 fprintf (file
, "%d", i
+ 1);
10604 if (GET_CODE (x
) == MEM
10605 && legitimate_indexed_address_p (XEXP (x
, 0), 0))
10610 /* Like 'L', for third word of TImode */
10611 if (GET_CODE (x
) == REG
)
10612 fputs (reg_names
[REGNO (x
) + 2], file
);
10613 else if (GET_CODE (x
) == MEM
)
10615 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10616 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10617 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
10619 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
10620 if (small_data_operand (x
, GET_MODE (x
)))
10621 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10622 reg_names
[SMALL_DATA_REG
]);
10627 /* X is a SYMBOL_REF. Write out the name preceded by a
10628 period and without any trailing data in brackets. Used for function
10629 names. If we are configured for System V (or the embedded ABI) on
10630 the PowerPC, do not emit the period, since those systems do not use
10631 TOCs and the like. */
10632 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
10634 /* Mark the decl as referenced so that cgraph will output the
10636 if (SYMBOL_REF_DECL (x
))
10637 mark_decl_referenced (SYMBOL_REF_DECL (x
));
10639 /* For macho, check to see if we need a stub. */
10642 const char *name
= XSTR (x
, 0);
10644 if (MACHOPIC_INDIRECT
10645 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
10646 name
= machopic_indirection_name (x
, /*stub_p=*/true);
10648 assemble_name (file
, name
);
10650 else if (!DOT_SYMBOLS
)
10651 assemble_name (file
, XSTR (x
, 0));
10653 rs6000_output_function_entry (file
, XSTR (x
, 0));
10657 /* Like 'L', for last word of TImode. */
10658 if (GET_CODE (x
) == REG
)
10659 fputs (reg_names
[REGNO (x
) + 3], file
);
10660 else if (GET_CODE (x
) == MEM
)
10662 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10663 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10664 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
10666 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
10667 if (small_data_operand (x
, GET_MODE (x
)))
10668 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10669 reg_names
[SMALL_DATA_REG
]);
10673 /* Print AltiVec or SPE memory operand. */
10678 gcc_assert (GET_CODE (x
) == MEM
);
10684 /* Handle [reg]. */
10685 if (GET_CODE (tmp
) == REG
)
10687 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
10690 /* Handle [reg+UIMM]. */
10691 else if (GET_CODE (tmp
) == PLUS
&&
10692 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
10696 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
10698 x
= INTVAL (XEXP (tmp
, 1));
10699 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
10703 /* Fall through. Must be [reg+reg]. */
10706 && GET_CODE (tmp
) == AND
10707 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
10708 && INTVAL (XEXP (tmp
, 1)) == -16)
10709 tmp
= XEXP (tmp
, 0);
10710 if (GET_CODE (tmp
) == REG
)
10711 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
10714 gcc_assert (GET_CODE (tmp
) == PLUS
10715 && REG_P (XEXP (tmp
, 0))
10716 && REG_P (XEXP (tmp
, 1)));
10718 if (REGNO (XEXP (tmp
, 0)) == 0)
10719 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
10720 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
10722 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
10723 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
10729 if (GET_CODE (x
) == REG
)
10730 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
10731 else if (GET_CODE (x
) == MEM
)
10733 /* We need to handle PRE_INC and PRE_DEC here, since we need to
10734 know the width from the mode. */
10735 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
10736 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
10737 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
10738 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10739 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
10740 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
10742 output_address (XEXP (x
, 0));
10745 output_addr_const (file
, x
);
10749 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
10753 output_operand_lossage ("invalid %%xn code");
10757 /* Print the address of an operand. */
10760 print_operand_address (FILE *file
, rtx x
)
10762 if (GET_CODE (x
) == REG
)
10763 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
10764 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
10765 || GET_CODE (x
) == LABEL_REF
)
10767 output_addr_const (file
, x
);
10768 if (small_data_operand (x
, GET_MODE (x
)))
10769 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10770 reg_names
[SMALL_DATA_REG
]);
10772 gcc_assert (!TARGET_TOC
);
10774 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
10776 gcc_assert (REG_P (XEXP (x
, 0)));
10777 if (REGNO (XEXP (x
, 0)) == 0)
10778 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
10779 reg_names
[ REGNO (XEXP (x
, 0)) ]);
10781 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
10782 reg_names
[ REGNO (XEXP (x
, 1)) ]);
10784 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
10785 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
10786 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
10788 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
10789 && CONSTANT_P (XEXP (x
, 1)))
10791 output_addr_const (file
, XEXP (x
, 1));
10792 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
10796 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
10797 && CONSTANT_P (XEXP (x
, 1)))
10799 fprintf (file
, "lo16(");
10800 output_addr_const (file
, XEXP (x
, 1));
10801 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
10804 else if (legitimate_constant_pool_address_p (x
))
10806 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
10808 rtx contains_minus
= XEXP (x
, 1);
10812 /* Find the (minus (sym) (toc)) buried in X, and temporarily
10813 turn it into (sym) for output_addr_const. */
10814 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
10815 contains_minus
= XEXP (contains_minus
, 0);
10817 minus
= XEXP (contains_minus
, 0);
10818 symref
= XEXP (minus
, 0);
10819 XEXP (contains_minus
, 0) = symref
;
10824 name
= XSTR (symref
, 0);
10825 newname
= alloca (strlen (name
) + sizeof ("@toc"));
10826 strcpy (newname
, name
);
10827 strcat (newname
, "@toc");
10828 XSTR (symref
, 0) = newname
;
10830 output_addr_const (file
, XEXP (x
, 1));
10832 XSTR (symref
, 0) = name
;
10833 XEXP (contains_minus
, 0) = minus
;
10836 output_addr_const (file
, XEXP (x
, 1));
10838 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
10841 gcc_unreachable ();
10844 /* Target hook for assembling integer objects. The PowerPC version has
10845 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
10846 is defined. It also needs to handle DI-mode objects on 64-bit
10850 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
10852 #ifdef RELOCATABLE_NEEDS_FIXUP
10853 /* Special handling for SI values. */
10854 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
10856 static int recurse
= 0;
10858 /* For -mrelocatable, we mark all addresses that need to be fixed up
10859 in the .fixup section. */
10860 if (TARGET_RELOCATABLE
10861 && in_section
!= toc_section
10862 && in_section
!= text_section
10863 && !unlikely_text_section_p (in_section
)
10865 && GET_CODE (x
) != CONST_INT
10866 && GET_CODE (x
) != CONST_DOUBLE
10872 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
10874 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
10875 fprintf (asm_out_file
, "\t.long\t(");
10876 output_addr_const (asm_out_file
, x
);
10877 fprintf (asm_out_file
, ")@fixup\n");
10878 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
10879 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
10880 fprintf (asm_out_file
, "\t.long\t");
10881 assemble_name (asm_out_file
, buf
);
10882 fprintf (asm_out_file
, "\n\t.previous\n");
10886 /* Remove initial .'s to turn a -mcall-aixdesc function
10887 address into the address of the descriptor, not the function
10889 else if (GET_CODE (x
) == SYMBOL_REF
10890 && XSTR (x
, 0)[0] == '.'
10891 && DEFAULT_ABI
== ABI_AIX
)
10893 const char *name
= XSTR (x
, 0);
10894 while (*name
== '.')
10897 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
10901 #endif /* RELOCATABLE_NEEDS_FIXUP */
10902 return default_assemble_integer (x
, size
, aligned_p
);
10905 #ifdef HAVE_GAS_HIDDEN
10906 /* Emit an assembler directive to set symbol visibility for DECL to
10907 VISIBILITY_TYPE. */
10910 rs6000_assemble_visibility (tree decl
, int vis
)
10912 /* Functions need to have their entry point symbol visibility set as
10913 well as their descriptor symbol visibility. */
10914 if (DEFAULT_ABI
== ABI_AIX
10916 && TREE_CODE (decl
) == FUNCTION_DECL
)
10918 static const char * const visibility_types
[] = {
10919 NULL
, "internal", "hidden", "protected"
10922 const char *name
, *type
;
10924 name
= ((* targetm
.strip_name_encoding
)
10925 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
10926 type
= visibility_types
[vis
];
10928 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
10929 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
10932 default_assemble_visibility (decl
, vis
);
10937 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
10939 /* Reversal of FP compares takes care -- an ordered compare
10940 becomes an unordered compare and vice versa. */
10941 if (mode
== CCFPmode
10942 && (!flag_finite_math_only
10943 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
10944 || code
== UNEQ
|| code
== LTGT
))
10945 return reverse_condition_maybe_unordered (code
);
10947 return reverse_condition (code
);
10950 /* Generate a compare for CODE. Return a brand-new rtx that
10951 represents the result of the compare. */
10954 rs6000_generate_compare (enum rtx_code code
)
10956 enum machine_mode comp_mode
;
10957 rtx compare_result
;
10959 if (rs6000_compare_fp_p
)
10960 comp_mode
= CCFPmode
;
10961 else if (code
== GTU
|| code
== LTU
10962 || code
== GEU
|| code
== LEU
)
10963 comp_mode
= CCUNSmode
;
10964 else if ((code
== EQ
|| code
== NE
)
10965 && GET_CODE (rs6000_compare_op0
) == SUBREG
10966 && GET_CODE (rs6000_compare_op1
) == SUBREG
10967 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
10968 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
10969 /* These are unsigned values, perhaps there will be a later
10970 ordering compare that can be shared with this one.
10971 Unfortunately we cannot detect the signedness of the operands
10972 for non-subregs. */
10973 comp_mode
= CCUNSmode
;
10975 comp_mode
= CCmode
;
10977 /* First, the compare. */
10978 compare_result
= gen_reg_rtx (comp_mode
);
10980 /* SPE FP compare instructions on the GPRs. Yuck! */
10981 if ((TARGET_E500
&& !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
10982 && rs6000_compare_fp_p
)
10984 rtx cmp
, or_result
, compare_result2
;
10985 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
10987 if (op_mode
== VOIDmode
)
10988 op_mode
= GET_MODE (rs6000_compare_op1
);
10990 /* Note: The E500 comparison instructions set the GT bit (x +
10991 1), on success. This explains the mess. */
10995 case EQ
: case UNEQ
: case NE
: case LTGT
:
10999 cmp
= flag_unsafe_math_optimizations
11000 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
11001 rs6000_compare_op1
)
11002 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
11003 rs6000_compare_op1
);
11007 cmp
= flag_unsafe_math_optimizations
11008 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
11009 rs6000_compare_op1
)
11010 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
11011 rs6000_compare_op1
);
11015 gcc_unreachable ();
11019 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
11023 cmp
= flag_unsafe_math_optimizations
11024 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
11025 rs6000_compare_op1
)
11026 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
11027 rs6000_compare_op1
);
11031 cmp
= flag_unsafe_math_optimizations
11032 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
11033 rs6000_compare_op1
)
11034 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
11035 rs6000_compare_op1
);
11039 gcc_unreachable ();
11043 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
11047 cmp
= flag_unsafe_math_optimizations
11048 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
11049 rs6000_compare_op1
)
11050 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
11051 rs6000_compare_op1
);
11055 cmp
= flag_unsafe_math_optimizations
11056 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
11057 rs6000_compare_op1
)
11058 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
11059 rs6000_compare_op1
);
11063 gcc_unreachable ();
11067 gcc_unreachable ();
11070 /* Synthesize LE and GE from LT/GT || EQ. */
11071 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
11077 case LE
: code
= LT
; break;
11078 case GE
: code
= GT
; break;
11079 case LEU
: code
= LT
; break;
11080 case GEU
: code
= GT
; break;
11081 default: gcc_unreachable ();
11084 compare_result2
= gen_reg_rtx (CCFPmode
);
11090 cmp
= flag_unsafe_math_optimizations
11091 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11092 rs6000_compare_op1
)
11093 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11094 rs6000_compare_op1
);
11098 cmp
= flag_unsafe_math_optimizations
11099 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11100 rs6000_compare_op1
)
11101 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11102 rs6000_compare_op1
);
11106 gcc_unreachable ();
11110 /* OR them together. */
11111 or_result
= gen_reg_rtx (CCFPmode
);
11112 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
11114 compare_result
= or_result
;
11119 if (code
== NE
|| code
== LTGT
)
11129 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11130 CLOBBERs to match cmptf_internal2 pattern. */
11131 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
11132 && GET_MODE (rs6000_compare_op0
) == TFmode
11133 && !TARGET_IEEEQUAD
11134 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
11135 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
11137 gen_rtx_SET (VOIDmode
,
11139 gen_rtx_COMPARE (comp_mode
,
11140 rs6000_compare_op0
,
11141 rs6000_compare_op1
)),
11142 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11143 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11144 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11145 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11146 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11147 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11148 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11149 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
11150 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
11151 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
11153 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
11154 comp_mode
= CCEQmode
;
11155 compare_result
= gen_reg_rtx (CCEQmode
);
11157 emit_insn (gen_stack_protect_testdi (compare_result
,
11158 rs6000_compare_op0
, op1
));
11160 emit_insn (gen_stack_protect_testsi (compare_result
,
11161 rs6000_compare_op0
, op1
));
11164 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
11165 gen_rtx_COMPARE (comp_mode
,
11166 rs6000_compare_op0
,
11167 rs6000_compare_op1
)));
11170 /* Some kinds of FP comparisons need an OR operation;
11171 under flag_finite_math_only we don't bother. */
11172 if (rs6000_compare_fp_p
11173 && !flag_finite_math_only
11174 && !(TARGET_HARD_FLOAT
&& TARGET_E500
&& !TARGET_FPRS
)
11175 && (code
== LE
|| code
== GE
11176 || code
== UNEQ
|| code
== LTGT
11177 || code
== UNGT
|| code
== UNLT
))
11179 enum rtx_code or1
, or2
;
11180 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
11181 rtx or_result
= gen_reg_rtx (CCEQmode
);
11185 case LE
: or1
= LT
; or2
= EQ
; break;
11186 case GE
: or1
= GT
; or2
= EQ
; break;
11187 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
11188 case LTGT
: or1
= LT
; or2
= GT
; break;
11189 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
11190 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
11191 default: gcc_unreachable ();
11193 validate_condition_mode (or1
, comp_mode
);
11194 validate_condition_mode (or2
, comp_mode
);
11195 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
11196 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
11197 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
11198 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
11200 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
11202 compare_result
= or_result
;
11206 validate_condition_mode (code
, GET_MODE (compare_result
));
11208 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
11212 /* Emit the RTL for an sCOND pattern. */
11215 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
11218 enum machine_mode op_mode
;
11219 enum rtx_code cond_code
;
11221 condition_rtx
= rs6000_generate_compare (code
);
11222 cond_code
= GET_CODE (condition_rtx
);
11224 if (TARGET_E500
&& rs6000_compare_fp_p
11225 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
11229 PUT_MODE (condition_rtx
, SImode
);
11230 t
= XEXP (condition_rtx
, 0);
11232 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
11234 if (cond_code
== NE
)
11235 emit_insn (gen_e500_flip_gt_bit (t
, t
));
11237 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
11241 if (cond_code
== NE
11242 || cond_code
== GE
|| cond_code
== LE
11243 || cond_code
== GEU
|| cond_code
== LEU
11244 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
11246 rtx not_result
= gen_reg_rtx (CCEQmode
);
11247 rtx not_op
, rev_cond_rtx
;
11248 enum machine_mode cc_mode
;
11250 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
11252 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
11253 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
11254 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
11255 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
11256 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
11259 op_mode
= GET_MODE (rs6000_compare_op0
);
11260 if (op_mode
== VOIDmode
)
11261 op_mode
= GET_MODE (rs6000_compare_op1
);
11263 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
11265 PUT_MODE (condition_rtx
, DImode
);
11266 convert_move (result
, condition_rtx
, 0);
11270 PUT_MODE (condition_rtx
, SImode
);
11271 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
11275 /* Emit a branch of kind CODE to location LOC. */
11278 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
11280 rtx condition_rtx
, loc_ref
;
11282 condition_rtx
= rs6000_generate_compare (code
);
11283 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
11284 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
11285 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
11286 loc_ref
, pc_rtx
)));
11289 /* Return the string to output a conditional branch to LABEL, which is
11290 the operand number of the label, or -1 if the branch is really a
11291 conditional return.
11293 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11294 condition code register and its mode specifies what kind of
11295 comparison we made.
11297 REVERSED is nonzero if we should reverse the sense of the comparison.
11299 INSN is the insn. */
11302 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
11304 static char string
[64];
11305 enum rtx_code code
= GET_CODE (op
);
11306 rtx cc_reg
= XEXP (op
, 0);
11307 enum machine_mode mode
= GET_MODE (cc_reg
);
11308 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
11309 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
11310 int really_reversed
= reversed
^ need_longbranch
;
11316 validate_condition_mode (code
, mode
);
11318 /* Work out which way this really branches. We could use
11319 reverse_condition_maybe_unordered here always but this
11320 makes the resulting assembler clearer. */
11321 if (really_reversed
)
11323 /* Reversal of FP compares takes care -- an ordered compare
11324 becomes an unordered compare and vice versa. */
11325 if (mode
== CCFPmode
)
11326 code
= reverse_condition_maybe_unordered (code
);
11328 code
= reverse_condition (code
);
11331 if ((TARGET_E500
&& !TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
11333 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11338 /* Opposite of GT. */
11347 gcc_unreachable ();
11353 /* Not all of these are actually distinct opcodes, but
11354 we distinguish them for clarity of the resulting assembler. */
11355 case NE
: case LTGT
:
11356 ccode
= "ne"; break;
11357 case EQ
: case UNEQ
:
11358 ccode
= "eq"; break;
11360 ccode
= "ge"; break;
11361 case GT
: case GTU
: case UNGT
:
11362 ccode
= "gt"; break;
11364 ccode
= "le"; break;
11365 case LT
: case LTU
: case UNLT
:
11366 ccode
= "lt"; break;
11367 case UNORDERED
: ccode
= "un"; break;
11368 case ORDERED
: ccode
= "nu"; break;
11369 case UNGE
: ccode
= "nl"; break;
11370 case UNLE
: ccode
= "ng"; break;
11372 gcc_unreachable ();
11375 /* Maybe we have a guess as to how likely the branch is.
11376 The old mnemonics don't have a way to specify this information. */
11378 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
11379 if (note
!= NULL_RTX
)
11381 /* PROB is the difference from 50%. */
11382 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
11384 /* Only hint for highly probable/improbable branches on newer
11385 cpus as static prediction overrides processor dynamic
11386 prediction. For older cpus we may as well always hint, but
11387 assume not taken for branches that are very close to 50% as a
11388 mispredicted taken branch is more expensive than a
11389 mispredicted not-taken branch. */
11390 if (rs6000_always_hint
11391 || abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48)
11393 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
11394 && ((prob
> 0) ^ need_longbranch
))
11402 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
11404 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
11406 /* We need to escape any '%' characters in the reg_names string.
11407 Assume they'd only be the first character.... */
11408 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
11410 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
11414 /* If the branch distance was too far, we may have to use an
11415 unconditional branch to go the distance. */
11416 if (need_longbranch
)
11417 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
11419 s
+= sprintf (s
, ",%s", label
);
11425 /* Return the string to flip the GT bit on a CR. */
11427 output_e500_flip_gt_bit (rtx dst
, rtx src
)
11429 static char string
[64];
11432 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
11433 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
11436 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
11437 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
11439 sprintf (string
, "crnot %d,%d", a
, b
);
11443 /* Return insn index for the vector compare instruction for given CODE,
11444 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11448 get_vec_cmp_insn (enum rtx_code code
,
11449 enum machine_mode dest_mode
,
11450 enum machine_mode op_mode
)
11452 if (!TARGET_ALTIVEC
)
11453 return INSN_NOT_AVAILABLE
;
11458 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11459 return UNSPEC_VCMPEQUB
;
11460 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11461 return UNSPEC_VCMPEQUH
;
11462 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11463 return UNSPEC_VCMPEQUW
;
11464 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11465 return UNSPEC_VCMPEQFP
;
11468 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11469 return UNSPEC_VCMPGEFP
;
11471 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11472 return UNSPEC_VCMPGTSB
;
11473 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11474 return UNSPEC_VCMPGTSH
;
11475 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11476 return UNSPEC_VCMPGTSW
;
11477 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11478 return UNSPEC_VCMPGTFP
;
11481 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11482 return UNSPEC_VCMPGTUB
;
11483 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11484 return UNSPEC_VCMPGTUH
;
11485 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11486 return UNSPEC_VCMPGTUW
;
11491 return INSN_NOT_AVAILABLE
;
11494 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11495 DMODE is expected destination mode. This is a recursive function. */
11498 rs6000_emit_vector_compare (enum rtx_code rcode
,
11500 enum machine_mode dmode
)
11504 enum machine_mode dest_mode
;
11505 enum machine_mode op_mode
= GET_MODE (op1
);
11507 gcc_assert (TARGET_ALTIVEC
);
11508 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
11510 /* Floating point vector compare instructions uses destination V4SImode.
11511 Move destination to appropriate mode later. */
11512 if (dmode
== V4SFmode
)
11513 dest_mode
= V4SImode
;
11517 mask
= gen_reg_rtx (dest_mode
);
11518 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
11520 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
11522 bool swap_operands
= false;
11523 bool try_again
= false;
11528 swap_operands
= true;
11533 swap_operands
= true;
11537 /* Treat A != B as ~(A==B). */
11539 enum insn_code nor_code
;
11540 rtx eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
11543 nor_code
= one_cmpl_optab
->handlers
[(int)dest_mode
].insn_code
;
11544 gcc_assert (nor_code
!= CODE_FOR_nothing
);
11545 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
11547 if (dmode
!= dest_mode
)
11549 rtx temp
= gen_reg_rtx (dest_mode
);
11550 convert_move (temp
, mask
, 0);
11560 /* Try GT/GTU/LT/LTU OR EQ */
11563 enum insn_code ior_code
;
11564 enum rtx_code new_code
;
11585 gcc_unreachable ();
11588 c_rtx
= rs6000_emit_vector_compare (new_code
,
11589 op0
, op1
, dest_mode
);
11590 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
11593 ior_code
= ior_optab
->handlers
[(int)dest_mode
].insn_code
;
11594 gcc_assert (ior_code
!= CODE_FOR_nothing
);
11595 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
11596 if (dmode
!= dest_mode
)
11598 rtx temp
= gen_reg_rtx (dest_mode
);
11599 convert_move (temp
, mask
, 0);
11606 gcc_unreachable ();
11611 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
11612 /* You only get two chances. */
11613 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
11625 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
11626 gen_rtx_UNSPEC (dest_mode
,
11627 gen_rtvec (2, op0
, op1
),
11629 if (dmode
!= dest_mode
)
11631 rtx temp
= gen_reg_rtx (dest_mode
);
11632 convert_move (temp
, mask
, 0);
11638 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
11639 valid insn doesn exist for given mode. */
11642 get_vsel_insn (enum machine_mode mode
)
11647 return UNSPEC_VSEL4SI
;
11650 return UNSPEC_VSEL4SF
;
11653 return UNSPEC_VSEL8HI
;
11656 return UNSPEC_VSEL16QI
;
11659 return INSN_NOT_AVAILABLE
;
11662 return INSN_NOT_AVAILABLE
;
11665 /* Emit vector select insn where DEST is destination using
11666 operands OP1, OP2 and MASK. */
11669 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
11672 enum machine_mode dest_mode
= GET_MODE (dest
);
11673 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
11675 temp
= gen_reg_rtx (dest_mode
);
11677 /* For each vector element, select op1 when mask is 1 otherwise
11679 t
= gen_rtx_SET (VOIDmode
, temp
,
11680 gen_rtx_UNSPEC (dest_mode
,
11681 gen_rtvec (3, op2
, op1
, mask
),
11684 emit_move_insn (dest
, temp
);
11688 /* Emit vector conditional expression.
11689 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
11690 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
11693 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
11694 rtx cond
, rtx cc_op0
, rtx cc_op1
)
11696 enum machine_mode dest_mode
= GET_MODE (dest
);
11697 enum rtx_code rcode
= GET_CODE (cond
);
11700 if (!TARGET_ALTIVEC
)
11703 /* Get the vector mask for the given relational operations. */
11704 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
11706 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
11711 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
11712 operands of the last comparison is nonzero/true, FALSE_COND if it
11713 is zero/false. Return 0 if the hardware has no such operation. */
11716 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
11718 enum rtx_code code
= GET_CODE (op
);
11719 rtx op0
= rs6000_compare_op0
;
11720 rtx op1
= rs6000_compare_op1
;
11721 REAL_VALUE_TYPE c1
;
11722 enum machine_mode compare_mode
= GET_MODE (op0
);
11723 enum machine_mode result_mode
= GET_MODE (dest
);
11725 bool is_against_zero
;
11727 /* These modes should always match. */
11728 if (GET_MODE (op1
) != compare_mode
11729 /* In the isel case however, we can use a compare immediate, so
11730 op1 may be a small constant. */
11731 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
11733 if (GET_MODE (true_cond
) != result_mode
)
11735 if (GET_MODE (false_cond
) != result_mode
)
11738 /* First, work out if the hardware can do this at all, or
11739 if it's too slow.... */
11740 if (! rs6000_compare_fp_p
)
11743 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
11746 else if (TARGET_E500
&& TARGET_HARD_FLOAT
&& !TARGET_FPRS
11747 && SCALAR_FLOAT_MODE_P (compare_mode
))
11750 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
11752 /* A floating-point subtract might overflow, underflow, or produce
11753 an inexact result, thus changing the floating-point flags, so it
11754 can't be generated if we care about that. It's safe if one side
11755 of the construct is zero, since then no subtract will be
11757 if (SCALAR_FLOAT_MODE_P (compare_mode
)
11758 && flag_trapping_math
&& ! is_against_zero
)
11761 /* Eliminate half of the comparisons by switching operands, this
11762 makes the remaining code simpler. */
11763 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
11764 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
11766 code
= reverse_condition_maybe_unordered (code
);
11768 true_cond
= false_cond
;
11772 /* UNEQ and LTGT take four instructions for a comparison with zero,
11773 it'll probably be faster to use a branch here too. */
11774 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
11777 if (GET_CODE (op1
) == CONST_DOUBLE
)
11778 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
11780 /* We're going to try to implement comparisons by performing
11781 a subtract, then comparing against zero. Unfortunately,
11782 Inf - Inf is NaN which is not zero, and so if we don't
11783 know that the operand is finite and the comparison
11784 would treat EQ different to UNORDERED, we can't do it. */
11785 if (HONOR_INFINITIES (compare_mode
)
11786 && code
!= GT
&& code
!= UNGE
11787 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
11788 /* Constructs of the form (a OP b ? a : b) are safe. */
11789 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
11790 || (! rtx_equal_p (op0
, true_cond
)
11791 && ! rtx_equal_p (op1
, true_cond
))))
11794 /* At this point we know we can use fsel. */
11796 /* Reduce the comparison to a comparison against zero. */
11797 if (! is_against_zero
)
11799 temp
= gen_reg_rtx (compare_mode
);
11800 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11801 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
11803 op1
= CONST0_RTX (compare_mode
);
11806 /* If we don't care about NaNs we can reduce some of the comparisons
11807 down to faster ones. */
11808 if (! HONOR_NANS (compare_mode
))
11814 true_cond
= false_cond
;
11827 /* Now, reduce everything down to a GE. */
11834 temp
= gen_reg_rtx (compare_mode
);
11835 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11840 temp
= gen_reg_rtx (compare_mode
);
11841 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
11846 temp
= gen_reg_rtx (compare_mode
);
11847 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11848 gen_rtx_NEG (compare_mode
,
11849 gen_rtx_ABS (compare_mode
, op0
))));
11854 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
11855 temp
= gen_reg_rtx (result_mode
);
11856 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11857 gen_rtx_IF_THEN_ELSE (result_mode
,
11858 gen_rtx_GE (VOIDmode
,
11860 true_cond
, false_cond
)));
11861 false_cond
= true_cond
;
11864 temp
= gen_reg_rtx (compare_mode
);
11865 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11870 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
11871 temp
= gen_reg_rtx (result_mode
);
11872 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
11873 gen_rtx_IF_THEN_ELSE (result_mode
,
11874 gen_rtx_GE (VOIDmode
,
11876 true_cond
, false_cond
)));
11877 true_cond
= false_cond
;
11880 temp
= gen_reg_rtx (compare_mode
);
11881 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
11886 gcc_unreachable ();
11889 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
11890 gen_rtx_IF_THEN_ELSE (result_mode
,
11891 gen_rtx_GE (VOIDmode
,
11893 true_cond
, false_cond
)));
11897 /* Same as above, but for ints (isel). */
11900 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
11902 rtx condition_rtx
, cr
;
11904 /* All isel implementations thus far are 32-bits. */
11905 if (GET_MODE (rs6000_compare_op0
) != SImode
)
11908 /* We still have to do the compare, because isel doesn't do a
11909 compare, it just looks at the CRx bits set by a previous compare
11911 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
11912 cr
= XEXP (condition_rtx
, 0);
11914 if (GET_MODE (cr
) == CCmode
)
11915 emit_insn (gen_isel_signed (dest
, condition_rtx
,
11916 true_cond
, false_cond
, cr
));
11918 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
11919 true_cond
, false_cond
, cr
));
11925 output_isel (rtx
*operands
)
11927 enum rtx_code code
;
11929 code
= GET_CODE (operands
[1]);
11930 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
11932 PUT_CODE (operands
[1], reverse_condition (code
));
11933 return "isel %0,%3,%2,%j1";
11936 return "isel %0,%2,%3,%j1";
11940 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
11942 enum machine_mode mode
= GET_MODE (op0
);
11946 if (code
== SMAX
|| code
== SMIN
)
11951 if (code
== SMAX
|| code
== UMAX
)
11952 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
11953 op0
, op1
, mode
, 0);
11955 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
11956 op1
, op0
, mode
, 0);
11957 gcc_assert (target
);
11958 if (target
!= dest
)
11959 emit_move_insn (dest
, target
);
11962 /* Emit instructions to perform a load-reserved/store-conditional operation.
11963 The operation performed is an atomic
11964 (set M (CODE:MODE M OP))
11965 If not NULL, BEFORE is atomically set to M before the operation, and
11966 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
11967 If SYNC_P then a memory barrier is emitted before the operation.
11968 Either OP or M may be wrapped in a NOT operation. */
11971 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
11972 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
11975 enum machine_mode used_mode
;
11976 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
11979 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
11980 rtx shift
= NULL_RTX
;
11983 emit_insn (gen_memory_barrier ());
11985 if (GET_CODE (m
) == NOT
)
11986 used_m
= XEXP (m
, 0);
11990 /* If this is smaller than SImode, we'll have to use SImode with
11992 if (mode
== QImode
|| mode
== HImode
)
11996 if (MEM_ALIGN (used_m
) >= 32)
11999 if (BYTES_BIG_ENDIAN
)
12000 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
12002 shift
= GEN_INT (ishift
);
12006 rtx addrSI
, aligned_addr
;
12007 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
12009 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
,
12010 XEXP (used_m
, 0)));
12011 shift
= gen_reg_rtx (SImode
);
12013 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
12014 GEN_INT (shift_mask
)));
12015 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
12017 aligned_addr
= expand_binop (Pmode
, and_optab
,
12019 GEN_INT (-4), NULL_RTX
,
12020 1, OPTAB_LIB_WIDEN
);
12021 used_m
= change_address (used_m
, SImode
, aligned_addr
);
12022 set_mem_align (used_m
, 32);
12023 /* It's safe to keep the old alias set of USED_M, because
12024 the operation is atomic and only affects the original
12026 if (GET_CODE (m
) == NOT
)
12027 m
= gen_rtx_NOT (SImode
, used_m
);
12032 if (GET_CODE (op
) == NOT
)
12034 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
12035 oldop
= gen_rtx_NOT (SImode
, oldop
);
12038 oldop
= lowpart_subreg (SImode
, op
, mode
);
12044 newop
= expand_binop (SImode
, and_optab
,
12045 oldop
, GEN_INT (imask
), NULL_RTX
,
12046 1, OPTAB_LIB_WIDEN
);
12047 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12051 newop
= expand_binop (SImode
, ior_optab
,
12052 oldop
, GEN_INT (~imask
), NULL_RTX
,
12053 1, OPTAB_LIB_WIDEN
);
12054 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
12062 newop
= expand_binop (SImode
, and_optab
,
12063 oldop
, GEN_INT (imask
), NULL_RTX
,
12064 1, OPTAB_LIB_WIDEN
);
12065 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12067 mask
= gen_reg_rtx (SImode
);
12068 emit_move_insn (mask
, GEN_INT (imask
));
12069 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12072 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
12074 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
12075 newop
= gen_rtx_AND (SImode
, newop
, mask
);
12076 newop
= gen_rtx_IOR (SImode
, newop
,
12077 gen_rtx_AND (SImode
,
12078 gen_rtx_NOT (SImode
, mask
),
12084 gcc_unreachable ();
12087 if (GET_CODE (m
) == NOT
)
12091 mask
= gen_reg_rtx (SImode
);
12092 emit_move_insn (mask
, GEN_INT (imask
));
12093 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12095 xorm
= gen_rtx_XOR (SImode
, used_m
, mask
);
12096 /* Depending on the value of 'op', the XOR or the operation might
12097 be able to be simplified away. */
12098 newop
= simplify_gen_binary (code
, SImode
, xorm
, newop
);
12101 used_mode
= SImode
;
12102 before
= gen_reg_rtx (used_mode
);
12103 after
= gen_reg_rtx (used_mode
);
12108 before
= before_param
;
12109 after
= after_param
;
12111 if (before
== NULL_RTX
)
12112 before
= gen_reg_rtx (used_mode
);
12113 if (after
== NULL_RTX
)
12114 after
= gen_reg_rtx (used_mode
);
12117 if ((code
== PLUS
|| code
== MINUS
|| GET_CODE (m
) == NOT
)
12118 && used_mode
!= mode
)
12119 the_op
= op
; /* Computed above. */
12120 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
12121 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
12123 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
12125 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
12126 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
12127 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
12128 gen_rtx_UNSPEC (used_mode
,
12129 gen_rtvec (1, the_op
),
12131 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
12133 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
12134 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
12135 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
12137 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
12138 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
12140 /* Shift and mask the return values properly. */
12141 if (used_mode
!= mode
&& before_param
)
12143 emit_insn (gen_lshrsi3 (before
, before
, shift
));
12144 convert_move (before_param
, before
, 1);
12147 if (used_mode
!= mode
&& after_param
)
12149 emit_insn (gen_lshrsi3 (after
, after
, shift
));
12150 convert_move (after_param
, after
, 1);
12153 /* The previous sequence will end with a branch that's dependent on
12154 the conditional store, so placing an isync will ensure that no
12155 other instructions (especially, no load or store instructions)
12156 can start before the atomic operation completes. */
12158 emit_insn (gen_isync ());
12161 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12162 COND is true. Mark the jump as unlikely to be taken. */
12165 emit_unlikely_jump (rtx cond
, rtx label
)
12167 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
12170 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
12171 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
12172 REG_NOTES (x
) = gen_rtx_EXPR_LIST (REG_BR_PROB
, very_unlikely
, NULL_RTX
);
12175 /* A subroutine of the atomic operation splitters. Emit a load-locked
12176 instruction in MODE. */
12179 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
12181 rtx (*fn
) (rtx
, rtx
) = NULL
;
12182 if (mode
== SImode
)
12183 fn
= gen_load_locked_si
;
12184 else if (mode
== DImode
)
12185 fn
= gen_load_locked_di
;
12186 emit_insn (fn (reg
, mem
));
12189 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12190 instruction in MODE. */
12193 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
12195 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
12196 if (mode
== SImode
)
12197 fn
= gen_store_conditional_si
;
12198 else if (mode
== DImode
)
12199 fn
= gen_store_conditional_di
;
12201 /* Emit sync before stwcx. to address PPC405 Erratum. */
12202 if (PPC405_ERRATUM77
)
12203 emit_insn (gen_memory_barrier ());
12205 emit_insn (fn (res
, mem
, val
));
12208 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12209 to perform. MEM is the memory on which to operate. VAL is the second
12210 operand of the binary operator. BEFORE and AFTER are optional locations to
12211 return the value of MEM either before of after the operation. SCRATCH is
12212 a scratch register. */
12215 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
12216 rtx before
, rtx after
, rtx scratch
)
12218 enum machine_mode mode
= GET_MODE (mem
);
12219 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12221 emit_insn (gen_memory_barrier ());
12223 label
= gen_label_rtx ();
12224 emit_label (label
);
12225 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
12227 if (before
== NULL_RTX
)
12229 emit_load_locked (mode
, before
, mem
);
12232 x
= gen_rtx_AND (mode
, gen_rtx_NOT (mode
, before
), val
);
12233 else if (code
== AND
)
12234 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
12236 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
12238 if (after
!= NULL_RTX
)
12239 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
12240 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
12242 emit_store_conditional (mode
, cond
, mem
, scratch
);
12244 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12245 emit_unlikely_jump (x
, label
);
12247 emit_insn (gen_isync ());
12250 /* Expand an atomic compare and swap operation. MEM is the memory on which
12251 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12252 value to be stored. SCRATCH is a scratch GPR. */
12255 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
12258 enum machine_mode mode
= GET_MODE (mem
);
12259 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12261 emit_insn (gen_memory_barrier ());
12263 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12264 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12265 emit_label (XEXP (label1
, 0));
12267 emit_load_locked (mode
, retval
, mem
);
12269 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
12270 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
12272 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12273 emit_unlikely_jump (x
, label2
);
12275 emit_move_insn (scratch
, newval
);
12276 emit_store_conditional (mode
, cond
, mem
, scratch
);
12278 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12279 emit_unlikely_jump (x
, label1
);
12281 emit_insn (gen_isync ());
12282 emit_label (XEXP (label2
, 0));
12285 /* Expand an atomic test and set operation. MEM is the memory on which
12286 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12289 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
12291 enum machine_mode mode
= GET_MODE (mem
);
12292 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12294 emit_insn (gen_memory_barrier ());
12296 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12297 emit_label (XEXP (label
, 0));
12299 emit_load_locked (mode
, retval
, mem
);
12300 emit_move_insn (scratch
, val
);
12301 emit_store_conditional (mode
, cond
, mem
, scratch
);
12303 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12304 emit_unlikely_jump (x
, label
);
12306 emit_insn (gen_isync ());
12310 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
12312 enum machine_mode mode
= GET_MODE (mem
);
12313 rtx addrSI
, align
, wdst
, shift
, mask
;
12314 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
12315 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
12317 /* Shift amount for subword relative to aligned word. */
12318 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, XEXP (mem
, 0)));
12319 shift
= gen_reg_rtx (SImode
);
12320 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
12321 GEN_INT (shift_mask
)));
12322 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
12324 /* Shift and mask old value into position within word. */
12325 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
12326 oldval
= expand_binop (SImode
, and_optab
,
12327 oldval
, GEN_INT (imask
), NULL_RTX
,
12328 1, OPTAB_LIB_WIDEN
);
12329 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
12331 /* Shift and mask new value into position within word. */
12332 newval
= convert_modes (SImode
, mode
, newval
, 1);
12333 newval
= expand_binop (SImode
, and_optab
,
12334 newval
, GEN_INT (imask
), NULL_RTX
,
12335 1, OPTAB_LIB_WIDEN
);
12336 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
12338 /* Mask for insertion. */
12339 mask
= gen_reg_rtx (SImode
);
12340 emit_move_insn (mask
, GEN_INT (imask
));
12341 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12343 /* Address of aligned word containing subword. */
12344 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
12345 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
12346 mem
= change_address (mem
, SImode
, align
);
12347 set_mem_align (mem
, 32);
12348 MEM_VOLATILE_P (mem
) = 1;
12350 wdst
= gen_reg_rtx (SImode
);
12351 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
12352 oldval
, newval
, mem
));
12354 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
12358 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
12359 rtx oldval
, rtx newval
, rtx mem
,
12362 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12364 emit_insn (gen_memory_barrier ());
12365 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12366 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12367 emit_label (XEXP (label1
, 0));
12369 emit_load_locked (SImode
, scratch
, mem
);
12371 /* Mask subword within loaded value for comparison with oldval.
12372 Use UNSPEC_AND to avoid clobber.*/
12373 emit_insn (gen_rtx_SET (SImode
, dest
,
12374 gen_rtx_UNSPEC (SImode
,
12375 gen_rtvec (2, scratch
, mask
),
12378 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
12379 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
12381 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12382 emit_unlikely_jump (x
, label2
);
12384 /* Clear subword within loaded value for insertion of new value. */
12385 emit_insn (gen_rtx_SET (SImode
, scratch
,
12386 gen_rtx_AND (SImode
,
12387 gen_rtx_NOT (SImode
, mask
), scratch
)));
12388 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
12389 emit_store_conditional (SImode
, cond
, mem
, scratch
);
12391 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12392 emit_unlikely_jump (x
, label1
);
12394 emit_insn (gen_isync ());
12395 emit_label (XEXP (label2
, 0));
12399 /* Emit instructions to move SRC to DST. Called by splitters for
12400 multi-register moves. It will emit at most one instruction for
12401 each register that is accessed; that is, it won't emit li/lis pairs
12402 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12406 rs6000_split_multireg_move (rtx dst
, rtx src
)
12408 /* The register number of the first register being moved. */
12410 /* The mode that is to be moved. */
12411 enum machine_mode mode
;
12412 /* The mode that the move is being done in, and its size. */
12413 enum machine_mode reg_mode
;
12415 /* The number of registers that will be moved. */
12418 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
12419 mode
= GET_MODE (dst
);
12420 nregs
= hard_regno_nregs
[reg
][mode
];
12421 if (FP_REGNO_P (reg
))
12423 else if (ALTIVEC_REGNO_P (reg
))
12424 reg_mode
= V16QImode
;
12426 reg_mode
= word_mode
;
12427 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
12429 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
12431 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
12433 /* Move register range backwards, if we might have destructive
12436 for (i
= nregs
- 1; i
>= 0; i
--)
12437 emit_insn (gen_rtx_SET (VOIDmode
,
12438 simplify_gen_subreg (reg_mode
, dst
, mode
,
12439 i
* reg_mode_size
),
12440 simplify_gen_subreg (reg_mode
, src
, mode
,
12441 i
* reg_mode_size
)));
12447 bool used_update
= false;
12449 if (MEM_P (src
) && INT_REGNO_P (reg
))
12453 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
12454 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
12457 breg
= XEXP (XEXP (src
, 0), 0);
12458 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
12459 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
12460 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
12461 emit_insn (TARGET_32BIT
12462 ? gen_addsi3 (breg
, breg
, delta_rtx
)
12463 : gen_adddi3 (breg
, breg
, delta_rtx
));
12464 src
= replace_equiv_address (src
, breg
);
12466 else if (! offsettable_memref_p (src
))
12469 basereg
= gen_rtx_REG (Pmode
, reg
);
12470 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
12471 src
= replace_equiv_address (src
, basereg
);
12474 breg
= XEXP (src
, 0);
12475 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
12476 breg
= XEXP (breg
, 0);
12478 /* If the base register we are using to address memory is
12479 also a destination reg, then change that register last. */
12481 && REGNO (breg
) >= REGNO (dst
)
12482 && REGNO (breg
) < REGNO (dst
) + nregs
)
12483 j
= REGNO (breg
) - REGNO (dst
);
12486 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
12490 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
12491 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
12494 breg
= XEXP (XEXP (dst
, 0), 0);
12495 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
12496 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
12497 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
12499 /* We have to update the breg before doing the store.
12500 Use store with update, if available. */
12504 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
12505 emit_insn (TARGET_32BIT
12506 ? (TARGET_POWERPC64
12507 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
12508 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
12509 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
12510 used_update
= true;
12513 emit_insn (TARGET_32BIT
12514 ? gen_addsi3 (breg
, breg
, delta_rtx
)
12515 : gen_adddi3 (breg
, breg
, delta_rtx
));
12516 dst
= replace_equiv_address (dst
, breg
);
12519 gcc_assert (offsettable_memref_p (dst
));
12522 for (i
= 0; i
< nregs
; i
++)
12524 /* Calculate index to next subword. */
12529 /* If compiler already emitted move of first word by
12530 store with update, no need to do anything. */
12531 if (j
== 0 && used_update
)
12534 emit_insn (gen_rtx_SET (VOIDmode
,
12535 simplify_gen_subreg (reg_mode
, dst
, mode
,
12536 j
* reg_mode_size
),
12537 simplify_gen_subreg (reg_mode
, src
, mode
,
12538 j
* reg_mode_size
)));
12544 /* This page contains routines that are used to determine what the
12545 function prologue and epilogue code will do and write them out. */
12547 /* Return the first fixed-point register that is required to be
12548 saved. 32 if none. */
12551 first_reg_to_save (void)
12555 /* Find lowest numbered live register. */
12556 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
12557 if (regs_ever_live
[first_reg
]
12558 && (! call_used_regs
[first_reg
]
12559 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
12560 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
12561 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
12562 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
12567 && current_function_uses_pic_offset_table
12568 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
12569 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
12575 /* Similar, for FP regs. */
12578 first_fp_reg_to_save (void)
12582 /* Find lowest numbered live register. */
12583 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
12584 if (regs_ever_live
[first_reg
])
12590 /* Similar, for AltiVec regs. */
12593 first_altivec_reg_to_save (void)
12597 /* Stack frame remains as is unless we are in AltiVec ABI. */
12598 if (! TARGET_ALTIVEC_ABI
)
12599 return LAST_ALTIVEC_REGNO
+ 1;
12601 /* Find lowest numbered live register. */
12602 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
12603 if (regs_ever_live
[i
])
12609 /* Return a 32-bit mask of the AltiVec registers we need to set in
12610 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
12611 the 32-bit word is 0. */
12613 static unsigned int
12614 compute_vrsave_mask (void)
12616 unsigned int i
, mask
= 0;
12618 /* First, find out if we use _any_ altivec registers. */
12619 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
12620 if (regs_ever_live
[i
])
12621 mask
|= ALTIVEC_REG_BIT (i
);
12626 /* Next, remove the argument registers from the set. These must
12627 be in the VRSAVE mask set by the caller, so we don't need to add
12628 them in again. More importantly, the mask we compute here is
12629 used to generate CLOBBERs in the set_vrsave insn, and we do not
12630 wish the argument registers to die. */
12631 for (i
= cfun
->args_info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
12632 mask
&= ~ALTIVEC_REG_BIT (i
);
12634 /* Similarly, remove the return value from the set. */
12637 diddle_return_value (is_altivec_return_reg
, &yes
);
12639 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
12645 /* For a very restricted set of circumstances, we can cut down the
12646 size of prologues/epilogues by calling our own save/restore-the-world
12650 compute_save_world_info (rs6000_stack_t
*info_ptr
)
12652 info_ptr
->world_save_p
= 1;
12653 info_ptr
->world_save_p
12654 = (WORLD_SAVE_P (info_ptr
)
12655 && DEFAULT_ABI
== ABI_DARWIN
12656 && ! (current_function_calls_setjmp
&& flag_exceptions
)
12657 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
12658 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
12659 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
12660 && info_ptr
->cr_save_p
);
12662 /* This will not work in conjunction with sibcalls. Make sure there
12663 are none. (This check is expensive, but seldom executed.) */
12664 if (WORLD_SAVE_P (info_ptr
))
12667 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
12668 if ( GET_CODE (insn
) == CALL_INSN
12669 && SIBLING_CALL_P (insn
))
12671 info_ptr
->world_save_p
= 0;
12676 if (WORLD_SAVE_P (info_ptr
))
12678 /* Even if we're not touching VRsave, make sure there's room on the
12679 stack for it, if it looks like we're calling SAVE_WORLD, which
12680 will attempt to save it. */
12681 info_ptr
->vrsave_size
= 4;
12683 /* "Save" the VRsave register too if we're saving the world. */
12684 if (info_ptr
->vrsave_mask
== 0)
12685 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
12687 /* Because the Darwin register save/restore routines only handle
12688 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
12690 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
12691 && (info_ptr
->first_altivec_reg_save
12692 >= FIRST_SAVED_ALTIVEC_REGNO
));
12699 is_altivec_return_reg (rtx reg
, void *xyes
)
12701 bool *yes
= (bool *) xyes
;
12702 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
12707 /* Calculate the stack information for the current function. This is
12708 complicated by having two separate calling sequences, the AIX calling
12709 sequence and the V.4 calling sequence.
12711 AIX (and Darwin/Mac OS X) stack frames look like:
12713 SP----> +---------------------------------------+
12714 | back chain to caller | 0 0
12715 +---------------------------------------+
12716 | saved CR | 4 8 (8-11)
12717 +---------------------------------------+
12719 +---------------------------------------+
12720 | reserved for compilers | 12 24
12721 +---------------------------------------+
12722 | reserved for binders | 16 32
12723 +---------------------------------------+
12724 | saved TOC pointer | 20 40
12725 +---------------------------------------+
12726 | Parameter save area (P) | 24 48
12727 +---------------------------------------+
12728 | Alloca space (A) | 24+P etc.
12729 +---------------------------------------+
12730 | Local variable space (L) | 24+P+A
12731 +---------------------------------------+
12732 | Float/int conversion temporary (X) | 24+P+A+L
12733 +---------------------------------------+
12734 | Save area for AltiVec registers (W) | 24+P+A+L+X
12735 +---------------------------------------+
12736 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
12737 +---------------------------------------+
12738 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
12739 +---------------------------------------+
12740 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
12741 +---------------------------------------+
12742 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
12743 +---------------------------------------+
12744 old SP->| back chain to caller's caller |
12745 +---------------------------------------+
12747 The required alignment for AIX configurations is two words (i.e., 8
12751 V.4 stack frames look like:
12753 SP----> +---------------------------------------+
12754 | back chain to caller | 0
12755 +---------------------------------------+
12756 | caller's saved LR | 4
12757 +---------------------------------------+
12758 | Parameter save area (P) | 8
12759 +---------------------------------------+
12760 | Alloca space (A) | 8+P
12761 +---------------------------------------+
12762 | Varargs save area (V) | 8+P+A
12763 +---------------------------------------+
12764 | Local variable space (L) | 8+P+A+V
12765 +---------------------------------------+
12766 | Float/int conversion temporary (X) | 8+P+A+V+L
12767 +---------------------------------------+
12768 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
12769 +---------------------------------------+
12770 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
12771 +---------------------------------------+
12772 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
12773 +---------------------------------------+
12774 | SPE: area for 64-bit GP registers |
12775 +---------------------------------------+
12776 | SPE alignment padding |
12777 +---------------------------------------+
12778 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
12779 +---------------------------------------+
12780 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
12781 +---------------------------------------+
12782 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
12783 +---------------------------------------+
12784 old SP->| back chain to caller's caller |
12785 +---------------------------------------+
12787 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
12788 given. (But note below and in sysv4.h that we require only 8 and
12789 may round up the size of our stack frame anyways. The historical
12790 reason is early versions of powerpc-linux which didn't properly
12791 align the stack at program startup. A happy side-effect is that
12792 -mno-eabi libraries can be used with -meabi programs.)
12794 The EABI configuration defaults to the V.4 layout. However,
12795 the stack alignment requirements may differ. If -mno-eabi is not
12796 given, the required stack alignment is 8 bytes; if -mno-eabi is
12797 given, the required alignment is 16 bytes. (But see V.4 comment
12800 #ifndef ABI_STACK_BOUNDARY
12801 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
12804 static rs6000_stack_t
*
12805 rs6000_stack_info (void)
12807 static rs6000_stack_t info
;
12808 rs6000_stack_t
*info_ptr
= &info
;
12809 int reg_size
= TARGET_32BIT
? 4 : 8;
12812 HOST_WIDE_INT non_fixed_size
;
12814 memset (&info
, 0, sizeof (info
));
12818 /* Cache value so we don't rescan instruction chain over and over. */
12819 if (cfun
->machine
->insn_chain_scanned_p
== 0)
12820 cfun
->machine
->insn_chain_scanned_p
12821 = spe_func_has_64bit_regs_p () + 1;
12822 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
12825 /* Select which calling sequence. */
12826 info_ptr
->abi
= DEFAULT_ABI
;
12828 /* Calculate which registers need to be saved & save area size. */
12829 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
12830 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
12831 even if it currently looks like we won't. */
12832 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
12833 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
12834 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
12835 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
12836 info_ptr
->gp_size
= reg_size
* (32 - RS6000_PIC_OFFSET_TABLE_REGNUM
);
12838 info_ptr
->gp_size
= reg_size
* (32 - info_ptr
->first_gp_reg_save
);
12840 /* For the SPE, we have an additional upper 32-bits on each GPR.
12841 Ideally we should save the entire 64-bits only when the upper
12842 half is used in SIMD instructions. Since we only record
12843 registers live (not the size they are used in), this proves
12844 difficult because we'd have to traverse the instruction chain at
12845 the right time, taking reload into account. This is a real pain,
12846 so we opt to save the GPRs in 64-bits always if but one register
12847 gets used in 64-bits. Otherwise, all the registers in the frame
12848 get saved in 32-bits.
12850 So... since when we save all GPRs (except the SP) in 64-bits, the
12851 traditional GP save area will be empty. */
12852 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12853 info_ptr
->gp_size
= 0;
12855 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
12856 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
12858 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
12859 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
12860 - info_ptr
->first_altivec_reg_save
);
12862 /* Does this function call anything? */
12863 info_ptr
->calls_p
= (! current_function_is_leaf
12864 || cfun
->machine
->ra_needs_full_frame
);
12866 /* Determine if we need to save the link register. */
12867 if ((DEFAULT_ABI
== ABI_AIX
12868 && current_function_profile
12869 && !TARGET_PROFILE_KERNEL
)
12870 #ifdef TARGET_RELOCATABLE
12871 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
12873 || (info_ptr
->first_fp_reg_save
!= 64
12874 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
12875 || info_ptr
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
12876 || (DEFAULT_ABI
== ABI_V4
&& current_function_calls_alloca
)
12877 || info_ptr
->calls_p
12878 || rs6000_ra_ever_killed ())
12880 info_ptr
->lr_save_p
= 1;
12881 regs_ever_live
[LINK_REGISTER_REGNUM
] = 1;
12884 /* Determine if we need to save the condition code registers. */
12885 if (regs_ever_live
[CR2_REGNO
]
12886 || regs_ever_live
[CR3_REGNO
]
12887 || regs_ever_live
[CR4_REGNO
])
12889 info_ptr
->cr_save_p
= 1;
12890 if (DEFAULT_ABI
== ABI_V4
)
12891 info_ptr
->cr_size
= reg_size
;
12894 /* If the current function calls __builtin_eh_return, then we need
12895 to allocate stack space for registers that will hold data for
12896 the exception handler. */
12897 if (current_function_calls_eh_return
)
12900 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
12903 /* SPE saves EH registers in 64-bits. */
12904 ehrd_size
= i
* (TARGET_SPE_ABI
12905 && info_ptr
->spe_64bit_regs_used
!= 0
12906 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
12911 /* Determine various sizes. */
12912 info_ptr
->reg_size
= reg_size
;
12913 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
12914 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
12915 info_ptr
->parm_size
= RS6000_ALIGN (current_function_outgoing_args_size
,
12916 TARGET_ALTIVEC
? 16 : 8);
12917 if (FRAME_GROWS_DOWNWARD
)
12918 info_ptr
->vars_size
12919 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
12920 + info_ptr
->parm_size
,
12921 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
12922 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
12923 + info_ptr
->parm_size
);
12925 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12926 info_ptr
->spe_gp_size
= 8 * (32 - info_ptr
->first_gp_reg_save
);
12928 info_ptr
->spe_gp_size
= 0;
12930 if (TARGET_ALTIVEC_ABI
)
12931 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
12933 info_ptr
->vrsave_mask
= 0;
12935 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
12936 info_ptr
->vrsave_size
= 4;
12938 info_ptr
->vrsave_size
= 0;
12940 compute_save_world_info (info_ptr
);
12942 /* Calculate the offsets. */
12943 switch (DEFAULT_ABI
)
12947 gcc_unreachable ();
12951 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
12952 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
12954 if (TARGET_ALTIVEC_ABI
)
12956 info_ptr
->vrsave_save_offset
12957 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
12959 /* Align stack so vector save area is on a quadword boundary. */
12960 if (info_ptr
->altivec_size
!= 0)
12961 info_ptr
->altivec_padding_size
12962 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
12964 info_ptr
->altivec_padding_size
= 0;
12966 info_ptr
->altivec_save_offset
12967 = info_ptr
->vrsave_save_offset
12968 - info_ptr
->altivec_padding_size
12969 - info_ptr
->altivec_size
;
12971 /* Adjust for AltiVec case. */
12972 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
12975 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
12976 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
12977 info_ptr
->lr_save_offset
= 2*reg_size
;
12981 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
12982 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
12983 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
12985 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
12987 /* Align stack so SPE GPR save area is aligned on a
12988 double-word boundary. */
12989 if (info_ptr
->spe_gp_size
!= 0)
12990 info_ptr
->spe_padding_size
12991 = 8 - (-info_ptr
->cr_save_offset
% 8);
12993 info_ptr
->spe_padding_size
= 0;
12995 info_ptr
->spe_gp_save_offset
12996 = info_ptr
->cr_save_offset
12997 - info_ptr
->spe_padding_size
12998 - info_ptr
->spe_gp_size
;
13000 /* Adjust for SPE case. */
13001 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
13003 else if (TARGET_ALTIVEC_ABI
)
13005 info_ptr
->vrsave_save_offset
13006 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
13008 /* Align stack so vector save area is on a quadword boundary. */
13009 if (info_ptr
->altivec_size
!= 0)
13010 info_ptr
->altivec_padding_size
13011 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
13013 info_ptr
->altivec_padding_size
= 0;
13015 info_ptr
->altivec_save_offset
13016 = info_ptr
->vrsave_save_offset
13017 - info_ptr
->altivec_padding_size
13018 - info_ptr
->altivec_size
;
13020 /* Adjust for AltiVec case. */
13021 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
13024 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
13025 info_ptr
->ehrd_offset
-= ehrd_size
;
13026 info_ptr
->lr_save_offset
= reg_size
;
13030 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
13031 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
13032 + info_ptr
->gp_size
13033 + info_ptr
->altivec_size
13034 + info_ptr
->altivec_padding_size
13035 + info_ptr
->spe_gp_size
13036 + info_ptr
->spe_padding_size
13038 + info_ptr
->cr_size
13039 + info_ptr
->vrsave_size
,
13042 non_fixed_size
= (info_ptr
->vars_size
13043 + info_ptr
->parm_size
13044 + info_ptr
->save_size
);
13046 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
13047 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
13049 /* Determine if we need to allocate any stack frame:
13051 For AIX we need to push the stack if a frame pointer is needed
13052 (because the stack might be dynamically adjusted), if we are
13053 debugging, if we make calls, or if the sum of fp_save, gp_save,
13054 and local variables are more than the space needed to save all
13055 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13056 + 18*8 = 288 (GPR13 reserved).
13058 For V.4 we don't have the stack cushion that AIX uses, but assume
13059 that the debugger can handle stackless frames. */
13061 if (info_ptr
->calls_p
)
13062 info_ptr
->push_p
= 1;
13064 else if (DEFAULT_ABI
== ABI_V4
)
13065 info_ptr
->push_p
= non_fixed_size
!= 0;
13067 else if (frame_pointer_needed
)
13068 info_ptr
->push_p
= 1;
13070 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
13071 info_ptr
->push_p
= 1;
13074 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
13076 /* Zero offsets if we're not saving those registers. */
13077 if (info_ptr
->fp_size
== 0)
13078 info_ptr
->fp_save_offset
= 0;
13080 if (info_ptr
->gp_size
== 0)
13081 info_ptr
->gp_save_offset
= 0;
13083 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
13084 info_ptr
->altivec_save_offset
= 0;
13086 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
13087 info_ptr
->vrsave_save_offset
= 0;
13089 if (! TARGET_SPE_ABI
13090 || info_ptr
->spe_64bit_regs_used
== 0
13091 || info_ptr
->spe_gp_size
== 0)
13092 info_ptr
->spe_gp_save_offset
= 0;
13094 if (! info_ptr
->lr_save_p
)
13095 info_ptr
->lr_save_offset
= 0;
13097 if (! info_ptr
->cr_save_p
)
13098 info_ptr
->cr_save_offset
= 0;
13103 /* Return true if the current function uses any GPRs in 64-bit SIMD
13107 spe_func_has_64bit_regs_p (void)
13111 /* Functions that save and restore all the call-saved registers will
13112 need to save/restore the registers in 64-bits. */
13113 if (current_function_calls_eh_return
13114 || current_function_calls_setjmp
13115 || current_function_has_nonlocal_goto
)
13118 insns
= get_insns ();
13120 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13126 /* FIXME: This should be implemented with attributes...
13128 (set_attr "spe64" "true")....then,
13129 if (get_spe64(insn)) return true;
13131 It's the only reliable way to do the stuff below. */
13133 i
= PATTERN (insn
);
13134 if (GET_CODE (i
) == SET
)
13136 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
13138 if (SPE_VECTOR_MODE (mode
))
13140 if (TARGET_E500_DOUBLE
&& mode
== DFmode
)
13150 debug_stack_info (rs6000_stack_t
*info
)
13152 const char *abi_string
;
13155 info
= rs6000_stack_info ();
13157 fprintf (stderr
, "\nStack information for function %s:\n",
13158 ((current_function_decl
&& DECL_NAME (current_function_decl
))
13159 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
13164 default: abi_string
= "Unknown"; break;
13165 case ABI_NONE
: abi_string
= "NONE"; break;
13166 case ABI_AIX
: abi_string
= "AIX"; break;
13167 case ABI_DARWIN
: abi_string
= "Darwin"; break;
13168 case ABI_V4
: abi_string
= "V.4"; break;
13171 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
13173 if (TARGET_ALTIVEC_ABI
)
13174 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
13176 if (TARGET_SPE_ABI
)
13177 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
13179 if (info
->first_gp_reg_save
!= 32)
13180 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
13182 if (info
->first_fp_reg_save
!= 64)
13183 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
13185 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
13186 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
13187 info
->first_altivec_reg_save
);
13189 if (info
->lr_save_p
)
13190 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
13192 if (info
->cr_save_p
)
13193 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
13195 if (info
->vrsave_mask
)
13196 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
13199 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
13202 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
13204 if (info
->gp_save_offset
)
13205 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
13207 if (info
->fp_save_offset
)
13208 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
13210 if (info
->altivec_save_offset
)
13211 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
13212 info
->altivec_save_offset
);
13214 if (info
->spe_gp_save_offset
)
13215 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
13216 info
->spe_gp_save_offset
);
13218 if (info
->vrsave_save_offset
)
13219 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
13220 info
->vrsave_save_offset
);
13222 if (info
->lr_save_offset
)
13223 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
13225 if (info
->cr_save_offset
)
13226 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
13228 if (info
->varargs_save_offset
)
13229 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
13231 if (info
->total_size
)
13232 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13235 if (info
->vars_size
)
13236 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13239 if (info
->parm_size
)
13240 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
13242 if (info
->fixed_size
)
13243 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
13246 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
13248 if (info
->spe_gp_size
)
13249 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
13252 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
13254 if (info
->altivec_size
)
13255 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
13257 if (info
->vrsave_size
)
13258 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
13260 if (info
->altivec_padding_size
)
13261 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
13262 info
->altivec_padding_size
);
13264 if (info
->spe_padding_size
)
13265 fprintf (stderr
, "\tspe_padding_size = %5d\n",
13266 info
->spe_padding_size
);
13269 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
13271 if (info
->save_size
)
13272 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
13274 if (info
->reg_size
!= 4)
13275 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
13277 fprintf (stderr
, "\n");
13281 rs6000_return_addr (int count
, rtx frame
)
13283 /* Currently we don't optimize very well between prolog and body
13284 code and for PIC code the code can be actually quite bad, so
13285 don't try to be too clever here. */
13286 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
13288 cfun
->machine
->ra_needs_full_frame
= 1;
13295 plus_constant (copy_to_reg
13296 (gen_rtx_MEM (Pmode
,
13297 memory_address (Pmode
, frame
))),
13298 RETURN_ADDRESS_OFFSET
)));
13301 cfun
->machine
->ra_need_lr
= 1;
13302 return get_hard_reg_initial_val (Pmode
, LINK_REGISTER_REGNUM
);
13305 /* Say whether a function is a candidate for sibcall handling or not.
13306 We do not allow indirect calls to be optimized into sibling calls.
13307 Also, we can't do it if there are any vector parameters; there's
13308 nowhere to put the VRsave code so it works; note that functions with
13309 vector parameters are required to have a prototype, so the argument
13310 type info must be available here. (The tail recursion case can work
13311 with vector parameters, but there's no way to distinguish here.) */
13313 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
13318 if (TARGET_ALTIVEC_VRSAVE
)
13320 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
13321 type
; type
= TREE_CHAIN (type
))
13323 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
13327 if (DEFAULT_ABI
== ABI_DARWIN
13328 || (*targetm
.binds_local_p
) (decl
))
13330 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
13332 if (!lookup_attribute ("longcall", attr_list
)
13333 || lookup_attribute ("shortcall", attr_list
))
13340 /* NULL if INSN insn is valid within a low-overhead loop.
13341 Otherwise return why doloop cannot be applied.
13342 PowerPC uses the COUNT register for branch on table instructions. */
13344 static const char *
13345 rs6000_invalid_within_doloop (rtx insn
)
13348 return "Function call in the loop.";
13351 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
13352 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
13353 return "Computed branch in the loop.";
13359 rs6000_ra_ever_killed (void)
13365 if (current_function_is_thunk
)
13368 /* regs_ever_live has LR marked as used if any sibcalls are present,
13369 but this should not force saving and restoring in the
13370 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13371 clobbers LR, so that is inappropriate. */
13373 /* Also, the prologue can generate a store into LR that
13374 doesn't really count, like this:
13377 bcl to set PIC register
13381 When we're called from the epilogue, we need to avoid counting
13382 this as a store. */
13384 push_topmost_sequence ();
13385 top
= get_insns ();
13386 pop_topmost_sequence ();
13387 reg
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13389 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13395 if (!SIBLING_CALL_P (insn
))
13398 else if (find_regno_note (insn
, REG_INC
, LINK_REGISTER_REGNUM
))
13400 else if (set_of (reg
, insn
) != NULL_RTX
13401 && !prologue_epilogue_contains (insn
))
13408 /* Add a REG_MAYBE_DEAD note to the insn. */
13410 rs6000_maybe_dead (rtx insn
)
13412 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
,
13417 /* Emit instructions needed to load the TOC register.
13418 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13419 a constant pool; or for SVR4 -fpic. */
13422 rs6000_emit_load_toc_table (int fromprolog
)
13425 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
13427 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
13430 rtx lab
, tmp1
, tmp2
, got
, tempLR
;
13432 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
13433 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13435 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
13437 got
= rs6000_got_sym ();
13438 tmp1
= tmp2
= dest
;
13441 tmp1
= gen_reg_rtx (Pmode
);
13442 tmp2
= gen_reg_rtx (Pmode
);
13444 tempLR
= (fromprolog
13445 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13446 : gen_reg_rtx (Pmode
));
13447 insn
= emit_insn (gen_load_toc_v4_PIC_1 (tempLR
, lab
));
13449 rs6000_maybe_dead (insn
);
13450 insn
= emit_move_insn (tmp1
, tempLR
);
13452 rs6000_maybe_dead (insn
);
13453 insn
= emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
13455 rs6000_maybe_dead (insn
);
13456 insn
= emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
13458 rs6000_maybe_dead (insn
);
13460 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
13462 rtx tempLR
= (fromprolog
13463 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13464 : gen_reg_rtx (Pmode
));
13466 insn
= emit_insn (gen_load_toc_v4_pic_si (tempLR
));
13468 rs6000_maybe_dead (insn
);
13469 insn
= emit_move_insn (dest
, tempLR
);
13471 rs6000_maybe_dead (insn
);
13473 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
13476 rtx tempLR
= (fromprolog
13477 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13478 : gen_reg_rtx (Pmode
));
13479 rtx temp0
= (fromprolog
13480 ? gen_rtx_REG (Pmode
, 0)
13481 : gen_reg_rtx (Pmode
));
13487 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
13488 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13490 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
13491 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13493 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR
,
13495 rs6000_maybe_dead (emit_move_insn (dest
, tempLR
));
13496 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
,
13504 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
13505 emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, tocsym
));
13506 emit_move_insn (dest
, tempLR
);
13507 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
13509 insn
= emit_insn (gen_addsi3 (dest
, temp0
, dest
));
13511 rs6000_maybe_dead (insn
);
13513 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
13515 /* This is for AIX code running in non-PIC ELF32. */
13518 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
13519 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13521 insn
= emit_insn (gen_elf_high (dest
, realsym
));
13523 rs6000_maybe_dead (insn
);
13524 insn
= emit_insn (gen_elf_low (dest
, dest
, realsym
));
13526 rs6000_maybe_dead (insn
);
13530 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
13533 insn
= emit_insn (gen_load_toc_aix_si (dest
));
13535 insn
= emit_insn (gen_load_toc_aix_di (dest
));
13537 rs6000_maybe_dead (insn
);
13541 /* Emit instructions to restore the link register after determining where
13542 its value has been stored. */
13545 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
13547 rs6000_stack_t
*info
= rs6000_stack_info ();
13550 operands
[0] = source
;
13551 operands
[1] = scratch
;
13553 if (info
->lr_save_p
)
13555 rtx frame_rtx
= stack_pointer_rtx
;
13556 HOST_WIDE_INT sp_offset
= 0;
13559 if (frame_pointer_needed
13560 || current_function_calls_alloca
13561 || info
->total_size
> 32767)
13563 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
13564 emit_move_insn (operands
[1], tmp
);
13565 frame_rtx
= operands
[1];
13567 else if (info
->push_p
)
13568 sp_offset
= info
->total_size
;
13570 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
13571 tmp
= gen_frame_mem (Pmode
, tmp
);
13572 emit_move_insn (tmp
, operands
[0]);
13575 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
), operands
[0]);
13578 static GTY(()) int set
= -1;
13581 get_TOC_alias_set (void)
13584 set
= new_alias_set ();
13588 /* This returns nonzero if the current function uses the TOC. This is
13589 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
13590 is generated by the ABI_V4 load_toc_* patterns. */
13597 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
13600 rtx pat
= PATTERN (insn
);
13603 if (GET_CODE (pat
) == PARALLEL
)
13604 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
13606 rtx sub
= XVECEXP (pat
, 0, i
);
13607 if (GET_CODE (sub
) == USE
)
13609 sub
= XEXP (sub
, 0);
13610 if (GET_CODE (sub
) == UNSPEC
13611 && XINT (sub
, 1) == UNSPEC_TOC
)
13621 create_TOC_reference (rtx symbol
)
13623 if (no_new_pseudos
)
13624 regs_ever_live
[TOC_REGISTER
] = 1;
13625 return gen_rtx_PLUS (Pmode
,
13626 gen_rtx_REG (Pmode
, TOC_REGISTER
),
13627 gen_rtx_CONST (Pmode
,
13628 gen_rtx_MINUS (Pmode
, symbol
,
13629 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
13632 /* If _Unwind_* has been called from within the same module,
13633 toc register is not guaranteed to be saved to 40(1) on function
13634 entry. Save it there in that case. */
13637 rs6000_aix_emit_builtin_unwind_init (void)
13640 rtx stack_top
= gen_reg_rtx (Pmode
);
13641 rtx opcode_addr
= gen_reg_rtx (Pmode
);
13642 rtx opcode
= gen_reg_rtx (SImode
);
13643 rtx tocompare
= gen_reg_rtx (SImode
);
13644 rtx no_toc_save_needed
= gen_label_rtx ();
13646 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
13647 emit_move_insn (stack_top
, mem
);
13649 mem
= gen_frame_mem (Pmode
,
13650 gen_rtx_PLUS (Pmode
, stack_top
,
13651 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
13652 emit_move_insn (opcode_addr
, mem
);
13653 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
13654 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
13655 : 0xE8410028, SImode
));
13657 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
13658 SImode
, NULL_RTX
, NULL_RTX
,
13659 no_toc_save_needed
);
13661 mem
= gen_frame_mem (Pmode
,
13662 gen_rtx_PLUS (Pmode
, stack_top
,
13663 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
13664 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
13665 emit_label (no_toc_save_needed
);
13668 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
13669 and the change to the stack pointer. */
13672 rs6000_emit_stack_tie (void)
13674 rtx mem
= gen_frame_mem (BLKmode
,
13675 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
13677 emit_insn (gen_stack_tie (mem
));
13680 /* Emit the correct code for allocating stack space, as insns.
13681 If COPY_R12, make sure a copy of the old frame is left in r12.
13682 The generated code may use hard register 0 as a temporary. */
13685 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
13688 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
13689 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
13690 rtx todec
= gen_int_mode (-size
, Pmode
);
13692 if (INTVAL (todec
) != -size
)
13694 warning (0, "stack frame too large");
13695 emit_insn (gen_trap ());
13699 if (current_function_limit_stack
)
13701 if (REG_P (stack_limit_rtx
)
13702 && REGNO (stack_limit_rtx
) > 1
13703 && REGNO (stack_limit_rtx
) <= 31)
13705 emit_insn (TARGET_32BIT
13706 ? gen_addsi3 (tmp_reg
,
13709 : gen_adddi3 (tmp_reg
,
13713 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
13716 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
13718 && DEFAULT_ABI
== ABI_V4
)
13720 rtx toload
= gen_rtx_CONST (VOIDmode
,
13721 gen_rtx_PLUS (Pmode
,
13725 emit_insn (gen_elf_high (tmp_reg
, toload
));
13726 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
13727 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
13731 warning (0, "stack limit expression is not supported");
13734 if (copy_r12
|| ! TARGET_UPDATE
)
13735 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
13741 /* Need a note here so that try_split doesn't get confused. */
13742 if (get_last_insn () == NULL_RTX
)
13743 emit_note (NOTE_INSN_DELETED
);
13744 insn
= emit_move_insn (tmp_reg
, todec
);
13745 try_split (PATTERN (insn
), insn
, 0);
13749 insn
= emit_insn (TARGET_32BIT
13750 ? gen_movsi_update (stack_reg
, stack_reg
,
13752 : gen_movdi_di_update (stack_reg
, stack_reg
,
13753 todec
, stack_reg
));
13757 insn
= emit_insn (TARGET_32BIT
13758 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
13759 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
13760 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
13761 gen_rtx_REG (Pmode
, 12));
13764 RTX_FRAME_RELATED_P (insn
) = 1;
13766 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13767 gen_rtx_SET (VOIDmode
, stack_reg
,
13768 gen_rtx_PLUS (Pmode
, stack_reg
,
13773 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
13774 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
13775 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
13776 deduce these equivalences by itself so it wasn't necessary to hold
13777 its hand so much. */
13780 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
13781 rtx reg2
, rtx rreg
)
13785 /* copy_rtx will not make unique copies of registers, so we need to
13786 ensure we don't have unwanted sharing here. */
13788 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
13791 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
13793 real
= copy_rtx (PATTERN (insn
));
13795 if (reg2
!= NULL_RTX
)
13796 real
= replace_rtx (real
, reg2
, rreg
);
13798 real
= replace_rtx (real
, reg
,
13799 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
13800 STACK_POINTER_REGNUM
),
13803 /* We expect that 'real' is either a SET or a PARALLEL containing
13804 SETs (and possibly other stuff). In a PARALLEL, all the SETs
13805 are important so they all have to be marked RTX_FRAME_RELATED_P. */
13807 if (GET_CODE (real
) == SET
)
13811 temp
= simplify_rtx (SET_SRC (set
));
13813 SET_SRC (set
) = temp
;
13814 temp
= simplify_rtx (SET_DEST (set
));
13816 SET_DEST (set
) = temp
;
13817 if (GET_CODE (SET_DEST (set
)) == MEM
)
13819 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
13821 XEXP (SET_DEST (set
), 0) = temp
;
13828 gcc_assert (GET_CODE (real
) == PARALLEL
);
13829 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
13830 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
13832 rtx set
= XVECEXP (real
, 0, i
);
13834 temp
= simplify_rtx (SET_SRC (set
));
13836 SET_SRC (set
) = temp
;
13837 temp
= simplify_rtx (SET_DEST (set
));
13839 SET_DEST (set
) = temp
;
13840 if (GET_CODE (SET_DEST (set
)) == MEM
)
13842 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
13844 XEXP (SET_DEST (set
), 0) = temp
;
13846 RTX_FRAME_RELATED_P (set
) = 1;
13851 real
= spe_synthesize_frame_save (real
);
13853 RTX_FRAME_RELATED_P (insn
) = 1;
13854 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
13859 /* Given an SPE frame note, return a PARALLEL of SETs with the
13860 original note, plus a synthetic register save. */
13863 spe_synthesize_frame_save (rtx real
)
13865 rtx synth
, offset
, reg
, real2
;
13867 if (GET_CODE (real
) != SET
13868 || GET_MODE (SET_SRC (real
)) != V2SImode
)
13871 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
13872 frame related note. The parallel contains a set of the register
13873 being saved, and another set to a synthetic register (n+1200).
13874 This is so we can differentiate between 64-bit and 32-bit saves.
13875 Words cannot describe this nastiness. */
13877 gcc_assert (GET_CODE (SET_DEST (real
)) == MEM
13878 && GET_CODE (XEXP (SET_DEST (real
), 0)) == PLUS
13879 && GET_CODE (SET_SRC (real
)) == REG
);
13882 (set (mem (plus (reg x) (const y)))
13885 (set (mem (plus (reg x) (const y+4)))
13889 real2
= copy_rtx (real
);
13890 PUT_MODE (SET_DEST (real2
), SImode
);
13891 reg
= SET_SRC (real2
);
13892 real2
= replace_rtx (real2
, reg
, gen_rtx_REG (SImode
, REGNO (reg
)));
13893 synth
= copy_rtx (real2
);
13895 if (BYTES_BIG_ENDIAN
)
13897 offset
= XEXP (XEXP (SET_DEST (real2
), 0), 1);
13898 real2
= replace_rtx (real2
, offset
, GEN_INT (INTVAL (offset
) + 4));
13901 reg
= SET_SRC (synth
);
13903 synth
= replace_rtx (synth
, reg
,
13904 gen_rtx_REG (SImode
, REGNO (reg
) + 1200));
13906 offset
= XEXP (XEXP (SET_DEST (synth
), 0), 1);
13907 synth
= replace_rtx (synth
, offset
,
13908 GEN_INT (INTVAL (offset
)
13909 + (BYTES_BIG_ENDIAN
? 0 : 4)));
13911 RTX_FRAME_RELATED_P (synth
) = 1;
13912 RTX_FRAME_RELATED_P (real2
) = 1;
13913 if (BYTES_BIG_ENDIAN
)
13914 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, synth
, real2
));
13916 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, real2
, synth
));
13921 /* Returns an insn that has a vrsave set operation with the
13922 appropriate CLOBBERs. */
13925 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
13928 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
13929 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
13932 = gen_rtx_SET (VOIDmode
,
13934 gen_rtx_UNSPEC_VOLATILE (SImode
,
13935 gen_rtvec (2, reg
, vrsave
),
13936 UNSPECV_SET_VRSAVE
));
13940 /* We need to clobber the registers in the mask so the scheduler
13941 does not move sets to VRSAVE before sets of AltiVec registers.
13943 However, if the function receives nonlocal gotos, reload will set
13944 all call saved registers live. We will end up with:
13946 (set (reg 999) (mem))
13947 (parallel [ (set (reg vrsave) (unspec blah))
13948 (clobber (reg 999))])
13950 The clobber will cause the store into reg 999 to be dead, and
13951 flow will attempt to delete an epilogue insn. In this case, we
13952 need an unspec use/set of the register. */
13954 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13955 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
13957 if (!epiloguep
|| call_used_regs
[i
])
13958 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
13959 gen_rtx_REG (V4SImode
, i
));
13962 rtx reg
= gen_rtx_REG (V4SImode
, i
);
13965 = gen_rtx_SET (VOIDmode
,
13967 gen_rtx_UNSPEC (V4SImode
,
13968 gen_rtvec (1, reg
), 27));
13972 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
13974 for (i
= 0; i
< nclobs
; ++i
)
13975 XVECEXP (insn
, 0, i
) = clobs
[i
];
13980 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
13981 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
13984 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
13985 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
13987 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
13988 rtx replacea
, replaceb
;
13990 int_rtx
= GEN_INT (offset
);
13992 /* Some cases that need register indexed addressing. */
13993 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
13994 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
13996 && SPE_VECTOR_MODE (mode
)
13997 && !SPE_CONST_OFFSET_OK (offset
)))
13999 /* Whomever calls us must make sure r11 is available in the
14000 flow path of instructions in the prologue. */
14001 offset_rtx
= gen_rtx_REG (Pmode
, 11);
14002 emit_move_insn (offset_rtx
, int_rtx
);
14004 replacea
= offset_rtx
;
14005 replaceb
= int_rtx
;
14009 offset_rtx
= int_rtx
;
14010 replacea
= NULL_RTX
;
14011 replaceb
= NULL_RTX
;
14014 reg
= gen_rtx_REG (mode
, regno
);
14015 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
14016 mem
= gen_frame_mem (mode
, addr
);
14018 insn
= emit_move_insn (mem
, reg
);
14020 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
14023 /* Emit an offset memory reference suitable for a frame store, while
14024 converting to a valid addressing mode. */
14027 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
14029 rtx int_rtx
, offset_rtx
;
14031 int_rtx
= GEN_INT (offset
);
14033 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
14034 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
14036 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14037 emit_move_insn (offset_rtx
, int_rtx
);
14040 offset_rtx
= int_rtx
;
14042 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
14045 /* Look for user-defined global regs. We should not save and restore these,
14046 and cannot use stmw/lmw if there are any in its range. */
14049 no_global_regs_above (int first_greg
)
14052 for (i
= 0; i
< 32 - first_greg
; i
++)
14053 if (global_regs
[first_greg
+ i
])
14058 #ifndef TARGET_FIX_AND_CONTINUE
14059 #define TARGET_FIX_AND_CONTINUE 0
14062 /* Emit function prologue as insns. */
14065 rs6000_emit_prologue (void)
14067 rs6000_stack_t
*info
= rs6000_stack_info ();
14068 enum machine_mode reg_mode
= Pmode
;
14069 int reg_size
= TARGET_32BIT
? 4 : 8;
14070 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
14071 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
14072 rtx frame_reg_rtx
= sp_reg_rtx
;
14073 rtx cr_save_rtx
= NULL_RTX
;
14075 int saving_FPRs_inline
;
14076 int using_store_multiple
;
14077 HOST_WIDE_INT sp_offset
= 0;
14079 if (TARGET_FIX_AND_CONTINUE
)
14081 /* gdb on darwin arranges to forward a function from the old
14082 address by modifying the first 5 instructions of the function
14083 to branch to the overriding function. This is necessary to
14084 permit function pointers that point to the old function to
14085 actually forward to the new function. */
14086 emit_insn (gen_nop ());
14087 emit_insn (gen_nop ());
14088 emit_insn (gen_nop ());
14089 emit_insn (gen_nop ());
14090 emit_insn (gen_nop ());
14093 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14095 reg_mode
= V2SImode
;
14099 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
14100 && (!TARGET_SPE_ABI
14101 || info
->spe_64bit_regs_used
== 0)
14102 && info
->first_gp_reg_save
< 31
14103 && no_global_regs_above (info
->first_gp_reg_save
));
14104 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
14105 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
14106 || current_function_calls_eh_return
14107 || cfun
->machine
->ra_need_lr
);
14109 /* For V.4, update stack before we do any saving and set back pointer. */
14111 && (DEFAULT_ABI
== ABI_V4
14112 || current_function_calls_eh_return
))
14114 if (info
->total_size
< 32767)
14115 sp_offset
= info
->total_size
;
14117 frame_reg_rtx
= frame_ptr_rtx
;
14118 rs6000_emit_allocate_stack (info
->total_size
,
14119 (frame_reg_rtx
!= sp_reg_rtx
14120 && (info
->cr_save_p
14122 || info
->first_fp_reg_save
< 64
14123 || info
->first_gp_reg_save
< 32
14125 if (frame_reg_rtx
!= sp_reg_rtx
)
14126 rs6000_emit_stack_tie ();
14129 /* Handle world saves specially here. */
14130 if (WORLD_SAVE_P (info
))
14136 /* save_world expects lr in r0. */
14137 if (info
->lr_save_p
)
14139 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
14140 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14141 RTX_FRAME_RELATED_P (insn
) = 1;
14144 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14145 assumptions about the offsets of various bits of the stack
14147 gcc_assert (info
->gp_save_offset
== -220
14148 && info
->fp_save_offset
== -144
14149 && info
->lr_save_offset
== 8
14150 && info
->cr_save_offset
== 4
14153 && (!current_function_calls_eh_return
14154 || info
->ehrd_offset
== -432)
14155 && info
->vrsave_save_offset
== -224
14156 && info
->altivec_save_offset
== (-224 -16 -192));
14158 treg
= gen_rtx_REG (SImode
, 11);
14159 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
14161 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14162 in R11. It also clobbers R12, so beware! */
14164 /* Preserve CR2 for save_world prologues */
14166 sz
+= 32 - info
->first_gp_reg_save
;
14167 sz
+= 64 - info
->first_fp_reg_save
;
14168 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
14169 p
= rtvec_alloc (sz
);
14171 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
14172 gen_rtx_REG (Pmode
,
14173 LINK_REGISTER_REGNUM
));
14174 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
14175 gen_rtx_SYMBOL_REF (Pmode
,
14177 /* We do floats first so that the instruction pattern matches
14179 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14181 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14182 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14183 GEN_INT (info
->fp_save_offset
14184 + sp_offset
+ 8 * i
));
14185 rtx mem
= gen_frame_mem (DFmode
, addr
);
14187 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14189 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
14191 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
14192 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14193 GEN_INT (info
->altivec_save_offset
14194 + sp_offset
+ 16 * i
));
14195 rtx mem
= gen_frame_mem (V4SImode
, addr
);
14197 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14199 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14201 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14202 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14203 GEN_INT (info
->gp_save_offset
14204 + sp_offset
+ reg_size
* i
));
14205 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14207 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14211 /* CR register traditionally saved as CR2. */
14212 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
14213 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14214 GEN_INT (info
->cr_save_offset
14216 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14218 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14220 /* Prevent any attempt to delete the setting of r0 and treg! */
14221 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, gen_rtx_REG (Pmode
, 0));
14222 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
, treg
);
14223 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
, sp_reg_rtx
);
14225 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14226 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14227 NULL_RTX
, NULL_RTX
);
14229 if (current_function_calls_eh_return
)
14234 unsigned int regno
= EH_RETURN_DATA_REGNO (i
);
14235 if (regno
== INVALID_REGNUM
)
14237 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
14238 info
->ehrd_offset
+ sp_offset
14239 + reg_size
* (int) i
,
14245 /* Save AltiVec registers if needed. */
14246 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
14250 /* There should be a non inline version of this, for when we
14251 are saving lots of vector registers. */
14252 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14253 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14255 rtx areg
, savereg
, mem
;
14258 offset
= info
->altivec_save_offset
+ sp_offset
14259 + 16 * (i
- info
->first_altivec_reg_save
);
14261 savereg
= gen_rtx_REG (V4SImode
, i
);
14263 areg
= gen_rtx_REG (Pmode
, 0);
14264 emit_move_insn (areg
, GEN_INT (offset
));
14266 /* AltiVec addressing mode is [reg+reg]. */
14267 mem
= gen_frame_mem (V4SImode
,
14268 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
14270 insn
= emit_move_insn (mem
, savereg
);
14272 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14273 areg
, GEN_INT (offset
));
14277 /* VRSAVE is a bit vector representing which AltiVec registers
14278 are used. The OS uses this to determine which vector
14279 registers to save on a context switch. We need to save
14280 VRSAVE on the stack frame, add whatever AltiVec registers we
14281 used in this function, and do the corresponding magic in the
14284 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
14285 && info
->vrsave_mask
!= 0)
14287 rtx reg
, mem
, vrsave
;
14290 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14291 as frame_reg_rtx and r11 as the static chain pointer for
14292 nested functions. */
14293 reg
= gen_rtx_REG (SImode
, 0);
14294 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
14296 emit_insn (gen_get_vrsave_internal (reg
));
14298 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
14300 if (!WORLD_SAVE_P (info
))
14303 offset
= info
->vrsave_save_offset
+ sp_offset
;
14304 mem
= gen_frame_mem (SImode
,
14305 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14306 GEN_INT (offset
)));
14307 insn
= emit_move_insn (mem
, reg
);
14310 /* Include the registers in the mask. */
14311 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
14313 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
14316 /* If we use the link register, get it into r0. */
14317 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
14319 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
14320 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14321 RTX_FRAME_RELATED_P (insn
) = 1;
14324 /* If we need to save CR, put it into r12. */
14325 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
14329 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
14330 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
14331 RTX_FRAME_RELATED_P (insn
) = 1;
14332 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14333 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14334 But that's OK. All we have to do is specify that _one_ condition
14335 code register is saved in this stack slot. The thrower's epilogue
14336 will then restore all the call-saved registers.
14337 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14338 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
14339 gen_rtx_REG (SImode
, CR2_REGNO
));
14340 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14345 /* Do any required saving of fpr's. If only one or two to save, do
14346 it ourselves. Otherwise, call function. */
14347 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
14350 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14351 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
14352 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
14353 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
14354 info
->first_fp_reg_save
+ i
,
14355 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
14358 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
14362 const char *alloc_rname
;
14364 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
14366 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
14367 gen_rtx_REG (Pmode
,
14368 LINK_REGISTER_REGNUM
));
14369 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
14370 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
14371 alloc_rname
= ggc_strdup (rname
);
14372 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
14373 gen_rtx_SYMBOL_REF (Pmode
,
14375 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14377 rtx addr
, reg
, mem
;
14378 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14379 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14380 GEN_INT (info
->fp_save_offset
14381 + sp_offset
+ 8*i
));
14382 mem
= gen_frame_mem (DFmode
, addr
);
14384 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14386 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14387 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14388 NULL_RTX
, NULL_RTX
);
14391 /* Save GPRs. This is done as a PARALLEL if we are using
14392 the store-multiple instructions. */
14393 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
14397 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14398 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14400 rtx addr
, reg
, mem
;
14401 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14402 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14403 GEN_INT (info
->gp_save_offset
14406 mem
= gen_frame_mem (reg_mode
, addr
);
14408 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14410 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14411 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14412 NULL_RTX
, NULL_RTX
);
14414 else if (!WORLD_SAVE_P (info
))
14417 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14418 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
14419 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
14420 || (i
+ info
->first_gp_reg_save
14421 == RS6000_PIC_OFFSET_TABLE_REGNUM
14422 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14423 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14424 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14425 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14427 rtx addr
, reg
, mem
;
14428 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14430 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14432 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14435 if (!SPE_CONST_OFFSET_OK (offset
))
14437 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14438 emit_move_insn (b
, GEN_INT (offset
));
14441 b
= GEN_INT (offset
);
14443 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
14444 mem
= gen_frame_mem (V2SImode
, addr
);
14445 insn
= emit_move_insn (mem
, reg
);
14447 if (GET_CODE (b
) == CONST_INT
)
14448 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14449 NULL_RTX
, NULL_RTX
);
14451 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14452 b
, GEN_INT (offset
));
14456 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14457 GEN_INT (info
->gp_save_offset
14460 mem
= gen_frame_mem (reg_mode
, addr
);
14462 insn
= emit_move_insn (mem
, reg
);
14463 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14464 NULL_RTX
, NULL_RTX
);
14469 /* ??? There's no need to emit actual instructions here, but it's the
14470 easiest way to get the frame unwind information emitted. */
14471 if (!WORLD_SAVE_P (info
) && current_function_calls_eh_return
)
14473 unsigned int i
, regno
;
14475 /* In AIX ABI we need to pretend we save r2 here. */
14478 rtx addr
, reg
, mem
;
14480 reg
= gen_rtx_REG (reg_mode
, 2);
14481 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14482 GEN_INT (sp_offset
+ 5 * reg_size
));
14483 mem
= gen_frame_mem (reg_mode
, addr
);
14485 insn
= emit_move_insn (mem
, reg
);
14486 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14487 NULL_RTX
, NULL_RTX
);
14488 PATTERN (insn
) = gen_blockage ();
14493 regno
= EH_RETURN_DATA_REGNO (i
);
14494 if (regno
== INVALID_REGNUM
)
14497 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
14498 info
->ehrd_offset
+ sp_offset
14499 + reg_size
* (int) i
,
14504 /* Save lr if we used it. */
14505 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
14507 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14508 GEN_INT (info
->lr_save_offset
+ sp_offset
));
14509 rtx reg
= gen_rtx_REG (Pmode
, 0);
14510 rtx mem
= gen_rtx_MEM (Pmode
, addr
);
14511 /* This should not be of frame_alias_set, because of
14512 __builtin_return_address. */
14514 insn
= emit_move_insn (mem
, reg
);
14515 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14516 NULL_RTX
, NULL_RTX
);
14519 /* Save CR if we use any that must be preserved. */
14520 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
14522 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14523 GEN_INT (info
->cr_save_offset
+ sp_offset
));
14524 rtx mem
= gen_frame_mem (SImode
, addr
);
14525 /* See the large comment above about why CR2_REGNO is used. */
14526 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
14528 /* If r12 was used to hold the original sp, copy cr into r0 now
14530 if (REGNO (frame_reg_rtx
) == 12)
14534 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
14535 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
14536 RTX_FRAME_RELATED_P (insn
) = 1;
14537 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
14538 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14543 insn
= emit_move_insn (mem
, cr_save_rtx
);
14545 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14546 NULL_RTX
, NULL_RTX
);
14549 /* Update stack and set back pointer unless this is V.4,
14550 for which it was done previously. */
14551 if (!WORLD_SAVE_P (info
) && info
->push_p
14552 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
14553 rs6000_emit_allocate_stack (info
->total_size
, FALSE
);
14555 /* Set frame pointer, if needed. */
14556 if (frame_pointer_needed
)
14558 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
14560 RTX_FRAME_RELATED_P (insn
) = 1;
14563 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
14564 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
14565 || (DEFAULT_ABI
== ABI_V4
14566 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
14567 && regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
]))
14569 /* If emit_load_toc_table will use the link register, we need to save
14570 it. We use R12 for this purpose because emit_load_toc_table
14571 can use register 0. This allows us to use a plain 'blr' to return
14572 from the procedure more often. */
14573 int save_LR_around_toc_setup
= (TARGET_ELF
14574 && DEFAULT_ABI
!= ABI_AIX
14576 && ! info
->lr_save_p
14577 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
14578 if (save_LR_around_toc_setup
)
14580 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
14582 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
14583 rs6000_maybe_dead (insn
);
14584 RTX_FRAME_RELATED_P (insn
) = 1;
14586 rs6000_emit_load_toc_table (TRUE
);
14588 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
14589 rs6000_maybe_dead (insn
);
14590 RTX_FRAME_RELATED_P (insn
) = 1;
14593 rs6000_emit_load_toc_table (TRUE
);
14597 if (DEFAULT_ABI
== ABI_DARWIN
14598 && flag_pic
&& current_function_uses_pic_offset_table
)
14600 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
14601 rtx src
= machopic_function_base_sym ();
14603 /* Save and restore LR locally around this call (in R0). */
14604 if (!info
->lr_save_p
)
14605 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
));
14607 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr
, src
)));
14609 insn
= emit_move_insn (gen_rtx_REG (Pmode
,
14610 RS6000_PIC_OFFSET_TABLE_REGNUM
),
14612 rs6000_maybe_dead (insn
);
14614 if (!info
->lr_save_p
)
14615 rs6000_maybe_dead (emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0)));
14620 /* Write function prologue. */
14623 rs6000_output_function_prologue (FILE *file
,
14624 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
14626 rs6000_stack_t
*info
= rs6000_stack_info ();
14628 if (TARGET_DEBUG_STACK
)
14629 debug_stack_info (info
);
14631 /* Write .extern for any function we will call to save and restore
14633 if (info
->first_fp_reg_save
< 64
14634 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
14635 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
14636 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
14637 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
14638 RESTORE_FP_SUFFIX
);
14640 /* Write .extern for AIX common mode routines, if needed. */
14641 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
14643 fputs ("\t.extern __mulh\n", file
);
14644 fputs ("\t.extern __mull\n", file
);
14645 fputs ("\t.extern __divss\n", file
);
14646 fputs ("\t.extern __divus\n", file
);
14647 fputs ("\t.extern __quoss\n", file
);
14648 fputs ("\t.extern __quous\n", file
);
14649 common_mode_defined
= 1;
14652 if (! HAVE_prologue
)
14656 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
14657 the "toplevel" insn chain. */
14658 emit_note (NOTE_INSN_DELETED
);
14659 rs6000_emit_prologue ();
14660 emit_note (NOTE_INSN_DELETED
);
14662 /* Expand INSN_ADDRESSES so final() doesn't crash. */
14666 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
14668 INSN_ADDRESSES_NEW (insn
, addr
);
14673 if (TARGET_DEBUG_STACK
)
14674 debug_rtx_list (get_insns (), 100);
14675 final (get_insns (), file
, FALSE
);
14679 rs6000_pic_labelno
++;
14682 /* Emit function epilogue as insns.
14684 At present, dwarf2out_frame_debug_expr doesn't understand
14685 register restores, so we don't bother setting RTX_FRAME_RELATED_P
14686 anywhere in the epilogue. Most of the insns below would in any case
14687 need special notes to explain where r11 is in relation to the stack. */
14690 rs6000_emit_epilogue (int sibcall
)
14692 rs6000_stack_t
*info
;
14693 int restoring_FPRs_inline
;
14694 int using_load_multiple
;
14695 int using_mfcr_multiple
;
14696 int use_backchain_to_restore_sp
;
14698 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
14699 rtx frame_reg_rtx
= sp_reg_rtx
;
14700 enum machine_mode reg_mode
= Pmode
;
14701 int reg_size
= TARGET_32BIT
? 4 : 8;
14704 info
= rs6000_stack_info ();
14706 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14708 reg_mode
= V2SImode
;
14712 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
14713 && (!TARGET_SPE_ABI
14714 || info
->spe_64bit_regs_used
== 0)
14715 && info
->first_gp_reg_save
< 31
14716 && no_global_regs_above (info
->first_gp_reg_save
));
14717 restoring_FPRs_inline
= (sibcall
14718 || current_function_calls_eh_return
14719 || info
->first_fp_reg_save
== 64
14720 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
14721 use_backchain_to_restore_sp
= (frame_pointer_needed
14722 || current_function_calls_alloca
14723 || info
->total_size
> 32767);
14724 using_mfcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
14725 || rs6000_cpu
== PROCESSOR_PPC603
14726 || rs6000_cpu
== PROCESSOR_PPC750
14729 if (WORLD_SAVE_P (info
))
14733 const char *alloc_rname
;
14736 /* eh_rest_world_r10 will return to the location saved in the LR
14737 stack slot (which is not likely to be our caller.)
14738 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
14739 rest_world is similar, except any R10 parameter is ignored.
14740 The exception-handling stuff that was here in 2.95 is no
14741 longer necessary. */
14745 + 32 - info
->first_gp_reg_save
14746 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
14747 + 63 + 1 - info
->first_fp_reg_save
);
14749 strcpy (rname
, ((current_function_calls_eh_return
) ?
14750 "*eh_rest_world_r10" : "*rest_world"));
14751 alloc_rname
= ggc_strdup (rname
);
14754 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
14755 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
14756 gen_rtx_REG (Pmode
,
14757 LINK_REGISTER_REGNUM
));
14759 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
14760 /* The instruction pattern requires a clobber here;
14761 it is shared with the restVEC helper. */
14763 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
14766 /* CR register traditionally saved as CR2. */
14767 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
14768 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14769 GEN_INT (info
->cr_save_offset
));
14770 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14772 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14775 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14777 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14778 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14779 GEN_INT (info
->gp_save_offset
14781 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14783 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14785 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
14787 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
14788 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14789 GEN_INT (info
->altivec_save_offset
14791 rtx mem
= gen_frame_mem (V4SImode
, addr
);
14793 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14795 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
14797 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14798 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14799 GEN_INT (info
->fp_save_offset
14801 rtx mem
= gen_frame_mem (DFmode
, addr
);
14803 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
14806 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
14808 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
14810 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
14812 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
14814 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
14815 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14820 /* If we have a frame pointer, a call to alloca, or a large stack
14821 frame, restore the old stack pointer using the backchain. Otherwise,
14822 we know what size to update it with. */
14823 if (use_backchain_to_restore_sp
)
14825 /* Under V.4, don't reset the stack pointer until after we're done
14826 loading the saved registers. */
14827 if (DEFAULT_ABI
== ABI_V4
)
14828 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
14830 emit_move_insn (frame_reg_rtx
,
14831 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
14833 else if (info
->push_p
)
14835 if (DEFAULT_ABI
== ABI_V4
14836 || current_function_calls_eh_return
)
14837 sp_offset
= info
->total_size
;
14840 emit_insn (TARGET_32BIT
14841 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
14842 GEN_INT (info
->total_size
))
14843 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
14844 GEN_INT (info
->total_size
)));
14848 /* Restore AltiVec registers if needed. */
14849 if (TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
14853 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14854 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14856 rtx addr
, areg
, mem
;
14858 areg
= gen_rtx_REG (Pmode
, 0);
14860 (areg
, GEN_INT (info
->altivec_save_offset
14862 + 16 * (i
- info
->first_altivec_reg_save
)));
14864 /* AltiVec addressing mode is [reg+reg]. */
14865 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
14866 mem
= gen_frame_mem (V4SImode
, addr
);
14868 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
14872 /* Restore VRSAVE if needed. */
14873 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
14874 && info
->vrsave_mask
!= 0)
14876 rtx addr
, mem
, reg
;
14878 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14879 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
14880 mem
= gen_frame_mem (SImode
, addr
);
14881 reg
= gen_rtx_REG (SImode
, 12);
14882 emit_move_insn (reg
, mem
);
14884 emit_insn (generate_set_vrsave (reg
, info
, 1));
14887 /* Get the old lr if we saved it. */
14888 if (info
->lr_save_p
)
14890 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
14891 info
->lr_save_offset
+ sp_offset
);
14893 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
14896 /* Get the old cr if we saved it. */
14897 if (info
->cr_save_p
)
14899 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14900 GEN_INT (info
->cr_save_offset
+ sp_offset
));
14901 rtx mem
= gen_frame_mem (SImode
, addr
);
14903 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
14906 /* Set LR here to try to overlap restores below. */
14907 if (info
->lr_save_p
)
14908 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
),
14909 gen_rtx_REG (Pmode
, 0));
14911 /* Load exception handler data registers, if needed. */
14912 if (current_function_calls_eh_return
)
14914 unsigned int i
, regno
;
14918 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14919 GEN_INT (sp_offset
+ 5 * reg_size
));
14920 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14922 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
14929 regno
= EH_RETURN_DATA_REGNO (i
);
14930 if (regno
== INVALID_REGNUM
)
14933 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
14934 info
->ehrd_offset
+ sp_offset
14935 + reg_size
* (int) i
);
14937 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
14941 /* Restore GPRs. This is done as a PARALLEL if we are using
14942 the load-multiple instructions. */
14943 if (using_load_multiple
)
14946 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14947 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14949 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14950 GEN_INT (info
->gp_save_offset
14953 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14956 gen_rtx_SET (VOIDmode
,
14957 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
14960 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14963 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14964 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
14965 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
14966 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14967 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14968 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14969 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14970 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14972 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14973 GEN_INT (info
->gp_save_offset
14976 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14978 /* Restore 64-bit quantities for SPE. */
14979 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14981 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14984 if (!SPE_CONST_OFFSET_OK (offset
))
14986 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14987 emit_move_insn (b
, GEN_INT (offset
));
14990 b
= GEN_INT (offset
);
14992 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
14993 mem
= gen_frame_mem (V2SImode
, addr
);
14996 emit_move_insn (gen_rtx_REG (reg_mode
,
14997 info
->first_gp_reg_save
+ i
), mem
);
15000 /* Restore fpr's if we need to do it without calling a function. */
15001 if (restoring_FPRs_inline
)
15002 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15003 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
15004 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
15007 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15008 GEN_INT (info
->fp_save_offset
15011 mem
= gen_frame_mem (DFmode
, addr
);
15013 emit_move_insn (gen_rtx_REG (DFmode
,
15014 info
->first_fp_reg_save
+ i
),
15018 /* If we saved cr, restore it here. Just those that were used. */
15019 if (info
->cr_save_p
)
15021 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
15024 if (using_mfcr_multiple
)
15026 for (i
= 0; i
< 8; i
++)
15027 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15029 gcc_assert (count
);
15032 if (using_mfcr_multiple
&& count
> 1)
15037 p
= rtvec_alloc (count
);
15040 for (i
= 0; i
< 8; i
++)
15041 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15043 rtvec r
= rtvec_alloc (2);
15044 RTVEC_ELT (r
, 0) = r12_rtx
;
15045 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
15046 RTVEC_ELT (p
, ndx
) =
15047 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
15048 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
15051 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15052 gcc_assert (ndx
== count
);
15055 for (i
= 0; i
< 8; i
++)
15056 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15058 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
15064 /* If this is V.4, unwind the stack pointer after all of the loads
15066 if (frame_reg_rtx
!= sp_reg_rtx
)
15068 /* This blockage is needed so that sched doesn't decide to move
15069 the sp change before the register restores. */
15070 rs6000_emit_stack_tie ();
15071 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
15073 else if (sp_offset
!= 0)
15074 emit_insn (TARGET_32BIT
15075 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
15076 GEN_INT (sp_offset
))
15077 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
15078 GEN_INT (sp_offset
)));
15080 if (current_function_calls_eh_return
)
15082 rtx sa
= EH_RETURN_STACKADJ_RTX
;
15083 emit_insn (TARGET_32BIT
15084 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
15085 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
15091 if (! restoring_FPRs_inline
)
15092 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
15094 p
= rtvec_alloc (2);
15096 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
15097 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
15098 gen_rtx_REG (Pmode
,
15099 LINK_REGISTER_REGNUM
));
15101 /* If we have to restore more than two FP registers, branch to the
15102 restore function. It will return to our caller. */
15103 if (! restoring_FPRs_inline
)
15107 const char *alloc_rname
;
15109 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
15110 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
15111 alloc_rname
= ggc_strdup (rname
);
15112 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
15113 gen_rtx_SYMBOL_REF (Pmode
,
15116 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15119 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
15120 GEN_INT (info
->fp_save_offset
+ 8*i
));
15121 mem
= gen_frame_mem (DFmode
, addr
);
15123 RTVEC_ELT (p
, i
+3) =
15124 gen_rtx_SET (VOIDmode
,
15125 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
15130 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15134 /* Write function epilogue. */
15137 rs6000_output_function_epilogue (FILE *file
,
15138 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
15140 rs6000_stack_t
*info
= rs6000_stack_info ();
15142 if (! HAVE_epilogue
)
15144 rtx insn
= get_last_insn ();
15145 /* If the last insn was a BARRIER, we don't have to write anything except
15146 the trace table. */
15147 if (GET_CODE (insn
) == NOTE
)
15148 insn
= prev_nonnote_insn (insn
);
15149 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
15151 /* This is slightly ugly, but at least we don't have two
15152 copies of the epilogue-emitting code. */
15155 /* A NOTE_INSN_DELETED is supposed to be at the start
15156 and end of the "toplevel" insn chain. */
15157 emit_note (NOTE_INSN_DELETED
);
15158 rs6000_emit_epilogue (FALSE
);
15159 emit_note (NOTE_INSN_DELETED
);
15161 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15165 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
15167 INSN_ADDRESSES_NEW (insn
, addr
);
15172 if (TARGET_DEBUG_STACK
)
15173 debug_rtx_list (get_insns (), 100);
15174 final (get_insns (), file
, FALSE
);
15180 macho_branch_islands ();
15181 /* Mach-O doesn't support labels at the end of objects, so if
15182 it looks like we might want one, insert a NOP. */
15184 rtx insn
= get_last_insn ();
15187 && NOTE_LINE_NUMBER (insn
) != NOTE_INSN_DELETED_LABEL
)
15188 insn
= PREV_INSN (insn
);
15192 && NOTE_LINE_NUMBER (insn
) == NOTE_INSN_DELETED_LABEL
)))
15193 fputs ("\tnop\n", file
);
15197 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15200 We don't output a traceback table if -finhibit-size-directive was
15201 used. The documentation for -finhibit-size-directive reads
15202 ``don't output a @code{.size} assembler directive, or anything
15203 else that would cause trouble if the function is split in the
15204 middle, and the two halves are placed at locations far apart in
15205 memory.'' The traceback table has this property, since it
15206 includes the offset from the start of the function to the
15207 traceback table itself.
15209 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15210 different traceback table. */
15211 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
15212 && rs6000_traceback
!= traceback_none
)
15214 const char *fname
= NULL
;
15215 const char *language_string
= lang_hooks
.name
;
15216 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
15218 int optional_tbtab
;
15220 if (rs6000_traceback
== traceback_full
)
15221 optional_tbtab
= 1;
15222 else if (rs6000_traceback
== traceback_part
)
15223 optional_tbtab
= 0;
15225 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
15227 if (optional_tbtab
)
15229 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
15230 while (*fname
== '.') /* V.4 encodes . in the name */
15233 /* Need label immediately before tbtab, so we can compute
15234 its offset from the function start. */
15235 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15236 ASM_OUTPUT_LABEL (file
, fname
);
15239 /* The .tbtab pseudo-op can only be used for the first eight
15240 expressions, since it can't handle the possibly variable
15241 length fields that follow. However, if you omit the optional
15242 fields, the assembler outputs zeros for all optional fields
15243 anyways, giving each variable length field is minimum length
15244 (as defined in sys/debug.h). Thus we can not use the .tbtab
15245 pseudo-op at all. */
15247 /* An all-zero word flags the start of the tbtab, for debuggers
15248 that have to find it by searching forward from the entry
15249 point or from the current pc. */
15250 fputs ("\t.long 0\n", file
);
15252 /* Tbtab format type. Use format type 0. */
15253 fputs ("\t.byte 0,", file
);
15255 /* Language type. Unfortunately, there does not seem to be any
15256 official way to discover the language being compiled, so we
15257 use language_string.
15258 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15259 Java is 13. Objective-C is 14. */
15260 if (! strcmp (language_string
, "GNU C"))
15262 else if (! strcmp (language_string
, "GNU F77")
15263 || ! strcmp (language_string
, "GNU F95"))
15265 else if (! strcmp (language_string
, "GNU Pascal"))
15267 else if (! strcmp (language_string
, "GNU Ada"))
15269 else if (! strcmp (language_string
, "GNU C++"))
15271 else if (! strcmp (language_string
, "GNU Java"))
15273 else if (! strcmp (language_string
, "GNU Objective-C"))
15276 gcc_unreachable ();
15277 fprintf (file
, "%d,", i
);
15279 /* 8 single bit fields: global linkage (not set for C extern linkage,
15280 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15281 from start of procedure stored in tbtab, internal function, function
15282 has controlled storage, function has no toc, function uses fp,
15283 function logs/aborts fp operations. */
15284 /* Assume that fp operations are used if any fp reg must be saved. */
15285 fprintf (file
, "%d,",
15286 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
15288 /* 6 bitfields: function is interrupt handler, name present in
15289 proc table, function calls alloca, on condition directives
15290 (controls stack walks, 3 bits), saves condition reg, saves
15292 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15293 set up as a frame pointer, even when there is no alloca call. */
15294 fprintf (file
, "%d,",
15295 ((optional_tbtab
<< 6)
15296 | ((optional_tbtab
& frame_pointer_needed
) << 5)
15297 | (info
->cr_save_p
<< 1)
15298 | (info
->lr_save_p
)));
15300 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15302 fprintf (file
, "%d,",
15303 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
15305 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15306 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
15308 if (optional_tbtab
)
15310 /* Compute the parameter info from the function decl argument
15313 int next_parm_info_bit
= 31;
15315 for (decl
= DECL_ARGUMENTS (current_function_decl
);
15316 decl
; decl
= TREE_CHAIN (decl
))
15318 rtx parameter
= DECL_INCOMING_RTL (decl
);
15319 enum machine_mode mode
= GET_MODE (parameter
);
15321 if (GET_CODE (parameter
) == REG
)
15323 if (SCALAR_FLOAT_MODE_P (mode
))
15341 gcc_unreachable ();
15344 /* If only one bit will fit, don't or in this entry. */
15345 if (next_parm_info_bit
> 0)
15346 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
15347 next_parm_info_bit
-= 2;
15351 fixed_parms
+= ((GET_MODE_SIZE (mode
)
15352 + (UNITS_PER_WORD
- 1))
15354 next_parm_info_bit
-= 1;
15360 /* Number of fixed point parameters. */
15361 /* This is actually the number of words of fixed point parameters; thus
15362 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15363 fprintf (file
, "%d,", fixed_parms
);
15365 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15367 /* This is actually the number of fp registers that hold parameters;
15368 and thus the maximum value is 13. */
15369 /* Set parameters on stack bit if parameters are not in their original
15370 registers, regardless of whether they are on the stack? Xlc
15371 seems to set the bit when not optimizing. */
15372 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
15374 if (! optional_tbtab
)
15377 /* Optional fields follow. Some are variable length. */
15379 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15380 11 double float. */
15381 /* There is an entry for each parameter in a register, in the order that
15382 they occur in the parameter list. Any intervening arguments on the
15383 stack are ignored. If the list overflows a long (max possible length
15384 34 bits) then completely leave off all elements that don't fit. */
15385 /* Only emit this long if there was at least one parameter. */
15386 if (fixed_parms
|| float_parms
)
15387 fprintf (file
, "\t.long %d\n", parm_info
);
15389 /* Offset from start of code to tb table. */
15390 fputs ("\t.long ", file
);
15391 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15393 RS6000_OUTPUT_BASENAME (file
, fname
);
15395 assemble_name (file
, fname
);
15397 rs6000_output_function_entry (file
, fname
);
15400 /* Interrupt handler mask. */
15401 /* Omit this long, since we never set the interrupt handler bit
15404 /* Number of CTL (controlled storage) anchors. */
15405 /* Omit this long, since the has_ctl bit is never set above. */
15407 /* Displacement into stack of each CTL anchor. */
15408 /* Omit this list of longs, because there are no CTL anchors. */
15410 /* Length of function name. */
15413 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
15415 /* Function name. */
15416 assemble_string (fname
, strlen (fname
));
15418 /* Register for alloca automatic storage; this is always reg 31.
15419 Only emit this if the alloca bit was set above. */
15420 if (frame_pointer_needed
)
15421 fputs ("\t.byte 31\n", file
);
15423 fputs ("\t.align 2\n", file
);
15427 /* A C compound statement that outputs the assembler code for a thunk
15428 function, used to implement C++ virtual function calls with
15429 multiple inheritance. The thunk acts as a wrapper around a virtual
15430 function, adjusting the implicit object parameter before handing
15431 control off to the real function.
15433 First, emit code to add the integer DELTA to the location that
15434 contains the incoming first argument. Assume that this argument
15435 contains a pointer, and is the one used to pass the `this' pointer
15436 in C++. This is the incoming argument *before* the function
15437 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15438 values of all other incoming arguments.
15440 After the addition, emit code to jump to FUNCTION, which is a
15441 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15442 not touch the return address. Hence returning from FUNCTION will
15443 return to whoever called the current `thunk'.
15445 The effect must be as if FUNCTION had been called directly with the
15446 adjusted first argument. This macro is responsible for emitting
15447 all of the code for a thunk function; output_function_prologue()
15448 and output_function_epilogue() are not invoked.
15450 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15451 been extracted from it.) It might possibly be useful on some
15452 targets, but probably not.
15454 If you do not define this macro, the target-independent code in the
15455 C++ frontend will generate a less efficient heavyweight thunk that
15456 calls FUNCTION instead of jumping to it. The generic approach does
15457 not support varargs. */
15460 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
15461 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
15464 rtx
this, insn
, funexp
;
15466 reload_completed
= 1;
15467 epilogue_completed
= 1;
15468 no_new_pseudos
= 1;
15469 reset_block_changes ();
15471 /* Mark the end of the (empty) prologue. */
15472 emit_note (NOTE_INSN_PROLOGUE_END
);
15474 /* Find the "this" pointer. If the function returns a structure,
15475 the structure return pointer is in r3. */
15476 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
15477 this = gen_rtx_REG (Pmode
, 4);
15479 this = gen_rtx_REG (Pmode
, 3);
15481 /* Apply the constant offset, if required. */
15484 rtx delta_rtx
= GEN_INT (delta
);
15485 emit_insn (TARGET_32BIT
15486 ? gen_addsi3 (this, this, delta_rtx
)
15487 : gen_adddi3 (this, this, delta_rtx
));
15490 /* Apply the offset from the vtable, if required. */
15493 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
15494 rtx tmp
= gen_rtx_REG (Pmode
, 12);
15496 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
15497 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
15499 emit_insn (TARGET_32BIT
15500 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
15501 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
15502 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
15506 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
15508 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
15510 emit_insn (TARGET_32BIT
15511 ? gen_addsi3 (this, this, tmp
)
15512 : gen_adddi3 (this, this, tmp
));
15515 /* Generate a tail call to the target function. */
15516 if (!TREE_USED (function
))
15518 assemble_external (function
);
15519 TREE_USED (function
) = 1;
15521 funexp
= XEXP (DECL_RTL (function
), 0);
15522 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
15525 if (MACHOPIC_INDIRECT
)
15526 funexp
= machopic_indirect_call_target (funexp
);
15529 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15530 generate sibcall RTL explicitly. */
15531 insn
= emit_call_insn (
15532 gen_rtx_PARALLEL (VOIDmode
,
15534 gen_rtx_CALL (VOIDmode
,
15535 funexp
, const0_rtx
),
15536 gen_rtx_USE (VOIDmode
, const0_rtx
),
15537 gen_rtx_USE (VOIDmode
,
15538 gen_rtx_REG (SImode
,
15539 LINK_REGISTER_REGNUM
)),
15540 gen_rtx_RETURN (VOIDmode
))));
15541 SIBLING_CALL_P (insn
) = 1;
15544 /* Run just enough of rest_of_compilation to get the insns emitted.
15545 There's not really enough bulk here to make other passes such as
15546 instruction scheduling worth while. Note that use_thunk calls
15547 assemble_start_function and assemble_end_function. */
15548 insn
= get_insns ();
15549 insn_locators_initialize ();
15550 shorten_branches (insn
);
15551 final_start_function (insn
, file
, 1);
15552 final (insn
, file
, 1);
15553 final_end_function ();
15555 reload_completed
= 0;
15556 epilogue_completed
= 0;
15557 no_new_pseudos
= 0;
15560 /* A quick summary of the various types of 'constant-pool tables'
15563 Target Flags Name One table per
15564 AIX (none) AIX TOC object file
15565 AIX -mfull-toc AIX TOC object file
15566 AIX -mminimal-toc AIX minimal TOC translation unit
15567 SVR4/EABI (none) SVR4 SDATA object file
15568 SVR4/EABI -fpic SVR4 pic object file
15569 SVR4/EABI -fPIC SVR4 PIC translation unit
15570 SVR4/EABI -mrelocatable EABI TOC function
15571 SVR4/EABI -maix AIX TOC object file
15572 SVR4/EABI -maix -mminimal-toc
15573 AIX minimal TOC translation unit
15575 Name Reg. Set by entries contains:
15576 made by addrs? fp? sum?
15578 AIX TOC 2 crt0 as Y option option
15579 AIX minimal TOC 30 prolog gcc Y Y option
15580 SVR4 SDATA 13 crt0 gcc N Y N
15581 SVR4 pic 30 prolog ld Y not yet N
15582 SVR4 PIC 30 prolog gcc Y option option
15583 EABI TOC 30 prolog gcc Y option option
15587 /* Hash functions for the hash table. */
15590 rs6000_hash_constant (rtx k
)
15592 enum rtx_code code
= GET_CODE (k
);
15593 enum machine_mode mode
= GET_MODE (k
);
15594 unsigned result
= (code
<< 3) ^ mode
;
15595 const char *format
;
15598 format
= GET_RTX_FORMAT (code
);
15599 flen
= strlen (format
);
15605 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
15608 if (mode
!= VOIDmode
)
15609 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
15621 for (; fidx
< flen
; fidx
++)
15622 switch (format
[fidx
])
15627 const char *str
= XSTR (k
, fidx
);
15628 len
= strlen (str
);
15629 result
= result
* 613 + len
;
15630 for (i
= 0; i
< len
; i
++)
15631 result
= result
* 613 + (unsigned) str
[i
];
15636 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
15640 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
15643 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
15644 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
15648 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
15649 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
15656 gcc_unreachable ();
15663 toc_hash_function (const void *hash_entry
)
15665 const struct toc_hash_struct
*thc
=
15666 (const struct toc_hash_struct
*) hash_entry
;
15667 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
15670 /* Compare H1 and H2 for equivalence. */
15673 toc_hash_eq (const void *h1
, const void *h2
)
15675 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
15676 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
15678 if (((const struct toc_hash_struct
*) h1
)->key_mode
15679 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
15682 return rtx_equal_p (r1
, r2
);
15685 /* These are the names given by the C++ front-end to vtables, and
15686 vtable-like objects. Ideally, this logic should not be here;
15687 instead, there should be some programmatic way of inquiring as
15688 to whether or not an object is a vtable. */
15690 #define VTABLE_NAME_P(NAME) \
15691 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
15692 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
15693 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
15694 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
15695 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
15698 rs6000_output_symbol_ref (FILE *file
, rtx x
)
15700 /* Currently C++ toc references to vtables can be emitted before it
15701 is decided whether the vtable is public or private. If this is
15702 the case, then the linker will eventually complain that there is
15703 a reference to an unknown section. Thus, for vtables only,
15704 we emit the TOC reference to reference the symbol and not the
15706 const char *name
= XSTR (x
, 0);
15708 if (VTABLE_NAME_P (name
))
15710 RS6000_OUTPUT_BASENAME (file
, name
);
15713 assemble_name (file
, name
);
15716 /* Output a TOC entry. We derive the entry name from what is being
15720 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
15723 const char *name
= buf
;
15724 const char *real_name
;
15726 HOST_WIDE_INT offset
= 0;
15728 gcc_assert (!TARGET_NO_TOC
);
15730 /* When the linker won't eliminate them, don't output duplicate
15731 TOC entries (this happens on AIX if there is any kind of TOC,
15732 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
15734 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
15736 struct toc_hash_struct
*h
;
15739 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
15740 time because GGC is not initialized at that point. */
15741 if (toc_hash_table
== NULL
)
15742 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
15743 toc_hash_eq
, NULL
);
15745 h
= ggc_alloc (sizeof (*h
));
15747 h
->key_mode
= mode
;
15748 h
->labelno
= labelno
;
15750 found
= htab_find_slot (toc_hash_table
, h
, 1);
15751 if (*found
== NULL
)
15753 else /* This is indeed a duplicate.
15754 Set this label equal to that label. */
15756 fputs ("\t.set ", file
);
15757 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
15758 fprintf (file
, "%d,", labelno
);
15759 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
15760 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
15766 /* If we're going to put a double constant in the TOC, make sure it's
15767 aligned properly when strict alignment is on. */
15768 if (GET_CODE (x
) == CONST_DOUBLE
15769 && STRICT_ALIGNMENT
15770 && GET_MODE_BITSIZE (mode
) >= 64
15771 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
15772 ASM_OUTPUT_ALIGN (file
, 3);
15775 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
15777 /* Handle FP constants specially. Note that if we have a minimal
15778 TOC, things we put here aren't actually in the TOC, so we can allow
15780 if (GET_CODE (x
) == CONST_DOUBLE
&&
15781 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
15783 REAL_VALUE_TYPE rv
;
15786 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
15787 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
15788 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
15790 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
15794 if (TARGET_MINIMAL_TOC
)
15795 fputs (DOUBLE_INT_ASM_OP
, file
);
15797 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15798 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15799 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15800 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
15801 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15802 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15807 if (TARGET_MINIMAL_TOC
)
15808 fputs ("\t.long ", file
);
15810 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15811 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15812 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15813 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
15814 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
15815 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
15819 else if (GET_CODE (x
) == CONST_DOUBLE
&&
15820 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
15822 REAL_VALUE_TYPE rv
;
15825 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
15827 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
15828 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
15830 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
15834 if (TARGET_MINIMAL_TOC
)
15835 fputs (DOUBLE_INT_ASM_OP
, file
);
15837 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
15838 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15839 fprintf (file
, "0x%lx%08lx\n",
15840 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15845 if (TARGET_MINIMAL_TOC
)
15846 fputs ("\t.long ", file
);
15848 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
15849 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15850 fprintf (file
, "0x%lx,0x%lx\n",
15851 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
15855 else if (GET_CODE (x
) == CONST_DOUBLE
&&
15856 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
15858 REAL_VALUE_TYPE rv
;
15861 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
15862 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
15863 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
15865 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
15869 if (TARGET_MINIMAL_TOC
)
15870 fputs (DOUBLE_INT_ASM_OP
, file
);
15872 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
15873 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
15878 if (TARGET_MINIMAL_TOC
)
15879 fputs ("\t.long ", file
);
15881 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
15882 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
15886 else if (GET_MODE (x
) == VOIDmode
15887 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
15889 unsigned HOST_WIDE_INT low
;
15890 HOST_WIDE_INT high
;
15892 if (GET_CODE (x
) == CONST_DOUBLE
)
15894 low
= CONST_DOUBLE_LOW (x
);
15895 high
= CONST_DOUBLE_HIGH (x
);
15898 #if HOST_BITS_PER_WIDE_INT == 32
15901 high
= (low
& 0x80000000) ? ~0 : 0;
15905 low
= INTVAL (x
) & 0xffffffff;
15906 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
15910 /* TOC entries are always Pmode-sized, but since this
15911 is a bigendian machine then if we're putting smaller
15912 integer constants in the TOC we have to pad them.
15913 (This is still a win over putting the constants in
15914 a separate constant pool, because then we'd have
15915 to have both a TOC entry _and_ the actual constant.)
15917 For a 32-bit target, CONST_INT values are loaded and shifted
15918 entirely within `low' and can be stored in one TOC entry. */
15920 /* It would be easy to make this work, but it doesn't now. */
15921 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
15923 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
15925 #if HOST_BITS_PER_WIDE_INT == 32
15926 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
15927 POINTER_SIZE
, &low
, &high
, 0);
15930 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
15931 high
= (HOST_WIDE_INT
) low
>> 32;
15938 if (TARGET_MINIMAL_TOC
)
15939 fputs (DOUBLE_INT_ASM_OP
, file
);
15941 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15942 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15943 fprintf (file
, "0x%lx%08lx\n",
15944 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15949 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
15951 if (TARGET_MINIMAL_TOC
)
15952 fputs ("\t.long ", file
);
15954 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
15955 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15956 fprintf (file
, "0x%lx,0x%lx\n",
15957 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
15961 if (TARGET_MINIMAL_TOC
)
15962 fputs ("\t.long ", file
);
15964 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
15965 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
15971 if (GET_CODE (x
) == CONST
)
15973 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
15975 base
= XEXP (XEXP (x
, 0), 0);
15976 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
15979 switch (GET_CODE (base
))
15982 name
= XSTR (base
, 0);
15986 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
15987 CODE_LABEL_NUMBER (XEXP (base
, 0)));
15991 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
15995 gcc_unreachable ();
15998 real_name
= (*targetm
.strip_name_encoding
) (name
);
15999 if (TARGET_MINIMAL_TOC
)
16000 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
16003 fprintf (file
, "\t.tc %s", real_name
);
16006 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
16008 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
16010 fputs ("[TC],", file
);
16013 /* Currently C++ toc references to vtables can be emitted before it
16014 is decided whether the vtable is public or private. If this is
16015 the case, then the linker will eventually complain that there is
16016 a TOC reference to an unknown section. Thus, for vtables only,
16017 we emit the TOC reference to reference the symbol and not the
16019 if (VTABLE_NAME_P (name
))
16021 RS6000_OUTPUT_BASENAME (file
, name
);
16023 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
16024 else if (offset
> 0)
16025 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
16028 output_addr_const (file
, x
);
16032 /* Output an assembler pseudo-op to write an ASCII string of N characters
16033 starting at P to FILE.
16035 On the RS/6000, we have to do this using the .byte operation and
16036 write out special characters outside the quoted string.
16037 Also, the assembler is broken; very long strings are truncated,
16038 so we must artificially break them up early. */
16041 output_ascii (FILE *file
, const char *p
, int n
)
16044 int i
, count_string
;
16045 const char *for_string
= "\t.byte \"";
16046 const char *for_decimal
= "\t.byte ";
16047 const char *to_close
= NULL
;
16050 for (i
= 0; i
< n
; i
++)
16053 if (c
>= ' ' && c
< 0177)
16056 fputs (for_string
, file
);
16059 /* Write two quotes to get one. */
16067 for_decimal
= "\"\n\t.byte ";
16071 if (count_string
>= 512)
16073 fputs (to_close
, file
);
16075 for_string
= "\t.byte \"";
16076 for_decimal
= "\t.byte ";
16084 fputs (for_decimal
, file
);
16085 fprintf (file
, "%d", c
);
16087 for_string
= "\n\t.byte \"";
16088 for_decimal
= ", ";
16094 /* Now close the string if we have written one. Then end the line. */
16096 fputs (to_close
, file
);
16099 /* Generate a unique section name for FILENAME for a section type
16100 represented by SECTION_DESC. Output goes into BUF.
16102 SECTION_DESC can be any string, as long as it is different for each
16103 possible section type.
16105 We name the section in the same manner as xlc. The name begins with an
16106 underscore followed by the filename (after stripping any leading directory
16107 names) with the last period replaced by the string SECTION_DESC. If
16108 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16112 rs6000_gen_section_name (char **buf
, const char *filename
,
16113 const char *section_desc
)
16115 const char *q
, *after_last_slash
, *last_period
= 0;
16119 after_last_slash
= filename
;
16120 for (q
= filename
; *q
; q
++)
16123 after_last_slash
= q
+ 1;
16124 else if (*q
== '.')
16128 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
16129 *buf
= (char *) xmalloc (len
);
16134 for (q
= after_last_slash
; *q
; q
++)
16136 if (q
== last_period
)
16138 strcpy (p
, section_desc
);
16139 p
+= strlen (section_desc
);
16143 else if (ISALNUM (*q
))
16147 if (last_period
== 0)
16148 strcpy (p
, section_desc
);
16153 /* Emit profile function. */
16156 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
16158 /* Non-standard profiling for kernels, which just saves LR then calls
16159 _mcount without worrying about arg saves. The idea is to change
16160 the function prologue as little as possible as it isn't easy to
16161 account for arg save/restore code added just for _mcount. */
16162 if (TARGET_PROFILE_KERNEL
)
16165 if (DEFAULT_ABI
== ABI_AIX
)
16167 #ifndef NO_PROFILE_COUNTERS
16168 # define NO_PROFILE_COUNTERS 0
16170 if (NO_PROFILE_COUNTERS
)
16171 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
16175 const char *label_name
;
16178 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16179 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
16180 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
16182 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
16186 else if (DEFAULT_ABI
== ABI_DARWIN
)
16188 const char *mcount_name
= RS6000_MCOUNT
;
16189 int caller_addr_regno
= LINK_REGISTER_REGNUM
;
16191 /* Be conservative and always set this, at least for now. */
16192 current_function_uses_pic_offset_table
= 1;
16195 /* For PIC code, set up a stub and collect the caller's address
16196 from r0, which is where the prologue puts it. */
16197 if (MACHOPIC_INDIRECT
16198 && current_function_uses_pic_offset_table
)
16199 caller_addr_regno
= 0;
16201 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
16203 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
16207 /* Write function profiler code. */
16210 output_function_profiler (FILE *file
, int labelno
)
16214 switch (DEFAULT_ABI
)
16217 gcc_unreachable ();
16222 warning (0, "no profiling of 64-bit code for this ABI");
16225 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16226 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16227 if (NO_PROFILE_COUNTERS
)
16229 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16230 reg_names
[0], reg_names
[1]);
16232 else if (TARGET_SECURE_PLT
&& flag_pic
)
16234 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16235 reg_names
[0], reg_names
[1]);
16236 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16237 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
16238 reg_names
[12], reg_names
[12]);
16239 assemble_name (file
, buf
);
16240 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
16241 assemble_name (file
, buf
);
16242 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
16244 else if (flag_pic
== 1)
16246 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
16247 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16248 reg_names
[0], reg_names
[1]);
16249 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16250 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
16251 assemble_name (file
, buf
);
16252 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
16254 else if (flag_pic
> 1)
16256 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16257 reg_names
[0], reg_names
[1]);
16258 /* Now, we need to get the address of the label. */
16259 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
16260 assemble_name (file
, buf
);
16261 fputs ("-.\n1:", file
);
16262 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
16263 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
16264 reg_names
[0], reg_names
[11]);
16265 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
16266 reg_names
[0], reg_names
[0], reg_names
[11]);
16270 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
16271 assemble_name (file
, buf
);
16272 fputs ("@ha\n", file
);
16273 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16274 reg_names
[0], reg_names
[1]);
16275 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
16276 assemble_name (file
, buf
);
16277 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
16280 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16281 fprintf (file
, "\tbl %s%s\n",
16282 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
16287 if (!TARGET_PROFILE_KERNEL
)
16289 /* Don't do anything, done in output_profile_hook (). */
16293 gcc_assert (!TARGET_32BIT
);
16295 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16296 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
16298 if (cfun
->static_chain_decl
!= NULL
)
16300 asm_fprintf (file
, "\tstd %s,24(%s)\n",
16301 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16302 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16303 asm_fprintf (file
, "\tld %s,24(%s)\n",
16304 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16307 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16314 /* Power4 load update and store update instructions are cracked into a
16315 load or store and an integer insn which are executed in the same cycle.
16316 Branches have their own dispatch slot which does not count against the
16317 GCC issue rate, but it changes the program flow so there are no other
16318 instructions to issue in this cycle. */
16321 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
16322 int verbose ATTRIBUTE_UNUSED
,
16323 rtx insn
, int more
)
16325 if (GET_CODE (PATTERN (insn
)) == USE
16326 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16329 if (rs6000_sched_groups
)
16331 if (is_microcoded_insn (insn
))
16333 else if (is_cracked_insn (insn
))
16334 return more
> 2 ? more
- 2 : 0;
16340 /* Adjust the cost of a scheduling dependency. Return the new cost of
16341 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16344 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
16346 if (! recog_memoized (insn
))
16349 if (REG_NOTE_KIND (link
) != 0)
16352 if (REG_NOTE_KIND (link
) == 0)
16354 /* Data dependency; DEP_INSN writes a register that INSN reads
16355 some cycles later. */
16357 /* Separate a load from a narrower, dependent store. */
16358 if (rs6000_sched_groups
16359 && GET_CODE (PATTERN (insn
)) == SET
16360 && GET_CODE (PATTERN (dep_insn
)) == SET
16361 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
16362 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
16363 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
16364 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
16367 switch (get_attr_type (insn
))
16370 /* Tell the first scheduling pass about the latency between
16371 a mtctr and bctr (and mtlr and br/blr). The first
16372 scheduling pass will not know about this latency since
16373 the mtctr instruction, which has the latency associated
16374 to it, will be generated by reload. */
16375 return TARGET_POWER
? 5 : 4;
16377 /* Leave some extra cycles between a compare and its
16378 dependent branch, to inhibit expensive mispredicts. */
16379 if ((rs6000_cpu_attr
== CPU_PPC603
16380 || rs6000_cpu_attr
== CPU_PPC604
16381 || rs6000_cpu_attr
== CPU_PPC604E
16382 || rs6000_cpu_attr
== CPU_PPC620
16383 || rs6000_cpu_attr
== CPU_PPC630
16384 || rs6000_cpu_attr
== CPU_PPC750
16385 || rs6000_cpu_attr
== CPU_PPC7400
16386 || rs6000_cpu_attr
== CPU_PPC7450
16387 || rs6000_cpu_attr
== CPU_POWER4
16388 || rs6000_cpu_attr
== CPU_POWER5
)
16389 && recog_memoized (dep_insn
)
16390 && (INSN_CODE (dep_insn
) >= 0)
16391 && (get_attr_type (dep_insn
) == TYPE_CMP
16392 || get_attr_type (dep_insn
) == TYPE_COMPARE
16393 || get_attr_type (dep_insn
) == TYPE_DELAYED_COMPARE
16394 || get_attr_type (dep_insn
) == TYPE_IMUL_COMPARE
16395 || get_attr_type (dep_insn
) == TYPE_LMUL_COMPARE
16396 || get_attr_type (dep_insn
) == TYPE_FPCOMPARE
16397 || get_attr_type (dep_insn
) == TYPE_CR_LOGICAL
16398 || get_attr_type (dep_insn
) == TYPE_DELAYED_CR
))
16403 /* Fall out to return default cost. */
16409 /* The function returns a true if INSN is microcoded.
16410 Return false otherwise. */
16413 is_microcoded_insn (rtx insn
)
16415 if (!insn
|| !INSN_P (insn
)
16416 || GET_CODE (PATTERN (insn
)) == USE
16417 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16420 if (rs6000_sched_groups
)
16422 enum attr_type type
= get_attr_type (insn
);
16423 if (type
== TYPE_LOAD_EXT_U
16424 || type
== TYPE_LOAD_EXT_UX
16425 || type
== TYPE_LOAD_UX
16426 || type
== TYPE_STORE_UX
16427 || type
== TYPE_MFCR
)
16434 /* The function returns a nonzero value if INSN can be scheduled only
16435 as the first insn in a dispatch group ("dispatch-slot restricted").
16436 In this case, the returned value indicates how many dispatch slots
16437 the insn occupies (at the beginning of the group).
16438 Return 0 otherwise. */
16441 is_dispatch_slot_restricted (rtx insn
)
16443 enum attr_type type
;
16445 if (!rs6000_sched_groups
)
16449 || insn
== NULL_RTX
16450 || GET_CODE (insn
) == NOTE
16451 || GET_CODE (PATTERN (insn
)) == USE
16452 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16455 type
= get_attr_type (insn
);
16462 case TYPE_DELAYED_CR
:
16463 case TYPE_CR_LOGICAL
:
16476 if (rs6000_cpu
== PROCESSOR_POWER5
16477 && is_cracked_insn (insn
))
16483 /* The function returns true if INSN is cracked into 2 instructions
16484 by the processor (and therefore occupies 2 issue slots). */
16487 is_cracked_insn (rtx insn
)
16489 if (!insn
|| !INSN_P (insn
)
16490 || GET_CODE (PATTERN (insn
)) == USE
16491 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16494 if (rs6000_sched_groups
)
16496 enum attr_type type
= get_attr_type (insn
);
16497 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
16498 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
16499 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
16500 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
16501 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
16502 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
16503 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
16504 || type
== TYPE_INSERT_WORD
)
16511 /* The function returns true if INSN can be issued only from
16512 the branch slot. */
16515 is_branch_slot_insn (rtx insn
)
16517 if (!insn
|| !INSN_P (insn
)
16518 || GET_CODE (PATTERN (insn
)) == USE
16519 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16522 if (rs6000_sched_groups
)
16524 enum attr_type type
= get_attr_type (insn
);
16525 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
16533 /* A C statement (sans semicolon) to update the integer scheduling
16534 priority INSN_PRIORITY (INSN). Increase the priority to execute the
16535 INSN earlier, reduce the priority to execute INSN later. Do not
16536 define this macro if you do not need to adjust the scheduling
16537 priorities of insns. */
16540 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
16542 /* On machines (like the 750) which have asymmetric integer units,
16543 where one integer unit can do multiply and divides and the other
16544 can't, reduce the priority of multiply/divide so it is scheduled
16545 before other integer operations. */
16548 if (! INSN_P (insn
))
16551 if (GET_CODE (PATTERN (insn
)) == USE
)
16554 switch (rs6000_cpu_attr
) {
16556 switch (get_attr_type (insn
))
16563 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
16564 priority
, priority
);
16565 if (priority
>= 0 && priority
< 0x01000000)
16572 if (is_dispatch_slot_restricted (insn
)
16573 && reload_completed
16574 && current_sched_info
->sched_max_insns_priority
16575 && rs6000_sched_restricted_insns_priority
)
16578 /* Prioritize insns that can be dispatched only in the first
16580 if (rs6000_sched_restricted_insns_priority
== 1)
16581 /* Attach highest priority to insn. This means that in
16582 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
16583 precede 'priority' (critical path) considerations. */
16584 return current_sched_info
->sched_max_insns_priority
;
16585 else if (rs6000_sched_restricted_insns_priority
== 2)
16586 /* Increase priority of insn by a minimal amount. This means that in
16587 haifa-sched.c:ready_sort(), only 'priority' (critical path)
16588 considerations precede dispatch-slot restriction considerations. */
16589 return (priority
+ 1);
16595 /* Return how many instructions the machine can issue per cycle. */
16598 rs6000_issue_rate (void)
16600 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
16601 if (!reload_completed
)
16604 switch (rs6000_cpu_attr
) {
16605 case CPU_RIOS1
: /* ? */
16607 case CPU_PPC601
: /* ? */
16630 /* Return how many instructions to look ahead for better insn
16634 rs6000_use_sched_lookahead (void)
16636 if (rs6000_cpu_attr
== CPU_PPC8540
)
16641 /* Determine is PAT refers to memory. */
16644 is_mem_ref (rtx pat
)
16650 if (GET_CODE (pat
) == MEM
)
16653 /* Recursively process the pattern. */
16654 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
16656 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
16659 ret
|= is_mem_ref (XEXP (pat
, i
));
16660 else if (fmt
[i
] == 'E')
16661 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
16662 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
16668 /* Determine if PAT is a PATTERN of a load insn. */
16671 is_load_insn1 (rtx pat
)
16673 if (!pat
|| pat
== NULL_RTX
)
16676 if (GET_CODE (pat
) == SET
)
16677 return is_mem_ref (SET_SRC (pat
));
16679 if (GET_CODE (pat
) == PARALLEL
)
16683 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
16684 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
16691 /* Determine if INSN loads from memory. */
16694 is_load_insn (rtx insn
)
16696 if (!insn
|| !INSN_P (insn
))
16699 if (GET_CODE (insn
) == CALL_INSN
)
16702 return is_load_insn1 (PATTERN (insn
));
16705 /* Determine if PAT is a PATTERN of a store insn. */
16708 is_store_insn1 (rtx pat
)
16710 if (!pat
|| pat
== NULL_RTX
)
16713 if (GET_CODE (pat
) == SET
)
16714 return is_mem_ref (SET_DEST (pat
));
16716 if (GET_CODE (pat
) == PARALLEL
)
16720 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
16721 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
16728 /* Determine if INSN stores to memory. */
16731 is_store_insn (rtx insn
)
16733 if (!insn
|| !INSN_P (insn
))
16736 return is_store_insn1 (PATTERN (insn
));
16739 /* Returns whether the dependence between INSN and NEXT is considered
16740 costly by the given target. */
16743 rs6000_is_costly_dependence (rtx insn
, rtx next
, rtx link
, int cost
,
16746 /* If the flag is not enabled - no dependence is considered costly;
16747 allow all dependent insns in the same group.
16748 This is the most aggressive option. */
16749 if (rs6000_sched_costly_dep
== no_dep_costly
)
16752 /* If the flag is set to 1 - a dependence is always considered costly;
16753 do not allow dependent instructions in the same group.
16754 This is the most conservative option. */
16755 if (rs6000_sched_costly_dep
== all_deps_costly
)
16758 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
16759 && is_load_insn (next
)
16760 && is_store_insn (insn
))
16761 /* Prevent load after store in the same group. */
16764 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
16765 && is_load_insn (next
)
16766 && is_store_insn (insn
)
16767 && (!link
|| (int) REG_NOTE_KIND (link
) == 0))
16768 /* Prevent load after store in the same group if it is a true
16772 /* The flag is set to X; dependences with latency >= X are considered costly,
16773 and will not be scheduled in the same group. */
16774 if (rs6000_sched_costly_dep
<= max_dep_latency
16775 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
16781 /* Return the next insn after INSN that is found before TAIL is reached,
16782 skipping any "non-active" insns - insns that will not actually occupy
16783 an issue slot. Return NULL_RTX if such an insn is not found. */
16786 get_next_active_insn (rtx insn
, rtx tail
)
16788 if (insn
== NULL_RTX
|| insn
== tail
)
16793 insn
= NEXT_INSN (insn
);
16794 if (insn
== NULL_RTX
|| insn
== tail
)
16799 || (NONJUMP_INSN_P (insn
)
16800 && GET_CODE (PATTERN (insn
)) != USE
16801 && GET_CODE (PATTERN (insn
)) != CLOBBER
16802 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
16808 /* Return whether the presence of INSN causes a dispatch group termination
16809 of group WHICH_GROUP.
16811 If WHICH_GROUP == current_group, this function will return true if INSN
16812 causes the termination of the current group (i.e, the dispatch group to
16813 which INSN belongs). This means that INSN will be the last insn in the
16814 group it belongs to.
16816 If WHICH_GROUP == previous_group, this function will return true if INSN
16817 causes the termination of the previous group (i.e, the dispatch group that
16818 precedes the group to which INSN belongs). This means that INSN will be
16819 the first insn in the group it belongs to). */
16822 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
16824 enum attr_type type
;
16829 type
= get_attr_type (insn
);
16831 if (is_microcoded_insn (insn
))
16834 if (which_group
== current_group
)
16836 if (is_branch_slot_insn (insn
))
16840 else if (which_group
== previous_group
)
16842 if (is_dispatch_slot_restricted (insn
))
16850 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
16851 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
16854 is_costly_group (rtx
*group_insns
, rtx next_insn
)
16859 int issue_rate
= rs6000_issue_rate ();
16861 for (i
= 0; i
< issue_rate
; i
++)
16863 rtx insn
= group_insns
[i
];
16866 for (link
= INSN_DEPEND (insn
); link
!= 0; link
= XEXP (link
, 1))
16868 rtx next
= XEXP (link
, 0);
16869 if (next
== next_insn
)
16871 cost
= insn_cost (insn
, link
, next_insn
);
16872 if (rs6000_is_costly_dependence (insn
, next_insn
, link
, cost
, 0))
16881 /* Utility of the function redefine_groups.
16882 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
16883 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
16884 to keep it "far" (in a separate group) from GROUP_INSNS, following
16885 one of the following schemes, depending on the value of the flag
16886 -minsert_sched_nops = X:
16887 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
16888 in order to force NEXT_INSN into a separate group.
16889 (2) X < sched_finish_regroup_exact: insert exactly X nops.
16890 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
16891 insertion (has a group just ended, how many vacant issue slots remain in the
16892 last group, and how many dispatch groups were encountered so far). */
16895 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
16896 rtx next_insn
, bool *group_end
, int can_issue_more
,
16901 int issue_rate
= rs6000_issue_rate ();
16902 bool end
= *group_end
;
16905 if (next_insn
== NULL_RTX
)
16906 return can_issue_more
;
16908 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
16909 return can_issue_more
;
16911 force
= is_costly_group (group_insns
, next_insn
);
16913 return can_issue_more
;
16915 if (sched_verbose
> 6)
16916 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
16917 *group_count
,can_issue_more
);
16919 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
16922 can_issue_more
= 0;
16924 /* Since only a branch can be issued in the last issue_slot, it is
16925 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
16926 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
16927 in this case the last nop will start a new group and the branch
16928 will be forced to the new group. */
16929 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
16932 while (can_issue_more
> 0)
16935 emit_insn_before (nop
, next_insn
);
16943 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
16945 int n_nops
= rs6000_sched_insert_nops
;
16947 /* Nops can't be issued from the branch slot, so the effective
16948 issue_rate for nops is 'issue_rate - 1'. */
16949 if (can_issue_more
== 0)
16950 can_issue_more
= issue_rate
;
16952 if (can_issue_more
== 0)
16954 can_issue_more
= issue_rate
- 1;
16957 for (i
= 0; i
< issue_rate
; i
++)
16959 group_insns
[i
] = 0;
16966 emit_insn_before (nop
, next_insn
);
16967 if (can_issue_more
== issue_rate
- 1) /* new group begins */
16970 if (can_issue_more
== 0)
16972 can_issue_more
= issue_rate
- 1;
16975 for (i
= 0; i
< issue_rate
; i
++)
16977 group_insns
[i
] = 0;
16983 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
16986 /* Is next_insn going to start a new group? */
16989 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
16990 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
16991 || (can_issue_more
< issue_rate
&&
16992 insn_terminates_group_p (next_insn
, previous_group
)));
16993 if (*group_end
&& end
)
16996 if (sched_verbose
> 6)
16997 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
16998 *group_count
, can_issue_more
);
16999 return can_issue_more
;
17002 return can_issue_more
;
17005 /* This function tries to synch the dispatch groups that the compiler "sees"
17006 with the dispatch groups that the processor dispatcher is expected to
17007 form in practice. It tries to achieve this synchronization by forcing the
17008 estimated processor grouping on the compiler (as opposed to the function
17009 'pad_goups' which tries to force the scheduler's grouping on the processor).
17011 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
17012 examines the (estimated) dispatch groups that will be formed by the processor
17013 dispatcher. It marks these group boundaries to reflect the estimated
17014 processor grouping, overriding the grouping that the scheduler had marked.
17015 Depending on the value of the flag '-minsert-sched-nops' this function can
17016 force certain insns into separate groups or force a certain distance between
17017 them by inserting nops, for example, if there exists a "costly dependence"
17020 The function estimates the group boundaries that the processor will form as
17021 follows: It keeps track of how many vacant issue slots are available after
17022 each insn. A subsequent insn will start a new group if one of the following
17024 - no more vacant issue slots remain in the current dispatch group.
17025 - only the last issue slot, which is the branch slot, is vacant, but the next
17026 insn is not a branch.
17027 - only the last 2 or less issue slots, including the branch slot, are vacant,
17028 which means that a cracked insn (which occupies two issue slots) can't be
17029 issued in this group.
17030 - less than 'issue_rate' slots are vacant, and the next insn always needs to
17031 start a new group. */
17034 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
17036 rtx insn
, next_insn
;
17038 int can_issue_more
;
17041 int group_count
= 0;
17045 issue_rate
= rs6000_issue_rate ();
17046 group_insns
= alloca (issue_rate
* sizeof (rtx
));
17047 for (i
= 0; i
< issue_rate
; i
++)
17049 group_insns
[i
] = 0;
17051 can_issue_more
= issue_rate
;
17053 insn
= get_next_active_insn (prev_head_insn
, tail
);
17056 while (insn
!= NULL_RTX
)
17058 slot
= (issue_rate
- can_issue_more
);
17059 group_insns
[slot
] = insn
;
17061 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
17062 if (insn_terminates_group_p (insn
, current_group
))
17063 can_issue_more
= 0;
17065 next_insn
= get_next_active_insn (insn
, tail
);
17066 if (next_insn
== NULL_RTX
)
17067 return group_count
+ 1;
17069 /* Is next_insn going to start a new group? */
17071 = (can_issue_more
== 0
17072 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
17073 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
17074 || (can_issue_more
< issue_rate
&&
17075 insn_terminates_group_p (next_insn
, previous_group
)));
17077 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
17078 next_insn
, &group_end
, can_issue_more
,
17084 can_issue_more
= 0;
17085 for (i
= 0; i
< issue_rate
; i
++)
17087 group_insns
[i
] = 0;
17091 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
17092 PUT_MODE (next_insn
, VOIDmode
);
17093 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
17094 PUT_MODE (next_insn
, TImode
);
17097 if (can_issue_more
== 0)
17098 can_issue_more
= issue_rate
;
17101 return group_count
;
17104 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
17105 dispatch group boundaries that the scheduler had marked. Pad with nops
17106 any dispatch groups which have vacant issue slots, in order to force the
17107 scheduler's grouping on the processor dispatcher. The function
17108 returns the number of dispatch groups found. */
17111 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
17113 rtx insn
, next_insn
;
17116 int can_issue_more
;
17118 int group_count
= 0;
17120 /* Initialize issue_rate. */
17121 issue_rate
= rs6000_issue_rate ();
17122 can_issue_more
= issue_rate
;
17124 insn
= get_next_active_insn (prev_head_insn
, tail
);
17125 next_insn
= get_next_active_insn (insn
, tail
);
17127 while (insn
!= NULL_RTX
)
17130 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
17132 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
17134 if (next_insn
== NULL_RTX
)
17139 /* If the scheduler had marked group termination at this location
17140 (between insn and next_indn), and neither insn nor next_insn will
17141 force group termination, pad the group with nops to force group
17144 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
17145 && !insn_terminates_group_p (insn
, current_group
)
17146 && !insn_terminates_group_p (next_insn
, previous_group
))
17148 if (!is_branch_slot_insn (next_insn
))
17151 while (can_issue_more
)
17154 emit_insn_before (nop
, next_insn
);
17159 can_issue_more
= issue_rate
;
17164 next_insn
= get_next_active_insn (insn
, tail
);
17167 return group_count
;
17170 /* The following function is called at the end of scheduling BB.
17171 After reload, it inserts nops at insn group bundling. */
17174 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
17179 fprintf (dump
, "=== Finishing schedule.\n");
17181 if (reload_completed
&& rs6000_sched_groups
)
17183 if (rs6000_sched_insert_nops
== sched_finish_none
)
17186 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
17187 n_groups
= pad_groups (dump
, sched_verbose
,
17188 current_sched_info
->prev_head
,
17189 current_sched_info
->next_tail
);
17191 n_groups
= redefine_groups (dump
, sched_verbose
,
17192 current_sched_info
->prev_head
,
17193 current_sched_info
->next_tail
);
17195 if (sched_verbose
>= 6)
17197 fprintf (dump
, "ngroups = %d\n", n_groups
);
17198 print_rtl (dump
, current_sched_info
->prev_head
);
17199 fprintf (dump
, "Done finish_sched\n");
17204 /* Length in units of the trampoline for entering a nested function. */
17207 rs6000_trampoline_size (void)
17211 switch (DEFAULT_ABI
)
17214 gcc_unreachable ();
17217 ret
= (TARGET_32BIT
) ? 12 : 24;
17222 ret
= (TARGET_32BIT
) ? 40 : 48;
17229 /* Emit RTL insns to initialize the variable parts of a trampoline.
17230 FNADDR is an RTX for the address of the function's pure code.
17231 CXT is an RTX for the static chain value for the function. */
17234 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
17236 enum machine_mode pmode
= Pmode
;
17237 int regsize
= (TARGET_32BIT
) ? 4 : 8;
17238 rtx ctx_reg
= force_reg (pmode
, cxt
);
17240 switch (DEFAULT_ABI
)
17243 gcc_unreachable ();
17245 /* Macros to shorten the code expansions below. */
17246 #define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
17247 #define MEM_PLUS(addr,offset) \
17248 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
17250 /* Under AIX, just build the 3 word function descriptor */
17253 rtx fn_reg
= gen_reg_rtx (pmode
);
17254 rtx toc_reg
= gen_reg_rtx (pmode
);
17255 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
17256 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
17257 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
17258 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
17259 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
17263 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
17266 emit_library_call (gen_rtx_SYMBOL_REF (SImode
, "__trampoline_setup"),
17267 FALSE
, VOIDmode
, 4,
17269 GEN_INT (rs6000_trampoline_size ()), SImode
,
17279 /* Table of valid machine attributes. */
17281 const struct attribute_spec rs6000_attribute_table
[] =
17283 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
17284 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
17285 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
17286 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
17287 #ifdef SUBTARGET_ATTRIBUTE_TABLE
17288 SUBTARGET_ATTRIBUTE_TABLE
,
17290 { NULL
, 0, 0, false, false, false, NULL
}
17293 /* Handle the "altivec" attribute. The attribute may have
17294 arguments as follows:
17296 __attribute__((altivec(vector__)))
17297 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
17298 __attribute__((altivec(bool__))) (always followed by 'unsigned')
17300 and may appear more than once (e.g., 'vector bool char') in a
17301 given declaration. */
17304 rs6000_handle_altivec_attribute (tree
*node
,
17305 tree name ATTRIBUTE_UNUSED
,
17307 int flags ATTRIBUTE_UNUSED
,
17308 bool *no_add_attrs
)
17310 tree type
= *node
, result
= NULL_TREE
;
17311 enum machine_mode mode
;
17314 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
17315 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
17316 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
17319 while (POINTER_TYPE_P (type
)
17320 || TREE_CODE (type
) == FUNCTION_TYPE
17321 || TREE_CODE (type
) == METHOD_TYPE
17322 || TREE_CODE (type
) == ARRAY_TYPE
)
17323 type
= TREE_TYPE (type
);
17325 mode
= TYPE_MODE (type
);
17327 /* Check for invalid AltiVec type qualifiers. */
17328 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
17331 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
17332 else if (rs6000_warn_altivec_long
)
17333 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
17335 else if (type
== long_long_unsigned_type_node
17336 || type
== long_long_integer_type_node
)
17337 error ("use of %<long long%> in AltiVec types is invalid");
17338 else if (type
== double_type_node
)
17339 error ("use of %<double%> in AltiVec types is invalid");
17340 else if (type
== long_double_type_node
)
17341 error ("use of %<long double%> in AltiVec types is invalid");
17342 else if (type
== boolean_type_node
)
17343 error ("use of boolean types in AltiVec types is invalid");
17344 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
17345 error ("use of %<complex%> in AltiVec types is invalid");
17346 else if (DECIMAL_FLOAT_MODE_P (mode
))
17347 error ("use of decimal floating point types in AltiVec types is invalid");
17349 switch (altivec_type
)
17352 unsigned_p
= TYPE_UNSIGNED (type
);
17356 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
17359 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
17362 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
17364 case SFmode
: result
= V4SF_type_node
; break;
17365 /* If the user says 'vector int bool', we may be handed the 'bool'
17366 attribute _before_ the 'vector' attribute, and so select the
17367 proper type in the 'b' case below. */
17368 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
17376 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
17377 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
17378 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
17385 case V8HImode
: result
= pixel_V8HI_type_node
;
17391 if (result
&& result
!= type
&& TYPE_READONLY (type
))
17392 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
17394 *no_add_attrs
= true; /* No need to hang on to the attribute. */
17397 *node
= reconstruct_complex_type (*node
, result
);
17402 /* AltiVec defines four built-in scalar types that serve as vector
17403 elements; we must teach the compiler how to mangle them. */
17405 static const char *
17406 rs6000_mangle_fundamental_type (tree type
)
17408 if (type
== bool_char_type_node
) return "U6__boolc";
17409 if (type
== bool_short_type_node
) return "U6__bools";
17410 if (type
== pixel_type_node
) return "u7__pixel";
17411 if (type
== bool_int_type_node
) return "U6__booli";
17413 /* For all other types, use normal C++ mangling. */
17417 /* Handle a "longcall" or "shortcall" attribute; arguments as in
17418 struct attribute_spec.handler. */
17421 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
17422 tree args ATTRIBUTE_UNUSED
,
17423 int flags ATTRIBUTE_UNUSED
,
17424 bool *no_add_attrs
)
17426 if (TREE_CODE (*node
) != FUNCTION_TYPE
17427 && TREE_CODE (*node
) != FIELD_DECL
17428 && TREE_CODE (*node
) != TYPE_DECL
)
17430 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
17431 IDENTIFIER_POINTER (name
));
17432 *no_add_attrs
= true;
17438 /* Set longcall attributes on all functions declared when
17439 rs6000_default_long_calls is true. */
17441 rs6000_set_default_type_attributes (tree type
)
17443 if (rs6000_default_long_calls
17444 && (TREE_CODE (type
) == FUNCTION_TYPE
17445 || TREE_CODE (type
) == METHOD_TYPE
))
17446 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
17448 TYPE_ATTRIBUTES (type
));
17451 /* Return a reference suitable for calling a function with the
17452 longcall attribute. */
17455 rs6000_longcall_ref (rtx call_ref
)
17457 const char *call_name
;
17460 if (GET_CODE (call_ref
) != SYMBOL_REF
)
17463 /* System V adds '.' to the internal name, so skip them. */
17464 call_name
= XSTR (call_ref
, 0);
17465 if (*call_name
== '.')
17467 while (*call_name
== '.')
17470 node
= get_identifier (call_name
);
17471 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
17474 return force_reg (Pmode
, call_ref
);
17477 #ifdef USING_ELFOS_H
17479 /* A get_unnamed_section callback, used for switching to toc_section. */
17482 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
17484 if (DEFAULT_ABI
== ABI_AIX
17485 && TARGET_MINIMAL_TOC
17486 && !TARGET_RELOCATABLE
)
17488 if (!toc_initialized
)
17490 toc_initialized
= 1;
17491 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
17492 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
17493 fprintf (asm_out_file
, "\t.tc ");
17494 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
17495 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
17496 fprintf (asm_out_file
, "\n");
17498 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
17499 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
17500 fprintf (asm_out_file
, " = .+32768\n");
17503 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
17505 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
17506 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
17509 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
17510 if (!toc_initialized
)
17512 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
17513 fprintf (asm_out_file
, " = .+32768\n");
17514 toc_initialized
= 1;
17519 /* Implement TARGET_ASM_INIT_SECTIONS. */
17522 rs6000_elf_asm_init_sections (void)
17525 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
17528 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
17529 SDATA2_SECTION_ASM_OP
);
17532 /* Implement TARGET_SELECT_RTX_SECTION. */
17535 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
17536 unsigned HOST_WIDE_INT align
)
17538 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
17539 return toc_section
;
17541 return default_elf_select_rtx_section (mode
, x
, align
);
17544 /* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */
17547 rs6000_elf_select_section (tree decl
, int reloc
,
17548 unsigned HOST_WIDE_INT align
)
17550 /* Pretend that we're always building for a shared library when
17551 ABI_AIX, because otherwise we end up with dynamic relocations
17552 in read-only sections. This happens for function pointers,
17553 references to vtables in typeinfo, and probably other cases. */
17554 return default_elf_select_section_1 (decl
, reloc
, align
,
17555 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
17558 /* A C statement to build up a unique section name, expressed as a
17559 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
17560 RELOC indicates whether the initial value of EXP requires
17561 link-time relocations. If you do not define this macro, GCC will use
17562 the symbol name prefixed by `.' as the section name. Note - this
17563 macro can now be called for uninitialized data items as well as
17564 initialized data and functions. */
17567 rs6000_elf_unique_section (tree decl
, int reloc
)
17569 /* As above, pretend that we're always building for a shared library
17570 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
17571 default_unique_section_1 (decl
, reloc
,
17572 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
17575 /* For a SYMBOL_REF, set generic flags and then perform some
17576 target-specific processing.
17578 When the AIX ABI is requested on a non-AIX system, replace the
17579 function name with the real name (with a leading .) rather than the
17580 function descriptor name. This saves a lot of overriding code to
17581 read the prefixes. */
17584 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
17586 default_encode_section_info (decl
, rtl
, first
);
17589 && TREE_CODE (decl
) == FUNCTION_DECL
17591 && DEFAULT_ABI
== ABI_AIX
)
17593 rtx sym_ref
= XEXP (rtl
, 0);
17594 size_t len
= strlen (XSTR (sym_ref
, 0));
17595 char *str
= alloca (len
+ 2);
17597 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
17598 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
17603 rs6000_elf_in_small_data_p (tree decl
)
17605 if (rs6000_sdata
== SDATA_NONE
)
17608 /* We want to merge strings, so we never consider them small data. */
17609 if (TREE_CODE (decl
) == STRING_CST
)
17612 /* Functions are never in the small data area. */
17613 if (TREE_CODE (decl
) == FUNCTION_DECL
)
17616 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
17618 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
17619 if (strcmp (section
, ".sdata") == 0
17620 || strcmp (section
, ".sdata2") == 0
17621 || strcmp (section
, ".sbss") == 0
17622 || strcmp (section
, ".sbss2") == 0
17623 || strcmp (section
, ".PPC.EMB.sdata0") == 0
17624 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
17629 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
17632 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
17633 /* If it's not public, and we're not going to reference it there,
17634 there's no need to put it in the small data section. */
17635 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
17642 #endif /* USING_ELFOS_H */
17645 /* Return a REG that occurs in ADDR with coefficient 1.
17646 ADDR can be effectively incremented by incrementing REG.
17648 r0 is special and we must not select it as an address
17649 register by this routine since our caller will try to
17650 increment the returned register via an "la" instruction. */
17653 find_addr_reg (rtx addr
)
17655 while (GET_CODE (addr
) == PLUS
)
17657 if (GET_CODE (XEXP (addr
, 0)) == REG
17658 && REGNO (XEXP (addr
, 0)) != 0)
17659 addr
= XEXP (addr
, 0);
17660 else if (GET_CODE (XEXP (addr
, 1)) == REG
17661 && REGNO (XEXP (addr
, 1)) != 0)
17662 addr
= XEXP (addr
, 1);
17663 else if (CONSTANT_P (XEXP (addr
, 0)))
17664 addr
= XEXP (addr
, 1);
17665 else if (CONSTANT_P (XEXP (addr
, 1)))
17666 addr
= XEXP (addr
, 0);
17668 gcc_unreachable ();
17670 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
17675 rs6000_fatal_bad_address (rtx op
)
17677 fatal_insn ("bad address", op
);
17682 static tree branch_island_list
= 0;
17684 /* Remember to generate a branch island for far calls to the given
17688 add_compiler_branch_island (tree label_name
, tree function_name
,
17691 tree branch_island
= build_tree_list (function_name
, label_name
);
17692 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
17693 TREE_CHAIN (branch_island
) = branch_island_list
;
17694 branch_island_list
= branch_island
;
17697 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
17698 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
17699 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
17700 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
17702 /* Generate far-jump branch islands for everything on the
17703 branch_island_list. Invoked immediately after the last instruction
17704 of the epilogue has been emitted; the branch-islands must be
17705 appended to, and contiguous with, the function body. Mach-O stubs
17706 are generated in machopic_output_stub(). */
17709 macho_branch_islands (void)
17712 tree branch_island
;
17714 for (branch_island
= branch_island_list
;
17716 branch_island
= TREE_CHAIN (branch_island
))
17718 const char *label
=
17719 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
17721 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
17722 char name_buf
[512];
17723 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
17724 if (name
[0] == '*' || name
[0] == '&')
17725 strcpy (name_buf
, name
+1);
17729 strcpy (name_buf
+1, name
);
17731 strcpy (tmp_buf
, "\n");
17732 strcat (tmp_buf
, label
);
17733 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17734 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
17735 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
17736 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17739 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
17740 strcat (tmp_buf
, label
);
17741 strcat (tmp_buf
, "_pic\n");
17742 strcat (tmp_buf
, label
);
17743 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
17745 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
17746 strcat (tmp_buf
, name_buf
);
17747 strcat (tmp_buf
, " - ");
17748 strcat (tmp_buf
, label
);
17749 strcat (tmp_buf
, "_pic)\n");
17751 strcat (tmp_buf
, "\tmtlr r0\n");
17753 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
17754 strcat (tmp_buf
, name_buf
);
17755 strcat (tmp_buf
, " - ");
17756 strcat (tmp_buf
, label
);
17757 strcat (tmp_buf
, "_pic)\n");
17759 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
17763 strcat (tmp_buf
, ":\nlis r12,hi16(");
17764 strcat (tmp_buf
, name_buf
);
17765 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
17766 strcat (tmp_buf
, name_buf
);
17767 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
17769 output_asm_insn (tmp_buf
, 0);
17770 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
17771 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
17772 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
17773 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
17776 branch_island_list
= 0;
17779 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
17780 already there or not. */
17783 no_previous_def (tree function_name
)
17785 tree branch_island
;
17786 for (branch_island
= branch_island_list
;
17788 branch_island
= TREE_CHAIN (branch_island
))
17789 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
17794 /* GET_PREV_LABEL gets the label name from the previous definition of
17798 get_prev_label (tree function_name
)
17800 tree branch_island
;
17801 for (branch_island
= branch_island_list
;
17803 branch_island
= TREE_CHAIN (branch_island
))
17804 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
17805 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
17809 /* INSN is either a function call or a millicode call. It may have an
17810 unconditional jump in its delay slot.
17812 CALL_DEST is the routine we are calling. */
17815 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
17816 int cookie_operand_number
)
17818 static char buf
[256];
17819 if (GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
17820 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
17823 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
17825 if (no_previous_def (funname
))
17827 int line_number
= 0;
17828 rtx label_rtx
= gen_label_rtx ();
17829 char *label_buf
, temp_buf
[256];
17830 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
17831 CODE_LABEL_NUMBER (label_rtx
));
17832 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
17833 labelname
= get_identifier (label_buf
);
17834 for (; insn
&& GET_CODE (insn
) != NOTE
; insn
= PREV_INSN (insn
));
17836 line_number
= NOTE_LINE_NUMBER (insn
);
17837 add_compiler_branch_island (labelname
, funname
, line_number
);
17840 labelname
= get_prev_label (funname
);
17842 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
17843 instruction will reach 'foo', otherwise link as 'bl L42'".
17844 "L42" should be a 'branch island', that will do a far jump to
17845 'foo'. Branch islands are generated in
17846 macho_branch_islands(). */
17847 sprintf (buf
, "jbsr %%z%d,%.246s",
17848 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
17851 sprintf (buf
, "bl %%z%d", dest_operand_number
);
17855 /* Generate PIC and indirect symbol stubs. */
17858 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
17860 unsigned int length
;
17861 char *symbol_name
, *lazy_ptr_name
;
17862 char *local_label_0
;
17863 static int label
= 0;
17865 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
17866 symb
= (*targetm
.strip_name_encoding
) (symb
);
17869 length
= strlen (symb
);
17870 symbol_name
= alloca (length
+ 32);
17871 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
17873 lazy_ptr_name
= alloca (length
+ 32);
17874 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
17877 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
17879 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
17883 fprintf (file
, "\t.align 5\n");
17885 fprintf (file
, "%s:\n", stub
);
17886 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17889 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
17890 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
17892 fprintf (file
, "\tmflr r0\n");
17893 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
17894 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
17895 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
17896 lazy_ptr_name
, local_label_0
);
17897 fprintf (file
, "\tmtlr r0\n");
17898 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
17899 (TARGET_64BIT
? "ldu" : "lwzu"),
17900 lazy_ptr_name
, local_label_0
);
17901 fprintf (file
, "\tmtctr r12\n");
17902 fprintf (file
, "\tbctr\n");
17906 fprintf (file
, "\t.align 4\n");
17908 fprintf (file
, "%s:\n", stub
);
17909 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17911 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
17912 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
17913 (TARGET_64BIT
? "ldu" : "lwzu"),
17915 fprintf (file
, "\tmtctr r12\n");
17916 fprintf (file
, "\tbctr\n");
17919 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
17920 fprintf (file
, "%s:\n", lazy_ptr_name
);
17921 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
17922 fprintf (file
, "%sdyld_stub_binding_helper\n",
17923 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
17926 /* Legitimize PIC addresses. If the address is already
17927 position-independent, we return ORIG. Newly generated
17928 position-independent addresses go into a reg. This is REG if non
17929 zero, otherwise we allocate register(s) as necessary. */
17931 #define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x8000) < 0x10000)
17934 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
17939 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
17940 reg
= gen_reg_rtx (Pmode
);
17942 if (GET_CODE (orig
) == CONST
)
17946 if (GET_CODE (XEXP (orig
, 0)) == PLUS
17947 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
17950 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
17952 /* Use a different reg for the intermediate value, as
17953 it will be marked UNCHANGING. */
17954 reg_temp
= no_new_pseudos
? reg
: gen_reg_rtx (Pmode
);
17955 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
17958 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
17961 if (GET_CODE (offset
) == CONST_INT
)
17963 if (SMALL_INT (offset
))
17964 return plus_constant (base
, INTVAL (offset
));
17965 else if (! reload_in_progress
&& ! reload_completed
)
17966 offset
= force_reg (Pmode
, offset
);
17969 rtx mem
= force_const_mem (Pmode
, orig
);
17970 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
17973 return gen_rtx_PLUS (Pmode
, base
, offset
);
17976 /* Fall back on generic machopic code. */
17977 return machopic_legitimize_pic_address (orig
, mode
, reg
);
17980 /* Output a .machine directive for the Darwin assembler, and call
17981 the generic start_file routine. */
17984 rs6000_darwin_file_start (void)
17986 static const struct
17992 { "ppc64", "ppc64", MASK_64BIT
},
17993 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
17994 { "power4", "ppc970", 0 },
17995 { "G5", "ppc970", 0 },
17996 { "7450", "ppc7450", 0 },
17997 { "7400", "ppc7400", MASK_ALTIVEC
},
17998 { "G4", "ppc7400", 0 },
17999 { "750", "ppc750", 0 },
18000 { "740", "ppc750", 0 },
18001 { "G3", "ppc750", 0 },
18002 { "604e", "ppc604e", 0 },
18003 { "604", "ppc604", 0 },
18004 { "603e", "ppc603", 0 },
18005 { "603", "ppc603", 0 },
18006 { "601", "ppc601", 0 },
18007 { NULL
, "ppc", 0 } };
18008 const char *cpu_id
= "";
18011 rs6000_file_start ();
18013 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
18014 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
18015 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
18016 && rs6000_select
[i
].string
[0] != '\0')
18017 cpu_id
= rs6000_select
[i
].string
;
18019 /* Look through the mapping array. Pick the first name that either
18020 matches the argument, has a bit set in IF_SET that is also set
18021 in the target flags, or has a NULL name. */
18024 while (mapping
[i
].arg
!= NULL
18025 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
18026 && (mapping
[i
].if_set
& target_flags
) == 0)
18029 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
18032 #endif /* TARGET_MACHO */
18035 static unsigned int
18036 rs6000_elf_section_type_flags (tree decl
, const char *name
, int reloc
)
18038 return default_section_type_flags_1 (decl
, name
, reloc
,
18039 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
18042 /* Record an element in the table of global constructors. SYMBOL is
18043 a SYMBOL_REF of the function to be called; PRIORITY is a number
18044 between 0 and MAX_INIT_PRIORITY.
18046 This differs from default_named_section_asm_out_constructor in
18047 that we have special handling for -mrelocatable. */
18050 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
18052 const char *section
= ".ctors";
18055 if (priority
!= DEFAULT_INIT_PRIORITY
)
18057 sprintf (buf
, ".ctors.%.5u",
18058 /* Invert the numbering so the linker puts us in the proper
18059 order; constructors are run from right to left, and the
18060 linker sorts in increasing order. */
18061 MAX_INIT_PRIORITY
- priority
);
18065 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
18066 assemble_align (POINTER_SIZE
);
18068 if (TARGET_RELOCATABLE
)
18070 fputs ("\t.long (", asm_out_file
);
18071 output_addr_const (asm_out_file
, symbol
);
18072 fputs (")@fixup\n", asm_out_file
);
18075 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
18079 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
18081 const char *section
= ".dtors";
18084 if (priority
!= DEFAULT_INIT_PRIORITY
)
18086 sprintf (buf
, ".dtors.%.5u",
18087 /* Invert the numbering so the linker puts us in the proper
18088 order; constructors are run from right to left, and the
18089 linker sorts in increasing order. */
18090 MAX_INIT_PRIORITY
- priority
);
18094 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
18095 assemble_align (POINTER_SIZE
);
18097 if (TARGET_RELOCATABLE
)
18099 fputs ("\t.long (", asm_out_file
);
18100 output_addr_const (asm_out_file
, symbol
);
18101 fputs (")@fixup\n", asm_out_file
);
18104 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
18108 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
18112 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
18113 ASM_OUTPUT_LABEL (file
, name
);
18114 fputs (DOUBLE_INT_ASM_OP
, file
);
18115 rs6000_output_function_entry (file
, name
);
18116 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
18119 fputs ("\t.size\t", file
);
18120 assemble_name (file
, name
);
18121 fputs (",24\n\t.type\t.", file
);
18122 assemble_name (file
, name
);
18123 fputs (",@function\n", file
);
18124 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
18126 fputs ("\t.globl\t.", file
);
18127 assemble_name (file
, name
);
18132 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
18133 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
18134 rs6000_output_function_entry (file
, name
);
18135 fputs (":\n", file
);
18139 if (TARGET_RELOCATABLE
18140 && !TARGET_SECURE_PLT
18141 && (get_pool_size () != 0 || current_function_profile
)
18146 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
18148 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
18149 fprintf (file
, "\t.long ");
18150 assemble_name (file
, buf
);
18152 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
18153 assemble_name (file
, buf
);
18157 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
18158 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
18160 if (DEFAULT_ABI
== ABI_AIX
)
18162 const char *desc_name
, *orig_name
;
18164 orig_name
= (*targetm
.strip_name_encoding
) (name
);
18165 desc_name
= orig_name
;
18166 while (*desc_name
== '.')
18169 if (TREE_PUBLIC (decl
))
18170 fprintf (file
, "\t.globl %s\n", desc_name
);
18172 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18173 fprintf (file
, "%s:\n", desc_name
);
18174 fprintf (file
, "\t.long %s\n", orig_name
);
18175 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
18176 if (DEFAULT_ABI
== ABI_AIX
)
18177 fputs ("\t.long 0\n", file
);
18178 fprintf (file
, "\t.previous\n");
18180 ASM_OUTPUT_LABEL (file
, name
);
18184 rs6000_elf_end_indicate_exec_stack (void)
18187 file_end_indicate_exec_stack ();
18193 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
18195 fputs (GLOBAL_ASM_OP
, stream
);
18196 RS6000_OUTPUT_BASENAME (stream
, name
);
18197 putc ('\n', stream
);
18200 /* A get_unnamed_decl callback, used for read-only sections. PTR
18201 points to the section string variable. */
18204 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
18206 fprintf (asm_out_file
, "\t.csect %s[RO],3\n",
18207 *(const char *const *) directive
);
18210 /* Likewise for read-write sections. */
18213 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
18215 fprintf (asm_out_file
, "\t.csect %s[RW],3\n",
18216 *(const char *const *) directive
);
18219 /* A get_unnamed_section callback, used for switching to toc_section. */
18222 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
18224 if (TARGET_MINIMAL_TOC
)
18226 /* toc_section is always selected at least once from
18227 rs6000_xcoff_file_start, so this is guaranteed to
18228 always be defined once and only once in each file. */
18229 if (!toc_initialized
)
18231 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
18232 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
18233 toc_initialized
= 1;
18235 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
18236 (TARGET_32BIT
? "" : ",3"));
18239 fputs ("\t.toc\n", asm_out_file
);
18242 /* Implement TARGET_ASM_INIT_SECTIONS. */
18245 rs6000_xcoff_asm_init_sections (void)
18247 read_only_data_section
18248 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
18249 &xcoff_read_only_section_name
);
18251 private_data_section
18252 = get_unnamed_section (SECTION_WRITE
,
18253 rs6000_xcoff_output_readwrite_section_asm_op
,
18254 &xcoff_private_data_section_name
);
18256 read_only_private_data_section
18257 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
18258 &xcoff_private_data_section_name
);
18261 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
18263 readonly_data_section
= read_only_data_section
;
18264 exception_section
= data_section
;
18268 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
18269 tree decl ATTRIBUTE_UNUSED
)
18272 static const char * const suffix
[3] = { "PR", "RO", "RW" };
18274 if (flags
& SECTION_CODE
)
18276 else if (flags
& SECTION_WRITE
)
18281 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
18282 (flags
& SECTION_CODE
) ? "." : "",
18283 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
18287 rs6000_xcoff_select_section (tree decl
, int reloc
,
18288 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
18290 if (decl_readonly_section_1 (decl
, reloc
, 1))
18292 if (TREE_PUBLIC (decl
))
18293 return read_only_data_section
;
18295 return read_only_private_data_section
;
18299 if (TREE_PUBLIC (decl
))
18300 return data_section
;
18302 return private_data_section
;
18307 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
18311 /* Use select_section for private and uninitialized data. */
18312 if (!TREE_PUBLIC (decl
)
18313 || DECL_COMMON (decl
)
18314 || DECL_INITIAL (decl
) == NULL_TREE
18315 || DECL_INITIAL (decl
) == error_mark_node
18316 || (flag_zero_initialized_in_bss
18317 && initializer_zerop (DECL_INITIAL (decl
))))
18320 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
18321 name
= (*targetm
.strip_name_encoding
) (name
);
18322 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
18325 /* Select section for constant in constant pool.
18327 On RS/6000, all constants are in the private read-only data area.
18328 However, if this is being placed in the TOC it must be output as a
18332 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
18333 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
18335 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
18336 return toc_section
;
18338 return read_only_private_data_section
;
18341 /* Remove any trailing [DS] or the like from the symbol name. */
18343 static const char *
18344 rs6000_xcoff_strip_name_encoding (const char *name
)
18349 len
= strlen (name
);
18350 if (name
[len
- 1] == ']')
18351 return ggc_alloc_string (name
, len
- 4);
18356 /* Section attributes. AIX is always PIC. */
18358 static unsigned int
18359 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
18361 unsigned int align
;
18362 unsigned int flags
= default_section_type_flags_1 (decl
, name
, reloc
, 1);
18364 /* Align to at least UNIT size. */
18365 if (flags
& SECTION_CODE
)
18366 align
= MIN_UNITS_PER_WORD
;
18368 /* Increase alignment of large objects if not already stricter. */
18369 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
18370 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
18371 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
18373 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
18376 /* Output at beginning of assembler file.
18378 Initialize the section names for the RS/6000 at this point.
18380 Specify filename, including full path, to assembler.
18382 We want to go into the TOC section so at least one .toc will be emitted.
18383 Also, in order to output proper .bs/.es pairs, we need at least one static
18384 [RW] section emitted.
18386 Finally, declare mcount when profiling to make the assembler happy. */
18389 rs6000_xcoff_file_start (void)
18391 rs6000_gen_section_name (&xcoff_bss_section_name
,
18392 main_input_filename
, ".bss_");
18393 rs6000_gen_section_name (&xcoff_private_data_section_name
,
18394 main_input_filename
, ".rw_");
18395 rs6000_gen_section_name (&xcoff_read_only_section_name
,
18396 main_input_filename
, ".ro_");
18398 fputs ("\t.file\t", asm_out_file
);
18399 output_quoted_string (asm_out_file
, main_input_filename
);
18400 fputc ('\n', asm_out_file
);
18401 if (write_symbols
!= NO_DEBUG
)
18402 switch_to_section (private_data_section
);
18403 switch_to_section (text_section
);
18405 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
18406 rs6000_file_start ();
18409 /* Output at end of assembler file.
18410 On the RS/6000, referencing data should automatically pull in text. */
18413 rs6000_xcoff_file_end (void)
18415 switch_to_section (text_section
);
18416 fputs ("_section_.text:\n", asm_out_file
);
18417 switch_to_section (data_section
);
18418 fputs (TARGET_32BIT
18419 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
18422 #endif /* TARGET_XCOFF */
18424 /* Compute a (partial) cost for rtx X. Return true if the complete
18425 cost has been computed, and false if subexpressions should be
18426 scanned. In either case, *TOTAL contains the cost result. */
18429 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
18431 enum machine_mode mode
= GET_MODE (x
);
18435 /* On the RS/6000, if it is valid in the insn, it is free. */
18437 if (((outer_code
== SET
18438 || outer_code
== PLUS
18439 || outer_code
== MINUS
)
18440 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
18441 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')))
18442 || (outer_code
== AND
18443 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18444 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
18445 mode
== SImode
? 'L' : 'J'))
18446 || mask_operand (x
, mode
)
18448 && mask64_operand (x
, DImode
))))
18449 || ((outer_code
== IOR
|| outer_code
== XOR
)
18450 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18451 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
18452 mode
== SImode
? 'L' : 'J'))))
18453 || outer_code
== ASHIFT
18454 || outer_code
== ASHIFTRT
18455 || outer_code
== LSHIFTRT
18456 || outer_code
== ROTATE
18457 || outer_code
== ROTATERT
18458 || outer_code
== ZERO_EXTRACT
18459 || (outer_code
== MULT
18460 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
18461 || ((outer_code
== DIV
|| outer_code
== UDIV
18462 || outer_code
== MOD
|| outer_code
== UMOD
)
18463 && exact_log2 (INTVAL (x
)) >= 0)
18464 || (outer_code
== COMPARE
18465 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
18466 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')))
18467 || (outer_code
== EQ
18468 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I')
18469 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18470 || (CONST_OK_FOR_LETTER_P (INTVAL (x
),
18471 mode
== SImode
? 'L' : 'J'))))
18472 || (outer_code
== GTU
18473 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'I'))
18474 || (outer_code
== LTU
18475 && CONST_OK_FOR_LETTER_P (INTVAL (x
), 'P')))
18480 else if ((outer_code
== PLUS
18481 && reg_or_add_cint_operand (x
, VOIDmode
))
18482 || (outer_code
== MINUS
18483 && reg_or_sub_cint_operand (x
, VOIDmode
))
18484 || ((outer_code
== SET
18485 || outer_code
== IOR
18486 || outer_code
== XOR
)
18488 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
18490 *total
= COSTS_N_INSNS (1);
18497 && ((outer_code
== AND
18498 && (CONST_OK_FOR_LETTER_P (INTVAL (x
), 'K')
18499 || CONST_OK_FOR_LETTER_P (INTVAL (x
), 'L')
18500 || mask_operand (x
, DImode
)
18501 || mask64_operand (x
, DImode
)))
18502 || ((outer_code
== IOR
|| outer_code
== XOR
)
18503 && CONST_DOUBLE_HIGH (x
) == 0
18504 && (CONST_DOUBLE_LOW (x
)
18505 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)))
18510 else if (mode
== DImode
18511 && (outer_code
== SET
18512 || outer_code
== IOR
18513 || outer_code
== XOR
)
18514 && CONST_DOUBLE_HIGH (x
) == 0)
18516 *total
= COSTS_N_INSNS (1);
18525 /* When optimizing for size, MEM should be slightly more expensive
18526 than generating address, e.g., (plus (reg) (const)).
18527 L1 cache latency is about two instructions. */
18528 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
18536 if (mode
== DFmode
)
18538 if (GET_CODE (XEXP (x
, 0)) == MULT
)
18540 /* FNMA accounted in outer NEG. */
18541 if (outer_code
== NEG
)
18542 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
18544 *total
= rs6000_cost
->dmul
;
18547 *total
= rs6000_cost
->fp
;
18549 else if (mode
== SFmode
)
18551 /* FNMA accounted in outer NEG. */
18552 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
18555 *total
= rs6000_cost
->fp
;
18558 *total
= COSTS_N_INSNS (1);
18562 if (mode
== DFmode
)
18564 if (GET_CODE (XEXP (x
, 0)) == MULT
)
18566 /* FNMA accounted in outer NEG. */
18567 if (outer_code
== NEG
)
18570 *total
= rs6000_cost
->dmul
;
18573 *total
= rs6000_cost
->fp
;
18575 else if (mode
== SFmode
)
18577 /* FNMA accounted in outer NEG. */
18578 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
18581 *total
= rs6000_cost
->fp
;
18584 *total
= COSTS_N_INSNS (1);
18588 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
18589 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x
, 1)), 'I'))
18591 if (INTVAL (XEXP (x
, 1)) >= -256
18592 && INTVAL (XEXP (x
, 1)) <= 255)
18593 *total
= rs6000_cost
->mulsi_const9
;
18595 *total
= rs6000_cost
->mulsi_const
;
18597 /* FMA accounted in outer PLUS/MINUS. */
18598 else if ((mode
== DFmode
|| mode
== SFmode
)
18599 && (outer_code
== PLUS
|| outer_code
== MINUS
))
18601 else if (mode
== DFmode
)
18602 *total
= rs6000_cost
->dmul
;
18603 else if (mode
== SFmode
)
18604 *total
= rs6000_cost
->fp
;
18605 else if (mode
== DImode
)
18606 *total
= rs6000_cost
->muldi
;
18608 *total
= rs6000_cost
->mulsi
;
18613 if (FLOAT_MODE_P (mode
))
18615 *total
= mode
== DFmode
? rs6000_cost
->ddiv
18616 : rs6000_cost
->sdiv
;
18623 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
18624 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
18626 if (code
== DIV
|| code
== MOD
)
18628 *total
= COSTS_N_INSNS (2);
18631 *total
= COSTS_N_INSNS (1);
18635 if (GET_MODE (XEXP (x
, 1)) == DImode
)
18636 *total
= rs6000_cost
->divdi
;
18638 *total
= rs6000_cost
->divsi
;
18640 /* Add in shift and subtract for MOD. */
18641 if (code
== MOD
|| code
== UMOD
)
18642 *total
+= COSTS_N_INSNS (2);
18646 *total
= COSTS_N_INSNS (4);
18650 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
18661 *total
= COSTS_N_INSNS (1);
18669 /* Handle mul_highpart. */
18670 if (outer_code
== TRUNCATE
18671 && GET_CODE (XEXP (x
, 0)) == MULT
)
18673 if (mode
== DImode
)
18674 *total
= rs6000_cost
->muldi
;
18676 *total
= rs6000_cost
->mulsi
;
18679 else if (outer_code
== AND
)
18682 *total
= COSTS_N_INSNS (1);
18687 if (GET_CODE (XEXP (x
, 0)) == MEM
)
18690 *total
= COSTS_N_INSNS (1);
18696 if (!FLOAT_MODE_P (mode
))
18698 *total
= COSTS_N_INSNS (1);
18704 case UNSIGNED_FLOAT
:
18707 case FLOAT_TRUNCATE
:
18708 *total
= rs6000_cost
->fp
;
18712 if (mode
== DFmode
)
18715 *total
= rs6000_cost
->fp
;
18719 switch (XINT (x
, 1))
18722 *total
= rs6000_cost
->fp
;
18734 *total
= COSTS_N_INSNS (1);
18737 else if (FLOAT_MODE_P (mode
)
18738 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
18740 *total
= rs6000_cost
->fp
;
18748 /* Carry bit requires mode == Pmode.
18749 NEG or PLUS already counted so only add one. */
18751 && (outer_code
== NEG
|| outer_code
== PLUS
))
18753 *total
= COSTS_N_INSNS (1);
18756 if (outer_code
== SET
)
18758 if (XEXP (x
, 1) == const0_rtx
)
18760 *total
= COSTS_N_INSNS (2);
18763 else if (mode
== Pmode
)
18765 *total
= COSTS_N_INSNS (3);
18774 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
18776 *total
= COSTS_N_INSNS (2);
18780 if (outer_code
== COMPARE
)
18794 /* A C expression returning the cost of moving data from a register of class
18795 CLASS1 to one of CLASS2. */
18798 rs6000_register_move_cost (enum machine_mode mode
,
18799 enum reg_class from
, enum reg_class to
)
18801 /* Moves from/to GENERAL_REGS. */
18802 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
18803 || reg_classes_intersect_p (from
, GENERAL_REGS
))
18805 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
18808 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
18809 return (rs6000_memory_move_cost (mode
, from
, 0)
18810 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
18812 /* It's more expensive to move CR_REGS than CR0_REGS because of the
18814 else if (from
== CR_REGS
)
18818 /* A move will cost one instruction per GPR moved. */
18819 return 2 * hard_regno_nregs
[0][mode
];
18822 /* Moving between two similar registers is just one instruction. */
18823 else if (reg_classes_intersect_p (to
, from
))
18824 return mode
== TFmode
? 4 : 2;
18826 /* Everything else has to go through GENERAL_REGS. */
18828 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
18829 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
18832 /* A C expressions returning the cost of moving data of MODE from a register to
18836 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
18837 int in ATTRIBUTE_UNUSED
)
18839 if (reg_classes_intersect_p (class, GENERAL_REGS
))
18840 return 4 * hard_regno_nregs
[0][mode
];
18841 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
18842 return 4 * hard_regno_nregs
[32][mode
];
18843 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
18844 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
18846 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
18849 /* Newton-Raphson approximation of single-precision floating point divide n/d.
18850 Assumes no trapping math and finite arguments. */
18853 rs6000_emit_swdivsf (rtx res
, rtx n
, rtx d
)
18855 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
18857 x0
= gen_reg_rtx (SFmode
);
18858 e0
= gen_reg_rtx (SFmode
);
18859 e1
= gen_reg_rtx (SFmode
);
18860 y1
= gen_reg_rtx (SFmode
);
18861 u0
= gen_reg_rtx (SFmode
);
18862 v0
= gen_reg_rtx (SFmode
);
18863 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
18865 /* x0 = 1./d estimate */
18866 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
18867 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
18869 /* e0 = 1. - d * x0 */
18870 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
18871 gen_rtx_MINUS (SFmode
, one
,
18872 gen_rtx_MULT (SFmode
, d
, x0
))));
18873 /* e1 = e0 + e0 * e0 */
18874 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
18875 gen_rtx_PLUS (SFmode
,
18876 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
18877 /* y1 = x0 + e1 * x0 */
18878 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
18879 gen_rtx_PLUS (SFmode
,
18880 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
18882 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
18883 gen_rtx_MULT (SFmode
, n
, y1
)));
18884 /* v0 = n - d * u0 */
18885 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
18886 gen_rtx_MINUS (SFmode
, n
,
18887 gen_rtx_MULT (SFmode
, d
, u0
))));
18888 /* res = u0 + v0 * y1 */
18889 emit_insn (gen_rtx_SET (VOIDmode
, res
,
18890 gen_rtx_PLUS (SFmode
,
18891 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
18894 /* Newton-Raphson approximation of double-precision floating point divide n/d.
18895 Assumes no trapping math and finite arguments. */
18898 rs6000_emit_swdivdf (rtx res
, rtx n
, rtx d
)
18900 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
18902 x0
= gen_reg_rtx (DFmode
);
18903 e0
= gen_reg_rtx (DFmode
);
18904 e1
= gen_reg_rtx (DFmode
);
18905 e2
= gen_reg_rtx (DFmode
);
18906 y1
= gen_reg_rtx (DFmode
);
18907 y2
= gen_reg_rtx (DFmode
);
18908 y3
= gen_reg_rtx (DFmode
);
18909 u0
= gen_reg_rtx (DFmode
);
18910 v0
= gen_reg_rtx (DFmode
);
18911 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
18913 /* x0 = 1./d estimate */
18914 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
18915 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
18917 /* e0 = 1. - d * x0 */
18918 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
18919 gen_rtx_MINUS (DFmode
, one
,
18920 gen_rtx_MULT (SFmode
, d
, x0
))));
18921 /* y1 = x0 + e0 * x0 */
18922 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
18923 gen_rtx_PLUS (DFmode
,
18924 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
18926 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
18927 gen_rtx_MULT (DFmode
, e0
, e0
)));
18928 /* y2 = y1 + e1 * y1 */
18929 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
18930 gen_rtx_PLUS (DFmode
,
18931 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
18933 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
18934 gen_rtx_MULT (DFmode
, e1
, e1
)));
18935 /* y3 = y2 + e2 * y2 */
18936 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
18937 gen_rtx_PLUS (DFmode
,
18938 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
18940 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
18941 gen_rtx_MULT (DFmode
, n
, y3
)));
18942 /* v0 = n - d * u0 */
18943 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
18944 gen_rtx_MINUS (DFmode
, n
,
18945 gen_rtx_MULT (DFmode
, d
, u0
))));
18946 /* res = u0 + v0 * y3 */
18947 emit_insn (gen_rtx_SET (VOIDmode
, res
,
18948 gen_rtx_PLUS (DFmode
,
18949 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
18952 /* Return an RTX representing where to find the function value of a
18953 function returning MODE. */
18955 rs6000_complex_function_value (enum machine_mode mode
)
18957 unsigned int regno
;
18959 enum machine_mode inner
= GET_MODE_INNER (mode
);
18960 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
18962 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
18963 regno
= FP_ARG_RETURN
;
18966 regno
= GP_ARG_RETURN
;
18968 /* 32-bit is OK since it'll go in r3/r4. */
18969 if (TARGET_32BIT
&& inner_bytes
>= 4)
18970 return gen_rtx_REG (mode
, regno
);
18973 if (inner_bytes
>= 8)
18974 return gen_rtx_REG (mode
, regno
);
18976 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
18978 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
18979 GEN_INT (inner_bytes
));
18980 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
18983 /* Define how to find the value returned by a function.
18984 VALTYPE is the data type of the value (as a tree).
18985 If the precise function being called is known, FUNC is its FUNCTION_DECL;
18986 otherwise, FUNC is 0.
18988 On the SPE, both FPs and vectors are returned in r3.
18990 On RS/6000 an integer value is in r3 and a floating-point value is in
18991 fp1, unless -msoft-float. */
18994 rs6000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
18996 enum machine_mode mode
;
18997 unsigned int regno
;
18999 /* Special handling for structs in darwin64. */
19000 if (rs6000_darwin64_abi
19001 && TYPE_MODE (valtype
) == BLKmode
19002 && TREE_CODE (valtype
) == RECORD_TYPE
19003 && int_size_in_bytes (valtype
) > 0)
19005 CUMULATIVE_ARGS valcum
;
19009 valcum
.fregno
= FP_ARG_MIN_REG
;
19010 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
19011 /* Do a trial code generation as if this were going to be passed as
19012 an argument; if any part goes in memory, we return NULL. */
19013 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
19016 /* Otherwise fall through to standard ABI rules. */
19019 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
19021 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
19022 return gen_rtx_PARALLEL (DImode
,
19024 gen_rtx_EXPR_LIST (VOIDmode
,
19025 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
19027 gen_rtx_EXPR_LIST (VOIDmode
,
19028 gen_rtx_REG (SImode
,
19029 GP_ARG_RETURN
+ 1),
19032 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
19034 return gen_rtx_PARALLEL (DCmode
,
19036 gen_rtx_EXPR_LIST (VOIDmode
,
19037 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
19039 gen_rtx_EXPR_LIST (VOIDmode
,
19040 gen_rtx_REG (SImode
,
19041 GP_ARG_RETURN
+ 1),
19043 gen_rtx_EXPR_LIST (VOIDmode
,
19044 gen_rtx_REG (SImode
,
19045 GP_ARG_RETURN
+ 2),
19047 gen_rtx_EXPR_LIST (VOIDmode
,
19048 gen_rtx_REG (SImode
,
19049 GP_ARG_RETURN
+ 3),
19053 if ((INTEGRAL_TYPE_P (valtype
)
19054 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
19055 || POINTER_TYPE_P (valtype
))
19056 mode
= TARGET_32BIT
? SImode
: DImode
;
19058 mode
= TYPE_MODE (valtype
);
19060 if (DECIMAL_FLOAT_MODE_P (mode
))
19061 regno
= GP_ARG_RETURN
;
19062 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
19063 regno
= FP_ARG_RETURN
;
19064 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
19065 && targetm
.calls
.split_complex_arg
)
19066 return rs6000_complex_function_value (mode
);
19067 else if (TREE_CODE (valtype
) == VECTOR_TYPE
19068 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
19069 && ALTIVEC_VECTOR_MODE (mode
))
19070 regno
= ALTIVEC_ARG_RETURN
;
19071 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
19072 && (mode
== DFmode
|| mode
== DCmode
))
19073 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
19075 regno
= GP_ARG_RETURN
;
19077 return gen_rtx_REG (mode
, regno
);
19080 /* Define how to find the value returned by a library function
19081 assuming the value has mode MODE. */
19083 rs6000_libcall_value (enum machine_mode mode
)
19085 unsigned int regno
;
19087 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
19089 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
19090 return gen_rtx_PARALLEL (DImode
,
19092 gen_rtx_EXPR_LIST (VOIDmode
,
19093 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
19095 gen_rtx_EXPR_LIST (VOIDmode
,
19096 gen_rtx_REG (SImode
,
19097 GP_ARG_RETURN
+ 1),
19101 if (DECIMAL_FLOAT_MODE_P (mode
))
19102 regno
= GP_ARG_RETURN
;
19103 else if (SCALAR_FLOAT_MODE_P (mode
)
19104 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
19105 regno
= FP_ARG_RETURN
;
19106 else if (ALTIVEC_VECTOR_MODE (mode
)
19107 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
19108 regno
= ALTIVEC_ARG_RETURN
;
19109 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
19110 return rs6000_complex_function_value (mode
);
19111 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
19112 && (mode
== DFmode
|| mode
== DCmode
))
19113 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
19115 regno
= GP_ARG_RETURN
;
19117 return gen_rtx_REG (mode
, regno
);
19120 /* Define the offset between two registers, FROM to be eliminated and its
19121 replacement TO, at the start of a routine. */
19123 rs6000_initial_elimination_offset (int from
, int to
)
19125 rs6000_stack_t
*info
= rs6000_stack_info ();
19126 HOST_WIDE_INT offset
;
19128 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
19129 offset
= info
->push_p
? 0 : -info
->total_size
;
19130 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
19132 offset
= info
->push_p
? 0 : -info
->total_size
;
19133 if (FRAME_GROWS_DOWNWARD
)
19134 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
19136 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
19137 offset
= FRAME_GROWS_DOWNWARD
19138 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
19140 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
19141 offset
= info
->total_size
;
19142 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
19143 offset
= info
->push_p
? info
->total_size
: 0;
19144 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
19147 gcc_unreachable ();
19152 /* Return true if TYPE is a SPE or AltiVec opaque type. */
19155 rs6000_is_opaque_type (tree type
)
19157 return (type
== opaque_V2SI_type_node
19158 || type
== opaque_V2SF_type_node
19159 || type
== opaque_p_V2SI_type_node
19160 || type
== opaque_V4SI_type_node
);
19164 rs6000_dwarf_register_span (rtx reg
)
19169 && (SPE_VECTOR_MODE (GET_MODE (reg
))
19170 || (TARGET_E500_DOUBLE
&& GET_MODE (reg
) == DFmode
)))
19175 regno
= REGNO (reg
);
19177 /* The duality of the SPE register size wreaks all kinds of havoc.
19178 This is a way of distinguishing r0 in 32-bits from r0 in
19181 gen_rtx_PARALLEL (VOIDmode
,
19184 gen_rtx_REG (SImode
, regno
+ 1200),
19185 gen_rtx_REG (SImode
, regno
))
19187 gen_rtx_REG (SImode
, regno
),
19188 gen_rtx_REG (SImode
, regno
+ 1200)));
19191 /* Map internal gcc register numbers to DWARF2 register numbers. */
19194 rs6000_dbx_register_number (unsigned int regno
)
19196 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
19198 if (regno
== MQ_REGNO
)
19200 if (regno
== LINK_REGISTER_REGNUM
)
19202 if (regno
== COUNT_REGISTER_REGNUM
)
19204 if (CR_REGNO_P (regno
))
19205 return regno
- CR0_REGNO
+ 86;
19206 if (regno
== XER_REGNO
)
19208 if (ALTIVEC_REGNO_P (regno
))
19209 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
19210 if (regno
== VRSAVE_REGNO
)
19212 if (regno
== VSCR_REGNO
)
19214 if (regno
== SPE_ACC_REGNO
)
19216 if (regno
== SPEFSCR_REGNO
)
19218 /* SPE high reg number. We get these values of regno from
19219 rs6000_dwarf_register_span. */
19220 gcc_assert (regno
>= 1200 && regno
< 1232);
19224 /* target hook eh_return_filter_mode */
19225 static enum machine_mode
19226 rs6000_eh_return_filter_mode (void)
19228 return TARGET_32BIT
? SImode
: word_mode
;
19231 /* Target hook for scalar_mode_supported_p. */
19233 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
19235 if (DECIMAL_FLOAT_MODE_P (mode
))
19238 return default_scalar_mode_supported_p (mode
);
19241 /* Target hook for vector_mode_supported_p. */
19243 rs6000_vector_mode_supported_p (enum machine_mode mode
)
19246 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
19249 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
19256 /* Target hook for invalid_arg_for_unprototyped_fn. */
19257 static const char *
19258 invalid_arg_for_unprototyped_fn (tree typelist
, tree funcdecl
, tree val
)
19260 return (!rs6000_darwin64_abi
19262 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
19263 && (funcdecl
== NULL_TREE
19264 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
19265 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
19266 ? N_("AltiVec argument passed to unprototyped function")
19270 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
19271 setup by using __stack_chk_fail_local hidden function instead of
19272 calling __stack_chk_fail directly. Otherwise it is better to call
19273 __stack_chk_fail directly. */
19276 rs6000_stack_protect_fail (void)
19278 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
19279 ? default_hidden_stack_protect_fail ()
19280 : default_external_stack_protect_fail ();
19283 #include "gt-rs6000.h"