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, 2007
4 Free Software Foundation, Inc.
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"
59 #include "tm-constrs.h"
61 #include "xcoffout.h" /* get declarations of xcoff_*_section_name */
64 #include "gstab.h" /* for N_SLINE */
67 #ifndef TARGET_NO_PROTOTYPE
68 #define TARGET_NO_PROTOTYPE 0
71 #define min(A,B) ((A) < (B) ? (A) : (B))
72 #define max(A,B) ((A) > (B) ? (A) : (B))
74 /* Structure used to define the rs6000 stack */
75 typedef struct rs6000_stack
{
76 int first_gp_reg_save
; /* first callee saved GP register used */
77 int first_fp_reg_save
; /* first callee saved FP register used */
78 int first_altivec_reg_save
; /* first callee saved AltiVec register used */
79 int lr_save_p
; /* true if the link reg needs to be saved */
80 int cr_save_p
; /* true if the CR reg needs to be saved */
81 unsigned int vrsave_mask
; /* mask of vec registers to save */
82 int push_p
; /* true if we need to allocate stack space */
83 int calls_p
; /* true if the function makes any calls */
84 int world_save_p
; /* true if we're saving *everything*:
85 r13-r31, cr, f14-f31, vrsave, v20-v31 */
86 enum rs6000_abi abi
; /* which ABI to use */
87 int gp_save_offset
; /* offset to save GP regs from initial SP */
88 int fp_save_offset
; /* offset to save FP regs from initial SP */
89 int altivec_save_offset
; /* offset to save AltiVec regs from initial SP */
90 int lr_save_offset
; /* offset to save LR from initial SP */
91 int cr_save_offset
; /* offset to save CR from initial SP */
92 int vrsave_save_offset
; /* offset to save VRSAVE from initial SP */
93 int spe_gp_save_offset
; /* offset to save spe 64-bit gprs */
94 int varargs_save_offset
; /* offset to save the varargs registers */
95 int ehrd_offset
; /* offset to EH return data */
96 int reg_size
; /* register size (4 or 8) */
97 HOST_WIDE_INT vars_size
; /* variable save area size */
98 int parm_size
; /* outgoing parameter size */
99 int save_size
; /* save area size */
100 int fixed_size
; /* fixed size of stack frame */
101 int gp_size
; /* size of saved GP registers */
102 int fp_size
; /* size of saved FP registers */
103 int altivec_size
; /* size of saved AltiVec registers */
104 int cr_size
; /* size to hold CR if not in save_size */
105 int vrsave_size
; /* size to hold VRSAVE if not in save_size */
106 int altivec_padding_size
; /* size of altivec alignment padding if
108 int spe_gp_size
; /* size of 64-bit GPR save size for SPE */
109 int spe_padding_size
;
110 HOST_WIDE_INT total_size
; /* total bytes allocated for stack */
111 int spe_64bit_regs_used
;
114 /* A C structure for machine-specific, per-function data.
115 This is added to the cfun structure. */
116 typedef struct machine_function
GTY(())
118 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
119 int ra_needs_full_frame
;
120 /* Some local-dynamic symbol. */
121 const char *some_ld_name
;
122 /* Whether the instruction chain has been scanned already. */
123 int insn_chain_scanned_p
;
124 /* Flags if __builtin_return_address (0) was used. */
126 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
127 varargs save area. */
128 HOST_WIDE_INT varargs_save_offset
;
131 /* Target cpu type */
133 enum processor_type rs6000_cpu
;
134 struct rs6000_cpu_select rs6000_select
[3] =
136 /* switch name, tune arch */
137 { (const char *)0, "--with-cpu=", 1, 1 },
138 { (const char *)0, "-mcpu=", 1, 1 },
139 { (const char *)0, "-mtune=", 1, 0 },
142 static GTY(()) bool rs6000_cell_dont_microcode
;
144 /* Always emit branch hint bits. */
145 static GTY(()) bool rs6000_always_hint
;
147 /* Schedule instructions for group formation. */
148 static GTY(()) bool rs6000_sched_groups
;
150 /* Align branch targets. */
151 static GTY(()) bool rs6000_align_branch_targets
;
153 /* Support for -msched-costly-dep option. */
154 const char *rs6000_sched_costly_dep_str
;
155 enum rs6000_dependence_cost rs6000_sched_costly_dep
;
157 /* Support for -minsert-sched-nops option. */
158 const char *rs6000_sched_insert_nops_str
;
159 enum rs6000_nop_insertion rs6000_sched_insert_nops
;
161 /* Support targetm.vectorize.builtin_mask_for_load. */
162 static GTY(()) tree altivec_builtin_mask_for_load
;
164 /* Size of long double. */
165 int rs6000_long_double_type_size
;
167 /* IEEE quad extended precision long double. */
170 /* Whether -mabi=altivec has appeared. */
171 int rs6000_altivec_abi
;
173 /* Nonzero if we want SPE ABI extensions. */
176 /* Nonzero if floating point operations are done in the GPRs. */
177 int rs6000_float_gprs
= 0;
179 /* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
180 int rs6000_darwin64_abi
;
182 /* Set to nonzero once AIX common-mode calls have been defined. */
183 static GTY(()) int common_mode_defined
;
185 /* Save information from a "cmpxx" operation until the branch or scc is
187 rtx rs6000_compare_op0
, rs6000_compare_op1
;
188 int rs6000_compare_fp_p
;
190 /* Label number of label created for -mrelocatable, to call to so we can
191 get the address of the GOT section */
192 int rs6000_pic_labelno
;
195 /* Which abi to adhere to */
196 const char *rs6000_abi_name
;
198 /* Semantics of the small data area */
199 enum rs6000_sdata_type rs6000_sdata
= SDATA_DATA
;
201 /* Which small data model to use */
202 const char *rs6000_sdata_name
= (char *)0;
204 /* Counter for labels which are to be placed in .fixup. */
205 int fixuplabelno
= 0;
208 /* Bit size of immediate TLS offsets and string from which it is decoded. */
209 int rs6000_tls_size
= 32;
210 const char *rs6000_tls_size_string
;
212 /* ABI enumeration available for subtarget to use. */
213 enum rs6000_abi rs6000_current_abi
;
215 /* Whether to use variant of AIX ABI for PowerPC64 Linux. */
219 const char *rs6000_debug_name
;
220 int rs6000_debug_stack
; /* debug stack applications */
221 int rs6000_debug_arg
; /* debug argument handling */
223 /* Value is TRUE if register/mode pair is acceptable. */
224 bool rs6000_hard_regno_mode_ok_p
[NUM_MACHINE_MODES
][FIRST_PSEUDO_REGISTER
];
226 /* Built in types. */
228 tree rs6000_builtin_types
[RS6000_BTI_MAX
];
229 tree rs6000_builtin_decls
[RS6000_BUILTIN_COUNT
];
231 const char *rs6000_traceback_name
;
233 traceback_default
= 0,
239 /* Flag to say the TOC is initialized */
241 char toc_label_name
[10];
243 /* Cached value of rs6000_variable_issue. This is cached in
244 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
245 static short cached_can_issue_more
;
247 static GTY(()) section
*read_only_data_section
;
248 static GTY(()) section
*private_data_section
;
249 static GTY(()) section
*read_only_private_data_section
;
250 static GTY(()) section
*sdata2_section
;
251 static GTY(()) section
*toc_section
;
253 /* Control alignment for fields within structures. */
254 /* String from -malign-XXXXX. */
255 int rs6000_alignment_flags
;
257 /* True for any options that were explicitly set. */
259 bool aix_struct_ret
; /* True if -maix-struct-ret was used. */
260 bool alignment
; /* True if -malign- was used. */
261 bool abi
; /* True if -mabi=spe/nospe was used. */
262 bool spe
; /* True if -mspe= was used. */
263 bool float_gprs
; /* True if -mfloat-gprs= was used. */
264 bool isel
; /* True if -misel was used. */
265 bool long_double
; /* True if -mlong-double- was used. */
266 bool ieee
; /* True if -mabi=ieee/ibmlongdouble used. */
267 } rs6000_explicit_options
;
269 struct builtin_description
271 /* mask is not const because we're going to alter it below. This
272 nonsense will go away when we rewrite the -march infrastructure
273 to give us more target flag bits. */
275 const enum insn_code icode
;
276 const char *const name
;
277 const enum rs6000_builtins code
;
280 /* Target cpu costs. */
282 struct processor_costs
{
283 const int mulsi
; /* cost of SImode multiplication. */
284 const int mulsi_const
; /* cost of SImode multiplication by constant. */
285 const int mulsi_const9
; /* cost of SImode mult by short constant. */
286 const int muldi
; /* cost of DImode multiplication. */
287 const int divsi
; /* cost of SImode division. */
288 const int divdi
; /* cost of DImode division. */
289 const int fp
; /* cost of simple SFmode and DFmode insns. */
290 const int dmul
; /* cost of DFmode multiplication (and fmadd). */
291 const int sdiv
; /* cost of SFmode division (fdivs). */
292 const int ddiv
; /* cost of DFmode division (fdiv). */
295 const struct processor_costs
*rs6000_cost
;
297 /* Processor costs (relative to an add) */
299 /* Instruction size costs on 32bit processors. */
301 struct processor_costs size32_cost
= {
302 COSTS_N_INSNS (1), /* mulsi */
303 COSTS_N_INSNS (1), /* mulsi_const */
304 COSTS_N_INSNS (1), /* mulsi_const9 */
305 COSTS_N_INSNS (1), /* muldi */
306 COSTS_N_INSNS (1), /* divsi */
307 COSTS_N_INSNS (1), /* divdi */
308 COSTS_N_INSNS (1), /* fp */
309 COSTS_N_INSNS (1), /* dmul */
310 COSTS_N_INSNS (1), /* sdiv */
311 COSTS_N_INSNS (1), /* ddiv */
314 /* Instruction size costs on 64bit processors. */
316 struct processor_costs size64_cost
= {
317 COSTS_N_INSNS (1), /* mulsi */
318 COSTS_N_INSNS (1), /* mulsi_const */
319 COSTS_N_INSNS (1), /* mulsi_const9 */
320 COSTS_N_INSNS (1), /* muldi */
321 COSTS_N_INSNS (1), /* divsi */
322 COSTS_N_INSNS (1), /* divdi */
323 COSTS_N_INSNS (1), /* fp */
324 COSTS_N_INSNS (1), /* dmul */
325 COSTS_N_INSNS (1), /* sdiv */
326 COSTS_N_INSNS (1), /* ddiv */
329 /* Instruction costs on RIOS1 processors. */
331 struct processor_costs rios1_cost
= {
332 COSTS_N_INSNS (5), /* mulsi */
333 COSTS_N_INSNS (4), /* mulsi_const */
334 COSTS_N_INSNS (3), /* mulsi_const9 */
335 COSTS_N_INSNS (5), /* muldi */
336 COSTS_N_INSNS (19), /* divsi */
337 COSTS_N_INSNS (19), /* divdi */
338 COSTS_N_INSNS (2), /* fp */
339 COSTS_N_INSNS (2), /* dmul */
340 COSTS_N_INSNS (19), /* sdiv */
341 COSTS_N_INSNS (19), /* ddiv */
344 /* Instruction costs on RIOS2 processors. */
346 struct processor_costs rios2_cost
= {
347 COSTS_N_INSNS (2), /* mulsi */
348 COSTS_N_INSNS (2), /* mulsi_const */
349 COSTS_N_INSNS (2), /* mulsi_const9 */
350 COSTS_N_INSNS (2), /* muldi */
351 COSTS_N_INSNS (13), /* divsi */
352 COSTS_N_INSNS (13), /* divdi */
353 COSTS_N_INSNS (2), /* fp */
354 COSTS_N_INSNS (2), /* dmul */
355 COSTS_N_INSNS (17), /* sdiv */
356 COSTS_N_INSNS (17), /* ddiv */
359 /* Instruction costs on RS64A processors. */
361 struct processor_costs rs64a_cost
= {
362 COSTS_N_INSNS (20), /* mulsi */
363 COSTS_N_INSNS (12), /* mulsi_const */
364 COSTS_N_INSNS (8), /* mulsi_const9 */
365 COSTS_N_INSNS (34), /* muldi */
366 COSTS_N_INSNS (65), /* divsi */
367 COSTS_N_INSNS (67), /* divdi */
368 COSTS_N_INSNS (4), /* fp */
369 COSTS_N_INSNS (4), /* dmul */
370 COSTS_N_INSNS (31), /* sdiv */
371 COSTS_N_INSNS (31), /* ddiv */
374 /* Instruction costs on MPCCORE processors. */
376 struct processor_costs mpccore_cost
= {
377 COSTS_N_INSNS (2), /* mulsi */
378 COSTS_N_INSNS (2), /* mulsi_const */
379 COSTS_N_INSNS (2), /* mulsi_const9 */
380 COSTS_N_INSNS (2), /* muldi */
381 COSTS_N_INSNS (6), /* divsi */
382 COSTS_N_INSNS (6), /* divdi */
383 COSTS_N_INSNS (4), /* fp */
384 COSTS_N_INSNS (5), /* dmul */
385 COSTS_N_INSNS (10), /* sdiv */
386 COSTS_N_INSNS (17), /* ddiv */
389 /* Instruction costs on PPC403 processors. */
391 struct processor_costs ppc403_cost
= {
392 COSTS_N_INSNS (4), /* mulsi */
393 COSTS_N_INSNS (4), /* mulsi_const */
394 COSTS_N_INSNS (4), /* mulsi_const9 */
395 COSTS_N_INSNS (4), /* muldi */
396 COSTS_N_INSNS (33), /* divsi */
397 COSTS_N_INSNS (33), /* divdi */
398 COSTS_N_INSNS (11), /* fp */
399 COSTS_N_INSNS (11), /* dmul */
400 COSTS_N_INSNS (11), /* sdiv */
401 COSTS_N_INSNS (11), /* ddiv */
404 /* Instruction costs on PPC405 processors. */
406 struct processor_costs ppc405_cost
= {
407 COSTS_N_INSNS (5), /* mulsi */
408 COSTS_N_INSNS (4), /* mulsi_const */
409 COSTS_N_INSNS (3), /* mulsi_const9 */
410 COSTS_N_INSNS (5), /* muldi */
411 COSTS_N_INSNS (35), /* divsi */
412 COSTS_N_INSNS (35), /* divdi */
413 COSTS_N_INSNS (11), /* fp */
414 COSTS_N_INSNS (11), /* dmul */
415 COSTS_N_INSNS (11), /* sdiv */
416 COSTS_N_INSNS (11), /* ddiv */
419 /* Instruction costs on PPC440 processors. */
421 struct processor_costs ppc440_cost
= {
422 COSTS_N_INSNS (3), /* mulsi */
423 COSTS_N_INSNS (2), /* mulsi_const */
424 COSTS_N_INSNS (2), /* mulsi_const9 */
425 COSTS_N_INSNS (3), /* muldi */
426 COSTS_N_INSNS (34), /* divsi */
427 COSTS_N_INSNS (34), /* divdi */
428 COSTS_N_INSNS (5), /* fp */
429 COSTS_N_INSNS (5), /* dmul */
430 COSTS_N_INSNS (19), /* sdiv */
431 COSTS_N_INSNS (33), /* ddiv */
434 /* Instruction costs on PPC601 processors. */
436 struct processor_costs ppc601_cost
= {
437 COSTS_N_INSNS (5), /* mulsi */
438 COSTS_N_INSNS (5), /* mulsi_const */
439 COSTS_N_INSNS (5), /* mulsi_const9 */
440 COSTS_N_INSNS (5), /* muldi */
441 COSTS_N_INSNS (36), /* divsi */
442 COSTS_N_INSNS (36), /* divdi */
443 COSTS_N_INSNS (4), /* fp */
444 COSTS_N_INSNS (5), /* dmul */
445 COSTS_N_INSNS (17), /* sdiv */
446 COSTS_N_INSNS (31), /* ddiv */
449 /* Instruction costs on PPC603 processors. */
451 struct processor_costs ppc603_cost
= {
452 COSTS_N_INSNS (5), /* mulsi */
453 COSTS_N_INSNS (3), /* mulsi_const */
454 COSTS_N_INSNS (2), /* mulsi_const9 */
455 COSTS_N_INSNS (5), /* muldi */
456 COSTS_N_INSNS (37), /* divsi */
457 COSTS_N_INSNS (37), /* divdi */
458 COSTS_N_INSNS (3), /* fp */
459 COSTS_N_INSNS (4), /* dmul */
460 COSTS_N_INSNS (18), /* sdiv */
461 COSTS_N_INSNS (33), /* ddiv */
464 /* Instruction costs on PPC604 processors. */
466 struct processor_costs ppc604_cost
= {
467 COSTS_N_INSNS (4), /* mulsi */
468 COSTS_N_INSNS (4), /* mulsi_const */
469 COSTS_N_INSNS (4), /* mulsi_const9 */
470 COSTS_N_INSNS (4), /* muldi */
471 COSTS_N_INSNS (20), /* divsi */
472 COSTS_N_INSNS (20), /* divdi */
473 COSTS_N_INSNS (3), /* fp */
474 COSTS_N_INSNS (3), /* dmul */
475 COSTS_N_INSNS (18), /* sdiv */
476 COSTS_N_INSNS (32), /* ddiv */
479 /* Instruction costs on PPC604e processors. */
481 struct processor_costs ppc604e_cost
= {
482 COSTS_N_INSNS (2), /* mulsi */
483 COSTS_N_INSNS (2), /* mulsi_const */
484 COSTS_N_INSNS (2), /* mulsi_const9 */
485 COSTS_N_INSNS (2), /* muldi */
486 COSTS_N_INSNS (20), /* divsi */
487 COSTS_N_INSNS (20), /* divdi */
488 COSTS_N_INSNS (3), /* fp */
489 COSTS_N_INSNS (3), /* dmul */
490 COSTS_N_INSNS (18), /* sdiv */
491 COSTS_N_INSNS (32), /* ddiv */
494 /* Instruction costs on PPC620 processors. */
496 struct processor_costs ppc620_cost
= {
497 COSTS_N_INSNS (5), /* mulsi */
498 COSTS_N_INSNS (4), /* mulsi_const */
499 COSTS_N_INSNS (3), /* mulsi_const9 */
500 COSTS_N_INSNS (7), /* muldi */
501 COSTS_N_INSNS (21), /* divsi */
502 COSTS_N_INSNS (37), /* divdi */
503 COSTS_N_INSNS (3), /* fp */
504 COSTS_N_INSNS (3), /* dmul */
505 COSTS_N_INSNS (18), /* sdiv */
506 COSTS_N_INSNS (32), /* ddiv */
509 /* Instruction costs on PPC630 processors. */
511 struct processor_costs ppc630_cost
= {
512 COSTS_N_INSNS (5), /* mulsi */
513 COSTS_N_INSNS (4), /* mulsi_const */
514 COSTS_N_INSNS (3), /* mulsi_const9 */
515 COSTS_N_INSNS (7), /* muldi */
516 COSTS_N_INSNS (21), /* divsi */
517 COSTS_N_INSNS (37), /* divdi */
518 COSTS_N_INSNS (3), /* fp */
519 COSTS_N_INSNS (3), /* dmul */
520 COSTS_N_INSNS (17), /* sdiv */
521 COSTS_N_INSNS (21), /* ddiv */
524 /* Instruction costs on Cell processor. */
525 /* COSTS_N_INSNS (1) ~ one add. */
527 struct processor_costs ppccell_cost
= {
528 COSTS_N_INSNS (9/2)+2, /* mulsi */
529 COSTS_N_INSNS (6/2), /* mulsi_const */
530 COSTS_N_INSNS (6/2), /* mulsi_const9 */
531 COSTS_N_INSNS (15/2)+2, /* muldi */
532 COSTS_N_INSNS (38/2), /* divsi */
533 COSTS_N_INSNS (70/2), /* divdi */
534 COSTS_N_INSNS (10/2), /* fp */
535 COSTS_N_INSNS (10/2), /* dmul */
536 COSTS_N_INSNS (74/2), /* sdiv */
537 COSTS_N_INSNS (74/2), /* ddiv */
540 /* Instruction costs on PPC750 and PPC7400 processors. */
542 struct processor_costs ppc750_cost
= {
543 COSTS_N_INSNS (5), /* mulsi */
544 COSTS_N_INSNS (3), /* mulsi_const */
545 COSTS_N_INSNS (2), /* mulsi_const9 */
546 COSTS_N_INSNS (5), /* muldi */
547 COSTS_N_INSNS (17), /* divsi */
548 COSTS_N_INSNS (17), /* divdi */
549 COSTS_N_INSNS (3), /* fp */
550 COSTS_N_INSNS (3), /* dmul */
551 COSTS_N_INSNS (17), /* sdiv */
552 COSTS_N_INSNS (31), /* ddiv */
555 /* Instruction costs on PPC7450 processors. */
557 struct processor_costs ppc7450_cost
= {
558 COSTS_N_INSNS (4), /* mulsi */
559 COSTS_N_INSNS (3), /* mulsi_const */
560 COSTS_N_INSNS (3), /* mulsi_const9 */
561 COSTS_N_INSNS (4), /* muldi */
562 COSTS_N_INSNS (23), /* divsi */
563 COSTS_N_INSNS (23), /* divdi */
564 COSTS_N_INSNS (5), /* fp */
565 COSTS_N_INSNS (5), /* dmul */
566 COSTS_N_INSNS (21), /* sdiv */
567 COSTS_N_INSNS (35), /* ddiv */
570 /* Instruction costs on PPC8540 processors. */
572 struct processor_costs ppc8540_cost
= {
573 COSTS_N_INSNS (4), /* mulsi */
574 COSTS_N_INSNS (4), /* mulsi_const */
575 COSTS_N_INSNS (4), /* mulsi_const9 */
576 COSTS_N_INSNS (4), /* muldi */
577 COSTS_N_INSNS (19), /* divsi */
578 COSTS_N_INSNS (19), /* divdi */
579 COSTS_N_INSNS (4), /* fp */
580 COSTS_N_INSNS (4), /* dmul */
581 COSTS_N_INSNS (29), /* sdiv */
582 COSTS_N_INSNS (29), /* ddiv */
585 /* Instruction costs on POWER4 and POWER5 processors. */
587 struct processor_costs power4_cost
= {
588 COSTS_N_INSNS (3), /* mulsi */
589 COSTS_N_INSNS (2), /* mulsi_const */
590 COSTS_N_INSNS (2), /* mulsi_const9 */
591 COSTS_N_INSNS (4), /* muldi */
592 COSTS_N_INSNS (18), /* divsi */
593 COSTS_N_INSNS (34), /* divdi */
594 COSTS_N_INSNS (3), /* fp */
595 COSTS_N_INSNS (3), /* dmul */
596 COSTS_N_INSNS (17), /* sdiv */
597 COSTS_N_INSNS (17), /* ddiv */
600 /* Instruction costs on POWER6 processors. */
602 struct processor_costs power6_cost
= {
603 COSTS_N_INSNS (8), /* mulsi */
604 COSTS_N_INSNS (8), /* mulsi_const */
605 COSTS_N_INSNS (8), /* mulsi_const9 */
606 COSTS_N_INSNS (8), /* muldi */
607 COSTS_N_INSNS (22), /* divsi */
608 COSTS_N_INSNS (28), /* divdi */
609 COSTS_N_INSNS (3), /* fp */
610 COSTS_N_INSNS (3), /* dmul */
611 COSTS_N_INSNS (13), /* sdiv */
612 COSTS_N_INSNS (16), /* ddiv */
616 static bool rs6000_function_ok_for_sibcall (tree
, tree
);
617 static const char *rs6000_invalid_within_doloop (rtx
);
618 static rtx
rs6000_generate_compare (enum rtx_code
);
619 static void rs6000_maybe_dead (rtx
);
620 static void rs6000_emit_stack_tie (void);
621 static void rs6000_frame_related (rtx
, rtx
, HOST_WIDE_INT
, rtx
, rtx
);
622 static rtx
spe_synthesize_frame_save (rtx
);
623 static bool spe_func_has_64bit_regs_p (void);
624 static void emit_frame_save (rtx
, rtx
, enum machine_mode
, unsigned int,
626 static rtx
gen_frame_mem_offset (enum machine_mode
, rtx
, int);
627 static void rs6000_emit_allocate_stack (HOST_WIDE_INT
, int);
628 static unsigned rs6000_hash_constant (rtx
);
629 static unsigned toc_hash_function (const void *);
630 static int toc_hash_eq (const void *, const void *);
631 static int constant_pool_expr_1 (rtx
, int *, int *);
632 static bool constant_pool_expr_p (rtx
);
633 static bool legitimate_small_data_p (enum machine_mode
, rtx
);
634 static bool legitimate_indexed_address_p (rtx
, int);
635 static bool legitimate_lo_sum_address_p (enum machine_mode
, rtx
, int);
636 static struct machine_function
* rs6000_init_machine_status (void);
637 static bool rs6000_assemble_integer (rtx
, unsigned int, int);
638 static bool no_global_regs_above (int);
639 #ifdef HAVE_GAS_HIDDEN
640 static void rs6000_assemble_visibility (tree
, int);
642 static int rs6000_ra_ever_killed (void);
643 static tree
rs6000_handle_longcall_attribute (tree
*, tree
, tree
, int, bool *);
644 static tree
rs6000_handle_altivec_attribute (tree
*, tree
, tree
, int, bool *);
645 static bool rs6000_ms_bitfield_layout_p (tree
);
646 static tree
rs6000_handle_struct_attribute (tree
*, tree
, tree
, int, bool *);
647 static void rs6000_eliminate_indexed_memrefs (rtx operands
[2]);
648 static const char *rs6000_mangle_fundamental_type (tree
);
649 extern const struct attribute_spec rs6000_attribute_table
[];
650 static void rs6000_set_default_type_attributes (tree
);
651 static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT
);
652 static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT
);
653 static void rs6000_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
655 static rtx
rs6000_emit_set_long_const (rtx
, HOST_WIDE_INT
, HOST_WIDE_INT
);
656 static bool rs6000_return_in_memory (tree
, tree
);
657 static void rs6000_file_start (void);
659 static unsigned int rs6000_elf_section_type_flags (tree
, const char *, int);
660 static void rs6000_elf_asm_out_constructor (rtx
, int);
661 static void rs6000_elf_asm_out_destructor (rtx
, int);
662 static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED
;
663 static void rs6000_elf_asm_init_sections (void);
664 static section
*rs6000_elf_select_section (tree
, int, unsigned HOST_WIDE_INT
);
665 static void rs6000_elf_unique_section (tree
, int);
666 static section
*rs6000_elf_select_rtx_section (enum machine_mode
, rtx
,
667 unsigned HOST_WIDE_INT
);
668 static void rs6000_elf_encode_section_info (tree
, rtx
, int)
671 static bool rs6000_use_blocks_for_constant_p (enum machine_mode
, rtx
);
673 static void rs6000_xcoff_asm_output_anchor (rtx
);
674 static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
675 static void rs6000_xcoff_asm_init_sections (void);
676 static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree
);
677 static section
*rs6000_xcoff_select_section (tree
, int,
678 unsigned HOST_WIDE_INT
);
679 static void rs6000_xcoff_unique_section (tree
, int);
680 static section
*rs6000_xcoff_select_rtx_section
681 (enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
);
682 static const char * rs6000_xcoff_strip_name_encoding (const char *);
683 static unsigned int rs6000_xcoff_section_type_flags (tree
, const char *, int);
684 static void rs6000_xcoff_file_start (void);
685 static void rs6000_xcoff_file_end (void);
687 static int rs6000_variable_issue (FILE *, int, rtx
, int);
688 static bool rs6000_rtx_costs (rtx
, int, int, int *);
689 static int rs6000_adjust_cost (rtx
, rtx
, rtx
, int);
690 static void rs6000_sched_init (FILE *, int, int);
691 static bool is_microcoded_insn (rtx
);
692 static bool is_nonpipeline_insn (rtx
);
693 static bool is_cracked_insn (rtx
);
694 static bool is_branch_slot_insn (rtx
);
695 static bool is_load_insn (rtx
);
696 static rtx
get_store_dest (rtx pat
);
697 static bool is_store_insn (rtx
);
698 static bool set_to_load_agen (rtx
,rtx
);
699 static bool adjacent_mem_locations (rtx
,rtx
);
700 static int rs6000_adjust_priority (rtx
, int);
701 static int rs6000_issue_rate (void);
702 static bool rs6000_is_costly_dependence (dep_t
, int, int);
703 static rtx
get_next_active_insn (rtx
, rtx
);
704 static bool insn_terminates_group_p (rtx
, enum group_termination
);
705 static bool insn_must_be_first_in_group (rtx
);
706 static bool insn_must_be_last_in_group (rtx
);
707 static bool is_costly_group (rtx
*, rtx
);
708 static int force_new_group (int, FILE *, rtx
*, rtx
, bool *, int, int *);
709 static int redefine_groups (FILE *, int, rtx
, rtx
);
710 static int pad_groups (FILE *, int, rtx
, rtx
);
711 static void rs6000_sched_finish (FILE *, int);
712 static int rs6000_sched_reorder (FILE *, int, rtx
*, int *, int);
713 static int rs6000_sched_reorder2 (FILE *, int, rtx
*, int *, int);
714 static int rs6000_use_sched_lookahead (void);
715 static int rs6000_use_sched_lookahead_guard (rtx
);
716 static tree
rs6000_builtin_mask_for_load (void);
717 static tree
rs6000_builtin_mul_widen_even (tree
);
718 static tree
rs6000_builtin_mul_widen_odd (tree
);
719 static tree
rs6000_builtin_conversion (enum tree_code
, tree
);
721 static void def_builtin (int, const char *, tree
, int);
722 static void rs6000_init_builtins (void);
723 static rtx
rs6000_expand_unop_builtin (enum insn_code
, tree
, rtx
);
724 static rtx
rs6000_expand_binop_builtin (enum insn_code
, tree
, rtx
);
725 static rtx
rs6000_expand_ternop_builtin (enum insn_code
, tree
, rtx
);
726 static rtx
rs6000_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
727 static void altivec_init_builtins (void);
728 static void rs6000_common_init_builtins (void);
729 static void rs6000_init_libfuncs (void);
731 static void enable_mask_for_builtins (struct builtin_description
*, int,
732 enum rs6000_builtins
,
733 enum rs6000_builtins
);
734 static tree
build_opaque_vector_type (tree
, int);
735 static void spe_init_builtins (void);
736 static rtx
spe_expand_builtin (tree
, rtx
, bool *);
737 static rtx
spe_expand_stv_builtin (enum insn_code
, tree
);
738 static rtx
spe_expand_predicate_builtin (enum insn_code
, tree
, rtx
);
739 static rtx
spe_expand_evsel_builtin (enum insn_code
, tree
, rtx
);
740 static int rs6000_emit_int_cmove (rtx
, rtx
, rtx
, rtx
);
741 static rs6000_stack_t
*rs6000_stack_info (void);
742 static void debug_stack_info (rs6000_stack_t
*);
744 static rtx
altivec_expand_builtin (tree
, rtx
, bool *);
745 static rtx
altivec_expand_ld_builtin (tree
, rtx
, bool *);
746 static rtx
altivec_expand_st_builtin (tree
, rtx
, bool *);
747 static rtx
altivec_expand_dst_builtin (tree
, rtx
, bool *);
748 static rtx
altivec_expand_abs_builtin (enum insn_code
, tree
, rtx
);
749 static rtx
altivec_expand_predicate_builtin (enum insn_code
,
750 const char *, tree
, rtx
);
751 static rtx
altivec_expand_lv_builtin (enum insn_code
, tree
, rtx
);
752 static rtx
altivec_expand_stv_builtin (enum insn_code
, tree
);
753 static rtx
altivec_expand_vec_init_builtin (tree
, tree
, rtx
);
754 static rtx
altivec_expand_vec_set_builtin (tree
);
755 static rtx
altivec_expand_vec_ext_builtin (tree
, rtx
);
756 static int get_element_number (tree
, tree
);
757 static bool rs6000_handle_option (size_t, const char *, int);
758 static void rs6000_parse_tls_size_option (void);
759 static void rs6000_parse_yes_no_option (const char *, const char *, int *);
760 static int first_altivec_reg_to_save (void);
761 static unsigned int compute_vrsave_mask (void);
762 static void compute_save_world_info (rs6000_stack_t
*info_ptr
);
763 static void is_altivec_return_reg (rtx
, void *);
764 static rtx
generate_set_vrsave (rtx
, rs6000_stack_t
*, int);
765 int easy_vector_constant (rtx
, enum machine_mode
);
766 static bool rs6000_is_opaque_type (tree
);
767 static rtx
rs6000_dwarf_register_span (rtx
);
768 static void rs6000_init_dwarf_reg_sizes_extra (tree
);
769 static rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
770 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
771 static rtx
rs6000_tls_get_addr (void);
772 static rtx
rs6000_got_sym (void);
773 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
774 static const char *rs6000_get_some_local_dynamic_name (void);
775 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
776 static rtx
rs6000_complex_function_value (enum machine_mode
);
777 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
778 enum machine_mode
, tree
);
779 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
781 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
782 tree
, HOST_WIDE_INT
);
783 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
786 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
789 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, tree
, int, bool);
790 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
791 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
792 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
793 enum machine_mode
, tree
,
795 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
797 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
799 static const char *invalid_arg_for_unprototyped_fn (tree
, tree
, tree
);
801 static void macho_branch_islands (void);
802 static int no_previous_def (tree function_name
);
803 static tree
get_prev_label (tree function_name
);
804 static void rs6000_darwin_file_start (void);
807 static tree
rs6000_build_builtin_va_list (void);
808 static tree
rs6000_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
809 static bool rs6000_must_pass_in_stack (enum machine_mode
, tree
);
810 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
811 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
812 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
814 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
816 static int get_vsel_insn (enum machine_mode
);
817 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
818 static tree
rs6000_stack_protect_fail (void);
820 const int INSN_NOT_AVAILABLE
= -1;
821 static enum machine_mode
rs6000_eh_return_filter_mode (void);
823 /* Hash table stuff for keeping track of TOC entries. */
825 struct toc_hash_struct
GTY(())
827 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
828 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
830 enum machine_mode key_mode
;
834 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
836 /* Default register names. */
837 char rs6000_reg_names
[][8] =
839 "0", "1", "2", "3", "4", "5", "6", "7",
840 "8", "9", "10", "11", "12", "13", "14", "15",
841 "16", "17", "18", "19", "20", "21", "22", "23",
842 "24", "25", "26", "27", "28", "29", "30", "31",
843 "0", "1", "2", "3", "4", "5", "6", "7",
844 "8", "9", "10", "11", "12", "13", "14", "15",
845 "16", "17", "18", "19", "20", "21", "22", "23",
846 "24", "25", "26", "27", "28", "29", "30", "31",
847 "mq", "lr", "ctr","ap",
848 "0", "1", "2", "3", "4", "5", "6", "7",
850 /* AltiVec registers. */
851 "0", "1", "2", "3", "4", "5", "6", "7",
852 "8", "9", "10", "11", "12", "13", "14", "15",
853 "16", "17", "18", "19", "20", "21", "22", "23",
854 "24", "25", "26", "27", "28", "29", "30", "31",
857 "spe_acc", "spefscr",
858 /* Soft frame pointer. */
862 #ifdef TARGET_REGNAMES
863 static const char alt_reg_names
[][8] =
865 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
866 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
867 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
868 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
869 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
870 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
871 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
872 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
873 "mq", "lr", "ctr", "ap",
874 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
876 /* AltiVec registers. */
877 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
878 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
879 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
880 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
883 "spe_acc", "spefscr",
884 /* Soft frame pointer. */
889 #ifndef MASK_STRICT_ALIGN
890 #define MASK_STRICT_ALIGN 0
892 #ifndef TARGET_PROFILE_KERNEL
893 #define TARGET_PROFILE_KERNEL 0
896 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
897 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
899 /* Initialize the GCC target structure. */
900 #undef TARGET_ATTRIBUTE_TABLE
901 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
902 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
903 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
905 #undef TARGET_ASM_ALIGNED_DI_OP
906 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
908 /* Default unaligned ops are only provided for ELF. Find the ops needed
909 for non-ELF systems. */
910 #ifndef OBJECT_FORMAT_ELF
912 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
914 #undef TARGET_ASM_UNALIGNED_HI_OP
915 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
916 #undef TARGET_ASM_UNALIGNED_SI_OP
917 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
918 #undef TARGET_ASM_UNALIGNED_DI_OP
919 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
922 #undef TARGET_ASM_UNALIGNED_HI_OP
923 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
924 #undef TARGET_ASM_UNALIGNED_SI_OP
925 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
926 #undef TARGET_ASM_UNALIGNED_DI_OP
927 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
928 #undef TARGET_ASM_ALIGNED_DI_OP
929 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
933 /* This hook deals with fixups for relocatable code and DI-mode objects
935 #undef TARGET_ASM_INTEGER
936 #define TARGET_ASM_INTEGER rs6000_assemble_integer
938 #ifdef HAVE_GAS_HIDDEN
939 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
940 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
943 #undef TARGET_HAVE_TLS
944 #define TARGET_HAVE_TLS HAVE_AS_TLS
946 #undef TARGET_CANNOT_FORCE_CONST_MEM
947 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
949 #undef TARGET_ASM_FUNCTION_PROLOGUE
950 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
951 #undef TARGET_ASM_FUNCTION_EPILOGUE
952 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
954 #undef TARGET_SCHED_VARIABLE_ISSUE
955 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
957 #undef TARGET_SCHED_ISSUE_RATE
958 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
959 #undef TARGET_SCHED_ADJUST_COST
960 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
961 #undef TARGET_SCHED_ADJUST_PRIORITY
962 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
963 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
964 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
965 #undef TARGET_SCHED_INIT
966 #define TARGET_SCHED_INIT rs6000_sched_init
967 #undef TARGET_SCHED_FINISH
968 #define TARGET_SCHED_FINISH rs6000_sched_finish
969 #undef TARGET_SCHED_REORDER
970 #define TARGET_SCHED_REORDER rs6000_sched_reorder
971 #undef TARGET_SCHED_REORDER2
972 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
974 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
975 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
977 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
978 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
980 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
981 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
982 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
983 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
984 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
985 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
986 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
987 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
989 #undef TARGET_INIT_BUILTINS
990 #define TARGET_INIT_BUILTINS rs6000_init_builtins
992 #undef TARGET_EXPAND_BUILTIN
993 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
995 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
996 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
998 #undef TARGET_INIT_LIBFUNCS
999 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1002 #undef TARGET_BINDS_LOCAL_P
1003 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1006 #undef TARGET_MS_BITFIELD_LAYOUT_P
1007 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1009 #undef TARGET_ASM_OUTPUT_MI_THUNK
1010 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1012 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1013 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
1015 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1016 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1018 #undef TARGET_INVALID_WITHIN_DOLOOP
1019 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1021 #undef TARGET_RTX_COSTS
1022 #define TARGET_RTX_COSTS rs6000_rtx_costs
1023 #undef TARGET_ADDRESS_COST
1024 #define TARGET_ADDRESS_COST hook_int_rtx_0
1026 #undef TARGET_VECTOR_OPAQUE_P
1027 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1029 #undef TARGET_DWARF_REGISTER_SPAN
1030 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1032 #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1033 #define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1035 /* On rs6000, function arguments are promoted, as are function return
1037 #undef TARGET_PROMOTE_FUNCTION_ARGS
1038 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
1039 #undef TARGET_PROMOTE_FUNCTION_RETURN
1040 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
1042 #undef TARGET_RETURN_IN_MEMORY
1043 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1045 #undef TARGET_SETUP_INCOMING_VARARGS
1046 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1048 /* Always strict argument naming on rs6000. */
1049 #undef TARGET_STRICT_ARGUMENT_NAMING
1050 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1051 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1052 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1053 #undef TARGET_SPLIT_COMPLEX_ARG
1054 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
1055 #undef TARGET_MUST_PASS_IN_STACK
1056 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1057 #undef TARGET_PASS_BY_REFERENCE
1058 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1059 #undef TARGET_ARG_PARTIAL_BYTES
1060 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1062 #undef TARGET_BUILD_BUILTIN_VA_LIST
1063 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1065 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1066 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1068 #undef TARGET_EH_RETURN_FILTER_MODE
1069 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1071 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1072 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1074 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1075 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1077 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1078 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1080 #undef TARGET_HANDLE_OPTION
1081 #define TARGET_HANDLE_OPTION rs6000_handle_option
1083 #undef TARGET_DEFAULT_TARGET_FLAGS
1084 #define TARGET_DEFAULT_TARGET_FLAGS \
1087 #undef TARGET_STACK_PROTECT_FAIL
1088 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1090 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1091 The PowerPC architecture requires only weak consistency among
1092 processors--that is, memory accesses between processors need not be
1093 sequentially consistent and memory accesses among processors can occur
1094 in any order. The ability to order memory accesses weakly provides
1095 opportunities for more efficient use of the system bus. Unless a
1096 dependency exists, the 604e allows read operations to precede store
1098 #undef TARGET_RELAXED_ORDERING
1099 #define TARGET_RELAXED_ORDERING true
1102 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1103 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1106 /* Use a 32-bit anchor range. This leads to sequences like:
1108 addis tmp,anchor,high
1111 where tmp itself acts as an anchor, and can be shared between
1112 accesses to the same 64k page. */
1113 #undef TARGET_MIN_ANCHOR_OFFSET
1114 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1115 #undef TARGET_MAX_ANCHOR_OFFSET
1116 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1117 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1118 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1120 struct gcc_target targetm
= TARGET_INITIALIZER
;
1123 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1126 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1128 /* The GPRs can hold any mode, but values bigger than one register
1129 cannot go past R31. */
1130 if (INT_REGNO_P (regno
))
1131 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1133 /* The float registers can only hold floating modes and DImode.
1134 This excludes the 32-bit decimal float mode for now. */
1135 if (FP_REGNO_P (regno
))
1137 (SCALAR_FLOAT_MODE_P (mode
)
1139 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1140 || (GET_MODE_CLASS (mode
) == MODE_INT
1141 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
);
1143 /* The CR register can only hold CC modes. */
1144 if (CR_REGNO_P (regno
))
1145 return GET_MODE_CLASS (mode
) == MODE_CC
;
1147 if (XER_REGNO_P (regno
))
1148 return mode
== PSImode
;
1150 /* AltiVec only in AldyVec registers. */
1151 if (ALTIVEC_REGNO_P (regno
))
1152 return ALTIVEC_VECTOR_MODE (mode
);
1154 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1155 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1158 /* We cannot put TImode anywhere except general register and it must be
1159 able to fit within the register set. */
1161 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1164 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1166 rs6000_init_hard_regno_mode_ok (void)
1170 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1171 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1172 if (rs6000_hard_regno_mode_ok (r
, m
))
1173 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1177 /* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1180 darwin_rs6000_override_options (void)
1182 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1184 rs6000_altivec_abi
= 1;
1185 TARGET_ALTIVEC_VRSAVE
= 1;
1186 if (DEFAULT_ABI
== ABI_DARWIN
)
1188 if (MACHO_DYNAMIC_NO_PIC_P
)
1191 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1194 else if (flag_pic
== 1)
1199 if (TARGET_64BIT
&& ! TARGET_POWERPC64
)
1201 target_flags
|= MASK_POWERPC64
;
1202 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1206 rs6000_default_long_calls
= 1;
1207 target_flags
|= MASK_SOFT_FLOAT
;
1210 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1212 if (!flag_mkernel
&& !flag_apple_kext
1214 && ! (target_flags_explicit
& MASK_ALTIVEC
))
1215 target_flags
|= MASK_ALTIVEC
;
1217 /* Unless the user (not the configurer) has explicitly overridden
1218 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1219 G4 unless targetting the kernel. */
1222 && strverscmp (darwin_macosx_version_min
, "10.5") >= 0
1223 && ! (target_flags_explicit
& MASK_ALTIVEC
)
1224 && ! rs6000_select
[1].string
)
1226 target_flags
|= MASK_ALTIVEC
;
1231 /* If not otherwise specified by a target, make 'long double' equivalent to
1234 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1235 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1238 /* Override command line options. Mostly we process the processor
1239 type and sometimes adjust other TARGET_ options. */
1242 rs6000_override_options (const char *default_cpu
)
1245 struct rs6000_cpu_select
*ptr
;
1248 /* Simplifications for entries below. */
1251 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1252 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1255 /* This table occasionally claims that a processor does not support
1256 a particular feature even though it does, but the feature is slower
1257 than the alternative. Thus, it shouldn't be relied on as a
1258 complete description of the processor's support.
1260 Please keep this list in order, and don't forget to update the
1261 documentation in invoke.texi when adding a new processor or
1265 const char *const name
; /* Canonical processor name. */
1266 const enum processor_type processor
; /* Processor type enum value. */
1267 const int target_enable
; /* Target flags to enable. */
1268 } const processor_target_table
[]
1269 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1270 {"403", PROCESSOR_PPC403
,
1271 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1272 {"405", PROCESSOR_PPC405
,
1273 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1274 {"405fp", PROCESSOR_PPC405
,
1275 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1276 {"440", PROCESSOR_PPC440
,
1277 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1278 {"440fp", PROCESSOR_PPC440
,
1279 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1280 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1281 {"601", PROCESSOR_PPC601
,
1282 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1283 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1284 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1285 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1286 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1287 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1288 {"620", PROCESSOR_PPC620
,
1289 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1290 {"630", PROCESSOR_PPC630
,
1291 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1292 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1293 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1294 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1295 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1296 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1297 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1298 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1299 {"8540", PROCESSOR_PPC8540
,
1300 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_STRICT_ALIGN
},
1301 /* 8548 has a dummy entry for now. */
1302 {"8548", PROCESSOR_PPC8540
,
1303 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_STRICT_ALIGN
},
1304 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1305 {"970", PROCESSOR_POWER4
,
1306 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1307 {"cell", PROCESSOR_CELL
,
1308 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1309 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1310 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1311 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1312 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1313 {"G5", PROCESSOR_POWER4
,
1314 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1315 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1316 {"power2", PROCESSOR_POWER
,
1317 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1318 {"power3", PROCESSOR_PPC630
,
1319 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1320 {"power4", PROCESSOR_POWER4
,
1321 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1322 {"power5", PROCESSOR_POWER5
,
1323 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1324 | MASK_MFCRF
| MASK_POPCNTB
},
1325 {"power5+", PROCESSOR_POWER5
,
1326 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1327 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1328 {"power6", PROCESSOR_POWER6
,
1329 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1330 | MASK_FPRND
| MASK_CMPB
| MASK_DFP
},
1331 {"power6x", PROCESSOR_POWER6
,
1332 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1333 | MASK_FPRND
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
},
1334 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1335 {"powerpc64", PROCESSOR_POWERPC64
,
1336 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1337 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1338 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1339 {"rios2", PROCESSOR_RIOS2
,
1340 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1341 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1342 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1343 {"rs64", PROCESSOR_RS64A
,
1344 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1347 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1349 /* Some OSs don't support saving the high part of 64-bit registers on
1350 context switch. Other OSs don't support saving Altivec registers.
1351 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1352 settings; if the user wants either, the user must explicitly specify
1353 them and we won't interfere with the user's specification. */
1356 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1357 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1358 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1359 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1360 | MASK_DLMZB
| MASK_CMPB
| MASK_MFPGPR
| MASK_DFP
)
1363 rs6000_init_hard_regno_mode_ok ();
1365 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1366 #ifdef OS_MISSING_POWERPC64
1367 if (OS_MISSING_POWERPC64
)
1368 set_masks
&= ~MASK_POWERPC64
;
1370 #ifdef OS_MISSING_ALTIVEC
1371 if (OS_MISSING_ALTIVEC
)
1372 set_masks
&= ~MASK_ALTIVEC
;
1375 /* Don't override by the processor default if given explicitly. */
1376 set_masks
&= ~target_flags_explicit
;
1378 /* Identify the processor type. */
1379 rs6000_select
[0].string
= default_cpu
;
1380 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1382 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1384 ptr
= &rs6000_select
[i
];
1385 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1387 for (j
= 0; j
< ptt_size
; j
++)
1388 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1390 if (ptr
->set_tune_p
)
1391 rs6000_cpu
= processor_target_table
[j
].processor
;
1393 if (ptr
->set_arch_p
)
1395 target_flags
&= ~set_masks
;
1396 target_flags
|= (processor_target_table
[j
].target_enable
1403 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1410 /* If we are optimizing big endian systems for space, use the load/store
1411 multiple and string instructions. */
1412 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1413 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1415 /* Don't allow -mmultiple or -mstring on little endian systems
1416 unless the cpu is a 750, because the hardware doesn't support the
1417 instructions used in little endian mode, and causes an alignment
1418 trap. The 750 does not cause an alignment trap (except when the
1419 target is unaligned). */
1421 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1423 if (TARGET_MULTIPLE
)
1425 target_flags
&= ~MASK_MULTIPLE
;
1426 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1427 warning (0, "-mmultiple is not supported on little endian systems");
1432 target_flags
&= ~MASK_STRING
;
1433 if ((target_flags_explicit
& MASK_STRING
) != 0)
1434 warning (0, "-mstring is not supported on little endian systems");
1438 /* Set debug flags */
1439 if (rs6000_debug_name
)
1441 if (! strcmp (rs6000_debug_name
, "all"))
1442 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1443 else if (! strcmp (rs6000_debug_name
, "stack"))
1444 rs6000_debug_stack
= 1;
1445 else if (! strcmp (rs6000_debug_name
, "arg"))
1446 rs6000_debug_arg
= 1;
1448 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1451 if (rs6000_traceback_name
)
1453 if (! strncmp (rs6000_traceback_name
, "full", 4))
1454 rs6000_traceback
= traceback_full
;
1455 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1456 rs6000_traceback
= traceback_part
;
1457 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1458 rs6000_traceback
= traceback_none
;
1460 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1461 rs6000_traceback_name
);
1464 if (!rs6000_explicit_options
.long_double
)
1465 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1467 #ifndef POWERPC_LINUX
1468 if (!rs6000_explicit_options
.ieee
)
1469 rs6000_ieeequad
= 1;
1472 /* Set Altivec ABI as default for powerpc64 linux. */
1473 if (TARGET_ELF
&& TARGET_64BIT
)
1475 rs6000_altivec_abi
= 1;
1476 TARGET_ALTIVEC_VRSAVE
= 1;
1479 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1480 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1482 rs6000_darwin64_abi
= 1;
1484 darwin_one_byte_bool
= 1;
1486 /* Default to natural alignment, for better performance. */
1487 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1490 /* Place FP constants in the constant pool instead of TOC
1491 if section anchors enabled. */
1492 if (flag_section_anchors
)
1493 TARGET_NO_FP_IN_TOC
= 1;
1495 /* Handle -mtls-size option. */
1496 rs6000_parse_tls_size_option ();
1498 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1499 SUBTARGET_OVERRIDE_OPTIONS
;
1501 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1502 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1504 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1505 SUB3TARGET_OVERRIDE_OPTIONS
;
1510 /* The e500 does not have string instructions, and we set
1511 MASK_STRING above when optimizing for size. */
1512 if ((target_flags
& MASK_STRING
) != 0)
1513 target_flags
= target_flags
& ~MASK_STRING
;
1515 else if (rs6000_select
[1].string
!= NULL
)
1517 /* For the powerpc-eabispe configuration, we set all these by
1518 default, so let's unset them if we manually set another
1519 CPU that is not the E500. */
1520 if (!rs6000_explicit_options
.abi
)
1522 if (!rs6000_explicit_options
.spe
)
1524 if (!rs6000_explicit_options
.float_gprs
)
1525 rs6000_float_gprs
= 0;
1526 if (!rs6000_explicit_options
.isel
)
1530 /* Detect invalid option combinations with E500. */
1533 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1534 && rs6000_cpu
!= PROCESSOR_POWER5
1535 && rs6000_cpu
!= PROCESSOR_POWER6
1536 && rs6000_cpu
!= PROCESSOR_CELL
);
1537 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1538 || rs6000_cpu
== PROCESSOR_POWER5
);
1539 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
1540 || rs6000_cpu
== PROCESSOR_POWER5
1541 || rs6000_cpu
== PROCESSOR_POWER6
);
1543 rs6000_sched_restricted_insns_priority
1544 = (rs6000_sched_groups
? 1 : 0);
1546 /* Handle -msched-costly-dep option. */
1547 rs6000_sched_costly_dep
1548 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1550 if (rs6000_sched_costly_dep_str
)
1552 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1553 rs6000_sched_costly_dep
= no_dep_costly
;
1554 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1555 rs6000_sched_costly_dep
= all_deps_costly
;
1556 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1557 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1558 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1559 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1561 rs6000_sched_costly_dep
= atoi (rs6000_sched_costly_dep_str
);
1564 /* Handle -minsert-sched-nops option. */
1565 rs6000_sched_insert_nops
1566 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1568 if (rs6000_sched_insert_nops_str
)
1570 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1571 rs6000_sched_insert_nops
= sched_finish_none
;
1572 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1573 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1574 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1575 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1577 rs6000_sched_insert_nops
= atoi (rs6000_sched_insert_nops_str
);
1580 #ifdef TARGET_REGNAMES
1581 /* If the user desires alternate register names, copy in the
1582 alternate names now. */
1583 if (TARGET_REGNAMES
)
1584 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1587 /* Set aix_struct_return last, after the ABI is determined.
1588 If -maix-struct-return or -msvr4-struct-return was explicitly
1589 used, don't override with the ABI default. */
1590 if (!rs6000_explicit_options
.aix_struct_ret
)
1591 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1593 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1594 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1597 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1599 /* We can only guarantee the availability of DI pseudo-ops when
1600 assembling for 64-bit targets. */
1603 targetm
.asm_out
.aligned_op
.di
= NULL
;
1604 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1607 /* Set branch target alignment, if not optimizing for size. */
1610 /* Cell wants to be aligned 8byte for dual issue. */
1611 if (rs6000_cpu
== PROCESSOR_CELL
)
1613 if (align_functions
<= 0)
1614 align_functions
= 8;
1615 if (align_jumps
<= 0)
1617 if (align_loops
<= 0)
1620 if (rs6000_align_branch_targets
)
1622 if (align_functions
<= 0)
1623 align_functions
= 16;
1624 if (align_jumps
<= 0)
1626 if (align_loops
<= 0)
1629 if (align_jumps_max_skip
<= 0)
1630 align_jumps_max_skip
= 15;
1631 if (align_loops_max_skip
<= 0)
1632 align_loops_max_skip
= 15;
1635 /* Arrange to save and restore machine status around nested functions. */
1636 init_machine_status
= rs6000_init_machine_status
;
1638 /* We should always be splitting complex arguments, but we can't break
1639 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1640 if (DEFAULT_ABI
!= ABI_AIX
)
1641 targetm
.calls
.split_complex_arg
= NULL
;
1643 /* Initialize rs6000_cost with the appropriate target costs. */
1645 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1649 case PROCESSOR_RIOS1
:
1650 rs6000_cost
= &rios1_cost
;
1653 case PROCESSOR_RIOS2
:
1654 rs6000_cost
= &rios2_cost
;
1657 case PROCESSOR_RS64A
:
1658 rs6000_cost
= &rs64a_cost
;
1661 case PROCESSOR_MPCCORE
:
1662 rs6000_cost
= &mpccore_cost
;
1665 case PROCESSOR_PPC403
:
1666 rs6000_cost
= &ppc403_cost
;
1669 case PROCESSOR_PPC405
:
1670 rs6000_cost
= &ppc405_cost
;
1673 case PROCESSOR_PPC440
:
1674 rs6000_cost
= &ppc440_cost
;
1677 case PROCESSOR_PPC601
:
1678 rs6000_cost
= &ppc601_cost
;
1681 case PROCESSOR_PPC603
:
1682 rs6000_cost
= &ppc603_cost
;
1685 case PROCESSOR_PPC604
:
1686 rs6000_cost
= &ppc604_cost
;
1689 case PROCESSOR_PPC604e
:
1690 rs6000_cost
= &ppc604e_cost
;
1693 case PROCESSOR_PPC620
:
1694 rs6000_cost
= &ppc620_cost
;
1697 case PROCESSOR_PPC630
:
1698 rs6000_cost
= &ppc630_cost
;
1701 case PROCESSOR_CELL
:
1702 rs6000_cost
= &ppccell_cost
;
1705 case PROCESSOR_PPC750
:
1706 case PROCESSOR_PPC7400
:
1707 rs6000_cost
= &ppc750_cost
;
1710 case PROCESSOR_PPC7450
:
1711 rs6000_cost
= &ppc7450_cost
;
1714 case PROCESSOR_PPC8540
:
1715 rs6000_cost
= &ppc8540_cost
;
1718 case PROCESSOR_POWER4
:
1719 case PROCESSOR_POWER5
:
1720 rs6000_cost
= &power4_cost
;
1723 case PROCESSOR_POWER6
:
1724 rs6000_cost
= &power6_cost
;
1732 /* Implement targetm.vectorize.builtin_mask_for_load. */
1734 rs6000_builtin_mask_for_load (void)
1737 return altivec_builtin_mask_for_load
;
1742 /* Implement targetm.vectorize.builtin_conversion. */
1744 rs6000_builtin_conversion (enum tree_code code
, tree type
)
1746 if (!TARGET_ALTIVEC
)
1752 switch (TYPE_MODE (type
))
1755 return TYPE_UNSIGNED (type
) ?
1756 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFUX
] :
1757 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFSX
];
1766 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1768 rs6000_builtin_mul_widen_even (tree type
)
1770 if (!TARGET_ALTIVEC
)
1773 switch (TYPE_MODE (type
))
1776 return TYPE_UNSIGNED (type
) ?
1777 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH
] :
1778 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
1781 return TYPE_UNSIGNED (type
) ?
1782 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB
] :
1783 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
1789 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1791 rs6000_builtin_mul_widen_odd (tree type
)
1793 if (!TARGET_ALTIVEC
)
1796 switch (TYPE_MODE (type
))
1799 return TYPE_UNSIGNED (type
) ?
1800 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH
] :
1801 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
1804 return TYPE_UNSIGNED (type
) ?
1805 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB
] :
1806 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
1812 /* Handle generic options of the form -mfoo=yes/no.
1813 NAME is the option name.
1814 VALUE is the option value.
1815 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1816 whether the option value is 'yes' or 'no' respectively. */
1818 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
1822 else if (!strcmp (value
, "yes"))
1824 else if (!strcmp (value
, "no"))
1827 error ("unknown -m%s= option specified: '%s'", name
, value
);
1830 /* Validate and record the size specified with the -mtls-size option. */
1833 rs6000_parse_tls_size_option (void)
1835 if (rs6000_tls_size_string
== 0)
1837 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
1838 rs6000_tls_size
= 16;
1839 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
1840 rs6000_tls_size
= 32;
1841 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
1842 rs6000_tls_size
= 64;
1844 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
1848 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1850 if (DEFAULT_ABI
== ABI_DARWIN
)
1851 /* The Darwin libraries never set errno, so we might as well
1852 avoid calling them when that's the only reason we would. */
1853 flag_errno_math
= 0;
1855 /* Double growth factor to counter reduced min jump length. */
1856 set_param_value ("max-grow-copy-bb-insns", 16);
1858 /* Enable section anchors by default.
1859 Skip section anchors for Objective C and Objective C++
1860 until front-ends fixed. */
1861 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
1862 flag_section_anchors
= 1;
1865 /* Implement TARGET_HANDLE_OPTION. */
1868 rs6000_handle_option (size_t code
, const char *arg
, int value
)
1873 target_flags
&= ~(MASK_POWER
| MASK_POWER2
1874 | MASK_MULTIPLE
| MASK_STRING
);
1875 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
1876 | MASK_MULTIPLE
| MASK_STRING
);
1878 case OPT_mno_powerpc
:
1879 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
1880 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1881 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
1882 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1885 target_flags
&= ~MASK_MINIMAL_TOC
;
1886 TARGET_NO_FP_IN_TOC
= 0;
1887 TARGET_NO_SUM_IN_TOC
= 0;
1888 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1889 #ifdef TARGET_USES_SYSV4_OPT
1890 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1891 just the same as -mminimal-toc. */
1892 target_flags
|= MASK_MINIMAL_TOC
;
1893 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1897 #ifdef TARGET_USES_SYSV4_OPT
1899 /* Make -mtoc behave like -mminimal-toc. */
1900 target_flags
|= MASK_MINIMAL_TOC
;
1901 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1905 #ifdef TARGET_USES_AIX64_OPT
1910 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
1911 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
1912 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
1915 #ifdef TARGET_USES_AIX64_OPT
1920 target_flags
&= ~MASK_POWERPC64
;
1921 target_flags_explicit
|= MASK_POWERPC64
;
1924 case OPT_minsert_sched_nops_
:
1925 rs6000_sched_insert_nops_str
= arg
;
1928 case OPT_mminimal_toc
:
1931 TARGET_NO_FP_IN_TOC
= 0;
1932 TARGET_NO_SUM_IN_TOC
= 0;
1939 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
1940 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
1947 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1948 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1952 case OPT_mpowerpc_gpopt
:
1953 case OPT_mpowerpc_gfxopt
:
1956 target_flags
|= MASK_POWERPC
;
1957 target_flags_explicit
|= MASK_POWERPC
;
1961 case OPT_maix_struct_return
:
1962 case OPT_msvr4_struct_return
:
1963 rs6000_explicit_options
.aix_struct_ret
= true;
1967 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
1971 rs6000_explicit_options
.isel
= true;
1972 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
1976 rs6000_explicit_options
.spe
= true;
1977 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
1981 rs6000_debug_name
= arg
;
1984 #ifdef TARGET_USES_SYSV4_OPT
1986 rs6000_abi_name
= arg
;
1990 rs6000_sdata_name
= arg
;
1993 case OPT_mtls_size_
:
1994 rs6000_tls_size_string
= arg
;
1997 case OPT_mrelocatable
:
2000 target_flags
|= MASK_MINIMAL_TOC
;
2001 target_flags_explicit
|= MASK_MINIMAL_TOC
;
2002 TARGET_NO_FP_IN_TOC
= 1;
2006 case OPT_mrelocatable_lib
:
2009 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2010 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
2011 TARGET_NO_FP_IN_TOC
= 1;
2015 target_flags
&= ~MASK_RELOCATABLE
;
2016 target_flags_explicit
|= MASK_RELOCATABLE
;
2022 if (!strcmp (arg
, "altivec"))
2024 rs6000_explicit_options
.abi
= true;
2025 rs6000_altivec_abi
= 1;
2028 else if (! strcmp (arg
, "no-altivec"))
2030 /* ??? Don't set rs6000_explicit_options.abi here, to allow
2031 the default for rs6000_spe_abi to be chosen later. */
2032 rs6000_altivec_abi
= 0;
2034 else if (! strcmp (arg
, "spe"))
2036 rs6000_explicit_options
.abi
= true;
2038 rs6000_altivec_abi
= 0;
2039 if (!TARGET_SPE_ABI
)
2040 error ("not configured for ABI: '%s'", arg
);
2042 else if (! strcmp (arg
, "no-spe"))
2044 rs6000_explicit_options
.abi
= true;
2048 /* These are here for testing during development only, do not
2049 document in the manual please. */
2050 else if (! strcmp (arg
, "d64"))
2052 rs6000_darwin64_abi
= 1;
2053 warning (0, "Using darwin64 ABI");
2055 else if (! strcmp (arg
, "d32"))
2057 rs6000_darwin64_abi
= 0;
2058 warning (0, "Using old darwin ABI");
2061 else if (! strcmp (arg
, "ibmlongdouble"))
2063 rs6000_explicit_options
.ieee
= true;
2064 rs6000_ieeequad
= 0;
2065 warning (0, "Using IBM extended precision long double");
2067 else if (! strcmp (arg
, "ieeelongdouble"))
2069 rs6000_explicit_options
.ieee
= true;
2070 rs6000_ieeequad
= 1;
2071 warning (0, "Using IEEE extended precision long double");
2076 error ("unknown ABI specified: '%s'", arg
);
2082 rs6000_select
[1].string
= arg
;
2086 rs6000_select
[2].string
= arg
;
2089 case OPT_mtraceback_
:
2090 rs6000_traceback_name
= arg
;
2093 case OPT_mfloat_gprs_
:
2094 rs6000_explicit_options
.float_gprs
= true;
2095 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
2096 rs6000_float_gprs
= 1;
2097 else if (! strcmp (arg
, "double"))
2098 rs6000_float_gprs
= 2;
2099 else if (! strcmp (arg
, "no"))
2100 rs6000_float_gprs
= 0;
2103 error ("invalid option for -mfloat-gprs: '%s'", arg
);
2108 case OPT_mlong_double_
:
2109 rs6000_explicit_options
.long_double
= true;
2110 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2111 if (value
!= 64 && value
!= 128)
2113 error ("Unknown switch -mlong-double-%s", arg
);
2114 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2118 rs6000_long_double_type_size
= value
;
2121 case OPT_msched_costly_dep_
:
2122 rs6000_sched_costly_dep_str
= arg
;
2126 rs6000_explicit_options
.alignment
= true;
2127 if (! strcmp (arg
, "power"))
2129 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2130 some C library functions, so warn about it. The flag may be
2131 useful for performance studies from time to time though, so
2132 don't disable it entirely. */
2133 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2134 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2135 " it is incompatible with the installed C and C++ libraries");
2136 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
2138 else if (! strcmp (arg
, "natural"))
2139 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2142 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
2150 /* Do anything needed at the start of the asm file. */
2153 rs6000_file_start (void)
2157 const char *start
= buffer
;
2158 struct rs6000_cpu_select
*ptr
;
2159 const char *default_cpu
= TARGET_CPU_DEFAULT
;
2160 FILE *file
= asm_out_file
;
2162 default_file_start ();
2164 #ifdef TARGET_BI_ARCH
2165 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
2169 if (flag_verbose_asm
)
2171 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
2172 rs6000_select
[0].string
= default_cpu
;
2174 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2176 ptr
= &rs6000_select
[i
];
2177 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2179 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
2184 if (PPC405_ERRATUM77
)
2186 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
2190 #ifdef USING_ELFOS_H
2191 switch (rs6000_sdata
)
2193 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
2194 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
2195 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
2196 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
2199 if (rs6000_sdata
&& g_switch_value
)
2201 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
2211 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
2213 switch_to_section (toc_section
);
2214 switch_to_section (text_section
);
2219 /* Return nonzero if this function is known to have a null epilogue. */
2222 direct_return (void)
2224 if (reload_completed
)
2226 rs6000_stack_t
*info
= rs6000_stack_info ();
2228 if (info
->first_gp_reg_save
== 32
2229 && info
->first_fp_reg_save
== 64
2230 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
2231 && ! info
->lr_save_p
2232 && ! info
->cr_save_p
2233 && info
->vrsave_mask
== 0
2241 /* Return the number of instructions it takes to form a constant in an
2242 integer register. */
2245 num_insns_constant_wide (HOST_WIDE_INT value
)
2247 /* signed constant loadable with {cal|addi} */
2248 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
2251 /* constant loadable with {cau|addis} */
2252 else if ((value
& 0xffff) == 0
2253 && (value
>> 31 == -1 || value
>> 31 == 0))
2256 #if HOST_BITS_PER_WIDE_INT == 64
2257 else if (TARGET_POWERPC64
)
2259 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2260 HOST_WIDE_INT high
= value
>> 31;
2262 if (high
== 0 || high
== -1)
2268 return num_insns_constant_wide (high
) + 1;
2270 return (num_insns_constant_wide (high
)
2271 + num_insns_constant_wide (low
) + 1);
2280 num_insns_constant (rtx op
, enum machine_mode mode
)
2282 HOST_WIDE_INT low
, high
;
2284 switch (GET_CODE (op
))
2287 #if HOST_BITS_PER_WIDE_INT == 64
2288 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2289 && mask64_operand (op
, mode
))
2293 return num_insns_constant_wide (INTVAL (op
));
2301 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2302 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2303 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2306 if (mode
== VOIDmode
|| mode
== DImode
)
2308 high
= CONST_DOUBLE_HIGH (op
);
2309 low
= CONST_DOUBLE_LOW (op
);
2316 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2317 if (DECIMAL_FLOAT_MODE_P (mode
))
2318 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, l
);
2320 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2321 high
= l
[WORDS_BIG_ENDIAN
== 0];
2322 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2326 return (num_insns_constant_wide (low
)
2327 + num_insns_constant_wide (high
));
2330 if ((high
== 0 && low
>= 0)
2331 || (high
== -1 && low
< 0))
2332 return num_insns_constant_wide (low
);
2334 else if (mask64_operand (op
, mode
))
2338 return num_insns_constant_wide (high
) + 1;
2341 return (num_insns_constant_wide (high
)
2342 + num_insns_constant_wide (low
) + 1);
2350 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2351 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2352 corresponding element of the vector, but for V4SFmode and V2SFmode,
2353 the corresponding "float" is interpreted as an SImode integer. */
2355 static HOST_WIDE_INT
2356 const_vector_elt_as_int (rtx op
, unsigned int elt
)
2358 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
2359 if (GET_MODE (op
) == V4SFmode
2360 || GET_MODE (op
) == V2SFmode
)
2361 tmp
= gen_lowpart (SImode
, tmp
);
2362 return INTVAL (tmp
);
2365 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2366 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2367 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2368 all items are set to the same value and contain COPIES replicas of the
2369 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2370 operand and the others are set to the value of the operand's msb. */
2373 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2375 enum machine_mode mode
= GET_MODE (op
);
2376 enum machine_mode inner
= GET_MODE_INNER (mode
);
2379 unsigned nunits
= GET_MODE_NUNITS (mode
);
2380 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2381 unsigned mask
= GET_MODE_MASK (inner
);
2383 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
2384 HOST_WIDE_INT splat_val
= val
;
2385 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2387 /* Construct the value to be splatted, if possible. If not, return 0. */
2388 for (i
= 2; i
<= copies
; i
*= 2)
2390 HOST_WIDE_INT small_val
;
2392 small_val
= splat_val
>> bitsize
;
2394 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2396 splat_val
= small_val
;
2399 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2400 if (EASY_VECTOR_15 (splat_val
))
2403 /* Also check if we can splat, and then add the result to itself. Do so if
2404 the value is positive, of if the splat instruction is using OP's mode;
2405 for splat_val < 0, the splat and the add should use the same mode. */
2406 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2407 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2413 /* Check if VAL is present in every STEP-th element, and the
2414 other elements are filled with its most significant bit. */
2415 for (i
= 0; i
< nunits
- 1; ++i
)
2417 HOST_WIDE_INT desired_val
;
2418 if (((i
+ 1) & (step
- 1)) == 0)
2421 desired_val
= msb_val
;
2423 if (desired_val
!= const_vector_elt_as_int (op
, i
))
2431 /* Return true if OP is of the given MODE and can be synthesized
2432 with a vspltisb, vspltish or vspltisw. */
2435 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2437 unsigned step
, copies
;
2439 if (mode
== VOIDmode
)
2440 mode
= GET_MODE (op
);
2441 else if (mode
!= GET_MODE (op
))
2444 /* Start with a vspltisw. */
2445 step
= GET_MODE_NUNITS (mode
) / 4;
2448 if (vspltis_constant (op
, step
, copies
))
2451 /* Then try with a vspltish. */
2457 if (vspltis_constant (op
, step
, copies
))
2460 /* And finally a vspltisb. */
2466 if (vspltis_constant (op
, step
, copies
))
2472 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2473 result is OP. Abort if it is not possible. */
2476 gen_easy_altivec_constant (rtx op
)
2478 enum machine_mode mode
= GET_MODE (op
);
2479 int nunits
= GET_MODE_NUNITS (mode
);
2480 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2481 unsigned step
= nunits
/ 4;
2482 unsigned copies
= 1;
2484 /* Start with a vspltisw. */
2485 if (vspltis_constant (op
, step
, copies
))
2486 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2488 /* Then try with a vspltish. */
2494 if (vspltis_constant (op
, step
, copies
))
2495 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2497 /* And finally a vspltisb. */
2503 if (vspltis_constant (op
, step
, copies
))
2504 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2510 output_vec_const_move (rtx
*operands
)
2513 enum machine_mode mode
;
2518 mode
= GET_MODE (dest
);
2523 if (zero_constant (vec
, mode
))
2524 return "vxor %0,%0,%0";
2526 splat_vec
= gen_easy_altivec_constant (vec
);
2527 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2528 operands
[1] = XEXP (splat_vec
, 0);
2529 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2532 switch (GET_MODE (splat_vec
))
2535 return "vspltisw %0,%1";
2538 return "vspltish %0,%1";
2541 return "vspltisb %0,%1";
2548 gcc_assert (TARGET_SPE
);
2550 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2551 pattern of V1DI, V4HI, and V2SF.
2553 FIXME: We should probably return # and add post reload
2554 splitters for these, but this way is so easy ;-). */
2555 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2556 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2557 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
2558 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
2560 return "li %0,%1\n\tevmergelo %0,%0,%0";
2562 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2565 /* Initialize vector TARGET to VALS. */
2568 rs6000_expand_vector_init (rtx target
, rtx vals
)
2570 enum machine_mode mode
= GET_MODE (target
);
2571 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2572 int n_elts
= GET_MODE_NUNITS (mode
);
2573 int n_var
= 0, one_var
= -1;
2574 bool all_same
= true, all_const_zero
= true;
2578 for (i
= 0; i
< n_elts
; ++i
)
2580 x
= XVECEXP (vals
, 0, i
);
2581 if (!CONSTANT_P (x
))
2582 ++n_var
, one_var
= i
;
2583 else if (x
!= CONST0_RTX (inner_mode
))
2584 all_const_zero
= false;
2586 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
2592 if (mode
!= V4SFmode
&& all_const_zero
)
2594 /* Zero register. */
2595 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2596 gen_rtx_XOR (mode
, target
, target
)));
2599 else if (mode
!= V4SFmode
&& easy_vector_constant (vals
, mode
))
2601 /* Splat immediate. */
2602 emit_insn (gen_rtx_SET (VOIDmode
, target
, vals
));
2606 ; /* Splat vector element. */
2609 /* Load from constant pool. */
2610 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
2615 /* Store value to stack temp. Load vector element. Splat. */
2618 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2619 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
2620 XVECEXP (vals
, 0, 0));
2621 x
= gen_rtx_UNSPEC (VOIDmode
,
2622 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2623 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2625 gen_rtx_SET (VOIDmode
,
2628 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
2629 gen_rtx_PARALLEL (VOIDmode
,
2630 gen_rtvec (1, const0_rtx
)));
2631 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2632 gen_rtx_VEC_DUPLICATE (mode
, x
)));
2636 /* One field is non-constant. Load constant then overwrite
2640 rtx copy
= copy_rtx (vals
);
2642 /* Load constant part of vector, substitute neighboring value for
2644 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
2645 rs6000_expand_vector_init (target
, copy
);
2647 /* Insert variable. */
2648 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
2652 /* Construct the vector in memory one field at a time
2653 and load the whole vector. */
2654 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2655 for (i
= 0; i
< n_elts
; i
++)
2656 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
2657 i
* GET_MODE_SIZE (inner_mode
)),
2658 XVECEXP (vals
, 0, i
));
2659 emit_move_insn (target
, mem
);
2662 /* Set field ELT of TARGET to VAL. */
2665 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
2667 enum machine_mode mode
= GET_MODE (target
);
2668 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2669 rtx reg
= gen_reg_rtx (mode
);
2671 int width
= GET_MODE_SIZE (inner_mode
);
2674 /* Load single variable value. */
2675 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2676 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
2677 x
= gen_rtx_UNSPEC (VOIDmode
,
2678 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2679 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2681 gen_rtx_SET (VOIDmode
,
2685 /* Linear sequence. */
2686 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
2687 for (i
= 0; i
< 16; ++i
)
2688 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
2690 /* Set permute mask to insert element into target. */
2691 for (i
= 0; i
< width
; ++i
)
2692 XVECEXP (mask
, 0, elt
*width
+ i
)
2693 = GEN_INT (i
+ 0x10);
2694 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
2695 x
= gen_rtx_UNSPEC (mode
,
2696 gen_rtvec (3, target
, reg
,
2697 force_reg (V16QImode
, x
)),
2699 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
2702 /* Extract field ELT from VEC into TARGET. */
2705 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
2707 enum machine_mode mode
= GET_MODE (vec
);
2708 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2711 /* Allocate mode-sized buffer. */
2712 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2714 /* Add offset to field within buffer matching vector element. */
2715 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
2717 /* Store single field into mode-sized buffer. */
2718 x
= gen_rtx_UNSPEC (VOIDmode
,
2719 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
2720 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2722 gen_rtx_SET (VOIDmode
,
2725 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
2728 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2729 implement ANDing by the mask IN. */
2731 build_mask64_2_operands (rtx in
, rtx
*out
)
2733 #if HOST_BITS_PER_WIDE_INT >= 64
2734 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
2737 gcc_assert (GET_CODE (in
) == CONST_INT
);
2742 /* Assume c initially something like 0x00fff000000fffff. The idea
2743 is to rotate the word so that the middle ^^^^^^ group of zeros
2744 is at the MS end and can be cleared with an rldicl mask. We then
2745 rotate back and clear off the MS ^^ group of zeros with a
2747 c
= ~c
; /* c == 0xff000ffffff00000 */
2748 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
2749 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
2750 c
= ~c
; /* c == 0x00fff000000fffff */
2751 c
&= -lsb
; /* c == 0x00fff00000000000 */
2752 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2753 c
= ~c
; /* c == 0xff000fffffffffff */
2754 c
&= -lsb
; /* c == 0xff00000000000000 */
2756 while ((lsb
>>= 1) != 0)
2757 shift
++; /* shift == 44 on exit from loop */
2758 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
2759 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
2760 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
2764 /* Assume c initially something like 0xff000f0000000000. The idea
2765 is to rotate the word so that the ^^^ middle group of zeros
2766 is at the LS end and can be cleared with an rldicr mask. We then
2767 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2769 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
2770 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
2771 c
= ~c
; /* c == 0x00fff0ffffffffff */
2772 c
&= -lsb
; /* c == 0x00fff00000000000 */
2773 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2774 c
= ~c
; /* c == 0xff000fffffffffff */
2775 c
&= -lsb
; /* c == 0xff00000000000000 */
2777 while ((lsb
>>= 1) != 0)
2778 shift
++; /* shift == 44 on exit from loop */
2779 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
2780 m1
>>= shift
; /* m1 == 0x0000000000000fff */
2781 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
2784 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2785 masks will be all 1's. We are guaranteed more than one transition. */
2786 out
[0] = GEN_INT (64 - shift
);
2787 out
[1] = GEN_INT (m1
);
2788 out
[2] = GEN_INT (shift
);
2789 out
[3] = GEN_INT (m2
);
2797 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2800 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
2802 if (TARGET_E500_DOUBLE
)
2804 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
2805 subreg:TI and reg:TF. */
2806 if (GET_CODE (op
) == SUBREG
2807 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
)
2808 && REG_P (SUBREG_REG (op
))
2809 && (GET_MODE (SUBREG_REG (op
)) == DFmode
2810 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
2813 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
2815 if (GET_CODE (op
) == SUBREG
2816 && (mode
== DFmode
|| mode
== TFmode
)
2817 && REG_P (SUBREG_REG (op
))
2818 && (GET_MODE (SUBREG_REG (op
)) == DImode
2819 || GET_MODE (SUBREG_REG (op
)) == TImode
))
2824 && GET_CODE (op
) == SUBREG
2826 && REG_P (SUBREG_REG (op
))
2827 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
2833 /* AIX increases natural record alignment to doubleword if the first
2834 field is an FP double while the FP fields remain word aligned. */
2837 rs6000_special_round_type_align (tree type
, unsigned int computed
,
2838 unsigned int specified
)
2840 unsigned int align
= MAX (computed
, specified
);
2841 tree field
= TYPE_FIELDS (type
);
2843 /* Skip all non field decls */
2844 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
2845 field
= TREE_CHAIN (field
);
2847 if (field
!= NULL
&& field
!= type
)
2849 type
= TREE_TYPE (field
);
2850 while (TREE_CODE (type
) == ARRAY_TYPE
)
2851 type
= TREE_TYPE (type
);
2853 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
2854 align
= MAX (align
, 64);
2860 /* Darwin increases record alignment to the natural alignment of
2864 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
2865 unsigned int specified
)
2867 unsigned int align
= MAX (computed
, specified
);
2869 if (TYPE_PACKED (type
))
2872 /* Find the first field, looking down into aggregates. */
2874 tree field
= TYPE_FIELDS (type
);
2875 /* Skip all non field decls */
2876 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
2877 field
= TREE_CHAIN (field
);
2880 type
= TREE_TYPE (field
);
2881 while (TREE_CODE (type
) == ARRAY_TYPE
)
2882 type
= TREE_TYPE (type
);
2883 } while (AGGREGATE_TYPE_P (type
));
2885 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
2886 align
= MAX (align
, TYPE_ALIGN (type
));
2891 /* Return 1 for an operand in small memory on V.4/eabi. */
2894 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
2895 enum machine_mode mode ATTRIBUTE_UNUSED
)
2900 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
2903 if (DEFAULT_ABI
!= ABI_V4
)
2906 if (GET_CODE (op
) == SYMBOL_REF
)
2909 else if (GET_CODE (op
) != CONST
2910 || GET_CODE (XEXP (op
, 0)) != PLUS
2911 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
2912 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
2917 rtx sum
= XEXP (op
, 0);
2918 HOST_WIDE_INT summand
;
2920 /* We have to be careful here, because it is the referenced address
2921 that must be 32k from _SDA_BASE_, not just the symbol. */
2922 summand
= INTVAL (XEXP (sum
, 1));
2923 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
2926 sym_ref
= XEXP (sum
, 0);
2929 return SYMBOL_REF_SMALL_P (sym_ref
);
2935 /* Return true if either operand is a general purpose register. */
2938 gpr_or_gpr_p (rtx op0
, rtx op1
)
2940 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
2941 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
2945 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2948 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
2950 switch (GET_CODE (op
))
2953 if (RS6000_SYMBOL_REF_TLS_P (op
))
2955 else if (CONSTANT_POOL_ADDRESS_P (op
))
2957 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
2965 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
2974 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
2975 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
2977 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
2986 constant_pool_expr_p (rtx op
)
2990 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
2994 toc_relative_expr_p (rtx op
)
2998 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
3002 legitimate_constant_pool_address_p (rtx x
)
3005 && GET_CODE (x
) == PLUS
3006 && GET_CODE (XEXP (x
, 0)) == REG
3007 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
3008 && constant_pool_expr_p (XEXP (x
, 1)));
3012 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
3014 return (DEFAULT_ABI
== ABI_V4
3015 && !flag_pic
&& !TARGET_TOC
3016 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
3017 && small_data_operand (x
, mode
));
3020 /* SPE offset addressing is limited to 5-bits worth of double words. */
3021 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3024 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
3026 unsigned HOST_WIDE_INT offset
, extra
;
3028 if (GET_CODE (x
) != PLUS
)
3030 if (GET_CODE (XEXP (x
, 0)) != REG
)
3032 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3034 if (legitimate_constant_pool_address_p (x
))
3036 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
3039 offset
= INTVAL (XEXP (x
, 1));
3047 /* AltiVec vector modes. Only reg+reg addressing is valid and
3048 constant offset zero should not occur due to canonicalization.
3049 Allow any offset when not strict before reload. */
3056 /* SPE vector modes. */
3057 return SPE_CONST_OFFSET_OK (offset
);
3061 if (TARGET_E500_DOUBLE
)
3062 return SPE_CONST_OFFSET_OK (offset
);
3065 /* On e500v2, we may have:
3067 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3069 Which gets addressed with evldd instructions. */
3070 if (TARGET_E500_DOUBLE
)
3071 return SPE_CONST_OFFSET_OK (offset
);
3073 if (mode
== DFmode
|| mode
== DDmode
|| !TARGET_POWERPC64
)
3075 else if (offset
& 3)
3080 if (TARGET_E500_DOUBLE
)
3081 return (SPE_CONST_OFFSET_OK (offset
)
3082 && SPE_CONST_OFFSET_OK (offset
+ 8));
3086 if (mode
== TFmode
|| mode
== TDmode
|| !TARGET_POWERPC64
)
3088 else if (offset
& 3)
3099 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
3103 legitimate_indexed_address_p (rtx x
, int strict
)
3107 if (GET_CODE (x
) != PLUS
)
3113 /* Recognize the rtl generated by reload which we know will later be
3114 replaced with proper base and index regs. */
3116 && reload_in_progress
3117 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
3121 return (REG_P (op0
) && REG_P (op1
)
3122 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
3123 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
3124 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
3125 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
3129 legitimate_indirect_address_p (rtx x
, int strict
)
3131 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
3135 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
3137 if (!TARGET_MACHO
|| !flag_pic
3138 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
3142 if (GET_CODE (x
) != LO_SUM
)
3144 if (GET_CODE (XEXP (x
, 0)) != REG
)
3146 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
3150 return CONSTANT_P (x
);
3154 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
3156 if (GET_CODE (x
) != LO_SUM
)
3158 if (GET_CODE (XEXP (x
, 0)) != REG
)
3160 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3162 /* Restrict addressing for DI because of our SUBREG hackery. */
3163 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3168 if (TARGET_ELF
|| TARGET_MACHO
)
3170 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
3174 if (GET_MODE_NUNITS (mode
) != 1)
3176 if (GET_MODE_BITSIZE (mode
) > 64
3177 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
3178 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& mode
== DFmode
)))
3181 return CONSTANT_P (x
);
3188 /* Try machine-dependent ways of modifying an illegitimate address
3189 to be legitimate. If we find one, return the new, valid address.
3190 This is used from only one place: `memory_address' in explow.c.
3192 OLDX is the address as it was before break_out_memory_refs was
3193 called. In some cases it is useful to look at this to decide what
3196 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3198 It is always safe for this function to do nothing. It exists to
3199 recognize opportunities to optimize the output.
3201 On RS/6000, first check for the sum of a register with a constant
3202 integer that is out of range. If so, generate code to add the
3203 constant with the low-order 16 bits masked to the register and force
3204 this result into another register (this can be done with `cau').
3205 Then generate an address of REG+(CONST&0xffff), allowing for the
3206 possibility of bit 16 being a one.
3208 Then check for the sum of a register and something not constant, try to
3209 load the other things into a register and return the sum. */
3212 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3213 enum machine_mode mode
)
3215 if (GET_CODE (x
) == SYMBOL_REF
)
3217 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3219 return rs6000_legitimize_tls_address (x
, model
);
3222 if (GET_CODE (x
) == PLUS
3223 && GET_CODE (XEXP (x
, 0)) == REG
3224 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3225 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000)
3227 HOST_WIDE_INT high_int
, low_int
;
3229 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3230 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
3231 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3232 GEN_INT (high_int
)), 0);
3233 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
3235 else if (GET_CODE (x
) == PLUS
3236 && GET_CODE (XEXP (x
, 0)) == REG
3237 && GET_CODE (XEXP (x
, 1)) != CONST_INT
3238 && GET_MODE_NUNITS (mode
) == 1
3239 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3241 || (((mode
!= DImode
&& mode
!= DFmode
&& mode
!= DDmode
)
3242 || TARGET_E500_DOUBLE
)
3243 && mode
!= TFmode
&& mode
!= TDmode
))
3244 && (TARGET_POWERPC64
|| mode
!= DImode
)
3247 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3248 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
3250 else if (ALTIVEC_VECTOR_MODE (mode
))
3254 /* Make sure both operands are registers. */
3255 if (GET_CODE (x
) == PLUS
)
3256 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
3257 force_reg (Pmode
, XEXP (x
, 1)));
3259 reg
= force_reg (Pmode
, x
);
3262 else if (SPE_VECTOR_MODE (mode
)
3263 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3264 || mode
== DDmode
|| mode
== TDmode
3265 || mode
== DImode
)))
3269 /* We accept [reg + reg] and [reg + OFFSET]. */
3271 if (GET_CODE (x
) == PLUS
)
3273 rtx op1
= XEXP (x
, 0);
3274 rtx op2
= XEXP (x
, 1);
3276 op1
= force_reg (Pmode
, op1
);
3278 if (GET_CODE (op2
) != REG
3279 && (GET_CODE (op2
) != CONST_INT
3280 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))))
3281 op2
= force_reg (Pmode
, op2
);
3283 return gen_rtx_PLUS (Pmode
, op1
, op2
);
3286 return force_reg (Pmode
, x
);
3292 && GET_CODE (x
) != CONST_INT
3293 && GET_CODE (x
) != CONST_DOUBLE
3295 && GET_MODE_NUNITS (mode
) == 1
3296 && (GET_MODE_BITSIZE (mode
) <= 32
3297 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) && mode
== DFmode
)))
3299 rtx reg
= gen_reg_rtx (Pmode
);
3300 emit_insn (gen_elf_high (reg
, x
));
3301 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3303 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
3306 && ! MACHO_DYNAMIC_NO_PIC_P
3308 && GET_CODE (x
) != CONST_INT
3309 && GET_CODE (x
) != CONST_DOUBLE
3311 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) || mode
!= DFmode
)
3315 rtx reg
= gen_reg_rtx (Pmode
);
3316 emit_insn (gen_macho_high (reg
, x
));
3317 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3320 && constant_pool_expr_p (x
)
3321 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
3323 return create_TOC_reference (x
);
3329 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3330 We need to emit DTP-relative relocations. */
3333 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3338 fputs ("\t.long\t", file
);
3341 fputs (DOUBLE_INT_ASM_OP
, file
);
3346 output_addr_const (file
, x
);
3347 fputs ("@dtprel+0x8000", file
);
3350 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3352 static GTY(()) rtx rs6000_tls_symbol
;
3354 rs6000_tls_get_addr (void)
3356 if (!rs6000_tls_symbol
)
3357 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3359 return rs6000_tls_symbol
;
3362 /* Construct the SYMBOL_REF for TLS GOT references. */
3364 static GTY(()) rtx rs6000_got_symbol
;
3366 rs6000_got_sym (void)
3368 if (!rs6000_got_symbol
)
3370 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
3371 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
3372 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
3375 return rs6000_got_symbol
;
3378 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3379 this (thread-local) address. */
3382 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
3386 dest
= gen_reg_rtx (Pmode
);
3387 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
3393 tlsreg
= gen_rtx_REG (Pmode
, 13);
3394 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
3398 tlsreg
= gen_rtx_REG (Pmode
, 2);
3399 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
3403 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
3407 tmp
= gen_reg_rtx (Pmode
);
3410 tlsreg
= gen_rtx_REG (Pmode
, 13);
3411 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
3415 tlsreg
= gen_rtx_REG (Pmode
, 2);
3416 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
3420 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
3422 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
3427 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
3429 /* We currently use relocations like @got@tlsgd for tls, which
3430 means the linker will handle allocation of tls entries, placing
3431 them in the .got section. So use a pointer to the .got section,
3432 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3433 or to secondary GOT sections used by 32-bit -fPIC. */
3435 got
= gen_rtx_REG (Pmode
, 2);
3439 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
3442 rtx gsym
= rs6000_got_sym ();
3443 got
= gen_reg_rtx (Pmode
);
3445 rs6000_emit_move (got
, gsym
, Pmode
);
3448 rtx tempLR
, tmp3
, mem
;
3451 tempLR
= gen_reg_rtx (Pmode
);
3452 tmp1
= gen_reg_rtx (Pmode
);
3453 tmp2
= gen_reg_rtx (Pmode
);
3454 tmp3
= gen_reg_rtx (Pmode
);
3455 mem
= gen_const_mem (Pmode
, tmp1
);
3457 first
= emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, gsym
));
3458 emit_move_insn (tmp1
, tempLR
);
3459 emit_move_insn (tmp2
, mem
);
3460 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
3461 last
= emit_move_insn (got
, tmp3
);
3462 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
3463 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
3465 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
,
3471 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
3473 r3
= gen_rtx_REG (Pmode
, 3);
3475 insn
= gen_tls_gd_64 (r3
, got
, addr
);
3477 insn
= gen_tls_gd_32 (r3
, got
, addr
);
3480 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3481 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3482 insn
= emit_call_insn (insn
);
3483 CONST_OR_PURE_CALL_P (insn
) = 1;
3484 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3485 insn
= get_insns ();
3487 emit_libcall_block (insn
, dest
, r3
, addr
);
3489 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
3491 r3
= gen_rtx_REG (Pmode
, 3);
3493 insn
= gen_tls_ld_64 (r3
, got
);
3495 insn
= gen_tls_ld_32 (r3
, got
);
3498 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3499 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3500 insn
= emit_call_insn (insn
);
3501 CONST_OR_PURE_CALL_P (insn
) = 1;
3502 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3503 insn
= get_insns ();
3505 tmp1
= gen_reg_rtx (Pmode
);
3506 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3508 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
3509 if (rs6000_tls_size
== 16)
3512 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
3514 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
3516 else if (rs6000_tls_size
== 32)
3518 tmp2
= gen_reg_rtx (Pmode
);
3520 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
3522 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
3525 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
3527 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
3531 tmp2
= gen_reg_rtx (Pmode
);
3533 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
3535 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
3537 insn
= gen_rtx_SET (Pmode
, dest
,
3538 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
3544 /* IE, or 64-bit offset LE. */
3545 tmp2
= gen_reg_rtx (Pmode
);
3547 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
3549 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
3552 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
3554 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
3562 /* Return 1 if X contains a thread-local symbol. */
3565 rs6000_tls_referenced_p (rtx x
)
3567 if (! TARGET_HAVE_TLS
)
3570 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
3573 /* Return 1 if *X is a thread-local symbol. This is the same as
3574 rs6000_tls_symbol_ref except for the type of the unused argument. */
3577 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
3579 return RS6000_SYMBOL_REF_TLS_P (*x
);
3582 /* The convention appears to be to define this wherever it is used.
3583 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3584 is now used here. */
3585 #ifndef REG_MODE_OK_FOR_BASE_P
3586 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3589 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3590 replace the input X, or the original X if no replacement is called for.
3591 The output parameter *WIN is 1 if the calling macro should goto WIN,
3594 For RS/6000, we wish to handle large displacements off a base
3595 register by splitting the addend across an addiu/addis and the mem insn.
3596 This cuts number of extra insns needed from 3 to 1.
3598 On Darwin, we use this to generate code for floating point constants.
3599 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3600 The Darwin code is inside #if TARGET_MACHO because only then is
3601 machopic_function_base_name() defined. */
3603 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
3604 int opnum
, int type
,
3605 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
3607 /* We must recognize output that we have already generated ourselves. */
3608 if (GET_CODE (x
) == PLUS
3609 && GET_CODE (XEXP (x
, 0)) == PLUS
3610 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3611 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3612 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3614 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3615 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3616 opnum
, (enum reload_type
)type
);
3622 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
3623 && GET_CODE (x
) == LO_SUM
3624 && GET_CODE (XEXP (x
, 0)) == PLUS
3625 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
3626 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
3627 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
3628 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
3629 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
3630 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
3631 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
3633 /* Result of previous invocation of this function on Darwin
3634 floating point constant. */
3635 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3636 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3637 opnum
, (enum reload_type
)type
);
3643 /* Force ld/std non-word aligned offset into base register by wrapping
3645 if (GET_CODE (x
) == PLUS
3646 && GET_CODE (XEXP (x
, 0)) == REG
3647 && REGNO (XEXP (x
, 0)) < 32
3648 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3649 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3650 && (INTVAL (XEXP (x
, 1)) & 3) != 0
3651 && !ALTIVEC_VECTOR_MODE (mode
)
3652 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
3653 && TARGET_POWERPC64
)
3655 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
3656 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3657 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3658 opnum
, (enum reload_type
) type
);
3663 if (GET_CODE (x
) == PLUS
3664 && GET_CODE (XEXP (x
, 0)) == REG
3665 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
3666 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3667 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3668 && !SPE_VECTOR_MODE (mode
)
3669 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3671 && !ALTIVEC_VECTOR_MODE (mode
))
3673 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
3674 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
3676 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3678 /* Check for 32-bit overflow. */
3679 if (high
+ low
!= val
)
3685 /* Reload the high part into a base reg; leave the low part
3686 in the mem directly. */
3688 x
= gen_rtx_PLUS (GET_MODE (x
),
3689 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
3693 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3694 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3695 opnum
, (enum reload_type
)type
);
3700 if (GET_CODE (x
) == SYMBOL_REF
3701 && !ALTIVEC_VECTOR_MODE (mode
)
3702 && !SPE_VECTOR_MODE (mode
)
3704 && DEFAULT_ABI
== ABI_DARWIN
3705 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
3707 && DEFAULT_ABI
== ABI_V4
3710 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
3711 The same goes for DImode without 64-bit gprs and DFmode
3715 && (mode
!= DImode
|| TARGET_POWERPC64
)
3716 && (mode
!= DFmode
|| TARGET_POWERPC64
3717 || (TARGET_FPRS
&& TARGET_HARD_FLOAT
)))
3722 rtx offset
= gen_rtx_CONST (Pmode
,
3723 gen_rtx_MINUS (Pmode
, x
,
3724 machopic_function_base_sym ()));
3725 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3726 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
3727 gen_rtx_HIGH (Pmode
, offset
)), offset
);
3731 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3732 gen_rtx_HIGH (Pmode
, x
), x
);
3734 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3735 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3736 opnum
, (enum reload_type
)type
);
3741 /* Reload an offset address wrapped by an AND that represents the
3742 masking of the lower bits. Strip the outer AND and let reload
3743 convert the offset address into an indirect address. */
3745 && ALTIVEC_VECTOR_MODE (mode
)
3746 && GET_CODE (x
) == AND
3747 && GET_CODE (XEXP (x
, 0)) == PLUS
3748 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3749 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3750 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3751 && INTVAL (XEXP (x
, 1)) == -16)
3759 && constant_pool_expr_p (x
)
3760 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
3762 x
= create_TOC_reference (x
);
3770 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3771 that is a valid memory address for an instruction.
3772 The MODE argument is the machine mode for the MEM expression
3773 that wants to use this address.
3775 On the RS/6000, there are four valid address: a SYMBOL_REF that
3776 refers to a constant pool entry of an address (or the sum of it
3777 plus a constant), a short (16-bit signed) constant plus a register,
3778 the sum of two registers, or a register indirect, possibly with an
3779 auto-increment. For DFmode and DImode with a constant plus register,
3780 we must ensure that both words are addressable or PowerPC64 with offset
3783 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3784 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
3785 because adjacent memory cells are accessed by adding word-sized offsets
3786 during assembly output. */
3788 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
3790 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3792 && ALTIVEC_VECTOR_MODE (mode
)
3793 && GET_CODE (x
) == AND
3794 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3795 && INTVAL (XEXP (x
, 1)) == -16)
3798 if (RS6000_SYMBOL_REF_TLS_P (x
))
3800 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
3802 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
3803 && !ALTIVEC_VECTOR_MODE (mode
)
3804 && !SPE_VECTOR_MODE (mode
)
3807 /* Restrict addressing for DI because of our SUBREG hackery. */
3808 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3811 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
3813 if (legitimate_small_data_p (mode
, x
))
3815 if (legitimate_constant_pool_address_p (x
))
3817 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3819 && GET_CODE (x
) == PLUS
3820 && GET_CODE (XEXP (x
, 0)) == REG
3821 && (XEXP (x
, 0) == virtual_stack_vars_rtx
3822 || XEXP (x
, 0) == arg_pointer_rtx
)
3823 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3825 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
3830 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3832 || ((mode
!= DFmode
|| TARGET_E500_DOUBLE
) && mode
!= TFmode
))
3833 && (TARGET_POWERPC64
|| mode
!= DImode
)
3834 && legitimate_indexed_address_p (x
, reg_ok_strict
))
3836 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
3841 /* Go to LABEL if ADDR (a legitimate address expression)
3842 has an effect that depends on the machine mode it is used for.
3844 On the RS/6000 this is true of all integral offsets (since AltiVec
3845 modes don't allow them) or is a pre-increment or decrement.
3847 ??? Except that due to conceptual problems in offsettable_address_p
3848 we can't really report the problems of integral offsets. So leave
3849 this assuming that the adjustable offset must be valid for the
3850 sub-words of a TFmode operand, which is what we had before. */
3853 rs6000_mode_dependent_address (rtx addr
)
3855 switch (GET_CODE (addr
))
3858 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
3860 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
3861 return val
+ 12 + 0x8000 >= 0x10000;
3868 /* Auto-increment cases are now treated generically in recog.c. */
3877 /* More elaborate version of recog's offsettable_memref_p predicate
3878 that works around the ??? note of rs6000_mode_dependent_address.
3879 In particular it accepts
3881 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
3883 in 32-bit mode, that the recog predicate rejects. */
3886 rs6000_offsettable_memref_p (rtx op
)
3891 /* First mimic offsettable_memref_p. */
3892 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
3895 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
3896 the latter predicate knows nothing about the mode of the memory
3897 reference and, therefore, assumes that it is the largest supported
3898 mode (TFmode). As a consequence, legitimate offsettable memory
3899 references are rejected. rs6000_legitimate_offset_address_p contains
3900 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
3901 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
3904 /* Return number of consecutive hard regs needed starting at reg REGNO
3905 to hold something of mode MODE.
3906 This is ordinarily the length in words of a value of mode MODE
3907 but can be less for certain modes in special long registers.
3909 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3910 scalar instructions. The upper 32 bits are only available to the
3913 POWER and PowerPC GPRs hold 32 bits worth;
3914 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3917 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
3919 if (FP_REGNO_P (regno
))
3920 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
3922 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
3923 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
3925 if (ALTIVEC_REGNO_P (regno
))
3927 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
3929 /* The value returned for SCmode in the E500 double case is 2 for
3930 ABI compatibility; storing an SCmode value in a single register
3931 would require function_arg and rs6000_spe_function_arg to handle
3932 SCmode so as to pass the value correctly in a pair of
3934 if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
)
3935 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
3937 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3940 /* Change register usage conditional on target flags. */
3942 rs6000_conditional_register_usage (void)
3946 /* Set MQ register fixed (already call_used) if not POWER
3947 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3952 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3954 fixed_regs
[13] = call_used_regs
[13]
3955 = call_really_used_regs
[13] = 1;
3957 /* Conditionally disable FPRs. */
3958 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
3959 for (i
= 32; i
< 64; i
++)
3960 fixed_regs
[i
] = call_used_regs
[i
]
3961 = call_really_used_regs
[i
] = 1;
3963 /* The TOC register is not killed across calls in a way that is
3964 visible to the compiler. */
3965 if (DEFAULT_ABI
== ABI_AIX
)
3966 call_really_used_regs
[2] = 0;
3968 if (DEFAULT_ABI
== ABI_V4
3969 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3971 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3973 if (DEFAULT_ABI
== ABI_V4
3974 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3976 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3977 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3978 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3980 if (DEFAULT_ABI
== ABI_DARWIN
3981 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
3982 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3983 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3984 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3986 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
3987 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3988 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3991 global_regs
[VSCR_REGNO
] = 1;
3995 global_regs
[SPEFSCR_REGNO
] = 1;
3996 fixed_regs
[FIXED_SCRATCH
]
3997 = call_used_regs
[FIXED_SCRATCH
]
3998 = call_really_used_regs
[FIXED_SCRATCH
] = 1;
4001 if (! TARGET_ALTIVEC
)
4003 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
4004 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4005 call_really_used_regs
[VRSAVE_REGNO
] = 1;
4008 if (TARGET_ALTIVEC_ABI
)
4009 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
4010 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
4013 /* Try to output insns to set TARGET equal to the constant C if it can
4014 be done in less than N insns. Do all computations in MODE.
4015 Returns the place where the output has been placed if it can be
4016 done and the insns have been emitted. If it would take more than N
4017 insns, zero is returned and no insns and emitted. */
4020 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
4021 rtx source
, int n ATTRIBUTE_UNUSED
)
4023 rtx result
, insn
, set
;
4024 HOST_WIDE_INT c0
, c1
;
4031 dest
= gen_reg_rtx (mode
);
4032 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
4036 result
= no_new_pseudos
? dest
: gen_reg_rtx (SImode
);
4038 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
4039 GEN_INT (INTVAL (source
)
4040 & (~ (HOST_WIDE_INT
) 0xffff))));
4041 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
4042 gen_rtx_IOR (SImode
, copy_rtx (result
),
4043 GEN_INT (INTVAL (source
) & 0xffff))));
4048 switch (GET_CODE (source
))
4051 c0
= INTVAL (source
);
4056 #if HOST_BITS_PER_WIDE_INT >= 64
4057 c0
= CONST_DOUBLE_LOW (source
);
4060 c0
= CONST_DOUBLE_LOW (source
);
4061 c1
= CONST_DOUBLE_HIGH (source
);
4069 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
4076 insn
= get_last_insn ();
4077 set
= single_set (insn
);
4078 if (! CONSTANT_P (SET_SRC (set
)))
4079 set_unique_reg_note (insn
, REG_EQUAL
, source
);
4084 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4085 fall back to a straight forward decomposition. We do this to avoid
4086 exponential run times encountered when looking for longer sequences
4087 with rs6000_emit_set_const. */
4089 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
4091 if (!TARGET_POWERPC64
)
4093 rtx operand1
, operand2
;
4095 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
4097 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
4099 emit_move_insn (operand1
, GEN_INT (c1
));
4100 emit_move_insn (operand2
, GEN_INT (c2
));
4104 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
4107 ud2
= (c1
& 0xffff0000) >> 16;
4108 #if HOST_BITS_PER_WIDE_INT >= 64
4112 ud4
= (c2
& 0xffff0000) >> 16;
4114 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
4115 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
4118 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
4120 emit_move_insn (dest
, GEN_INT (ud1
));
4123 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
4124 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
4127 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
4130 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
4132 emit_move_insn (copy_rtx (dest
),
4133 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4136 else if ((ud4
== 0xffff && (ud3
& 0x8000))
4137 || (ud4
== 0 && ! (ud3
& 0x8000)))
4140 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
4143 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
4146 emit_move_insn (copy_rtx (dest
),
4147 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4149 emit_move_insn (copy_rtx (dest
),
4150 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4153 emit_move_insn (copy_rtx (dest
),
4154 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4160 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
4163 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
4166 emit_move_insn (copy_rtx (dest
),
4167 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4170 emit_move_insn (copy_rtx (dest
),
4171 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4174 emit_move_insn (copy_rtx (dest
),
4175 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4176 GEN_INT (ud2
<< 16)));
4178 emit_move_insn (copy_rtx (dest
),
4179 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
4185 /* Helper for the following. Get rid of [r+r] memory refs
4186 in cases where it won't work (TImode, TFmode, TDmode). */
4189 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
4191 if (GET_CODE (operands
[0]) == MEM
4192 && GET_CODE (XEXP (operands
[0], 0)) != REG
4193 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
4194 && ! reload_in_progress
)
4196 = replace_equiv_address (operands
[0],
4197 copy_addr_to_reg (XEXP (operands
[0], 0)));
4199 if (GET_CODE (operands
[1]) == MEM
4200 && GET_CODE (XEXP (operands
[1], 0)) != REG
4201 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
4202 && ! reload_in_progress
)
4204 = replace_equiv_address (operands
[1],
4205 copy_addr_to_reg (XEXP (operands
[1], 0)));
4208 /* Emit a move from SOURCE to DEST in mode MODE. */
4210 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
4214 operands
[1] = source
;
4216 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4217 if (GET_CODE (operands
[1]) == CONST_DOUBLE
4218 && ! FLOAT_MODE_P (mode
)
4219 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
4221 /* FIXME. This should never happen. */
4222 /* Since it seems that it does, do the safe thing and convert
4224 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
4226 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
4227 || FLOAT_MODE_P (mode
)
4228 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
4229 || CONST_DOUBLE_LOW (operands
[1]) < 0)
4230 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
4231 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
4233 /* Check if GCC is setting up a block move that will end up using FP
4234 registers as temporaries. We must make sure this is acceptable. */
4235 if (GET_CODE (operands
[0]) == MEM
4236 && GET_CODE (operands
[1]) == MEM
4238 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
4239 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
4240 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
4241 ? 32 : MEM_ALIGN (operands
[0])))
4242 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
4244 : MEM_ALIGN (operands
[1]))))
4245 && ! MEM_VOLATILE_P (operands
[0])
4246 && ! MEM_VOLATILE_P (operands
[1]))
4248 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
4249 adjust_address (operands
[1], SImode
, 0));
4250 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
4251 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
4255 if (!no_new_pseudos
&& GET_CODE (operands
[0]) == MEM
4256 && !gpc_reg_operand (operands
[1], mode
))
4257 operands
[1] = force_reg (mode
, operands
[1]);
4259 if (mode
== SFmode
&& ! TARGET_POWERPC
4260 && TARGET_HARD_FLOAT
&& TARGET_FPRS
4261 && GET_CODE (operands
[0]) == MEM
)
4265 if (reload_in_progress
|| reload_completed
)
4266 regnum
= true_regnum (operands
[1]);
4267 else if (GET_CODE (operands
[1]) == REG
)
4268 regnum
= REGNO (operands
[1]);
4272 /* If operands[1] is a register, on POWER it may have
4273 double-precision data in it, so truncate it to single
4275 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
4278 newreg
= (no_new_pseudos
? copy_rtx (operands
[1])
4279 : gen_reg_rtx (mode
));
4280 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
4281 operands
[1] = newreg
;
4285 /* Recognize the case where operand[1] is a reference to thread-local
4286 data and load its address to a register. */
4287 if (rs6000_tls_referenced_p (operands
[1]))
4289 enum tls_model model
;
4290 rtx tmp
= operands
[1];
4293 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
4295 addend
= XEXP (XEXP (tmp
, 0), 1);
4296 tmp
= XEXP (XEXP (tmp
, 0), 0);
4299 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
4300 model
= SYMBOL_REF_TLS_MODEL (tmp
);
4301 gcc_assert (model
!= 0);
4303 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
4306 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
4307 tmp
= force_operand (tmp
, operands
[0]);
4312 /* Handle the case where reload calls us with an invalid address. */
4313 if (reload_in_progress
&& mode
== Pmode
4314 && (! general_operand (operands
[1], mode
)
4315 || ! nonimmediate_operand (operands
[0], mode
)))
4318 /* 128-bit constant floating-point values on Darwin should really be
4319 loaded as two parts. */
4320 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
4321 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
4323 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4324 know how to get a DFmode SUBREG of a TFmode. */
4325 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
4326 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
4327 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
4329 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
4330 GET_MODE_SIZE (imode
)),
4331 simplify_gen_subreg (imode
, operands
[1], mode
,
4332 GET_MODE_SIZE (imode
)),
4337 /* FIXME: In the long term, this switch statement should go away
4338 and be replaced by a sequence of tests based on things like
4344 if (CONSTANT_P (operands
[1])
4345 && GET_CODE (operands
[1]) != CONST_INT
)
4346 operands
[1] = force_const_mem (mode
, operands
[1]);
4351 rs6000_eliminate_indexed_memrefs (operands
);
4357 if (CONSTANT_P (operands
[1])
4358 && ! easy_fp_constant (operands
[1], mode
))
4359 operands
[1] = force_const_mem (mode
, operands
[1]);
4370 if (CONSTANT_P (operands
[1])
4371 && !easy_vector_constant (operands
[1], mode
))
4372 operands
[1] = force_const_mem (mode
, operands
[1]);
4377 /* Use default pattern for address of ELF small data */
4380 && DEFAULT_ABI
== ABI_V4
4381 && (GET_CODE (operands
[1]) == SYMBOL_REF
4382 || GET_CODE (operands
[1]) == CONST
)
4383 && small_data_operand (operands
[1], mode
))
4385 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4389 if (DEFAULT_ABI
== ABI_V4
4390 && mode
== Pmode
&& mode
== SImode
4391 && flag_pic
== 1 && got_operand (operands
[1], mode
))
4393 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
4397 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
4401 && CONSTANT_P (operands
[1])
4402 && GET_CODE (operands
[1]) != HIGH
4403 && GET_CODE (operands
[1]) != CONST_INT
)
4405 rtx target
= (no_new_pseudos
? operands
[0] : gen_reg_rtx (mode
));
4407 /* If this is a function address on -mcall-aixdesc,
4408 convert it to the address of the descriptor. */
4409 if (DEFAULT_ABI
== ABI_AIX
4410 && GET_CODE (operands
[1]) == SYMBOL_REF
4411 && XSTR (operands
[1], 0)[0] == '.')
4413 const char *name
= XSTR (operands
[1], 0);
4415 while (*name
== '.')
4417 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
4418 CONSTANT_POOL_ADDRESS_P (new_ref
)
4419 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
4420 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
4421 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
4422 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
4423 operands
[1] = new_ref
;
4426 if (DEFAULT_ABI
== ABI_DARWIN
)
4429 if (MACHO_DYNAMIC_NO_PIC_P
)
4431 /* Take care of any required data indirection. */
4432 operands
[1] = rs6000_machopic_legitimize_pic_address (
4433 operands
[1], mode
, operands
[0]);
4434 if (operands
[0] != operands
[1])
4435 emit_insn (gen_rtx_SET (VOIDmode
,
4436 operands
[0], operands
[1]));
4440 emit_insn (gen_macho_high (target
, operands
[1]));
4441 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
4445 emit_insn (gen_elf_high (target
, operands
[1]));
4446 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
4450 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4451 and we have put it in the TOC, we just need to make a TOC-relative
4454 && GET_CODE (operands
[1]) == SYMBOL_REF
4455 && constant_pool_expr_p (operands
[1])
4456 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
4457 get_pool_mode (operands
[1])))
4459 operands
[1] = create_TOC_reference (operands
[1]);
4461 else if (mode
== Pmode
4462 && CONSTANT_P (operands
[1])
4463 && ((GET_CODE (operands
[1]) != CONST_INT
4464 && ! easy_fp_constant (operands
[1], mode
))
4465 || (GET_CODE (operands
[1]) == CONST_INT
4466 && num_insns_constant (operands
[1], mode
) > 2)
4467 || (GET_CODE (operands
[0]) == REG
4468 && FP_REGNO_P (REGNO (operands
[0]))))
4469 && GET_CODE (operands
[1]) != HIGH
4470 && ! legitimate_constant_pool_address_p (operands
[1])
4471 && ! toc_relative_expr_p (operands
[1]))
4473 /* Emit a USE operation so that the constant isn't deleted if
4474 expensive optimizations are turned on because nobody
4475 references it. This should only be done for operands that
4476 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4477 This should not be done for operands that contain LABEL_REFs.
4478 For now, we just handle the obvious case. */
4479 if (GET_CODE (operands
[1]) != LABEL_REF
)
4480 emit_insn (gen_rtx_USE (VOIDmode
, operands
[1]));
4483 /* Darwin uses a special PIC legitimizer. */
4484 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
4487 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
4489 if (operands
[0] != operands
[1])
4490 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4495 /* If we are to limit the number of things we put in the TOC and
4496 this is a symbol plus a constant we can add in one insn,
4497 just put the symbol in the TOC and add the constant. Don't do
4498 this if reload is in progress. */
4499 if (GET_CODE (operands
[1]) == CONST
4500 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
4501 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
4502 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
4503 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
4504 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
4505 && ! side_effects_p (operands
[0]))
4508 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
4509 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
4511 sym
= force_reg (mode
, sym
);
4513 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
4515 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
4519 operands
[1] = force_const_mem (mode
, operands
[1]);
4522 && constant_pool_expr_p (XEXP (operands
[1], 0))
4523 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4524 get_pool_constant (XEXP (operands
[1], 0)),
4525 get_pool_mode (XEXP (operands
[1], 0))))
4528 = gen_const_mem (mode
,
4529 create_TOC_reference (XEXP (operands
[1], 0)));
4530 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
4536 rs6000_eliminate_indexed_memrefs (operands
);
4540 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4542 gen_rtx_SET (VOIDmode
,
4543 operands
[0], operands
[1]),
4544 gen_rtx_CLOBBER (VOIDmode
,
4545 gen_rtx_SCRATCH (SImode
)))));
4554 /* Above, we may have called force_const_mem which may have returned
4555 an invalid address. If we can, fix this up; otherwise, reload will
4556 have to deal with it. */
4557 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
4558 operands
[1] = validize_mem (operands
[1]);
4561 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4564 /* Nonzero if we can use a floating-point register to pass this arg. */
4565 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4566 (SCALAR_FLOAT_MODE_P (MODE) \
4567 && (MODE) != SDmode \
4568 && (CUM)->fregno <= FP_ARG_MAX_REG \
4569 && TARGET_HARD_FLOAT && TARGET_FPRS)
4571 /* Nonzero if we can use an AltiVec register to pass this arg. */
4572 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4573 (ALTIVEC_VECTOR_MODE (MODE) \
4574 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4575 && TARGET_ALTIVEC_ABI \
4578 /* Return a nonzero value to say to return the function value in
4579 memory, just as large structures are always returned. TYPE will be
4580 the data type of the value, and FNTYPE will be the type of the
4581 function doing the returning, or @code{NULL} for libcalls.
4583 The AIX ABI for the RS/6000 specifies that all structures are
4584 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4585 specifies that structures <= 8 bytes are returned in r3/r4, but a
4586 draft put them in memory, and GCC used to implement the draft
4587 instead of the final standard. Therefore, aix_struct_return
4588 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4589 compatibility can change DRAFT_V4_STRUCT_RET to override the
4590 default, and -m switches get the final word. See
4591 rs6000_override_options for more details.
4593 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4594 long double support is enabled. These values are returned in memory.
4596 int_size_in_bytes returns -1 for variable size objects, which go in
4597 memory always. The cast to unsigned makes -1 > 8. */
4600 rs6000_return_in_memory (tree type
, tree fntype ATTRIBUTE_UNUSED
)
4602 /* In the darwin64 abi, try to use registers for larger structs
4604 if (rs6000_darwin64_abi
4605 && TREE_CODE (type
) == RECORD_TYPE
4606 && int_size_in_bytes (type
) > 0)
4608 CUMULATIVE_ARGS valcum
;
4612 valcum
.fregno
= FP_ARG_MIN_REG
;
4613 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
4614 /* Do a trial code generation as if this were going to be passed
4615 as an argument; if any part goes in memory, we return NULL. */
4616 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
4619 /* Otherwise fall through to more conventional ABI rules. */
4622 if (AGGREGATE_TYPE_P (type
)
4623 && (aix_struct_return
4624 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
4627 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4628 modes only exist for GCC vector types if -maltivec. */
4629 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
4630 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
4633 /* Return synthetic vectors in memory. */
4634 if (TREE_CODE (type
) == VECTOR_TYPE
4635 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
4637 static bool warned_for_return_big_vectors
= false;
4638 if (!warned_for_return_big_vectors
)
4640 warning (0, "GCC vector returned by reference: "
4641 "non-standard ABI extension with no compatibility guarantee");
4642 warned_for_return_big_vectors
= true;
4647 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
4653 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4654 for a call to a function whose data type is FNTYPE.
4655 For a library call, FNTYPE is 0.
4657 For incoming args we set the number of arguments in the prototype large
4658 so we never return a PARALLEL. */
4661 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
4662 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
4663 int libcall
, int n_named_args
)
4665 static CUMULATIVE_ARGS zero_cumulative
;
4667 *cum
= zero_cumulative
;
4669 cum
->fregno
= FP_ARG_MIN_REG
;
4670 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
4671 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
4672 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
4673 ? CALL_LIBCALL
: CALL_NORMAL
);
4674 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
4675 cum
->stdarg
= fntype
4676 && (TYPE_ARG_TYPES (fntype
) != 0
4677 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
4678 != void_type_node
));
4680 cum
->nargs_prototype
= 0;
4681 if (incoming
|| cum
->prototype
)
4682 cum
->nargs_prototype
= n_named_args
;
4684 /* Check for a longcall attribute. */
4685 if ((!fntype
&& rs6000_default_long_calls
)
4687 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
4688 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
4689 cum
->call_cookie
|= CALL_LONG
;
4691 if (TARGET_DEBUG_ARG
)
4693 fprintf (stderr
, "\ninit_cumulative_args:");
4696 tree ret_type
= TREE_TYPE (fntype
);
4697 fprintf (stderr
, " ret code = %s,",
4698 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
4701 if (cum
->call_cookie
& CALL_LONG
)
4702 fprintf (stderr
, " longcall,");
4704 fprintf (stderr
, " proto = %d, nargs = %d\n",
4705 cum
->prototype
, cum
->nargs_prototype
);
4710 && TARGET_ALTIVEC_ABI
4711 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
4713 error ("cannot return value in vector register because"
4714 " altivec instructions are disabled, use -maltivec"
4719 /* Return true if TYPE must be passed on the stack and not in registers. */
4722 rs6000_must_pass_in_stack (enum machine_mode mode
, tree type
)
4724 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
4725 return must_pass_in_stack_var_size (mode
, type
);
4727 return must_pass_in_stack_var_size_or_pad (mode
, type
);
4730 /* If defined, a C expression which determines whether, and in which
4731 direction, to pad out an argument with extra space. The value
4732 should be of type `enum direction': either `upward' to pad above
4733 the argument, `downward' to pad below, or `none' to inhibit
4736 For the AIX ABI structs are always stored left shifted in their
4740 function_arg_padding (enum machine_mode mode
, tree type
)
4742 #ifndef AGGREGATE_PADDING_FIXED
4743 #define AGGREGATE_PADDING_FIXED 0
4745 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4746 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4749 if (!AGGREGATE_PADDING_FIXED
)
4751 /* GCC used to pass structures of the same size as integer types as
4752 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4753 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4754 passed padded downward, except that -mstrict-align further
4755 muddied the water in that multi-component structures of 2 and 4
4756 bytes in size were passed padded upward.
4758 The following arranges for best compatibility with previous
4759 versions of gcc, but removes the -mstrict-align dependency. */
4760 if (BYTES_BIG_ENDIAN
)
4762 HOST_WIDE_INT size
= 0;
4764 if (mode
== BLKmode
)
4766 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
4767 size
= int_size_in_bytes (type
);
4770 size
= GET_MODE_SIZE (mode
);
4772 if (size
== 1 || size
== 2 || size
== 4)
4778 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
4780 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
4784 /* Fall back to the default. */
4785 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
4788 /* If defined, a C expression that gives the alignment boundary, in bits,
4789 of an argument with the specified mode and type. If it is not defined,
4790 PARM_BOUNDARY is used for all arguments.
4792 V.4 wants long longs and doubles to be double word aligned. Just
4793 testing the mode size is a boneheaded way to do this as it means
4794 that other types such as complex int are also double word aligned.
4795 However, we're stuck with this because changing the ABI might break
4796 existing library interfaces.
4798 Doubleword align SPE vectors.
4799 Quadword align Altivec vectors.
4800 Quadword align large synthetic vector types. */
4803 function_arg_boundary (enum machine_mode mode
, tree type
)
4805 if (DEFAULT_ABI
== ABI_V4
4806 && (GET_MODE_SIZE (mode
) == 8
4807 || (TARGET_HARD_FLOAT
4809 && (mode
== TFmode
|| mode
== TDmode
))))
4811 else if (SPE_VECTOR_MODE (mode
)
4812 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4813 && int_size_in_bytes (type
) >= 8
4814 && int_size_in_bytes (type
) < 16))
4816 else if (ALTIVEC_VECTOR_MODE (mode
)
4817 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4818 && int_size_in_bytes (type
) >= 16))
4820 else if (rs6000_darwin64_abi
&& mode
== BLKmode
4821 && type
&& TYPE_ALIGN (type
) > 64)
4824 return PARM_BOUNDARY
;
4827 /* For a function parm of MODE and TYPE, return the starting word in
4828 the parameter area. NWORDS of the parameter area are already used. */
4831 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
4834 unsigned int parm_offset
;
4836 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
4837 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
4838 return nwords
+ (-(parm_offset
+ nwords
) & align
);
4841 /* Compute the size (in words) of a function argument. */
4843 static unsigned long
4844 rs6000_arg_size (enum machine_mode mode
, tree type
)
4848 if (mode
!= BLKmode
)
4849 size
= GET_MODE_SIZE (mode
);
4851 size
= int_size_in_bytes (type
);
4854 return (size
+ 3) >> 2;
4856 return (size
+ 7) >> 3;
4859 /* Use this to flush pending int fields. */
4862 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
4863 HOST_WIDE_INT bitpos
)
4865 unsigned int startbit
, endbit
;
4866 int intregs
, intoffset
;
4867 enum machine_mode mode
;
4869 if (cum
->intoffset
== -1)
4872 intoffset
= cum
->intoffset
;
4873 cum
->intoffset
= -1;
4875 if (intoffset
% BITS_PER_WORD
!= 0)
4877 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4879 if (mode
== BLKmode
)
4881 /* We couldn't find an appropriate mode, which happens,
4882 e.g., in packed structs when there are 3 bytes to load.
4883 Back intoffset back to the beginning of the word in this
4885 intoffset
= intoffset
& -BITS_PER_WORD
;
4889 startbit
= intoffset
& -BITS_PER_WORD
;
4890 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4891 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4892 cum
->words
+= intregs
;
4895 /* The darwin64 ABI calls for us to recurse down through structs,
4896 looking for elements passed in registers. Unfortunately, we have
4897 to track int register count here also because of misalignments
4898 in powerpc alignment mode. */
4901 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
4903 HOST_WIDE_INT startbitpos
)
4907 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4908 if (TREE_CODE (f
) == FIELD_DECL
)
4910 HOST_WIDE_INT bitpos
= startbitpos
;
4911 tree ftype
= TREE_TYPE (f
);
4912 enum machine_mode mode
;
4913 if (ftype
== error_mark_node
)
4915 mode
= TYPE_MODE (ftype
);
4917 if (DECL_SIZE (f
) != 0
4918 && host_integerp (bit_position (f
), 1))
4919 bitpos
+= int_bit_position (f
);
4921 /* ??? FIXME: else assume zero offset. */
4923 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4924 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
4925 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4927 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4928 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4929 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4931 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
4933 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4937 else if (cum
->intoffset
== -1)
4938 cum
->intoffset
= bitpos
;
4942 /* Update the data in CUM to advance over an argument
4943 of mode MODE and data type TYPE.
4944 (TYPE is null for libcalls where that information may not be available.)
4946 Note that for args passed by reference, function_arg will be called
4947 with MODE and TYPE set to that of the pointer to the arg, not the arg
4951 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4952 tree type
, int named
, int depth
)
4956 /* Only tick off an argument if we're not recursing. */
4958 cum
->nargs_prototype
--;
4960 if (TARGET_ALTIVEC_ABI
4961 && (ALTIVEC_VECTOR_MODE (mode
)
4962 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4963 && int_size_in_bytes (type
) == 16)))
4967 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
4970 if (!TARGET_ALTIVEC
)
4971 error ("cannot pass argument in vector register because"
4972 " altivec instructions are disabled, use -maltivec"
4975 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4976 even if it is going to be passed in a vector register.
4977 Darwin does the same for variable-argument functions. */
4978 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4979 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
4989 /* Vector parameters must be 16-byte aligned. This places
4990 them at 2 mod 4 in terms of words in 32-bit mode, since
4991 the parameter save area starts at offset 24 from the
4992 stack. In 64-bit mode, they just have to start on an
4993 even word, since the parameter save area is 16-byte
4994 aligned. Space for GPRs is reserved even if the argument
4995 will be passed in memory. */
4997 align
= (2 - cum
->words
) & 3;
4999 align
= cum
->words
& 1;
5000 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
5002 if (TARGET_DEBUG_ARG
)
5004 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
5006 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
5007 cum
->nargs_prototype
, cum
->prototype
,
5008 GET_MODE_NAME (mode
));
5012 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
5014 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
5017 else if (rs6000_darwin64_abi
5019 && TREE_CODE (type
) == RECORD_TYPE
5020 && (size
= int_size_in_bytes (type
)) > 0)
5022 /* Variable sized types have size == -1 and are
5023 treated as if consisting entirely of ints.
5024 Pad to 16 byte boundary if needed. */
5025 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5026 && (cum
->words
% 2) != 0)
5028 /* For varargs, we can just go up by the size of the struct. */
5030 cum
->words
+= (size
+ 7) / 8;
5033 /* It is tempting to say int register count just goes up by
5034 sizeof(type)/8, but this is wrong in a case such as
5035 { int; double; int; } [powerpc alignment]. We have to
5036 grovel through the fields for these too. */
5038 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
5039 rs6000_darwin64_record_arg_advance_flush (cum
,
5040 size
* BITS_PER_UNIT
);
5043 else if (DEFAULT_ABI
== ABI_V4
)
5045 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5046 && (mode
== SFmode
|| mode
== DFmode
5047 || mode
== DDmode
|| mode
== TDmode
5048 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
5050 /* _Decimal128 must use an even/odd register pair. */
5051 if (mode
== TDmode
&& cum
->fregno
% 2)
5054 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
5055 <= FP_ARG_V4_MAX_REG
)
5056 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5059 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
5060 if (mode
== DFmode
|| mode
== TFmode
|| mode
== DDmode
|| mode
== TDmode
)
5061 cum
->words
+= cum
->words
& 1;
5062 cum
->words
+= rs6000_arg_size (mode
, type
);
5067 int n_words
= rs6000_arg_size (mode
, type
);
5068 int gregno
= cum
->sysv_gregno
;
5070 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5071 (r7,r8) or (r9,r10). As does any other 2 word item such
5072 as complex int due to a historical mistake. */
5074 gregno
+= (1 - gregno
) & 1;
5076 /* Multi-reg args are not split between registers and stack. */
5077 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5079 /* Long long and SPE vectors are aligned on the stack.
5080 So are other 2 word items such as complex int due to
5081 a historical mistake. */
5083 cum
->words
+= cum
->words
& 1;
5084 cum
->words
+= n_words
;
5087 /* Note: continuing to accumulate gregno past when we've started
5088 spilling to the stack indicates the fact that we've started
5089 spilling to the stack to expand_builtin_saveregs. */
5090 cum
->sysv_gregno
= gregno
+ n_words
;
5093 if (TARGET_DEBUG_ARG
)
5095 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5096 cum
->words
, cum
->fregno
);
5097 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
5098 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
5099 fprintf (stderr
, "mode = %4s, named = %d\n",
5100 GET_MODE_NAME (mode
), named
);
5105 int n_words
= rs6000_arg_size (mode
, type
);
5106 int start_words
= cum
->words
;
5107 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
5109 cum
->words
= align_words
+ n_words
;
5111 if (SCALAR_FLOAT_MODE_P (mode
)
5113 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5114 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5116 if (TARGET_DEBUG_ARG
)
5118 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5119 cum
->words
, cum
->fregno
);
5120 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
5121 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
5122 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
5123 named
, align_words
- start_words
, depth
);
5129 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
5136 r1
= gen_rtx_REG (DImode
, gregno
);
5137 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5138 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
5142 r1
= gen_rtx_REG (DImode
, gregno
);
5143 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5144 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5145 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5146 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
5149 r1
= gen_rtx_REG (DImode
, gregno
);
5150 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5151 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5152 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5153 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
5154 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
5155 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
5156 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
5157 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
5164 /* Determine where to put a SIMD argument on the SPE. */
5166 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5169 int gregno
= cum
->sysv_gregno
;
5171 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5172 are passed and returned in a pair of GPRs for ABI compatibility. */
5173 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DCmode
5174 || mode
== TFmode
|| mode
== TCmode
))
5176 int n_words
= rs6000_arg_size (mode
, type
);
5178 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5180 gregno
+= (1 - gregno
) & 1;
5182 /* Multi-reg args are not split between registers and stack. */
5183 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5186 return spe_build_register_parallel (mode
, gregno
);
5190 int n_words
= rs6000_arg_size (mode
, type
);
5192 /* SPE vectors are put in odd registers. */
5193 if (n_words
== 2 && (gregno
& 1) == 0)
5196 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
5199 enum machine_mode m
= SImode
;
5201 r1
= gen_rtx_REG (m
, gregno
);
5202 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
5203 r2
= gen_rtx_REG (m
, gregno
+ 1);
5204 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
5205 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
5212 if (gregno
<= GP_ARG_MAX_REG
)
5213 return gen_rtx_REG (mode
, gregno
);
5219 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5220 structure between cum->intoffset and bitpos to integer registers. */
5223 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
5224 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
5226 enum machine_mode mode
;
5228 unsigned int startbit
, endbit
;
5229 int this_regno
, intregs
, intoffset
;
5232 if (cum
->intoffset
== -1)
5235 intoffset
= cum
->intoffset
;
5236 cum
->intoffset
= -1;
5238 /* If this is the trailing part of a word, try to only load that
5239 much into the register. Otherwise load the whole register. Note
5240 that in the latter case we may pick up unwanted bits. It's not a
5241 problem at the moment but may wish to revisit. */
5243 if (intoffset
% BITS_PER_WORD
!= 0)
5245 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5247 if (mode
== BLKmode
)
5249 /* We couldn't find an appropriate mode, which happens,
5250 e.g., in packed structs when there are 3 bytes to load.
5251 Back intoffset back to the beginning of the word in this
5253 intoffset
= intoffset
& -BITS_PER_WORD
;
5260 startbit
= intoffset
& -BITS_PER_WORD
;
5261 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5262 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5263 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
5265 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
5268 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
5272 intoffset
/= BITS_PER_UNIT
;
5275 regno
= GP_ARG_MIN_REG
+ this_regno
;
5276 reg
= gen_rtx_REG (mode
, regno
);
5278 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
5281 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
5285 while (intregs
> 0);
5288 /* Recursive workhorse for the following. */
5291 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, tree type
,
5292 HOST_WIDE_INT startbitpos
, rtx rvec
[],
5297 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5298 if (TREE_CODE (f
) == FIELD_DECL
)
5300 HOST_WIDE_INT bitpos
= startbitpos
;
5301 tree ftype
= TREE_TYPE (f
);
5302 enum machine_mode mode
;
5303 if (ftype
== error_mark_node
)
5305 mode
= TYPE_MODE (ftype
);
5307 if (DECL_SIZE (f
) != 0
5308 && host_integerp (bit_position (f
), 1))
5309 bitpos
+= int_bit_position (f
);
5311 /* ??? FIXME: else assume zero offset. */
5313 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5314 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
5315 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5320 case SCmode
: mode
= SFmode
; break;
5321 case DCmode
: mode
= DFmode
; break;
5322 case TCmode
: mode
= TFmode
; break;
5326 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5328 = gen_rtx_EXPR_LIST (VOIDmode
,
5329 gen_rtx_REG (mode
, cum
->fregno
++),
5330 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5331 if (mode
== TFmode
|| mode
== TDmode
)
5334 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
5336 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5338 = gen_rtx_EXPR_LIST (VOIDmode
,
5339 gen_rtx_REG (mode
, cum
->vregno
++),
5340 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5342 else if (cum
->intoffset
== -1)
5343 cum
->intoffset
= bitpos
;
5347 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5348 the register(s) to be used for each field and subfield of a struct
5349 being passed by value, along with the offset of where the
5350 register's value may be found in the block. FP fields go in FP
5351 register, vector fields go in vector registers, and everything
5352 else goes in int registers, packed as in memory.
5354 This code is also used for function return values. RETVAL indicates
5355 whether this is the case.
5357 Much of this is taken from the SPARC V9 port, which has a similar
5358 calling convention. */
5361 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, tree type
,
5362 int named
, bool retval
)
5364 rtx rvec
[FIRST_PSEUDO_REGISTER
];
5365 int k
= 1, kbase
= 1;
5366 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
5367 /* This is a copy; modifications are not visible to our caller. */
5368 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
5369 CUMULATIVE_ARGS
*cum
= ©_cum
;
5371 /* Pad to 16 byte boundary if needed. */
5372 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5373 && (cum
->words
% 2) != 0)
5380 /* Put entries into rvec[] for individual FP and vector fields, and
5381 for the chunks of memory that go in int regs. Note we start at
5382 element 1; 0 is reserved for an indication of using memory, and
5383 may or may not be filled in below. */
5384 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
5385 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
5387 /* If any part of the struct went on the stack put all of it there.
5388 This hack is because the generic code for
5389 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5390 parts of the struct are not at the beginning. */
5394 return NULL_RTX
; /* doesn't go in registers at all */
5396 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5398 if (k
> 1 || cum
->use_stack
)
5399 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
5404 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5407 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
5411 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5413 if (align_words
>= GP_ARG_NUM_REG
)
5416 n_units
= rs6000_arg_size (mode
, type
);
5418 /* Optimize the simple case where the arg fits in one gpr, except in
5419 the case of BLKmode due to assign_parms assuming that registers are
5420 BITS_PER_WORD wide. */
5422 || (n_units
== 1 && mode
!= BLKmode
))
5423 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5426 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
5427 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5428 using a magic NULL_RTX component.
5429 This is not strictly correct. Only some of the arg belongs in
5430 memory, not all of it. However, the normal scheme using
5431 function_arg_partial_nregs can result in unusual subregs, eg.
5432 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5433 store the whole arg to memory is often more efficient than code
5434 to store pieces, and we know that space is available in the right
5435 place for the whole arg. */
5436 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5441 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
5442 rtx off
= GEN_INT (i
++ * 4);
5443 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5445 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
5447 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5450 /* Determine where to put an argument to a function.
5451 Value is zero to push the argument on the stack,
5452 or a hard register in which to store the argument.
5454 MODE is the argument's machine mode.
5455 TYPE is the data type of the argument (as a tree).
5456 This is null for libcalls where that information may
5458 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5459 the preceding args and about the function being called. It is
5460 not modified in this routine.
5461 NAMED is nonzero if this argument is a named parameter
5462 (otherwise it is an extra parameter matching an ellipsis).
5464 On RS/6000 the first eight words of non-FP are normally in registers
5465 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5466 Under V.4, the first 8 FP args are in registers.
5468 If this is floating-point and no prototype is specified, we use
5469 both an FP and integer register (or possibly FP reg and stack). Library
5470 functions (when CALL_LIBCALL is set) always have the proper types for args,
5471 so we can pass the FP value just in one register. emit_library_function
5472 doesn't support PARALLEL anyway.
5474 Note that for args passed by reference, function_arg will be called
5475 with MODE and TYPE set to that of the pointer to the arg, not the arg
5479 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5480 tree type
, int named
)
5482 enum rs6000_abi abi
= DEFAULT_ABI
;
5484 /* Return a marker to indicate whether CR1 needs to set or clear the
5485 bit that V.4 uses to say fp args were passed in registers.
5486 Assume that we don't need the marker for software floating point,
5487 or compiler generated library calls. */
5488 if (mode
== VOIDmode
)
5491 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
5493 || (cum
->nargs_prototype
< 0
5494 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
5496 /* For the SPE, we need to crxor CR6 always. */
5498 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
5499 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5500 return GEN_INT (cum
->call_cookie
5501 | ((cum
->fregno
== FP_ARG_MIN_REG
)
5502 ? CALL_V4_SET_FP_ARGS
5503 : CALL_V4_CLEAR_FP_ARGS
));
5506 return GEN_INT (cum
->call_cookie
);
5509 if (rs6000_darwin64_abi
&& mode
== BLKmode
5510 && TREE_CODE (type
) == RECORD_TYPE
)
5512 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
5513 if (rslt
!= NULL_RTX
)
5515 /* Else fall through to usual handling. */
5518 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5519 if (TARGET_64BIT
&& ! cum
->prototype
)
5521 /* Vector parameters get passed in vector register
5522 and also in GPRs or memory, in absence of prototype. */
5525 align_words
= (cum
->words
+ 1) & ~1;
5527 if (align_words
>= GP_ARG_NUM_REG
)
5533 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5535 return gen_rtx_PARALLEL (mode
,
5537 gen_rtx_EXPR_LIST (VOIDmode
,
5539 gen_rtx_EXPR_LIST (VOIDmode
,
5540 gen_rtx_REG (mode
, cum
->vregno
),
5544 return gen_rtx_REG (mode
, cum
->vregno
);
5545 else if (TARGET_ALTIVEC_ABI
5546 && (ALTIVEC_VECTOR_MODE (mode
)
5547 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5548 && int_size_in_bytes (type
) == 16)))
5550 if (named
|| abi
== ABI_V4
)
5554 /* Vector parameters to varargs functions under AIX or Darwin
5555 get passed in memory and possibly also in GPRs. */
5556 int align
, align_words
, n_words
;
5557 enum machine_mode part_mode
;
5559 /* Vector parameters must be 16-byte aligned. This places them at
5560 2 mod 4 in terms of words in 32-bit mode, since the parameter
5561 save area starts at offset 24 from the stack. In 64-bit mode,
5562 they just have to start on an even word, since the parameter
5563 save area is 16-byte aligned. */
5565 align
= (2 - cum
->words
) & 3;
5567 align
= cum
->words
& 1;
5568 align_words
= cum
->words
+ align
;
5570 /* Out of registers? Memory, then. */
5571 if (align_words
>= GP_ARG_NUM_REG
)
5574 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5575 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5577 /* The vector value goes in GPRs. Only the part of the
5578 value in GPRs is reported here. */
5580 n_words
= rs6000_arg_size (mode
, type
);
5581 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
5582 /* Fortunately, there are only two possibilities, the value
5583 is either wholly in GPRs or half in GPRs and half not. */
5586 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
5589 else if (TARGET_SPE_ABI
&& TARGET_SPE
5590 && (SPE_VECTOR_MODE (mode
)
5591 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
5596 || mode
== TCmode
))))
5597 return rs6000_spe_function_arg (cum
, mode
, type
);
5599 else if (abi
== ABI_V4
)
5601 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5602 && (mode
== SFmode
|| mode
== DFmode
5603 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)
5604 || mode
== DDmode
|| mode
== TDmode
))
5606 /* _Decimal128 must use an even/odd register pair. */
5607 if (mode
== TDmode
&& cum
->fregno
% 2)
5610 if (cum
->fregno
+ (mode
== TFmode
|| mode
== TDmode
? 1 : 0)
5611 <= FP_ARG_V4_MAX_REG
)
5612 return gen_rtx_REG (mode
, cum
->fregno
);
5618 int n_words
= rs6000_arg_size (mode
, type
);
5619 int gregno
= cum
->sysv_gregno
;
5621 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5622 (r7,r8) or (r9,r10). As does any other 2 word item such
5623 as complex int due to a historical mistake. */
5625 gregno
+= (1 - gregno
) & 1;
5627 /* Multi-reg args are not split between registers and stack. */
5628 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5631 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5632 return rs6000_mixed_function_arg (mode
, type
,
5633 gregno
- GP_ARG_MIN_REG
);
5634 return gen_rtx_REG (mode
, gregno
);
5639 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5641 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
5643 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5647 enum machine_mode fmode
= mode
;
5648 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
5650 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
5652 /* Currently, we only ever need one reg here because complex
5653 doubles are split. */
5654 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
5655 && (fmode
== TFmode
|| fmode
== TDmode
));
5657 /* Long double or _Decimal128 split over regs and memory. */
5658 fmode
= DECIMAL_FLOAT_MODE_P (fmode
) ? DDmode
: DFmode
;
5661 /* Do we also need to pass this arg in the parameter save
5664 && (cum
->nargs_prototype
<= 0
5665 || (DEFAULT_ABI
== ABI_AIX
5667 && align_words
>= GP_ARG_NUM_REG
)));
5669 if (!needs_psave
&& mode
== fmode
)
5670 return gen_rtx_REG (fmode
, cum
->fregno
);
5675 /* Describe the part that goes in gprs or the stack.
5676 This piece must come first, before the fprs. */
5677 if (align_words
< GP_ARG_NUM_REG
)
5679 unsigned long n_words
= rs6000_arg_size (mode
, type
);
5681 if (align_words
+ n_words
> GP_ARG_NUM_REG
5682 || (TARGET_32BIT
&& TARGET_POWERPC64
))
5684 /* If this is partially on the stack, then we only
5685 include the portion actually in registers here. */
5686 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
5689 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
5690 /* Not all of the arg fits in gprs. Say that it
5691 goes in memory too, using a magic NULL_RTX
5692 component. Also see comment in
5693 rs6000_mixed_function_arg for why the normal
5694 function_arg_partial_nregs scheme doesn't work
5696 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
5700 r
= gen_rtx_REG (rmode
,
5701 GP_ARG_MIN_REG
+ align_words
);
5702 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
5703 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5705 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
5709 /* The whole arg fits in gprs. */
5710 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5711 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5715 /* It's entirely in memory. */
5716 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5719 /* Describe where this piece goes in the fprs. */
5720 r
= gen_rtx_REG (fmode
, cum
->fregno
);
5721 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5723 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5725 else if (align_words
< GP_ARG_NUM_REG
)
5727 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5728 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5730 if (mode
== BLKmode
)
5733 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5740 /* For an arg passed partly in registers and partly in memory, this is
5741 the number of bytes passed in registers. For args passed entirely in
5742 registers or entirely in memory, zero. When an arg is described by a
5743 PARALLEL, perhaps using more than one register type, this function
5744 returns the number of bytes used by the first element of the PARALLEL. */
5747 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5748 tree type
, bool named
)
5753 if (DEFAULT_ABI
== ABI_V4
)
5756 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
5757 && cum
->nargs_prototype
>= 0)
5760 /* In this complicated case we just disable the partial_nregs code. */
5761 if (rs6000_darwin64_abi
&& mode
== BLKmode
5762 && TREE_CODE (type
) == RECORD_TYPE
5763 && int_size_in_bytes (type
) > 0)
5766 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5768 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
5770 /* If we are passing this arg in the fixed parameter save area
5771 (gprs or memory) as well as fprs, then this function should
5772 return the number of partial bytes passed in the parameter
5773 save area rather than partial bytes passed in fprs. */
5775 && (cum
->nargs_prototype
<= 0
5776 || (DEFAULT_ABI
== ABI_AIX
5778 && align_words
>= GP_ARG_NUM_REG
)))
5780 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
5781 > FP_ARG_MAX_REG
+ 1)
5782 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
5783 else if (cum
->nargs_prototype
>= 0)
5787 if (align_words
< GP_ARG_NUM_REG
5788 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
5789 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
5791 if (ret
!= 0 && TARGET_DEBUG_ARG
)
5792 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
5797 /* A C expression that indicates when an argument must be passed by
5798 reference. If nonzero for an argument, a copy of that argument is
5799 made in memory and a pointer to the argument is passed instead of
5800 the argument itself. The pointer is passed in whatever way is
5801 appropriate for passing a pointer to that type.
5803 Under V.4, aggregates and long double are passed by reference.
5805 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5806 reference unless the AltiVec vector extension ABI is in force.
5808 As an extension to all ABIs, variable sized types are passed by
5812 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
5813 enum machine_mode mode
, tree type
,
5814 bool named ATTRIBUTE_UNUSED
)
5816 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
5818 if (TARGET_DEBUG_ARG
)
5819 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
5826 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
5828 if (TARGET_DEBUG_ARG
)
5829 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
5833 if (int_size_in_bytes (type
) < 0)
5835 if (TARGET_DEBUG_ARG
)
5836 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
5840 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5841 modes only exist for GCC vector types if -maltivec. */
5842 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
5844 if (TARGET_DEBUG_ARG
)
5845 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
5849 /* Pass synthetic vectors in memory. */
5850 if (TREE_CODE (type
) == VECTOR_TYPE
5851 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5853 static bool warned_for_pass_big_vectors
= false;
5854 if (TARGET_DEBUG_ARG
)
5855 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
5856 if (!warned_for_pass_big_vectors
)
5858 warning (0, "GCC vector passed by reference: "
5859 "non-standard ABI extension with no compatibility guarantee");
5860 warned_for_pass_big_vectors
= true;
5869 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
5872 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
5877 for (i
= 0; i
< nregs
; i
++)
5879 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
5880 if (reload_completed
)
5882 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
5885 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
5886 i
* GET_MODE_SIZE (reg_mode
));
5889 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
5893 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
5897 /* Perform any needed actions needed for a function that is receiving a
5898 variable number of arguments.
5902 MODE and TYPE are the mode and type of the current parameter.
5904 PRETEND_SIZE is a variable that should be set to the amount of stack
5905 that must be pushed by the prolog to pretend that our caller pushed
5908 Normally, this macro will push all remaining incoming registers on the
5909 stack and set PRETEND_SIZE to the length of the registers pushed. */
5912 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5913 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
5916 CUMULATIVE_ARGS next_cum
;
5917 int reg_size
= TARGET_32BIT
? 4 : 8;
5918 rtx save_area
= NULL_RTX
, mem
;
5919 int first_reg_offset
, set
;
5921 /* Skip the last named argument. */
5923 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
5925 if (DEFAULT_ABI
== ABI_V4
)
5927 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
5931 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
5932 HOST_WIDE_INT offset
= 0;
5934 /* Try to optimize the size of the varargs save area.
5935 The ABI requires that ap.reg_save_area is doubleword
5936 aligned, but we don't need to allocate space for all
5937 the bytes, only those to which we actually will save
5939 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
5940 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
5941 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5942 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5943 && cfun
->va_list_fpr_size
)
5946 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
5947 * UNITS_PER_FP_WORD
;
5948 if (cfun
->va_list_fpr_size
5949 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5950 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
5952 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5953 * UNITS_PER_FP_WORD
;
5957 offset
= -((first_reg_offset
* reg_size
) & ~7);
5958 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
5960 gpr_reg_num
= cfun
->va_list_gpr_size
;
5961 if (reg_size
== 4 && (first_reg_offset
& 1))
5964 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
5967 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
5969 - (int) (GP_ARG_NUM_REG
* reg_size
);
5971 if (gpr_size
+ fpr_size
)
5974 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
5975 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
5976 reg_save_area
= XEXP (reg_save_area
, 0);
5977 if (GET_CODE (reg_save_area
) == PLUS
)
5979 gcc_assert (XEXP (reg_save_area
, 0)
5980 == virtual_stack_vars_rtx
);
5981 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
5982 offset
+= INTVAL (XEXP (reg_save_area
, 1));
5985 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
5988 cfun
->machine
->varargs_save_offset
= offset
;
5989 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
5994 first_reg_offset
= next_cum
.words
;
5995 save_area
= virtual_incoming_args_rtx
;
5997 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
5998 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
6001 set
= get_varargs_alias_set ();
6002 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
6003 && cfun
->va_list_gpr_size
)
6005 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
6007 if (va_list_gpr_counter_field
)
6009 /* V4 va_list_gpr_size counts number of registers needed. */
6010 if (nregs
> cfun
->va_list_gpr_size
)
6011 nregs
= cfun
->va_list_gpr_size
;
6015 /* char * va_list instead counts number of bytes needed. */
6016 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
6017 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
6020 mem
= gen_rtx_MEM (BLKmode
,
6021 plus_constant (save_area
,
6022 first_reg_offset
* reg_size
));
6023 MEM_NOTRAP_P (mem
) = 1;
6024 set_mem_alias_set (mem
, set
);
6025 set_mem_align (mem
, BITS_PER_WORD
);
6027 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
6031 /* Save FP registers if needed. */
6032 if (DEFAULT_ABI
== ABI_V4
6033 && TARGET_HARD_FLOAT
&& TARGET_FPRS
6035 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
6036 && cfun
->va_list_fpr_size
)
6038 int fregno
= next_cum
.fregno
, nregs
;
6039 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
6040 rtx lab
= gen_label_rtx ();
6041 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
6042 * UNITS_PER_FP_WORD
);
6045 (gen_rtx_SET (VOIDmode
,
6047 gen_rtx_IF_THEN_ELSE (VOIDmode
,
6048 gen_rtx_NE (VOIDmode
, cr1
,
6050 gen_rtx_LABEL_REF (VOIDmode
, lab
),
6054 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
6055 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
6057 mem
= gen_rtx_MEM (DFmode
, plus_constant (save_area
, off
));
6058 MEM_NOTRAP_P (mem
) = 1;
6059 set_mem_alias_set (mem
, set
);
6060 set_mem_align (mem
, GET_MODE_ALIGNMENT (DFmode
));
6061 emit_move_insn (mem
, gen_rtx_REG (DFmode
, fregno
));
6068 /* Create the va_list data type. */
6071 rs6000_build_builtin_va_list (void)
6073 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
6075 /* For AIX, prefer 'char *' because that's what the system
6076 header files like. */
6077 if (DEFAULT_ABI
!= ABI_V4
)
6078 return build_pointer_type (char_type_node
);
6080 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
6081 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
6083 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
6084 unsigned_char_type_node
);
6085 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
6086 unsigned_char_type_node
);
6087 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6089 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
6090 short_unsigned_type_node
);
6091 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
6093 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
6096 va_list_gpr_counter_field
= f_gpr
;
6097 va_list_fpr_counter_field
= f_fpr
;
6099 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6100 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6101 DECL_FIELD_CONTEXT (f_res
) = record
;
6102 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6103 DECL_FIELD_CONTEXT (f_sav
) = record
;
6105 TREE_CHAIN (record
) = type_decl
;
6106 TYPE_NAME (record
) = type_decl
;
6107 TYPE_FIELDS (record
) = f_gpr
;
6108 TREE_CHAIN (f_gpr
) = f_fpr
;
6109 TREE_CHAIN (f_fpr
) = f_res
;
6110 TREE_CHAIN (f_res
) = f_ovf
;
6111 TREE_CHAIN (f_ovf
) = f_sav
;
6113 layout_type (record
);
6115 /* The correct type is an array type of one element. */
6116 return build_array_type (record
, build_index_type (size_zero_node
));
6119 /* Implement va_start. */
6122 rs6000_va_start (tree valist
, rtx nextarg
)
6124 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
6125 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6126 tree gpr
, fpr
, ovf
, sav
, t
;
6128 /* Only SVR4 needs something special. */
6129 if (DEFAULT_ABI
!= ABI_V4
)
6131 std_expand_builtin_va_start (valist
, nextarg
);
6135 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6136 f_fpr
= TREE_CHAIN (f_gpr
);
6137 f_res
= TREE_CHAIN (f_fpr
);
6138 f_ovf
= TREE_CHAIN (f_res
);
6139 f_sav
= TREE_CHAIN (f_ovf
);
6141 valist
= build_va_arg_indirect_ref (valist
);
6142 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6143 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6144 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6145 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6147 /* Count number of gp and fp argument registers used. */
6148 words
= current_function_args_info
.words
;
6149 n_gpr
= MIN (current_function_args_info
.sysv_gregno
- GP_ARG_MIN_REG
,
6151 n_fpr
= MIN (current_function_args_info
.fregno
- FP_ARG_MIN_REG
,
6154 if (TARGET_DEBUG_ARG
)
6155 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
6156 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
6157 words
, n_gpr
, n_fpr
);
6159 if (cfun
->va_list_gpr_size
)
6161 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (gpr
), gpr
,
6162 build_int_cst (NULL_TREE
, n_gpr
));
6163 TREE_SIDE_EFFECTS (t
) = 1;
6164 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6167 if (cfun
->va_list_fpr_size
)
6169 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (fpr
), fpr
,
6170 build_int_cst (NULL_TREE
, n_fpr
));
6171 TREE_SIDE_EFFECTS (t
) = 1;
6172 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6175 /* Find the overflow area. */
6176 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6178 t
= build2 (PLUS_EXPR
, TREE_TYPE (ovf
), t
,
6179 build_int_cst (NULL_TREE
, words
* UNITS_PER_WORD
));
6180 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6181 TREE_SIDE_EFFECTS (t
) = 1;
6182 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6184 /* If there were no va_arg invocations, don't set up the register
6186 if (!cfun
->va_list_gpr_size
6187 && !cfun
->va_list_fpr_size
6188 && n_gpr
< GP_ARG_NUM_REG
6189 && n_fpr
< FP_ARG_V4_MAX_REG
)
6192 /* Find the register save area. */
6193 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
6194 if (cfun
->machine
->varargs_save_offset
)
6195 t
= build2 (PLUS_EXPR
, TREE_TYPE (sav
), t
,
6196 build_int_cst (NULL_TREE
, cfun
->machine
->varargs_save_offset
));
6197 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (sav
), sav
, t
);
6198 TREE_SIDE_EFFECTS (t
) = 1;
6199 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6202 /* Implement va_arg. */
6205 rs6000_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
6207 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6208 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6209 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
6210 tree lab_false
, lab_over
, addr
;
6212 tree ptrtype
= build_pointer_type (type
);
6215 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6217 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
6218 return build_va_arg_indirect_ref (t
);
6221 if (DEFAULT_ABI
!= ABI_V4
)
6223 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
6225 tree elem_type
= TREE_TYPE (type
);
6226 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
6227 int elem_size
= GET_MODE_SIZE (elem_mode
);
6229 if (elem_size
< UNITS_PER_WORD
)
6231 tree real_part
, imag_part
;
6232 tree post
= NULL_TREE
;
6234 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6236 /* Copy the value into a temporary, lest the formal temporary
6237 be reused out from under us. */
6238 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
6239 append_to_statement_list (post
, pre_p
);
6241 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6244 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
6248 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6251 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6252 f_fpr
= TREE_CHAIN (f_gpr
);
6253 f_res
= TREE_CHAIN (f_fpr
);
6254 f_ovf
= TREE_CHAIN (f_res
);
6255 f_sav
= TREE_CHAIN (f_ovf
);
6257 valist
= build_va_arg_indirect_ref (valist
);
6258 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6259 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6260 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6261 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6263 size
= int_size_in_bytes (type
);
6264 rsize
= (size
+ 3) / 4;
6267 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6268 && (TYPE_MODE (type
) == SFmode
6269 || TYPE_MODE (type
) == DFmode
6270 || TYPE_MODE (type
) == TFmode
6271 || TYPE_MODE (type
) == DDmode
6272 || TYPE_MODE (type
) == TDmode
))
6274 /* FP args go in FP registers, if present. */
6276 n_reg
= (size
+ 7) / 8;
6279 if (TYPE_MODE (type
) != SFmode
)
6284 /* Otherwise into GP registers. */
6293 /* Pull the value out of the saved registers.... */
6296 addr
= create_tmp_var (ptr_type_node
, "addr");
6297 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
6299 /* AltiVec vectors never go in registers when -mabi=altivec. */
6300 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
6304 lab_false
= create_artificial_label ();
6305 lab_over
= create_artificial_label ();
6307 /* Long long and SPE vectors are aligned in the registers.
6308 As are any other 2 gpr item such as complex int due to a
6309 historical mistake. */
6311 if (n_reg
== 2 && reg
== gpr
)
6314 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), reg
,
6315 size_int (n_reg
- 1));
6316 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, u
);
6318 /* _Decimal128 is passed in even/odd fpr pairs; the stored
6319 reg number is 0 for f1, so we want to make it odd. */
6320 else if (reg
== fpr
&& TYPE_MODE (type
) == TDmode
)
6323 t
= build2 (BIT_IOR_EXPR
, TREE_TYPE (reg
), reg
, size_int (1));
6324 u
= build2 (MODIFY_EXPR
, void_type_node
, reg
, t
);
6327 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
6328 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
6329 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
6330 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
6331 gimplify_and_add (t
, pre_p
);
6335 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
6337 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, size_int (n_reg
));
6338 u
= build1 (CONVERT_EXPR
, integer_type_node
, u
);
6339 u
= build2 (MULT_EXPR
, integer_type_node
, u
, size_int (sav_scale
));
6340 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, u
);
6342 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6343 gimplify_and_add (t
, pre_p
);
6345 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
6346 gimplify_and_add (t
, pre_p
);
6348 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
6349 append_to_statement_list (t
, pre_p
);
6351 if ((n_reg
== 2 && !regalign
) || n_reg
> 2)
6353 /* Ensure that we don't find any more args in regs.
6354 Alignment has taken care of for special cases. */
6355 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (reg
), reg
, size_int (8));
6356 gimplify_and_add (t
, pre_p
);
6360 /* ... otherwise out of the overflow area. */
6362 /* Care for on-stack alignment if needed. */
6366 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
6367 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
6368 build_int_cst (NULL_TREE
, -align
));
6370 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
6372 u
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6373 gimplify_and_add (u
, pre_p
);
6375 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
6376 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6377 gimplify_and_add (t
, pre_p
);
6381 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
6382 append_to_statement_list (t
, pre_p
);
6385 if (STRICT_ALIGNMENT
6386 && (TYPE_ALIGN (type
)
6387 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
6389 /* The value (of type complex double, for example) may not be
6390 aligned in memory in the saved registers, so copy via a
6391 temporary. (This is the same code as used for SPARC.) */
6392 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
6393 tree dest_addr
= build_fold_addr_expr (tmp
);
6395 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
6396 3, dest_addr
, addr
, size_int (rsize
* 4));
6398 gimplify_and_add (copy
, pre_p
);
6402 addr
= fold_convert (ptrtype
, addr
);
6403 return build_va_arg_indirect_ref (addr
);
6409 def_builtin (int mask
, const char *name
, tree type
, int code
)
6411 if (mask
& target_flags
)
6413 if (rs6000_builtin_decls
[code
])
6416 rs6000_builtin_decls
[code
] =
6417 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
6422 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6424 static const struct builtin_description bdesc_3arg
[] =
6426 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
6427 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
6428 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
6429 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
6430 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
6431 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
6432 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
6433 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
6434 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
6435 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
6436 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
6437 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
6438 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
6439 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
6440 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
6441 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
6442 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
6443 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
6444 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
6445 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
6446 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
6447 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
6448 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
6450 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
6451 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
6452 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
6453 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
6454 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
6455 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
6456 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
6457 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
6458 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
6459 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
6460 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
6461 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
6462 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
6463 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
6464 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
6467 /* DST operations: void foo (void *, const int, const char). */
6469 static const struct builtin_description bdesc_dst
[] =
6471 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
6472 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
6473 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
6474 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
6476 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
6477 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
6478 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
6479 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
6482 /* Simple binary operations: VECc = foo (VECa, VECb). */
6484 static struct builtin_description bdesc_2arg
[] =
6486 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
6487 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
6488 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
6489 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
6490 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
6491 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
6492 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
6493 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
6494 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
6495 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
6496 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
6497 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
6498 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
6499 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
6500 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
6501 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
6502 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
6503 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
6504 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
6505 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
6506 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
6507 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
6508 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
6509 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
6510 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
6511 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
6512 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
6513 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
6514 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
6515 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
6516 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
6517 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
6518 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
6519 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
6520 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
6521 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
6522 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
6523 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
6524 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
6525 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
6526 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
6527 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
6528 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
6529 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
6530 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
6531 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
6532 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
6533 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
6534 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
6535 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
6536 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
6537 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
6538 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
6539 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
6540 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
6541 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
6542 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
6543 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
6544 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
6545 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
6546 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
6547 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
6548 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
6549 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
6550 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
6551 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
6552 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
6553 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
6554 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
6555 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
6556 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
6557 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
6558 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
6559 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
6560 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
6561 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
6562 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
6563 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
6564 { MASK_ALTIVEC
, CODE_FOR_altivec_vslb
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
6565 { MASK_ALTIVEC
, CODE_FOR_altivec_vslh
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
6566 { MASK_ALTIVEC
, CODE_FOR_altivec_vslw
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
6567 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
6568 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
6569 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
6570 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
6571 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
6572 { MASK_ALTIVEC
, CODE_FOR_lshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
6573 { MASK_ALTIVEC
, CODE_FOR_lshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
6574 { MASK_ALTIVEC
, CODE_FOR_lshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
6575 { MASK_ALTIVEC
, CODE_FOR_ashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
6576 { MASK_ALTIVEC
, CODE_FOR_ashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
6577 { MASK_ALTIVEC
, CODE_FOR_ashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
6578 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
6579 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
6580 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
6581 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
6582 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
6583 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
6584 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
6585 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
6586 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
6587 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
6588 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
6589 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
6590 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
6591 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
6592 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
6593 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
6594 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
6595 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
6596 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
6598 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
6599 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
6600 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
6601 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
6602 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
6603 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
6604 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
6605 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
6606 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
6607 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
6608 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
6609 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
6610 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
6611 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
6612 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
6613 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
6614 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
6615 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
6616 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
6617 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
6618 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
6619 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
6620 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
6621 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
6622 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
6623 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
6624 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
6625 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
6626 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
6627 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
6628 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
6629 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
6630 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
6631 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
6632 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
6633 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
6634 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
6635 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
6636 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
6637 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
6638 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
6639 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
6640 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
6641 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
6642 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
6643 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
6644 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
6645 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
6646 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
6647 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
6648 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
6649 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
6650 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
6651 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
6652 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
6653 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
6654 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
6655 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
6656 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
6657 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
6658 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
6659 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
6660 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
6661 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
6662 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
6663 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
6664 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
6665 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
6666 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
6667 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
6668 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
6669 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
6670 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
6671 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
6672 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
6673 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
6674 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
6675 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
6676 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
6677 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
6678 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
6679 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
6680 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
6681 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
6682 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
6683 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
6684 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
6685 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
6686 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
6687 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
6688 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
6689 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
6690 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
6691 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
6692 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
6693 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
6694 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
6695 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
6696 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
6697 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
6698 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
6699 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
6700 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
6701 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
6702 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
6703 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
6704 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
6705 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
6706 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
6707 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
6708 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
6709 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
6710 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
6711 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
6712 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
6713 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
6714 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
6715 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
6716 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
6717 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
6718 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
6719 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
6720 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
6721 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
6722 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
6723 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
6724 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
6726 /* Place holder, leave as first spe builtin. */
6727 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
6728 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
6729 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
6730 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
6731 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
6732 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
6733 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
6734 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
6735 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
6736 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
6737 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
6738 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
6739 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
6740 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
6741 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
6742 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
6743 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
6744 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
6745 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
6746 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
6747 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
6748 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
6749 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
6750 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
6751 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
6752 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
6753 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
6754 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
6755 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
6756 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
6757 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
6758 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
6759 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
6760 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
6761 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
6762 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
6763 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
6764 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
6765 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
6766 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
6767 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
6768 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
6769 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
6770 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
6771 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
6772 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
6773 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
6774 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
6775 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
6776 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
6777 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
6778 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
6779 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
6780 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
6781 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
6782 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
6783 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
6784 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
6785 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
6786 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
6787 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
6788 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
6789 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
6790 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
6791 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
6792 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
6793 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
6794 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
6795 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
6796 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
6797 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
6798 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
6799 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
6800 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
6801 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
6802 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
6803 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
6804 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
6805 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
6806 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
6807 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
6808 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
6809 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
6810 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
6811 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
6812 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
6813 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
6814 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
6815 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
6816 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
6817 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
6818 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
6819 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
6820 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
6821 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
6822 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
6823 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
6824 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
6825 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
6826 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
6827 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
6828 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
6829 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
6830 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
6831 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
6832 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
6833 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
6834 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
6835 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
6837 /* SPE binary operations expecting a 5-bit unsigned literal. */
6838 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
6840 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
6841 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
6842 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
6843 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
6844 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
6845 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
6846 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
6847 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
6848 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
6849 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
6850 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
6851 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
6852 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
6853 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
6854 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
6855 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
6856 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
6857 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
6858 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
6859 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
6860 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
6861 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
6862 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
6863 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
6864 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
6865 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
6867 /* Place-holder. Leave as last binary SPE builtin. */
6868 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
6871 /* AltiVec predicates. */
6873 struct builtin_description_predicates
6875 const unsigned int mask
;
6876 const enum insn_code icode
;
6878 const char *const name
;
6879 const enum rs6000_builtins code
;
6882 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
6884 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
6885 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
6886 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
6887 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
6888 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
6889 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
6890 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
6891 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
6892 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
6893 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
6894 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
6895 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
6896 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
6898 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
6899 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
6900 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
6903 /* SPE predicates. */
6904 static struct builtin_description bdesc_spe_predicates
[] =
6906 /* Place-holder. Leave as first. */
6907 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
6908 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
6909 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
6910 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
6911 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
6912 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
6913 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
6914 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
6915 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
6916 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
6917 /* Place-holder. Leave as last. */
6918 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
6921 /* SPE evsel predicates. */
6922 static struct builtin_description bdesc_spe_evsel
[] =
6924 /* Place-holder. Leave as first. */
6925 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
6926 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
6927 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
6928 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
6929 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
6930 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
6931 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
6932 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
6933 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
6934 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
6935 /* Place-holder. Leave as last. */
6936 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
6939 /* ABS* operations. */
6941 static const struct builtin_description bdesc_abs
[] =
6943 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
6944 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
6945 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
6946 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
6947 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
6948 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
6949 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
6952 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6955 static struct builtin_description bdesc_1arg
[] =
6957 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
6958 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
6959 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
6960 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
6961 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
6962 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
6963 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
6964 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
6965 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
6966 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
6967 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
6968 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
6969 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
6970 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
6971 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
6972 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
6973 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
6975 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
6976 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
6977 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
6978 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
6979 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
6980 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
6981 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
6982 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
6983 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
6984 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
6985 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
6986 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
6987 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
6988 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
6989 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
6990 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
6991 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
6992 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
6993 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
6995 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6996 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6997 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
6998 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
6999 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
7000 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
7001 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
7002 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
7003 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
7004 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
7005 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
7006 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
7007 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
7008 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
7009 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
7010 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
7011 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
7012 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
7013 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
7014 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
7015 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
7016 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
7017 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
7018 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
7019 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
7020 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
7021 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
7022 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
7023 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
7024 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
7026 /* Place-holder. Leave as last unary SPE builtin. */
7027 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
}
7031 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7034 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7035 rtx op0
= expand_normal (arg0
);
7036 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7037 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7039 if (icode
== CODE_FOR_nothing
)
7040 /* Builtin not supported on this processor. */
7043 /* If we got invalid arguments bail out before generating bad rtl. */
7044 if (arg0
== error_mark_node
)
7047 if (icode
== CODE_FOR_altivec_vspltisb
7048 || icode
== CODE_FOR_altivec_vspltish
7049 || icode
== CODE_FOR_altivec_vspltisw
7050 || icode
== CODE_FOR_spe_evsplatfi
7051 || icode
== CODE_FOR_spe_evsplati
)
7053 /* Only allow 5-bit *signed* literals. */
7054 if (GET_CODE (op0
) != CONST_INT
7055 || INTVAL (op0
) > 15
7056 || INTVAL (op0
) < -16)
7058 error ("argument 1 must be a 5-bit signed literal");
7064 || GET_MODE (target
) != tmode
7065 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7066 target
= gen_reg_rtx (tmode
);
7068 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7069 op0
= copy_to_mode_reg (mode0
, op0
);
7071 pat
= GEN_FCN (icode
) (target
, op0
);
7080 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
7082 rtx pat
, scratch1
, scratch2
;
7083 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7084 rtx op0
= expand_normal (arg0
);
7085 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7086 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7088 /* If we have invalid arguments, bail out before generating bad rtl. */
7089 if (arg0
== error_mark_node
)
7093 || GET_MODE (target
) != tmode
7094 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7095 target
= gen_reg_rtx (tmode
);
7097 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7098 op0
= copy_to_mode_reg (mode0
, op0
);
7100 scratch1
= gen_reg_rtx (mode0
);
7101 scratch2
= gen_reg_rtx (mode0
);
7103 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
7112 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7115 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7116 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7117 rtx op0
= expand_normal (arg0
);
7118 rtx op1
= expand_normal (arg1
);
7119 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7120 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7121 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7123 if (icode
== CODE_FOR_nothing
)
7124 /* Builtin not supported on this processor. */
7127 /* If we got invalid arguments bail out before generating bad rtl. */
7128 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7131 if (icode
== CODE_FOR_altivec_vcfux
7132 || icode
== CODE_FOR_altivec_vcfsx
7133 || icode
== CODE_FOR_altivec_vctsxs
7134 || icode
== CODE_FOR_altivec_vctuxs
7135 || icode
== CODE_FOR_altivec_vspltb
7136 || icode
== CODE_FOR_altivec_vsplth
7137 || icode
== CODE_FOR_altivec_vspltw
7138 || icode
== CODE_FOR_spe_evaddiw
7139 || icode
== CODE_FOR_spe_evldd
7140 || icode
== CODE_FOR_spe_evldh
7141 || icode
== CODE_FOR_spe_evldw
7142 || icode
== CODE_FOR_spe_evlhhesplat
7143 || icode
== CODE_FOR_spe_evlhhossplat
7144 || icode
== CODE_FOR_spe_evlhhousplat
7145 || icode
== CODE_FOR_spe_evlwhe
7146 || icode
== CODE_FOR_spe_evlwhos
7147 || icode
== CODE_FOR_spe_evlwhou
7148 || icode
== CODE_FOR_spe_evlwhsplat
7149 || icode
== CODE_FOR_spe_evlwwsplat
7150 || icode
== CODE_FOR_spe_evrlwi
7151 || icode
== CODE_FOR_spe_evslwi
7152 || icode
== CODE_FOR_spe_evsrwis
7153 || icode
== CODE_FOR_spe_evsubifw
7154 || icode
== CODE_FOR_spe_evsrwiu
)
7156 /* Only allow 5-bit unsigned literals. */
7158 if (TREE_CODE (arg1
) != INTEGER_CST
7159 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7161 error ("argument 2 must be a 5-bit unsigned literal");
7167 || GET_MODE (target
) != tmode
7168 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7169 target
= gen_reg_rtx (tmode
);
7171 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7172 op0
= copy_to_mode_reg (mode0
, op0
);
7173 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7174 op1
= copy_to_mode_reg (mode1
, op1
);
7176 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
7185 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
7186 tree exp
, rtx target
)
7189 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
7190 tree arg0
= CALL_EXPR_ARG (exp
, 1);
7191 tree arg1
= CALL_EXPR_ARG (exp
, 2);
7192 rtx op0
= expand_normal (arg0
);
7193 rtx op1
= expand_normal (arg1
);
7194 enum machine_mode tmode
= SImode
;
7195 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7196 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7199 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
7201 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7205 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
7207 gcc_assert (mode0
== mode1
);
7209 /* If we have invalid arguments, bail out before generating bad rtl. */
7210 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7214 || GET_MODE (target
) != tmode
7215 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7216 target
= gen_reg_rtx (tmode
);
7218 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7219 op0
= copy_to_mode_reg (mode0
, op0
);
7220 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7221 op1
= copy_to_mode_reg (mode1
, op1
);
7223 scratch
= gen_reg_rtx (mode0
);
7225 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
7226 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
7231 /* The vec_any* and vec_all* predicates use the same opcodes for two
7232 different operations, but the bits in CR6 will be different
7233 depending on what information we want. So we have to play tricks
7234 with CR6 to get the right bits out.
7236 If you think this is disgusting, look at the specs for the
7237 AltiVec predicates. */
7239 switch (cr6_form_int
)
7242 emit_insn (gen_cr6_test_for_zero (target
));
7245 emit_insn (gen_cr6_test_for_zero_reverse (target
));
7248 emit_insn (gen_cr6_test_for_lt (target
));
7251 emit_insn (gen_cr6_test_for_lt_reverse (target
));
7254 error ("argument 1 of __builtin_altivec_predicate is out of range");
7262 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
7265 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7266 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7267 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7268 enum machine_mode mode0
= Pmode
;
7269 enum machine_mode mode1
= Pmode
;
7270 rtx op0
= expand_normal (arg0
);
7271 rtx op1
= expand_normal (arg1
);
7273 if (icode
== CODE_FOR_nothing
)
7274 /* Builtin not supported on this processor. */
7277 /* If we got invalid arguments bail out before generating bad rtl. */
7278 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7282 || GET_MODE (target
) != tmode
7283 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7284 target
= gen_reg_rtx (tmode
);
7286 op1
= copy_to_mode_reg (mode1
, op1
);
7288 if (op0
== const0_rtx
)
7290 addr
= gen_rtx_MEM (tmode
, op1
);
7294 op0
= copy_to_mode_reg (mode0
, op0
);
7295 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
7298 pat
= GEN_FCN (icode
) (target
, addr
);
7308 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
7310 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7311 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7312 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7313 rtx op0
= expand_normal (arg0
);
7314 rtx op1
= expand_normal (arg1
);
7315 rtx op2
= expand_normal (arg2
);
7317 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
7318 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
7319 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
7321 /* Invalid arguments. Bail before doing anything stoopid! */
7322 if (arg0
== error_mark_node
7323 || arg1
== error_mark_node
7324 || arg2
== error_mark_node
)
7327 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
7328 op0
= copy_to_mode_reg (mode2
, op0
);
7329 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
7330 op1
= copy_to_mode_reg (mode0
, op1
);
7331 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
7332 op2
= copy_to_mode_reg (mode1
, op2
);
7334 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
7341 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
7343 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7344 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7345 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7346 rtx op0
= expand_normal (arg0
);
7347 rtx op1
= expand_normal (arg1
);
7348 rtx op2
= expand_normal (arg2
);
7350 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7351 enum machine_mode mode1
= Pmode
;
7352 enum machine_mode mode2
= Pmode
;
7354 /* Invalid arguments. Bail before doing anything stoopid! */
7355 if (arg0
== error_mark_node
7356 || arg1
== error_mark_node
7357 || arg2
== error_mark_node
)
7360 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
7361 op0
= copy_to_mode_reg (tmode
, op0
);
7363 op2
= copy_to_mode_reg (mode2
, op2
);
7365 if (op1
== const0_rtx
)
7367 addr
= gen_rtx_MEM (tmode
, op2
);
7371 op1
= copy_to_mode_reg (mode1
, op1
);
7372 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
7375 pat
= GEN_FCN (icode
) (addr
, op0
);
7382 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7385 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7386 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7387 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7388 rtx op0
= expand_normal (arg0
);
7389 rtx op1
= expand_normal (arg1
);
7390 rtx op2
= expand_normal (arg2
);
7391 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7392 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7393 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7394 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
7396 if (icode
== CODE_FOR_nothing
)
7397 /* Builtin not supported on this processor. */
7400 /* If we got invalid arguments bail out before generating bad rtl. */
7401 if (arg0
== error_mark_node
7402 || arg1
== error_mark_node
7403 || arg2
== error_mark_node
)
7406 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
7407 || icode
== CODE_FOR_altivec_vsldoi_v4si
7408 || icode
== CODE_FOR_altivec_vsldoi_v8hi
7409 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
7411 /* Only allow 4-bit unsigned literals. */
7413 if (TREE_CODE (arg2
) != INTEGER_CST
7414 || TREE_INT_CST_LOW (arg2
) & ~0xf)
7416 error ("argument 3 must be a 4-bit unsigned literal");
7422 || GET_MODE (target
) != tmode
7423 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7424 target
= gen_reg_rtx (tmode
);
7426 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7427 op0
= copy_to_mode_reg (mode0
, op0
);
7428 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7429 op1
= copy_to_mode_reg (mode1
, op1
);
7430 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
7431 op2
= copy_to_mode_reg (mode2
, op2
);
7433 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
7441 /* Expand the lvx builtins. */
7443 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
7445 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7446 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7448 enum machine_mode tmode
, mode0
;
7450 enum insn_code icode
;
7454 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
7455 icode
= CODE_FOR_altivec_lvx_v16qi
;
7457 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
7458 icode
= CODE_FOR_altivec_lvx_v8hi
;
7460 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
7461 icode
= CODE_FOR_altivec_lvx_v4si
;
7463 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
7464 icode
= CODE_FOR_altivec_lvx_v4sf
;
7473 arg0
= CALL_EXPR_ARG (exp
, 0);
7474 op0
= expand_normal (arg0
);
7475 tmode
= insn_data
[icode
].operand
[0].mode
;
7476 mode0
= insn_data
[icode
].operand
[1].mode
;
7479 || GET_MODE (target
) != tmode
7480 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7481 target
= gen_reg_rtx (tmode
);
7483 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7484 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
7486 pat
= GEN_FCN (icode
) (target
, op0
);
7493 /* Expand the stvx builtins. */
7495 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
7498 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7499 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7501 enum machine_mode mode0
, mode1
;
7503 enum insn_code icode
;
7507 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
7508 icode
= CODE_FOR_altivec_stvx_v16qi
;
7510 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
7511 icode
= CODE_FOR_altivec_stvx_v8hi
;
7513 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
7514 icode
= CODE_FOR_altivec_stvx_v4si
;
7516 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
7517 icode
= CODE_FOR_altivec_stvx_v4sf
;
7524 arg0
= CALL_EXPR_ARG (exp
, 0);
7525 arg1
= CALL_EXPR_ARG (exp
, 1);
7526 op0
= expand_normal (arg0
);
7527 op1
= expand_normal (arg1
);
7528 mode0
= insn_data
[icode
].operand
[0].mode
;
7529 mode1
= insn_data
[icode
].operand
[1].mode
;
7531 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7532 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
7533 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
7534 op1
= copy_to_mode_reg (mode1
, op1
);
7536 pat
= GEN_FCN (icode
) (op0
, op1
);
7544 /* Expand the dst builtins. */
7546 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
7549 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7550 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7551 tree arg0
, arg1
, arg2
;
7552 enum machine_mode mode0
, mode1
, mode2
;
7553 rtx pat
, op0
, op1
, op2
;
7554 struct builtin_description
*d
;
7559 /* Handle DST variants. */
7560 d
= (struct builtin_description
*) bdesc_dst
;
7561 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
7562 if (d
->code
== fcode
)
7564 arg0
= CALL_EXPR_ARG (exp
, 0);
7565 arg1
= CALL_EXPR_ARG (exp
, 1);
7566 arg2
= CALL_EXPR_ARG (exp
, 2);
7567 op0
= expand_normal (arg0
);
7568 op1
= expand_normal (arg1
);
7569 op2
= expand_normal (arg2
);
7570 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
7571 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
7572 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
7574 /* Invalid arguments, bail out before generating bad rtl. */
7575 if (arg0
== error_mark_node
7576 || arg1
== error_mark_node
7577 || arg2
== error_mark_node
)
7582 if (TREE_CODE (arg2
) != INTEGER_CST
7583 || TREE_INT_CST_LOW (arg2
) & ~0x3)
7585 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
7589 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
7590 op0
= copy_to_mode_reg (Pmode
, op0
);
7591 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
7592 op1
= copy_to_mode_reg (mode1
, op1
);
7594 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
7604 /* Expand vec_init builtin. */
7606 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
7608 enum machine_mode tmode
= TYPE_MODE (type
);
7609 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
7610 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
7611 rtvec v
= rtvec_alloc (n_elt
);
7613 gcc_assert (VECTOR_MODE_P (tmode
));
7614 gcc_assert (n_elt
== call_expr_nargs (exp
));
7616 for (i
= 0; i
< n_elt
; ++i
)
7618 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
7619 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
7622 if (!target
|| !register_operand (target
, tmode
))
7623 target
= gen_reg_rtx (tmode
);
7625 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
7629 /* Return the integer constant in ARG. Constrain it to be in the range
7630 of the subparts of VEC_TYPE; issue an error if not. */
7633 get_element_number (tree vec_type
, tree arg
)
7635 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
7637 if (!host_integerp (arg
, 1)
7638 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
7640 error ("selector must be an integer constant in the range 0..%wi", max
);
7647 /* Expand vec_set builtin. */
7649 altivec_expand_vec_set_builtin (tree exp
)
7651 enum machine_mode tmode
, mode1
;
7652 tree arg0
, arg1
, arg2
;
7656 arg0
= CALL_EXPR_ARG (exp
, 0);
7657 arg1
= CALL_EXPR_ARG (exp
, 1);
7658 arg2
= CALL_EXPR_ARG (exp
, 2);
7660 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
7661 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7662 gcc_assert (VECTOR_MODE_P (tmode
));
7664 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, 0);
7665 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, 0);
7666 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
7668 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
7669 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
7671 op0
= force_reg (tmode
, op0
);
7672 op1
= force_reg (mode1
, op1
);
7674 rs6000_expand_vector_set (op0
, op1
, elt
);
7679 /* Expand vec_ext builtin. */
7681 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
7683 enum machine_mode tmode
, mode0
;
7688 arg0
= CALL_EXPR_ARG (exp
, 0);
7689 arg1
= CALL_EXPR_ARG (exp
, 1);
7691 op0
= expand_normal (arg0
);
7692 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
7694 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7695 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
7696 gcc_assert (VECTOR_MODE_P (mode0
));
7698 op0
= force_reg (mode0
, op0
);
7700 if (optimize
|| !target
|| !register_operand (target
, tmode
))
7701 target
= gen_reg_rtx (tmode
);
7703 rs6000_expand_vector_extract (target
, op0
, elt
);
7708 /* Expand the builtin in EXP and store the result in TARGET. Store
7709 true in *EXPANDEDP if we found a builtin to expand. */
7711 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7713 struct builtin_description
*d
;
7714 struct builtin_description_predicates
*dp
;
7716 enum insn_code icode
;
7717 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7720 enum machine_mode tmode
, mode0
;
7721 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7723 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7724 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
7727 error ("unresolved overload for Altivec builtin %qF", fndecl
);
7731 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
7735 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
7739 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
7747 case ALTIVEC_BUILTIN_STVX
:
7748 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
7749 case ALTIVEC_BUILTIN_STVEBX
:
7750 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
7751 case ALTIVEC_BUILTIN_STVEHX
:
7752 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
7753 case ALTIVEC_BUILTIN_STVEWX
:
7754 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
7755 case ALTIVEC_BUILTIN_STVXL
:
7756 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
7758 case ALTIVEC_BUILTIN_MFVSCR
:
7759 icode
= CODE_FOR_altivec_mfvscr
;
7760 tmode
= insn_data
[icode
].operand
[0].mode
;
7763 || GET_MODE (target
) != tmode
7764 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7765 target
= gen_reg_rtx (tmode
);
7767 pat
= GEN_FCN (icode
) (target
);
7773 case ALTIVEC_BUILTIN_MTVSCR
:
7774 icode
= CODE_FOR_altivec_mtvscr
;
7775 arg0
= CALL_EXPR_ARG (exp
, 0);
7776 op0
= expand_normal (arg0
);
7777 mode0
= insn_data
[icode
].operand
[0].mode
;
7779 /* If we got invalid arguments bail out before generating bad rtl. */
7780 if (arg0
== error_mark_node
)
7783 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7784 op0
= copy_to_mode_reg (mode0
, op0
);
7786 pat
= GEN_FCN (icode
) (op0
);
7791 case ALTIVEC_BUILTIN_DSSALL
:
7792 emit_insn (gen_altivec_dssall ());
7795 case ALTIVEC_BUILTIN_DSS
:
7796 icode
= CODE_FOR_altivec_dss
;
7797 arg0
= CALL_EXPR_ARG (exp
, 0);
7799 op0
= expand_normal (arg0
);
7800 mode0
= insn_data
[icode
].operand
[0].mode
;
7802 /* If we got invalid arguments bail out before generating bad rtl. */
7803 if (arg0
== error_mark_node
)
7806 if (TREE_CODE (arg0
) != INTEGER_CST
7807 || TREE_INT_CST_LOW (arg0
) & ~0x3)
7809 error ("argument to dss must be a 2-bit unsigned literal");
7813 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7814 op0
= copy_to_mode_reg (mode0
, op0
);
7816 emit_insn (gen_altivec_dss (op0
));
7819 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
7820 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
7821 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
7822 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
7823 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
7825 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
7826 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
7827 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
7828 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
7829 return altivec_expand_vec_set_builtin (exp
);
7831 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
7832 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
7833 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
7834 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
7835 return altivec_expand_vec_ext_builtin (exp
, target
);
7842 /* Expand abs* operations. */
7843 d
= (struct builtin_description
*) bdesc_abs
;
7844 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
7845 if (d
->code
== fcode
)
7846 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
7848 /* Expand the AltiVec predicates. */
7849 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
7850 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
7851 if (dp
->code
== fcode
)
7852 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
7855 /* LV* are funky. We initialized them differently. */
7858 case ALTIVEC_BUILTIN_LVSL
:
7859 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
7861 case ALTIVEC_BUILTIN_LVSR
:
7862 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
7864 case ALTIVEC_BUILTIN_LVEBX
:
7865 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
7867 case ALTIVEC_BUILTIN_LVEHX
:
7868 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
7870 case ALTIVEC_BUILTIN_LVEWX
:
7871 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
7873 case ALTIVEC_BUILTIN_LVXL
:
7874 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
7876 case ALTIVEC_BUILTIN_LVX
:
7877 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
7888 /* Binops that need to be initialized manually, but can be expanded
7889 automagically by rs6000_expand_binop_builtin. */
7890 static struct builtin_description bdesc_2arg_spe
[] =
7892 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
7893 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
7894 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
7895 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
7896 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
7897 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
7898 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
7899 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
7900 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
7901 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
7902 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
7903 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
7904 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
7905 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
7906 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
7907 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
7908 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
7909 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
7910 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
7911 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
7912 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
7913 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
7916 /* Expand the builtin in EXP and store the result in TARGET. Store
7917 true in *EXPANDEDP if we found a builtin to expand.
7919 This expands the SPE builtins that are not simple unary and binary
7922 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7924 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7926 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7927 enum insn_code icode
;
7928 enum machine_mode tmode
, mode0
;
7930 struct builtin_description
*d
;
7935 /* Syntax check for a 5-bit unsigned immediate. */
7938 case SPE_BUILTIN_EVSTDD
:
7939 case SPE_BUILTIN_EVSTDH
:
7940 case SPE_BUILTIN_EVSTDW
:
7941 case SPE_BUILTIN_EVSTWHE
:
7942 case SPE_BUILTIN_EVSTWHO
:
7943 case SPE_BUILTIN_EVSTWWE
:
7944 case SPE_BUILTIN_EVSTWWO
:
7945 arg1
= CALL_EXPR_ARG (exp
, 2);
7946 if (TREE_CODE (arg1
) != INTEGER_CST
7947 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7949 error ("argument 2 must be a 5-bit unsigned literal");
7957 /* The evsplat*i instructions are not quite generic. */
7960 case SPE_BUILTIN_EVSPLATFI
:
7961 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
7963 case SPE_BUILTIN_EVSPLATI
:
7964 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
7970 d
= (struct builtin_description
*) bdesc_2arg_spe
;
7971 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
7972 if (d
->code
== fcode
)
7973 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
7975 d
= (struct builtin_description
*) bdesc_spe_predicates
;
7976 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
7977 if (d
->code
== fcode
)
7978 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
7980 d
= (struct builtin_description
*) bdesc_spe_evsel
;
7981 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
7982 if (d
->code
== fcode
)
7983 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
7987 case SPE_BUILTIN_EVSTDDX
:
7988 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
7989 case SPE_BUILTIN_EVSTDHX
:
7990 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
7991 case SPE_BUILTIN_EVSTDWX
:
7992 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
7993 case SPE_BUILTIN_EVSTWHEX
:
7994 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
7995 case SPE_BUILTIN_EVSTWHOX
:
7996 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
7997 case SPE_BUILTIN_EVSTWWEX
:
7998 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
7999 case SPE_BUILTIN_EVSTWWOX
:
8000 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
8001 case SPE_BUILTIN_EVSTDD
:
8002 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
8003 case SPE_BUILTIN_EVSTDH
:
8004 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
8005 case SPE_BUILTIN_EVSTDW
:
8006 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
8007 case SPE_BUILTIN_EVSTWHE
:
8008 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
8009 case SPE_BUILTIN_EVSTWHO
:
8010 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
8011 case SPE_BUILTIN_EVSTWWE
:
8012 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
8013 case SPE_BUILTIN_EVSTWWO
:
8014 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
8015 case SPE_BUILTIN_MFSPEFSCR
:
8016 icode
= CODE_FOR_spe_mfspefscr
;
8017 tmode
= insn_data
[icode
].operand
[0].mode
;
8020 || GET_MODE (target
) != tmode
8021 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8022 target
= gen_reg_rtx (tmode
);
8024 pat
= GEN_FCN (icode
) (target
);
8029 case SPE_BUILTIN_MTSPEFSCR
:
8030 icode
= CODE_FOR_spe_mtspefscr
;
8031 arg0
= CALL_EXPR_ARG (exp
, 0);
8032 op0
= expand_normal (arg0
);
8033 mode0
= insn_data
[icode
].operand
[0].mode
;
8035 if (arg0
== error_mark_node
)
8038 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
8039 op0
= copy_to_mode_reg (mode0
, op0
);
8041 pat
= GEN_FCN (icode
) (op0
);
8054 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
8056 rtx pat
, scratch
, tmp
;
8057 tree form
= CALL_EXPR_ARG (exp
, 0);
8058 tree arg0
= CALL_EXPR_ARG (exp
, 1);
8059 tree arg1
= CALL_EXPR_ARG (exp
, 2);
8060 rtx op0
= expand_normal (arg0
);
8061 rtx op1
= expand_normal (arg1
);
8062 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8063 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8067 if (TREE_CODE (form
) != INTEGER_CST
)
8069 error ("argument 1 of __builtin_spe_predicate must be a constant");
8073 form_int
= TREE_INT_CST_LOW (form
);
8075 gcc_assert (mode0
== mode1
);
8077 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
8081 || GET_MODE (target
) != SImode
8082 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
8083 target
= gen_reg_rtx (SImode
);
8085 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8086 op0
= copy_to_mode_reg (mode0
, op0
);
8087 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
8088 op1
= copy_to_mode_reg (mode1
, op1
);
8090 scratch
= gen_reg_rtx (CCmode
);
8092 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8097 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8098 _lower_. We use one compare, but look in different bits of the
8099 CR for each variant.
8101 There are 2 elements in each SPE simd type (upper/lower). The CR
8102 bits are set as follows:
8104 BIT0 | BIT 1 | BIT 2 | BIT 3
8105 U | L | (U | L) | (U & L)
8107 So, for an "all" relationship, BIT 3 would be set.
8108 For an "any" relationship, BIT 2 would be set. Etc.
8110 Following traditional nomenclature, these bits map to:
8112 BIT0 | BIT 1 | BIT 2 | BIT 3
8115 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8120 /* All variant. OV bit. */
8122 /* We need to get to the OV bit, which is the ORDERED bit. We
8123 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8124 that's ugly and will make validate_condition_mode die.
8125 So let's just use another pattern. */
8126 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
8128 /* Any variant. EQ bit. */
8132 /* Upper variant. LT bit. */
8136 /* Lower variant. GT bit. */
8141 error ("argument 1 of __builtin_spe_predicate is out of range");
8145 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
8146 emit_move_insn (target
, tmp
);
8151 /* The evsel builtins look like this:
8153 e = __builtin_spe_evsel_OP (a, b, c, d);
8157 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8158 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8162 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
8165 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8166 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8167 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8168 tree arg3
= CALL_EXPR_ARG (exp
, 3);
8169 rtx op0
= expand_normal (arg0
);
8170 rtx op1
= expand_normal (arg1
);
8171 rtx op2
= expand_normal (arg2
);
8172 rtx op3
= expand_normal (arg3
);
8173 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8174 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8176 gcc_assert (mode0
== mode1
);
8178 if (arg0
== error_mark_node
|| arg1
== error_mark_node
8179 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
8183 || GET_MODE (target
) != mode0
8184 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
8185 target
= gen_reg_rtx (mode0
);
8187 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8188 op0
= copy_to_mode_reg (mode0
, op0
);
8189 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8190 op1
= copy_to_mode_reg (mode0
, op1
);
8191 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
8192 op2
= copy_to_mode_reg (mode0
, op2
);
8193 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
8194 op3
= copy_to_mode_reg (mode0
, op3
);
8196 /* Generate the compare. */
8197 scratch
= gen_reg_rtx (CCmode
);
8198 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8203 if (mode0
== V2SImode
)
8204 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
8206 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
8211 /* Expand an expression EXP that calls a built-in function,
8212 with result going to TARGET if that's convenient
8213 (and in mode MODE if that's convenient).
8214 SUBTARGET may be used as the target for computing one of EXP's operands.
8215 IGNORE is nonzero if the value is to be ignored. */
8218 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8219 enum machine_mode mode ATTRIBUTE_UNUSED
,
8220 int ignore ATTRIBUTE_UNUSED
)
8222 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8223 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8224 struct builtin_description
*d
;
8229 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
8230 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
8232 int icode
= (int) CODE_FOR_altivec_lvsr
;
8233 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8234 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
8238 gcc_assert (TARGET_ALTIVEC
);
8240 arg
= CALL_EXPR_ARG (exp
, 0);
8241 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
8242 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
8243 addr
= memory_address (mode
, op
);
8244 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
8248 /* For the load case need to negate the address. */
8249 op
= gen_reg_rtx (GET_MODE (addr
));
8250 emit_insn (gen_rtx_SET (VOIDmode
, op
,
8251 gen_rtx_NEG (GET_MODE (addr
), addr
)));
8253 op
= gen_rtx_MEM (mode
, op
);
8256 || GET_MODE (target
) != tmode
8257 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8258 target
= gen_reg_rtx (tmode
);
8260 /*pat = gen_altivec_lvsr (target, op);*/
8261 pat
= GEN_FCN (icode
) (target
, op
);
8269 /* FIXME: There's got to be a nicer way to handle this case than
8270 constructing a new CALL_EXPR. */
8271 if (fcode
== ALTIVEC_BUILTIN_VCFUX
8272 || fcode
== ALTIVEC_BUILTIN_VCFSX
)
8274 if (call_expr_nargs (exp
) == 1)
8275 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
8276 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
8281 ret
= altivec_expand_builtin (exp
, target
, &success
);
8288 ret
= spe_expand_builtin (exp
, target
, &success
);
8294 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
);
8296 /* Handle simple unary operations. */
8297 d
= (struct builtin_description
*) bdesc_1arg
;
8298 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
8299 if (d
->code
== fcode
)
8300 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
8302 /* Handle simple binary operations. */
8303 d
= (struct builtin_description
*) bdesc_2arg
;
8304 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
8305 if (d
->code
== fcode
)
8306 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
8308 /* Handle simple ternary operations. */
8309 d
= (struct builtin_description
*) bdesc_3arg
;
8310 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
8311 if (d
->code
== fcode
)
8312 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
8318 build_opaque_vector_type (tree node
, int nunits
)
8320 node
= copy_node (node
);
8321 TYPE_MAIN_VARIANT (node
) = node
;
8322 return build_vector_type (node
, nunits
);
8326 rs6000_init_builtins (void)
8328 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
8329 V2SF_type_node
= build_vector_type (float_type_node
, 2);
8330 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
8331 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
8332 V4SF_type_node
= build_vector_type (float_type_node
, 4);
8333 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
8334 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
8336 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
8337 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
8338 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
8340 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
8341 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
8342 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
8343 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
8345 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
8346 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
8347 'vector unsigned short'. */
8349 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
8350 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
8351 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
8352 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
8354 long_integer_type_internal_node
= long_integer_type_node
;
8355 long_unsigned_type_internal_node
= long_unsigned_type_node
;
8356 intQI_type_internal_node
= intQI_type_node
;
8357 uintQI_type_internal_node
= unsigned_intQI_type_node
;
8358 intHI_type_internal_node
= intHI_type_node
;
8359 uintHI_type_internal_node
= unsigned_intHI_type_node
;
8360 intSI_type_internal_node
= intSI_type_node
;
8361 uintSI_type_internal_node
= unsigned_intSI_type_node
;
8362 float_type_internal_node
= float_type_node
;
8363 void_type_internal_node
= void_type_node
;
8365 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8366 get_identifier ("__bool char"),
8367 bool_char_type_node
));
8368 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8369 get_identifier ("__bool short"),
8370 bool_short_type_node
));
8371 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8372 get_identifier ("__bool int"),
8373 bool_int_type_node
));
8374 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8375 get_identifier ("__pixel"),
8378 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
8379 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
8380 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
8381 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
8383 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8384 get_identifier ("__vector unsigned char"),
8385 unsigned_V16QI_type_node
));
8386 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8387 get_identifier ("__vector signed char"),
8389 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8390 get_identifier ("__vector __bool char"),
8391 bool_V16QI_type_node
));
8393 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8394 get_identifier ("__vector unsigned short"),
8395 unsigned_V8HI_type_node
));
8396 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8397 get_identifier ("__vector signed short"),
8399 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8400 get_identifier ("__vector __bool short"),
8401 bool_V8HI_type_node
));
8403 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8404 get_identifier ("__vector unsigned int"),
8405 unsigned_V4SI_type_node
));
8406 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8407 get_identifier ("__vector signed int"),
8409 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8410 get_identifier ("__vector __bool int"),
8411 bool_V4SI_type_node
));
8413 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8414 get_identifier ("__vector float"),
8416 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8417 get_identifier ("__vector __pixel"),
8418 pixel_V8HI_type_node
));
8421 spe_init_builtins ();
8423 altivec_init_builtins ();
8424 if (TARGET_ALTIVEC
|| TARGET_SPE
)
8425 rs6000_common_init_builtins ();
8428 /* AIX libm provides clog as __clog. */
8429 if (built_in_decls
[BUILT_IN_CLOG
])
8430 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
8434 /* Search through a set of builtins and enable the mask bits.
8435 DESC is an array of builtins.
8436 SIZE is the total number of builtins.
8437 START is the builtin enum at which to start.
8438 END is the builtin enum at which to end. */
8440 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
8441 enum rs6000_builtins start
,
8442 enum rs6000_builtins end
)
8446 for (i
= 0; i
< size
; ++i
)
8447 if (desc
[i
].code
== start
)
8453 for (; i
< size
; ++i
)
8455 /* Flip all the bits on. */
8456 desc
[i
].mask
= target_flags
;
8457 if (desc
[i
].code
== end
)
8463 spe_init_builtins (void)
8465 tree endlink
= void_list_node
;
8466 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
8467 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
8468 struct builtin_description
*d
;
8471 tree v2si_ftype_4_v2si
8472 = build_function_type
8473 (opaque_V2SI_type_node
,
8474 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8475 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8476 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8477 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8480 tree v2sf_ftype_4_v2sf
8481 = build_function_type
8482 (opaque_V2SF_type_node
,
8483 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8484 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8485 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8486 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8489 tree int_ftype_int_v2si_v2si
8490 = build_function_type
8492 tree_cons (NULL_TREE
, integer_type_node
,
8493 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8494 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8497 tree int_ftype_int_v2sf_v2sf
8498 = build_function_type
8500 tree_cons (NULL_TREE
, integer_type_node
,
8501 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8502 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8505 tree void_ftype_v2si_puint_int
8506 = build_function_type (void_type_node
,
8507 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8508 tree_cons (NULL_TREE
, puint_type_node
,
8509 tree_cons (NULL_TREE
,
8513 tree void_ftype_v2si_puint_char
8514 = build_function_type (void_type_node
,
8515 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8516 tree_cons (NULL_TREE
, puint_type_node
,
8517 tree_cons (NULL_TREE
,
8521 tree void_ftype_v2si_pv2si_int
8522 = build_function_type (void_type_node
,
8523 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8524 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8525 tree_cons (NULL_TREE
,
8529 tree void_ftype_v2si_pv2si_char
8530 = build_function_type (void_type_node
,
8531 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8532 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8533 tree_cons (NULL_TREE
,
8538 = build_function_type (void_type_node
,
8539 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
8542 = build_function_type (integer_type_node
, endlink
);
8544 tree v2si_ftype_pv2si_int
8545 = build_function_type (opaque_V2SI_type_node
,
8546 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8547 tree_cons (NULL_TREE
, integer_type_node
,
8550 tree v2si_ftype_puint_int
8551 = build_function_type (opaque_V2SI_type_node
,
8552 tree_cons (NULL_TREE
, puint_type_node
,
8553 tree_cons (NULL_TREE
, integer_type_node
,
8556 tree v2si_ftype_pushort_int
8557 = build_function_type (opaque_V2SI_type_node
,
8558 tree_cons (NULL_TREE
, pushort_type_node
,
8559 tree_cons (NULL_TREE
, integer_type_node
,
8562 tree v2si_ftype_signed_char
8563 = build_function_type (opaque_V2SI_type_node
,
8564 tree_cons (NULL_TREE
, signed_char_type_node
,
8567 /* The initialization of the simple binary and unary builtins is
8568 done in rs6000_common_init_builtins, but we have to enable the
8569 mask bits here manually because we have run out of `target_flags'
8570 bits. We really need to redesign this mask business. */
8572 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
8573 ARRAY_SIZE (bdesc_2arg
),
8576 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
8577 ARRAY_SIZE (bdesc_1arg
),
8579 SPE_BUILTIN_EVSUBFUSIAAW
);
8580 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
8581 ARRAY_SIZE (bdesc_spe_predicates
),
8582 SPE_BUILTIN_EVCMPEQ
,
8583 SPE_BUILTIN_EVFSTSTLT
);
8584 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
8585 ARRAY_SIZE (bdesc_spe_evsel
),
8586 SPE_BUILTIN_EVSEL_CMPGTS
,
8587 SPE_BUILTIN_EVSEL_FSTSTEQ
);
8589 (*lang_hooks
.decls
.pushdecl
)
8590 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
8591 opaque_V2SI_type_node
));
8593 /* Initialize irregular SPE builtins. */
8595 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
8596 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
8597 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
8598 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
8599 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
8600 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
8601 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
8602 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
8603 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
8604 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
8605 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
8606 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
8607 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
8608 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
8609 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
8610 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
8611 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
8612 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
8615 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
8616 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
8617 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
8618 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
8619 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
8620 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
8621 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
8622 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
8623 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
8624 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
8625 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
8626 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
8627 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
8628 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
8629 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
8630 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
8631 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
8632 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
8633 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
8634 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
8635 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
8636 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
8639 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8640 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
8644 switch (insn_data
[d
->icode
].operand
[1].mode
)
8647 type
= int_ftype_int_v2si_v2si
;
8650 type
= int_ftype_int_v2sf_v2sf
;
8656 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8659 /* Evsel predicates. */
8660 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8661 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
8665 switch (insn_data
[d
->icode
].operand
[1].mode
)
8668 type
= v2si_ftype_4_v2si
;
8671 type
= v2sf_ftype_4_v2sf
;
8677 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8682 altivec_init_builtins (void)
8684 struct builtin_description
*d
;
8685 struct builtin_description_predicates
*dp
;
8689 tree pfloat_type_node
= build_pointer_type (float_type_node
);
8690 tree pint_type_node
= build_pointer_type (integer_type_node
);
8691 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
8692 tree pchar_type_node
= build_pointer_type (char_type_node
);
8694 tree pvoid_type_node
= build_pointer_type (void_type_node
);
8696 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
8697 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
8698 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
8699 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
8701 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
8703 tree int_ftype_opaque
8704 = build_function_type_list (integer_type_node
,
8705 opaque_V4SI_type_node
, NULL_TREE
);
8707 tree opaque_ftype_opaque_int
8708 = build_function_type_list (opaque_V4SI_type_node
,
8709 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
8710 tree opaque_ftype_opaque_opaque_int
8711 = build_function_type_list (opaque_V4SI_type_node
,
8712 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
8713 integer_type_node
, NULL_TREE
);
8714 tree int_ftype_int_opaque_opaque
8715 = build_function_type_list (integer_type_node
,
8716 integer_type_node
, opaque_V4SI_type_node
,
8717 opaque_V4SI_type_node
, NULL_TREE
);
8718 tree int_ftype_int_v4si_v4si
8719 = build_function_type_list (integer_type_node
,
8720 integer_type_node
, V4SI_type_node
,
8721 V4SI_type_node
, NULL_TREE
);
8722 tree v4sf_ftype_pcfloat
8723 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
8724 tree void_ftype_pfloat_v4sf
8725 = build_function_type_list (void_type_node
,
8726 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
8727 tree v4si_ftype_pcint
8728 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
8729 tree void_ftype_pint_v4si
8730 = build_function_type_list (void_type_node
,
8731 pint_type_node
, V4SI_type_node
, NULL_TREE
);
8732 tree v8hi_ftype_pcshort
8733 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
8734 tree void_ftype_pshort_v8hi
8735 = build_function_type_list (void_type_node
,
8736 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
8737 tree v16qi_ftype_pcchar
8738 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
8739 tree void_ftype_pchar_v16qi
8740 = build_function_type_list (void_type_node
,
8741 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
8742 tree void_ftype_v4si
8743 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
8744 tree v8hi_ftype_void
8745 = build_function_type (V8HI_type_node
, void_list_node
);
8746 tree void_ftype_void
8747 = build_function_type (void_type_node
, void_list_node
);
8749 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
8751 tree opaque_ftype_long_pcvoid
8752 = build_function_type_list (opaque_V4SI_type_node
,
8753 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8754 tree v16qi_ftype_long_pcvoid
8755 = build_function_type_list (V16QI_type_node
,
8756 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8757 tree v8hi_ftype_long_pcvoid
8758 = build_function_type_list (V8HI_type_node
,
8759 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8760 tree v4si_ftype_long_pcvoid
8761 = build_function_type_list (V4SI_type_node
,
8762 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8764 tree void_ftype_opaque_long_pvoid
8765 = build_function_type_list (void_type_node
,
8766 opaque_V4SI_type_node
, long_integer_type_node
,
8767 pvoid_type_node
, NULL_TREE
);
8768 tree void_ftype_v4si_long_pvoid
8769 = build_function_type_list (void_type_node
,
8770 V4SI_type_node
, long_integer_type_node
,
8771 pvoid_type_node
, NULL_TREE
);
8772 tree void_ftype_v16qi_long_pvoid
8773 = build_function_type_list (void_type_node
,
8774 V16QI_type_node
, long_integer_type_node
,
8775 pvoid_type_node
, NULL_TREE
);
8776 tree void_ftype_v8hi_long_pvoid
8777 = build_function_type_list (void_type_node
,
8778 V8HI_type_node
, long_integer_type_node
,
8779 pvoid_type_node
, NULL_TREE
);
8780 tree int_ftype_int_v8hi_v8hi
8781 = build_function_type_list (integer_type_node
,
8782 integer_type_node
, V8HI_type_node
,
8783 V8HI_type_node
, NULL_TREE
);
8784 tree int_ftype_int_v16qi_v16qi
8785 = build_function_type_list (integer_type_node
,
8786 integer_type_node
, V16QI_type_node
,
8787 V16QI_type_node
, NULL_TREE
);
8788 tree int_ftype_int_v4sf_v4sf
8789 = build_function_type_list (integer_type_node
,
8790 integer_type_node
, V4SF_type_node
,
8791 V4SF_type_node
, NULL_TREE
);
8792 tree v4si_ftype_v4si
8793 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8794 tree v8hi_ftype_v8hi
8795 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8796 tree v16qi_ftype_v16qi
8797 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8798 tree v4sf_ftype_v4sf
8799 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8800 tree void_ftype_pcvoid_int_int
8801 = build_function_type_list (void_type_node
,
8802 pcvoid_type_node
, integer_type_node
,
8803 integer_type_node
, NULL_TREE
);
8805 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
8806 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
8807 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
8808 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
8809 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
8810 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
8811 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
8812 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
8813 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
8814 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
8815 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
8816 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
8817 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
8818 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
8819 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
8820 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
8821 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
8822 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
8823 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
8824 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
8825 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
8826 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
8827 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
8828 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
8829 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
8830 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
8831 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
8832 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
8833 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
8834 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
8835 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
8836 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
8837 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
8838 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
8839 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
8840 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
8841 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
8842 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
8843 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
8844 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
8845 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
8846 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
8847 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
8848 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
8849 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
8850 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
8852 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
8854 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
8855 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
8856 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
8857 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
8858 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
8859 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
8860 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
8861 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
8862 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
8863 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
8865 /* Add the DST variants. */
8866 d
= (struct builtin_description
*) bdesc_dst
;
8867 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8868 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
8870 /* Initialize the predicates. */
8871 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
8872 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8874 enum machine_mode mode1
;
8876 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8877 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8882 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
8887 type
= int_ftype_int_opaque_opaque
;
8890 type
= int_ftype_int_v4si_v4si
;
8893 type
= int_ftype_int_v8hi_v8hi
;
8896 type
= int_ftype_int_v16qi_v16qi
;
8899 type
= int_ftype_int_v4sf_v4sf
;
8905 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
8908 /* Initialize the abs* operators. */
8909 d
= (struct builtin_description
*) bdesc_abs
;
8910 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8912 enum machine_mode mode0
;
8915 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8920 type
= v4si_ftype_v4si
;
8923 type
= v8hi_ftype_v8hi
;
8926 type
= v16qi_ftype_v16qi
;
8929 type
= v4sf_ftype_v4sf
;
8935 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8942 /* Initialize target builtin that implements
8943 targetm.vectorize.builtin_mask_for_load. */
8945 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
8946 v16qi_ftype_long_pcvoid
,
8947 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
8948 BUILT_IN_MD
, NULL
, NULL_TREE
);
8949 TREE_READONLY (decl
) = 1;
8950 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8951 altivec_builtin_mask_for_load
= decl
;
8954 /* Access to the vec_init patterns. */
8955 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
8956 integer_type_node
, integer_type_node
,
8957 integer_type_node
, NULL_TREE
);
8958 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
8959 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
8961 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
8962 short_integer_type_node
,
8963 short_integer_type_node
,
8964 short_integer_type_node
,
8965 short_integer_type_node
,
8966 short_integer_type_node
,
8967 short_integer_type_node
,
8968 short_integer_type_node
, NULL_TREE
);
8969 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
8970 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
8972 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
8973 char_type_node
, char_type_node
,
8974 char_type_node
, char_type_node
,
8975 char_type_node
, char_type_node
,
8976 char_type_node
, char_type_node
,
8977 char_type_node
, char_type_node
,
8978 char_type_node
, char_type_node
,
8979 char_type_node
, char_type_node
,
8980 char_type_node
, NULL_TREE
);
8981 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
8982 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
8984 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
8985 float_type_node
, float_type_node
,
8986 float_type_node
, NULL_TREE
);
8987 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
8988 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
8990 /* Access to the vec_set patterns. */
8991 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
8993 integer_type_node
, NULL_TREE
);
8994 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
8995 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
8997 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
8999 integer_type_node
, NULL_TREE
);
9000 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
9001 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
9003 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
9005 integer_type_node
, NULL_TREE
);
9006 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
9007 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
9009 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
9011 integer_type_node
, NULL_TREE
);
9012 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
9013 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
9015 /* Access to the vec_extract patterns. */
9016 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
9017 integer_type_node
, NULL_TREE
);
9018 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
9019 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
9021 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
9022 integer_type_node
, NULL_TREE
);
9023 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
9024 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
9026 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
9027 integer_type_node
, NULL_TREE
);
9028 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
9029 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
9031 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
9032 integer_type_node
, NULL_TREE
);
9033 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
9034 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
9038 rs6000_common_init_builtins (void)
9040 struct builtin_description
*d
;
9043 tree v4sf_ftype_v4sf_v4sf_v16qi
9044 = build_function_type_list (V4SF_type_node
,
9045 V4SF_type_node
, V4SF_type_node
,
9046 V16QI_type_node
, NULL_TREE
);
9047 tree v4si_ftype_v4si_v4si_v16qi
9048 = build_function_type_list (V4SI_type_node
,
9049 V4SI_type_node
, V4SI_type_node
,
9050 V16QI_type_node
, NULL_TREE
);
9051 tree v8hi_ftype_v8hi_v8hi_v16qi
9052 = build_function_type_list (V8HI_type_node
,
9053 V8HI_type_node
, V8HI_type_node
,
9054 V16QI_type_node
, NULL_TREE
);
9055 tree v16qi_ftype_v16qi_v16qi_v16qi
9056 = build_function_type_list (V16QI_type_node
,
9057 V16QI_type_node
, V16QI_type_node
,
9058 V16QI_type_node
, NULL_TREE
);
9060 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
9062 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
9063 tree v16qi_ftype_int
9064 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
9065 tree v8hi_ftype_v16qi
9066 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
9067 tree v4sf_ftype_v4sf
9068 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9070 tree v2si_ftype_v2si_v2si
9071 = build_function_type_list (opaque_V2SI_type_node
,
9072 opaque_V2SI_type_node
,
9073 opaque_V2SI_type_node
, NULL_TREE
);
9075 tree v2sf_ftype_v2sf_v2sf
9076 = build_function_type_list (opaque_V2SF_type_node
,
9077 opaque_V2SF_type_node
,
9078 opaque_V2SF_type_node
, NULL_TREE
);
9080 tree v2si_ftype_int_int
9081 = build_function_type_list (opaque_V2SI_type_node
,
9082 integer_type_node
, integer_type_node
,
9085 tree opaque_ftype_opaque
9086 = build_function_type_list (opaque_V4SI_type_node
,
9087 opaque_V4SI_type_node
, NULL_TREE
);
9089 tree v2si_ftype_v2si
9090 = build_function_type_list (opaque_V2SI_type_node
,
9091 opaque_V2SI_type_node
, NULL_TREE
);
9093 tree v2sf_ftype_v2sf
9094 = build_function_type_list (opaque_V2SF_type_node
,
9095 opaque_V2SF_type_node
, NULL_TREE
);
9097 tree v2sf_ftype_v2si
9098 = build_function_type_list (opaque_V2SF_type_node
,
9099 opaque_V2SI_type_node
, NULL_TREE
);
9101 tree v2si_ftype_v2sf
9102 = build_function_type_list (opaque_V2SI_type_node
,
9103 opaque_V2SF_type_node
, NULL_TREE
);
9105 tree v2si_ftype_v2si_char
9106 = build_function_type_list (opaque_V2SI_type_node
,
9107 opaque_V2SI_type_node
,
9108 char_type_node
, NULL_TREE
);
9110 tree v2si_ftype_int_char
9111 = build_function_type_list (opaque_V2SI_type_node
,
9112 integer_type_node
, char_type_node
, NULL_TREE
);
9114 tree v2si_ftype_char
9115 = build_function_type_list (opaque_V2SI_type_node
,
9116 char_type_node
, NULL_TREE
);
9118 tree int_ftype_int_int
9119 = build_function_type_list (integer_type_node
,
9120 integer_type_node
, integer_type_node
,
9123 tree opaque_ftype_opaque_opaque
9124 = build_function_type_list (opaque_V4SI_type_node
,
9125 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
9126 tree v4si_ftype_v4si_v4si
9127 = build_function_type_list (V4SI_type_node
,
9128 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9129 tree v4sf_ftype_v4si_int
9130 = build_function_type_list (V4SF_type_node
,
9131 V4SI_type_node
, integer_type_node
, NULL_TREE
);
9132 tree v4si_ftype_v4sf_int
9133 = build_function_type_list (V4SI_type_node
,
9134 V4SF_type_node
, integer_type_node
, NULL_TREE
);
9135 tree v4si_ftype_v4si_int
9136 = build_function_type_list (V4SI_type_node
,
9137 V4SI_type_node
, integer_type_node
, NULL_TREE
);
9138 tree v8hi_ftype_v8hi_int
9139 = build_function_type_list (V8HI_type_node
,
9140 V8HI_type_node
, integer_type_node
, NULL_TREE
);
9141 tree v16qi_ftype_v16qi_int
9142 = build_function_type_list (V16QI_type_node
,
9143 V16QI_type_node
, integer_type_node
, NULL_TREE
);
9144 tree v16qi_ftype_v16qi_v16qi_int
9145 = build_function_type_list (V16QI_type_node
,
9146 V16QI_type_node
, V16QI_type_node
,
9147 integer_type_node
, NULL_TREE
);
9148 tree v8hi_ftype_v8hi_v8hi_int
9149 = build_function_type_list (V8HI_type_node
,
9150 V8HI_type_node
, V8HI_type_node
,
9151 integer_type_node
, NULL_TREE
);
9152 tree v4si_ftype_v4si_v4si_int
9153 = build_function_type_list (V4SI_type_node
,
9154 V4SI_type_node
, V4SI_type_node
,
9155 integer_type_node
, NULL_TREE
);
9156 tree v4sf_ftype_v4sf_v4sf_int
9157 = build_function_type_list (V4SF_type_node
,
9158 V4SF_type_node
, V4SF_type_node
,
9159 integer_type_node
, NULL_TREE
);
9160 tree v4sf_ftype_v4sf_v4sf
9161 = build_function_type_list (V4SF_type_node
,
9162 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9163 tree opaque_ftype_opaque_opaque_opaque
9164 = build_function_type_list (opaque_V4SI_type_node
,
9165 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
9166 opaque_V4SI_type_node
, NULL_TREE
);
9167 tree v4sf_ftype_v4sf_v4sf_v4si
9168 = build_function_type_list (V4SF_type_node
,
9169 V4SF_type_node
, V4SF_type_node
,
9170 V4SI_type_node
, NULL_TREE
);
9171 tree v4sf_ftype_v4sf_v4sf_v4sf
9172 = build_function_type_list (V4SF_type_node
,
9173 V4SF_type_node
, V4SF_type_node
,
9174 V4SF_type_node
, NULL_TREE
);
9175 tree v4si_ftype_v4si_v4si_v4si
9176 = build_function_type_list (V4SI_type_node
,
9177 V4SI_type_node
, V4SI_type_node
,
9178 V4SI_type_node
, NULL_TREE
);
9179 tree v8hi_ftype_v8hi_v8hi
9180 = build_function_type_list (V8HI_type_node
,
9181 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9182 tree v8hi_ftype_v8hi_v8hi_v8hi
9183 = build_function_type_list (V8HI_type_node
,
9184 V8HI_type_node
, V8HI_type_node
,
9185 V8HI_type_node
, NULL_TREE
);
9186 tree v4si_ftype_v8hi_v8hi_v4si
9187 = build_function_type_list (V4SI_type_node
,
9188 V8HI_type_node
, V8HI_type_node
,
9189 V4SI_type_node
, NULL_TREE
);
9190 tree v4si_ftype_v16qi_v16qi_v4si
9191 = build_function_type_list (V4SI_type_node
,
9192 V16QI_type_node
, V16QI_type_node
,
9193 V4SI_type_node
, NULL_TREE
);
9194 tree v16qi_ftype_v16qi_v16qi
9195 = build_function_type_list (V16QI_type_node
,
9196 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9197 tree v4si_ftype_v4sf_v4sf
9198 = build_function_type_list (V4SI_type_node
,
9199 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9200 tree v8hi_ftype_v16qi_v16qi
9201 = build_function_type_list (V8HI_type_node
,
9202 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9203 tree v4si_ftype_v8hi_v8hi
9204 = build_function_type_list (V4SI_type_node
,
9205 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9206 tree v8hi_ftype_v4si_v4si
9207 = build_function_type_list (V8HI_type_node
,
9208 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9209 tree v16qi_ftype_v8hi_v8hi
9210 = build_function_type_list (V16QI_type_node
,
9211 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9212 tree v4si_ftype_v16qi_v4si
9213 = build_function_type_list (V4SI_type_node
,
9214 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
9215 tree v4si_ftype_v16qi_v16qi
9216 = build_function_type_list (V4SI_type_node
,
9217 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9218 tree v4si_ftype_v8hi_v4si
9219 = build_function_type_list (V4SI_type_node
,
9220 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
9221 tree v4si_ftype_v8hi
9222 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
9223 tree int_ftype_v4si_v4si
9224 = build_function_type_list (integer_type_node
,
9225 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9226 tree int_ftype_v4sf_v4sf
9227 = build_function_type_list (integer_type_node
,
9228 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9229 tree int_ftype_v16qi_v16qi
9230 = build_function_type_list (integer_type_node
,
9231 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9232 tree int_ftype_v8hi_v8hi
9233 = build_function_type_list (integer_type_node
,
9234 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9236 /* Add the simple ternary operators. */
9237 d
= (struct builtin_description
*) bdesc_3arg
;
9238 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
9240 enum machine_mode mode0
, mode1
, mode2
, mode3
;
9242 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9243 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9254 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
9257 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9258 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
9259 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
9260 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
9263 /* When all four are of the same mode. */
9264 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
9269 type
= opaque_ftype_opaque_opaque_opaque
;
9272 type
= v4si_ftype_v4si_v4si_v4si
;
9275 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
9278 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
9281 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
9287 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
9292 type
= v4si_ftype_v4si_v4si_v16qi
;
9295 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
9298 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
9301 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
9307 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
9308 && mode3
== V4SImode
)
9309 type
= v4si_ftype_v16qi_v16qi_v4si
;
9310 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
9311 && mode3
== V4SImode
)
9312 type
= v4si_ftype_v8hi_v8hi_v4si
;
9313 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
9314 && mode3
== V4SImode
)
9315 type
= v4sf_ftype_v4sf_v4sf_v4si
;
9317 /* vchar, vchar, vchar, 4-bit literal. */
9318 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
9320 type
= v16qi_ftype_v16qi_v16qi_int
;
9322 /* vshort, vshort, vshort, 4-bit literal. */
9323 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
9325 type
= v8hi_ftype_v8hi_v8hi_int
;
9327 /* vint, vint, vint, 4-bit literal. */
9328 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
9330 type
= v4si_ftype_v4si_v4si_int
;
9332 /* vfloat, vfloat, vfloat, 4-bit literal. */
9333 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
9335 type
= v4sf_ftype_v4sf_v4sf_int
;
9340 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9343 /* Add the simple binary operators. */
9344 d
= (struct builtin_description
*) bdesc_2arg
;
9345 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9347 enum machine_mode mode0
, mode1
, mode2
;
9349 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9350 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9360 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
9363 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9364 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
9365 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
9368 /* When all three operands are of the same mode. */
9369 if (mode0
== mode1
&& mode1
== mode2
)
9374 type
= opaque_ftype_opaque_opaque
;
9377 type
= v4sf_ftype_v4sf_v4sf
;
9380 type
= v4si_ftype_v4si_v4si
;
9383 type
= v16qi_ftype_v16qi_v16qi
;
9386 type
= v8hi_ftype_v8hi_v8hi
;
9389 type
= v2si_ftype_v2si_v2si
;
9392 type
= v2sf_ftype_v2sf_v2sf
;
9395 type
= int_ftype_int_int
;
9402 /* A few other combos we really don't want to do manually. */
9404 /* vint, vfloat, vfloat. */
9405 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
9406 type
= v4si_ftype_v4sf_v4sf
;
9408 /* vshort, vchar, vchar. */
9409 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
9410 type
= v8hi_ftype_v16qi_v16qi
;
9412 /* vint, vshort, vshort. */
9413 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
9414 type
= v4si_ftype_v8hi_v8hi
;
9416 /* vshort, vint, vint. */
9417 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
9418 type
= v8hi_ftype_v4si_v4si
;
9420 /* vchar, vshort, vshort. */
9421 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
9422 type
= v16qi_ftype_v8hi_v8hi
;
9424 /* vint, vchar, vint. */
9425 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
9426 type
= v4si_ftype_v16qi_v4si
;
9428 /* vint, vchar, vchar. */
9429 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
9430 type
= v4si_ftype_v16qi_v16qi
;
9432 /* vint, vshort, vint. */
9433 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
9434 type
= v4si_ftype_v8hi_v4si
;
9436 /* vint, vint, 5-bit literal. */
9437 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
9438 type
= v4si_ftype_v4si_int
;
9440 /* vshort, vshort, 5-bit literal. */
9441 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
9442 type
= v8hi_ftype_v8hi_int
;
9444 /* vchar, vchar, 5-bit literal. */
9445 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
9446 type
= v16qi_ftype_v16qi_int
;
9448 /* vfloat, vint, 5-bit literal. */
9449 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
9450 type
= v4sf_ftype_v4si_int
;
9452 /* vint, vfloat, 5-bit literal. */
9453 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
9454 type
= v4si_ftype_v4sf_int
;
9456 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
9457 type
= v2si_ftype_int_int
;
9459 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
9460 type
= v2si_ftype_v2si_char
;
9462 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
9463 type
= v2si_ftype_int_char
;
9468 gcc_assert (mode0
== SImode
);
9472 type
= int_ftype_v4si_v4si
;
9475 type
= int_ftype_v4sf_v4sf
;
9478 type
= int_ftype_v16qi_v16qi
;
9481 type
= int_ftype_v8hi_v8hi
;
9488 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9491 /* Add the simple unary operators. */
9492 d
= (struct builtin_description
*) bdesc_1arg
;
9493 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9495 enum machine_mode mode0
, mode1
;
9497 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9498 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9507 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
9510 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9511 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
9514 if (mode0
== V4SImode
&& mode1
== QImode
)
9515 type
= v4si_ftype_int
;
9516 else if (mode0
== V8HImode
&& mode1
== QImode
)
9517 type
= v8hi_ftype_int
;
9518 else if (mode0
== V16QImode
&& mode1
== QImode
)
9519 type
= v16qi_ftype_int
;
9520 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
9521 type
= opaque_ftype_opaque
;
9522 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
9523 type
= v4sf_ftype_v4sf
;
9524 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
9525 type
= v8hi_ftype_v16qi
;
9526 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
9527 type
= v4si_ftype_v8hi
;
9528 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
9529 type
= v2si_ftype_v2si
;
9530 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
9531 type
= v2sf_ftype_v2sf
;
9532 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
9533 type
= v2sf_ftype_v2si
;
9534 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
9535 type
= v2si_ftype_v2sf
;
9536 else if (mode0
== V2SImode
&& mode1
== QImode
)
9537 type
= v2si_ftype_char
;
9541 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9546 rs6000_init_libfuncs (void)
9548 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
9549 && !TARGET_POWER2
&& !TARGET_POWERPC
)
9551 /* AIX library routines for float->int conversion. */
9552 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
9553 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
9554 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
9555 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
9558 if (!TARGET_IEEEQUAD
)
9559 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9560 if (!TARGET_XL_COMPAT
)
9562 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
9563 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
9564 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
9565 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
9567 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
9569 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
9570 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
9571 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
9572 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
9573 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
9574 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
9575 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
9576 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
9578 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
9579 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
9580 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
9581 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
9582 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
9583 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
9584 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
9585 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
9590 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
9591 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
9592 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
9593 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
9597 /* 32-bit SVR4 quad floating point routines. */
9599 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
9600 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
9601 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
9602 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
9603 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
9604 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
9605 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
9607 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
9608 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
9609 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
9610 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
9611 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
9612 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
9614 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
9615 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
9616 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
9617 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
9618 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
9619 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
9620 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
9621 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
9626 /* Expand a block clear operation, and return 1 if successful. Return 0
9627 if we should let the compiler generate normal code.
9629 operands[0] is the destination
9630 operands[1] is the length
9631 operands[3] is the alignment */
9634 expand_block_clear (rtx operands
[])
9636 rtx orig_dest
= operands
[0];
9637 rtx bytes_rtx
= operands
[1];
9638 rtx align_rtx
= operands
[3];
9639 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9640 HOST_WIDE_INT align
;
9641 HOST_WIDE_INT bytes
;
9646 /* If this is not a fixed size move, just call memcpy */
9650 /* This must be a fixed size alignment */
9651 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9652 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9654 /* Anything to clear? */
9655 bytes
= INTVAL (bytes_rtx
);
9659 /* Use the builtin memset after a point, to avoid huge code bloat.
9660 When optimize_size, avoid any significant code bloat; calling
9661 memset is about 4 instructions, so allow for one instruction to
9662 load zero and three to do clearing. */
9663 if (TARGET_ALTIVEC
&& align
>= 128)
9665 else if (TARGET_POWERPC64
&& align
>= 32)
9670 if (optimize_size
&& bytes
> 3 * clear_step
)
9672 if (! optimize_size
&& bytes
> 8 * clear_step
)
9675 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
9677 enum machine_mode mode
= BLKmode
;
9680 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
9685 else if (bytes
>= 8 && TARGET_POWERPC64
9686 /* 64-bit loads and stores require word-aligned
9688 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9693 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9694 { /* move 4 bytes */
9698 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9699 { /* move 2 bytes */
9703 else /* move 1 byte at a time */
9709 dest
= adjust_address (orig_dest
, mode
, offset
);
9711 emit_move_insn (dest
, CONST0_RTX (mode
));
9718 /* Expand a block move operation, and return 1 if successful. Return 0
9719 if we should let the compiler generate normal code.
9721 operands[0] is the destination
9722 operands[1] is the source
9723 operands[2] is the length
9724 operands[3] is the alignment */
9726 #define MAX_MOVE_REG 4
9729 expand_block_move (rtx operands
[])
9731 rtx orig_dest
= operands
[0];
9732 rtx orig_src
= operands
[1];
9733 rtx bytes_rtx
= operands
[2];
9734 rtx align_rtx
= operands
[3];
9735 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9740 rtx stores
[MAX_MOVE_REG
];
9743 /* If this is not a fixed size move, just call memcpy */
9747 /* This must be a fixed size alignment */
9748 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9749 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9751 /* Anything to move? */
9752 bytes
= INTVAL (bytes_rtx
);
9756 /* store_one_arg depends on expand_block_move to handle at least the size of
9757 reg_parm_stack_space. */
9758 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
9761 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
9764 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
9765 rtx (*mov
) (rtx
, rtx
);
9767 enum machine_mode mode
= BLKmode
;
9770 /* Altivec first, since it will be faster than a string move
9771 when it applies, and usually not significantly larger. */
9772 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
9776 gen_func
.mov
= gen_movv4si
;
9778 else if (TARGET_STRING
9779 && bytes
> 24 /* move up to 32 bytes at a time */
9787 && ! fixed_regs
[12])
9789 move_bytes
= (bytes
> 32) ? 32 : bytes
;
9790 gen_func
.movmemsi
= gen_movmemsi_8reg
;
9792 else if (TARGET_STRING
9793 && bytes
> 16 /* move up to 24 bytes at a time */
9799 && ! fixed_regs
[10])
9801 move_bytes
= (bytes
> 24) ? 24 : bytes
;
9802 gen_func
.movmemsi
= gen_movmemsi_6reg
;
9804 else if (TARGET_STRING
9805 && bytes
> 8 /* move up to 16 bytes at a time */
9811 move_bytes
= (bytes
> 16) ? 16 : bytes
;
9812 gen_func
.movmemsi
= gen_movmemsi_4reg
;
9814 else if (bytes
>= 8 && TARGET_POWERPC64
9815 /* 64-bit loads and stores require word-aligned
9817 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9821 gen_func
.mov
= gen_movdi
;
9823 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
9824 { /* move up to 8 bytes at a time */
9825 move_bytes
= (bytes
> 8) ? 8 : bytes
;
9826 gen_func
.movmemsi
= gen_movmemsi_2reg
;
9828 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9829 { /* move 4 bytes */
9832 gen_func
.mov
= gen_movsi
;
9834 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9835 { /* move 2 bytes */
9838 gen_func
.mov
= gen_movhi
;
9840 else if (TARGET_STRING
&& bytes
> 1)
9841 { /* move up to 4 bytes at a time */
9842 move_bytes
= (bytes
> 4) ? 4 : bytes
;
9843 gen_func
.movmemsi
= gen_movmemsi_1reg
;
9845 else /* move 1 byte at a time */
9849 gen_func
.mov
= gen_movqi
;
9852 src
= adjust_address (orig_src
, mode
, offset
);
9853 dest
= adjust_address (orig_dest
, mode
, offset
);
9855 if (mode
!= BLKmode
)
9857 rtx tmp_reg
= gen_reg_rtx (mode
);
9859 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
9860 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
9863 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
9866 for (i
= 0; i
< num_reg
; i
++)
9867 emit_insn (stores
[i
]);
9871 if (mode
== BLKmode
)
9873 /* Move the address into scratch registers. The movmemsi
9874 patterns require zero offset. */
9875 if (!REG_P (XEXP (src
, 0)))
9877 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
9878 src
= replace_equiv_address (src
, src_reg
);
9880 set_mem_size (src
, GEN_INT (move_bytes
));
9882 if (!REG_P (XEXP (dest
, 0)))
9884 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
9885 dest
= replace_equiv_address (dest
, dest_reg
);
9887 set_mem_size (dest
, GEN_INT (move_bytes
));
9889 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
9890 GEN_INT (move_bytes
& 31),
9899 /* Return a string to perform a load_multiple operation.
9900 operands[0] is the vector.
9901 operands[1] is the source address.
9902 operands[2] is the first destination register. */
9905 rs6000_output_load_multiple (rtx operands
[3])
9907 /* We have to handle the case where the pseudo used to contain the address
9908 is assigned to one of the output registers. */
9910 int words
= XVECLEN (operands
[0], 0);
9913 if (XVECLEN (operands
[0], 0) == 1)
9914 return "{l|lwz} %2,0(%1)";
9916 for (i
= 0; i
< words
; i
++)
9917 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
9918 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
9922 xop
[0] = GEN_INT (4 * (words
-1));
9923 xop
[1] = operands
[1];
9924 xop
[2] = operands
[2];
9925 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
9930 xop
[0] = GEN_INT (4 * (words
-1));
9931 xop
[1] = operands
[1];
9932 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
9933 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
);
9938 for (j
= 0; j
< words
; j
++)
9941 xop
[0] = GEN_INT (j
* 4);
9942 xop
[1] = operands
[1];
9943 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
9944 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
9946 xop
[0] = GEN_INT (i
* 4);
9947 xop
[1] = operands
[1];
9948 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
9953 return "{lsi|lswi} %2,%1,%N0";
9957 /* A validation routine: say whether CODE, a condition code, and MODE
9958 match. The other alternatives either don't make sense or should
9959 never be generated. */
9962 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
9964 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
9965 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
9966 && GET_MODE_CLASS (mode
) == MODE_CC
);
9968 /* These don't make sense. */
9969 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
9970 || mode
!= CCUNSmode
);
9972 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
9973 || mode
== CCUNSmode
);
9975 gcc_assert (mode
== CCFPmode
9976 || (code
!= ORDERED
&& code
!= UNORDERED
9977 && code
!= UNEQ
&& code
!= LTGT
9978 && code
!= UNGT
&& code
!= UNLT
9979 && code
!= UNGE
&& code
!= UNLE
));
9981 /* These should never be generated except for
9982 flag_finite_math_only. */
9983 gcc_assert (mode
!= CCFPmode
9984 || flag_finite_math_only
9985 || (code
!= LE
&& code
!= GE
9986 && code
!= UNEQ
&& code
!= LTGT
9987 && code
!= UNGT
&& code
!= UNLT
));
9989 /* These are invalid; the information is not there. */
9990 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
9994 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9995 mask required to convert the result of a rotate insn into a shift
9996 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9999 includes_lshift_p (rtx shiftop
, rtx andop
)
10001 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
10003 shift_mask
<<= INTVAL (shiftop
);
10005 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
10008 /* Similar, but for right shift. */
10011 includes_rshift_p (rtx shiftop
, rtx andop
)
10013 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
10015 shift_mask
>>= INTVAL (shiftop
);
10017 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
10020 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
10021 to perform a left shift. It must have exactly SHIFTOP least
10022 significant 0's, then one or more 1's, then zero or more 0's. */
10025 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
10027 if (GET_CODE (andop
) == CONST_INT
)
10029 HOST_WIDE_INT c
, lsb
, shift_mask
;
10031 c
= INTVAL (andop
);
10032 if (c
== 0 || c
== ~0)
10036 shift_mask
<<= INTVAL (shiftop
);
10038 /* Find the least significant one bit. */
10041 /* It must coincide with the LSB of the shift mask. */
10042 if (-lsb
!= shift_mask
)
10045 /* Invert to look for the next transition (if any). */
10048 /* Remove the low group of ones (originally low group of zeros). */
10051 /* Again find the lsb, and check we have all 1's above. */
10055 else if (GET_CODE (andop
) == CONST_DOUBLE
10056 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
10058 HOST_WIDE_INT low
, high
, lsb
;
10059 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
10061 low
= CONST_DOUBLE_LOW (andop
);
10062 if (HOST_BITS_PER_WIDE_INT
< 64)
10063 high
= CONST_DOUBLE_HIGH (andop
);
10065 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
10066 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
10069 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
10071 shift_mask_high
= ~0;
10072 if (INTVAL (shiftop
) > 32)
10073 shift_mask_high
<<= INTVAL (shiftop
) - 32;
10075 lsb
= high
& -high
;
10077 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
10083 lsb
= high
& -high
;
10084 return high
== -lsb
;
10087 shift_mask_low
= ~0;
10088 shift_mask_low
<<= INTVAL (shiftop
);
10092 if (-lsb
!= shift_mask_low
)
10095 if (HOST_BITS_PER_WIDE_INT
< 64)
10100 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
10102 lsb
= high
& -high
;
10103 return high
== -lsb
;
10107 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
10113 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
10114 to perform a left shift. It must have SHIFTOP or more least
10115 significant 0's, with the remainder of the word 1's. */
10118 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
10120 if (GET_CODE (andop
) == CONST_INT
)
10122 HOST_WIDE_INT c
, lsb
, shift_mask
;
10125 shift_mask
<<= INTVAL (shiftop
);
10126 c
= INTVAL (andop
);
10128 /* Find the least significant one bit. */
10131 /* It must be covered by the shift mask.
10132 This test also rejects c == 0. */
10133 if ((lsb
& shift_mask
) == 0)
10136 /* Check we have all 1's above the transition, and reject all 1's. */
10137 return c
== -lsb
&& lsb
!= 1;
10139 else if (GET_CODE (andop
) == CONST_DOUBLE
10140 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
10142 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
10144 low
= CONST_DOUBLE_LOW (andop
);
10146 if (HOST_BITS_PER_WIDE_INT
< 64)
10148 HOST_WIDE_INT high
, shift_mask_high
;
10150 high
= CONST_DOUBLE_HIGH (andop
);
10154 shift_mask_high
= ~0;
10155 if (INTVAL (shiftop
) > 32)
10156 shift_mask_high
<<= INTVAL (shiftop
) - 32;
10158 lsb
= high
& -high
;
10160 if ((lsb
& shift_mask_high
) == 0)
10163 return high
== -lsb
;
10169 shift_mask_low
= ~0;
10170 shift_mask_low
<<= INTVAL (shiftop
);
10174 if ((lsb
& shift_mask_low
) == 0)
10177 return low
== -lsb
&& lsb
!= 1;
10183 /* Return 1 if operands will generate a valid arguments to rlwimi
10184 instruction for insert with right shift in 64-bit mode. The mask may
10185 not start on the first bit or stop on the last bit because wrap-around
10186 effects of instruction do not correspond to semantics of RTL insn. */
10189 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
10191 if (INTVAL (startop
) > 32
10192 && INTVAL (startop
) < 64
10193 && INTVAL (sizeop
) > 1
10194 && INTVAL (sizeop
) + INTVAL (startop
) < 64
10195 && INTVAL (shiftop
) > 0
10196 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
10197 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
10203 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
10204 for lfq and stfq insns iff the registers are hard registers. */
10207 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
10209 /* We might have been passed a SUBREG. */
10210 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
10213 /* We might have been passed non floating point registers. */
10214 if (!FP_REGNO_P (REGNO (reg1
))
10215 || !FP_REGNO_P (REGNO (reg2
)))
10218 return (REGNO (reg1
) == REGNO (reg2
) - 1);
10221 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
10222 addr1 and addr2 must be in consecutive memory locations
10223 (addr2 == addr1 + 8). */
10226 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
10229 unsigned int reg1
, reg2
;
10230 int offset1
, offset2
;
10232 /* The mems cannot be volatile. */
10233 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
10236 addr1
= XEXP (mem1
, 0);
10237 addr2
= XEXP (mem2
, 0);
10239 /* Extract an offset (if used) from the first addr. */
10240 if (GET_CODE (addr1
) == PLUS
)
10242 /* If not a REG, return zero. */
10243 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
10247 reg1
= REGNO (XEXP (addr1
, 0));
10248 /* The offset must be constant! */
10249 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
10251 offset1
= INTVAL (XEXP (addr1
, 1));
10254 else if (GET_CODE (addr1
) != REG
)
10258 reg1
= REGNO (addr1
);
10259 /* This was a simple (mem (reg)) expression. Offset is 0. */
10263 /* And now for the second addr. */
10264 if (GET_CODE (addr2
) == PLUS
)
10266 /* If not a REG, return zero. */
10267 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
10271 reg2
= REGNO (XEXP (addr2
, 0));
10272 /* The offset must be constant. */
10273 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
10275 offset2
= INTVAL (XEXP (addr2
, 1));
10278 else if (GET_CODE (addr2
) != REG
)
10282 reg2
= REGNO (addr2
);
10283 /* This was a simple (mem (reg)) expression. Offset is 0. */
10287 /* Both of these must have the same base register. */
10291 /* The offset for the second addr must be 8 more than the first addr. */
10292 if (offset2
!= offset1
+ 8)
10295 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
10300 /* Return the register class of a scratch register needed to copy IN into
10301 or out of a register in CLASS in MODE. If it can be done directly,
10302 NO_REGS is returned. */
10305 rs6000_secondary_reload_class (enum reg_class
class,
10306 enum machine_mode mode ATTRIBUTE_UNUSED
,
10311 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
10313 && MACHOPIC_INDIRECT
10317 /* We cannot copy a symbolic operand directly into anything
10318 other than BASE_REGS for TARGET_ELF. So indicate that a
10319 register from BASE_REGS is needed as an intermediate
10322 On Darwin, pic addresses require a load from memory, which
10323 needs a base register. */
10324 if (class != BASE_REGS
10325 && (GET_CODE (in
) == SYMBOL_REF
10326 || GET_CODE (in
) == HIGH
10327 || GET_CODE (in
) == LABEL_REF
10328 || GET_CODE (in
) == CONST
))
10332 if (GET_CODE (in
) == REG
)
10334 regno
= REGNO (in
);
10335 if (regno
>= FIRST_PSEUDO_REGISTER
)
10337 regno
= true_regnum (in
);
10338 if (regno
>= FIRST_PSEUDO_REGISTER
)
10342 else if (GET_CODE (in
) == SUBREG
)
10344 regno
= true_regnum (in
);
10345 if (regno
>= FIRST_PSEUDO_REGISTER
)
10351 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
10353 if (class == GENERAL_REGS
|| class == BASE_REGS
10354 || (regno
>= 0 && INT_REGNO_P (regno
)))
10357 /* Constants, memory, and FP registers can go into FP registers. */
10358 if ((regno
== -1 || FP_REGNO_P (regno
))
10359 && (class == FLOAT_REGS
|| class == NON_SPECIAL_REGS
))
10362 /* Memory, and AltiVec registers can go into AltiVec registers. */
10363 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
10364 && class == ALTIVEC_REGS
)
10367 /* We can copy among the CR registers. */
10368 if ((class == CR_REGS
|| class == CR0_REGS
)
10369 && regno
>= 0 && CR_REGNO_P (regno
))
10372 /* Otherwise, we need GENERAL_REGS. */
10373 return GENERAL_REGS
;
10376 /* Given a comparison operation, return the bit number in CCR to test. We
10377 know this is a valid comparison.
10379 SCC_P is 1 if this is for an scc. That means that %D will have been
10380 used instead of %C, so the bits will be in different places.
10382 Return -1 if OP isn't a valid comparison for some reason. */
10385 ccr_bit (rtx op
, int scc_p
)
10387 enum rtx_code code
= GET_CODE (op
);
10388 enum machine_mode cc_mode
;
10393 if (!COMPARISON_P (op
))
10396 reg
= XEXP (op
, 0);
10398 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
10400 cc_mode
= GET_MODE (reg
);
10401 cc_regnum
= REGNO (reg
);
10402 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
10404 validate_condition_mode (code
, cc_mode
);
10406 /* When generating a sCOND operation, only positive conditions are
10409 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
10410 || code
== GTU
|| code
== LTU
);
10415 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
10417 return base_bit
+ 2;
10418 case GT
: case GTU
: case UNLE
:
10419 return base_bit
+ 1;
10420 case LT
: case LTU
: case UNGE
:
10422 case ORDERED
: case UNORDERED
:
10423 return base_bit
+ 3;
10426 /* If scc, we will have done a cror to put the bit in the
10427 unordered position. So test that bit. For integer, this is ! LT
10428 unless this is an scc insn. */
10429 return scc_p
? base_bit
+ 3 : base_bit
;
10432 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
10435 gcc_unreachable ();
10439 /* Return the GOT register. */
10442 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
10444 /* The second flow pass currently (June 1999) can't update
10445 regs_ever_live without disturbing other parts of the compiler, so
10446 update it here to make the prolog/epilogue code happy. */
10447 if (no_new_pseudos
&& ! regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
])
10448 regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
10450 current_function_uses_pic_offset_table
= 1;
10452 return pic_offset_table_rtx
;
10455 /* Function to init struct machine_function.
10456 This will be called, via a pointer variable,
10457 from push_function_context. */
10459 static struct machine_function
*
10460 rs6000_init_machine_status (void)
10462 return ggc_alloc_cleared (sizeof (machine_function
));
10465 /* These macros test for integers and extract the low-order bits. */
10467 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
10468 && GET_MODE (X) == VOIDmode)
10470 #define INT_LOWPART(X) \
10471 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
10474 extract_MB (rtx op
)
10477 unsigned long val
= INT_LOWPART (op
);
10479 /* If the high bit is zero, the value is the first 1 bit we find
10481 if ((val
& 0x80000000) == 0)
10483 gcc_assert (val
& 0xffffffff);
10486 while (((val
<<= 1) & 0x80000000) == 0)
10491 /* If the high bit is set and the low bit is not, or the mask is all
10492 1's, the value is zero. */
10493 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
10496 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10499 while (((val
>>= 1) & 1) != 0)
10506 extract_ME (rtx op
)
10509 unsigned long val
= INT_LOWPART (op
);
10511 /* If the low bit is zero, the value is the first 1 bit we find from
10513 if ((val
& 1) == 0)
10515 gcc_assert (val
& 0xffffffff);
10518 while (((val
>>= 1) & 1) == 0)
10524 /* If the low bit is set and the high bit is not, or the mask is all
10525 1's, the value is 31. */
10526 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
10529 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10532 while (((val
<<= 1) & 0x80000000) != 0)
10538 /* Locate some local-dynamic symbol still in use by this function
10539 so that we can print its name in some tls_ld pattern. */
10541 static const char *
10542 rs6000_get_some_local_dynamic_name (void)
10546 if (cfun
->machine
->some_ld_name
)
10547 return cfun
->machine
->some_ld_name
;
10549 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10551 && for_each_rtx (&PATTERN (insn
),
10552 rs6000_get_some_local_dynamic_name_1
, 0))
10553 return cfun
->machine
->some_ld_name
;
10555 gcc_unreachable ();
10558 /* Helper function for rs6000_get_some_local_dynamic_name. */
10561 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
10565 if (GET_CODE (x
) == SYMBOL_REF
)
10567 const char *str
= XSTR (x
, 0);
10568 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
10570 cfun
->machine
->some_ld_name
= str
;
10578 /* Write out a function code label. */
10581 rs6000_output_function_entry (FILE *file
, const char *fname
)
10583 if (fname
[0] != '.')
10585 switch (DEFAULT_ABI
)
10588 gcc_unreachable ();
10594 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
10603 RS6000_OUTPUT_BASENAME (file
, fname
);
10605 assemble_name (file
, fname
);
10608 /* Print an operand. Recognize special options, documented below. */
10611 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10612 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10614 #define SMALL_DATA_RELOC "sda21"
10615 #define SMALL_DATA_REG 0
10619 print_operand (FILE *file
, rtx x
, int code
)
10623 unsigned HOST_WIDE_INT uval
;
10628 /* Write out an instruction after the call which may be replaced
10629 with glue code by the loader. This depends on the AIX version. */
10630 asm_fprintf (file
, RS6000_CALL_GLUE
);
10633 /* %a is output_address. */
10636 /* If X is a constant integer whose low-order 5 bits are zero,
10637 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10638 in the AIX assembler where "sri" with a zero shift count
10639 writes a trash instruction. */
10640 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
10647 /* If constant, low-order 16 bits of constant, unsigned.
10648 Otherwise, write normally. */
10650 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
10652 print_operand (file
, x
, 0);
10656 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10657 for 64-bit mask direction. */
10658 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
10661 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10665 /* X is a CR register. Print the number of the GT bit of the CR. */
10666 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10667 output_operand_lossage ("invalid %%E value");
10669 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
10673 /* Like 'J' but get to the GT bit only. */
10674 gcc_assert (GET_CODE (x
) == REG
);
10676 /* Bit 1 is GT bit. */
10677 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
10679 /* Add one for shift count in rlinm for scc. */
10680 fprintf (file
, "%d", i
+ 1);
10684 /* X is a CR register. Print the number of the EQ bit of the CR */
10685 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10686 output_operand_lossage ("invalid %%E value");
10688 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
10692 /* X is a CR register. Print the shift count needed to move it
10693 to the high-order four bits. */
10694 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10695 output_operand_lossage ("invalid %%f value");
10697 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
10701 /* Similar, but print the count for the rotate in the opposite
10703 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10704 output_operand_lossage ("invalid %%F value");
10706 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
10710 /* X is a constant integer. If it is negative, print "m",
10711 otherwise print "z". This is to make an aze or ame insn. */
10712 if (GET_CODE (x
) != CONST_INT
)
10713 output_operand_lossage ("invalid %%G value");
10714 else if (INTVAL (x
) >= 0)
10721 /* If constant, output low-order five bits. Otherwise, write
10724 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
10726 print_operand (file
, x
, 0);
10730 /* If constant, output low-order six bits. Otherwise, write
10733 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
10735 print_operand (file
, x
, 0);
10739 /* Print `i' if this is a constant, else nothing. */
10745 /* Write the bit number in CCR for jump. */
10746 i
= ccr_bit (x
, 0);
10748 output_operand_lossage ("invalid %%j code");
10750 fprintf (file
, "%d", i
);
10754 /* Similar, but add one for shift count in rlinm for scc and pass
10755 scc flag to `ccr_bit'. */
10756 i
= ccr_bit (x
, 1);
10758 output_operand_lossage ("invalid %%J code");
10760 /* If we want bit 31, write a shift count of zero, not 32. */
10761 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10765 /* X must be a constant. Write the 1's complement of the
10768 output_operand_lossage ("invalid %%k value");
10770 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
10774 /* X must be a symbolic constant on ELF. Write an
10775 expression suitable for an 'addi' that adds in the low 16
10776 bits of the MEM. */
10777 if (GET_CODE (x
) != CONST
)
10779 print_operand_address (file
, x
);
10780 fputs ("@l", file
);
10784 if (GET_CODE (XEXP (x
, 0)) != PLUS
10785 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
10786 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
10787 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
10788 output_operand_lossage ("invalid %%K value");
10789 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
10790 fputs ("@l", file
);
10791 /* For GNU as, there must be a non-alphanumeric character
10792 between 'l' and the number. The '-' is added by
10793 print_operand() already. */
10794 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
10796 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
10800 /* %l is output_asm_label. */
10803 /* Write second word of DImode or DFmode reference. Works on register
10804 or non-indexed memory only. */
10805 if (GET_CODE (x
) == REG
)
10806 fputs (reg_names
[REGNO (x
) + 1], file
);
10807 else if (GET_CODE (x
) == MEM
)
10809 /* Handle possible auto-increment. Since it is pre-increment and
10810 we have already done it, we can just use an offset of word. */
10811 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10812 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10813 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
10816 output_address (XEXP (adjust_address_nv (x
, SImode
,
10820 if (small_data_operand (x
, GET_MODE (x
)))
10821 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10822 reg_names
[SMALL_DATA_REG
]);
10827 /* MB value for a mask operand. */
10828 if (! mask_operand (x
, SImode
))
10829 output_operand_lossage ("invalid %%m value");
10831 fprintf (file
, "%d", extract_MB (x
));
10835 /* ME value for a mask operand. */
10836 if (! mask_operand (x
, SImode
))
10837 output_operand_lossage ("invalid %%M value");
10839 fprintf (file
, "%d", extract_ME (x
));
10842 /* %n outputs the negative of its operand. */
10845 /* Write the number of elements in the vector times 4. */
10846 if (GET_CODE (x
) != PARALLEL
)
10847 output_operand_lossage ("invalid %%N value");
10849 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
10853 /* Similar, but subtract 1 first. */
10854 if (GET_CODE (x
) != PARALLEL
)
10855 output_operand_lossage ("invalid %%O value");
10857 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
10861 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10863 || INT_LOWPART (x
) < 0
10864 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
10865 output_operand_lossage ("invalid %%p value");
10867 fprintf (file
, "%d", i
);
10871 /* The operand must be an indirect memory reference. The result
10872 is the register name. */
10873 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
10874 || REGNO (XEXP (x
, 0)) >= 32)
10875 output_operand_lossage ("invalid %%P value");
10877 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
10881 /* This outputs the logical code corresponding to a boolean
10882 expression. The expression may have one or both operands
10883 negated (if one, only the first one). For condition register
10884 logical operations, it will also treat the negated
10885 CR codes as NOTs, but not handle NOTs of them. */
10887 const char *const *t
= 0;
10889 enum rtx_code code
= GET_CODE (x
);
10890 static const char * const tbl
[3][3] = {
10891 { "and", "andc", "nor" },
10892 { "or", "orc", "nand" },
10893 { "xor", "eqv", "xor" } };
10897 else if (code
== IOR
)
10899 else if (code
== XOR
)
10902 output_operand_lossage ("invalid %%q value");
10904 if (GET_CODE (XEXP (x
, 0)) != NOT
)
10908 if (GET_CODE (XEXP (x
, 1)) == NOT
)
10926 /* X is a CR register. Print the mask for `mtcrf'. */
10927 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10928 output_operand_lossage ("invalid %%R value");
10930 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
10934 /* Low 5 bits of 32 - value */
10936 output_operand_lossage ("invalid %%s value");
10938 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
10942 /* PowerPC64 mask position. All 0's is excluded.
10943 CONST_INT 32-bit mask is considered sign-extended so any
10944 transition must occur within the CONST_INT, not on the boundary. */
10945 if (! mask64_operand (x
, DImode
))
10946 output_operand_lossage ("invalid %%S value");
10948 uval
= INT_LOWPART (x
);
10950 if (uval
& 1) /* Clear Left */
10952 #if HOST_BITS_PER_WIDE_INT > 64
10953 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10957 else /* Clear Right */
10960 #if HOST_BITS_PER_WIDE_INT > 64
10961 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10967 gcc_assert (i
>= 0);
10968 fprintf (file
, "%d", i
);
10972 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10973 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
10975 /* Bit 3 is OV bit. */
10976 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
10978 /* If we want bit 31, write a shift count of zero, not 32. */
10979 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10983 /* Print the symbolic name of a branch target register. */
10984 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LINK_REGISTER_REGNUM
10985 && REGNO (x
) != COUNT_REGISTER_REGNUM
))
10986 output_operand_lossage ("invalid %%T value");
10987 else if (REGNO (x
) == LINK_REGISTER_REGNUM
)
10988 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
10990 fputs ("ctr", file
);
10994 /* High-order 16 bits of constant for use in unsigned operand. */
10996 output_operand_lossage ("invalid %%u value");
10998 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
10999 (INT_LOWPART (x
) >> 16) & 0xffff);
11003 /* High-order 16 bits of constant for use in signed operand. */
11005 output_operand_lossage ("invalid %%v value");
11007 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
11008 (INT_LOWPART (x
) >> 16) & 0xffff);
11012 /* Print `u' if this has an auto-increment or auto-decrement. */
11013 if (GET_CODE (x
) == MEM
11014 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
11015 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
))
11020 /* Print the trap code for this operand. */
11021 switch (GET_CODE (x
))
11024 fputs ("eq", file
); /* 4 */
11027 fputs ("ne", file
); /* 24 */
11030 fputs ("lt", file
); /* 16 */
11033 fputs ("le", file
); /* 20 */
11036 fputs ("gt", file
); /* 8 */
11039 fputs ("ge", file
); /* 12 */
11042 fputs ("llt", file
); /* 2 */
11045 fputs ("lle", file
); /* 6 */
11048 fputs ("lgt", file
); /* 1 */
11051 fputs ("lge", file
); /* 5 */
11054 gcc_unreachable ();
11059 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
11062 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
11063 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
11065 print_operand (file
, x
, 0);
11069 /* MB value for a PowerPC64 rldic operand. */
11070 val
= (GET_CODE (x
) == CONST_INT
11071 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
11076 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
11077 if ((val
<<= 1) < 0)
11080 #if HOST_BITS_PER_WIDE_INT == 32
11081 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
11082 i
+= 32; /* zero-extend high-part was all 0's */
11083 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
11085 val
= CONST_DOUBLE_LOW (x
);
11091 for ( ; i
< 64; i
++)
11092 if ((val
<<= 1) < 0)
11097 fprintf (file
, "%d", i
+ 1);
11101 if (GET_CODE (x
) == MEM
11102 && legitimate_indexed_address_p (XEXP (x
, 0), 0))
11107 /* Like 'L', for third word of TImode */
11108 if (GET_CODE (x
) == REG
)
11109 fputs (reg_names
[REGNO (x
) + 2], file
);
11110 else if (GET_CODE (x
) == MEM
)
11112 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
11113 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11114 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
11116 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
11117 if (small_data_operand (x
, GET_MODE (x
)))
11118 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11119 reg_names
[SMALL_DATA_REG
]);
11124 /* X is a SYMBOL_REF. Write out the name preceded by a
11125 period and without any trailing data in brackets. Used for function
11126 names. If we are configured for System V (or the embedded ABI) on
11127 the PowerPC, do not emit the period, since those systems do not use
11128 TOCs and the like. */
11129 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
11131 /* Mark the decl as referenced so that cgraph will output the
11133 if (SYMBOL_REF_DECL (x
))
11134 mark_decl_referenced (SYMBOL_REF_DECL (x
));
11136 /* For macho, check to see if we need a stub. */
11139 const char *name
= XSTR (x
, 0);
11141 if (MACHOPIC_INDIRECT
11142 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
11143 name
= machopic_indirection_name (x
, /*stub_p=*/true);
11145 assemble_name (file
, name
);
11147 else if (!DOT_SYMBOLS
)
11148 assemble_name (file
, XSTR (x
, 0));
11150 rs6000_output_function_entry (file
, XSTR (x
, 0));
11154 /* Like 'L', for last word of TImode. */
11155 if (GET_CODE (x
) == REG
)
11156 fputs (reg_names
[REGNO (x
) + 3], file
);
11157 else if (GET_CODE (x
) == MEM
)
11159 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
11160 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11161 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
11163 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
11164 if (small_data_operand (x
, GET_MODE (x
)))
11165 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11166 reg_names
[SMALL_DATA_REG
]);
11170 /* Print AltiVec or SPE memory operand. */
11175 gcc_assert (GET_CODE (x
) == MEM
);
11179 /* Ugly hack because %y is overloaded. */
11180 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
11181 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
11182 || GET_MODE (x
) == TFmode
11183 || GET_MODE (x
) == TImode
))
11185 /* Handle [reg]. */
11186 if (GET_CODE (tmp
) == REG
)
11188 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
11191 /* Handle [reg+UIMM]. */
11192 else if (GET_CODE (tmp
) == PLUS
&&
11193 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
11197 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
11199 x
= INTVAL (XEXP (tmp
, 1));
11200 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
11204 /* Fall through. Must be [reg+reg]. */
11207 && GET_CODE (tmp
) == AND
11208 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
11209 && INTVAL (XEXP (tmp
, 1)) == -16)
11210 tmp
= XEXP (tmp
, 0);
11211 if (GET_CODE (tmp
) == REG
)
11212 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
11215 gcc_assert (GET_CODE (tmp
) == PLUS
11216 && REG_P (XEXP (tmp
, 0))
11217 && REG_P (XEXP (tmp
, 1)));
11219 if (REGNO (XEXP (tmp
, 0)) == 0)
11220 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
11221 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
11223 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
11224 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
11230 if (GET_CODE (x
) == REG
)
11231 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
11232 else if (GET_CODE (x
) == MEM
)
11234 /* We need to handle PRE_INC and PRE_DEC here, since we need to
11235 know the width from the mode. */
11236 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
11237 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
11238 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
11239 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11240 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
11241 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
11243 output_address (XEXP (x
, 0));
11246 output_addr_const (file
, x
);
11250 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
11254 output_operand_lossage ("invalid %%xn code");
11258 /* Print the address of an operand. */
11261 print_operand_address (FILE *file
, rtx x
)
11263 if (GET_CODE (x
) == REG
)
11264 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
11265 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
11266 || GET_CODE (x
) == LABEL_REF
)
11268 output_addr_const (file
, x
);
11269 if (small_data_operand (x
, GET_MODE (x
)))
11270 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11271 reg_names
[SMALL_DATA_REG
]);
11273 gcc_assert (!TARGET_TOC
);
11275 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
11277 gcc_assert (REG_P (XEXP (x
, 0)));
11278 if (REGNO (XEXP (x
, 0)) == 0)
11279 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
11280 reg_names
[ REGNO (XEXP (x
, 0)) ]);
11282 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
11283 reg_names
[ REGNO (XEXP (x
, 1)) ]);
11285 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
11286 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
11287 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
11289 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
11290 && CONSTANT_P (XEXP (x
, 1)))
11292 output_addr_const (file
, XEXP (x
, 1));
11293 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
11297 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
11298 && CONSTANT_P (XEXP (x
, 1)))
11300 fprintf (file
, "lo16(");
11301 output_addr_const (file
, XEXP (x
, 1));
11302 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
11305 else if (legitimate_constant_pool_address_p (x
))
11307 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
11309 rtx contains_minus
= XEXP (x
, 1);
11313 /* Find the (minus (sym) (toc)) buried in X, and temporarily
11314 turn it into (sym) for output_addr_const. */
11315 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
11316 contains_minus
= XEXP (contains_minus
, 0);
11318 minus
= XEXP (contains_minus
, 0);
11319 symref
= XEXP (minus
, 0);
11320 XEXP (contains_minus
, 0) = symref
;
11325 name
= XSTR (symref
, 0);
11326 newname
= alloca (strlen (name
) + sizeof ("@toc"));
11327 strcpy (newname
, name
);
11328 strcat (newname
, "@toc");
11329 XSTR (symref
, 0) = newname
;
11331 output_addr_const (file
, XEXP (x
, 1));
11333 XSTR (symref
, 0) = name
;
11334 XEXP (contains_minus
, 0) = minus
;
11337 output_addr_const (file
, XEXP (x
, 1));
11339 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
11342 gcc_unreachable ();
11345 /* Target hook for assembling integer objects. The PowerPC version has
11346 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
11347 is defined. It also needs to handle DI-mode objects on 64-bit
11351 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
11353 #ifdef RELOCATABLE_NEEDS_FIXUP
11354 /* Special handling for SI values. */
11355 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
11357 static int recurse
= 0;
11359 /* For -mrelocatable, we mark all addresses that need to be fixed up
11360 in the .fixup section. */
11361 if (TARGET_RELOCATABLE
11362 && in_section
!= toc_section
11363 && in_section
!= text_section
11364 && !unlikely_text_section_p (in_section
)
11366 && GET_CODE (x
) != CONST_INT
11367 && GET_CODE (x
) != CONST_DOUBLE
11373 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
11375 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
11376 fprintf (asm_out_file
, "\t.long\t(");
11377 output_addr_const (asm_out_file
, x
);
11378 fprintf (asm_out_file
, ")@fixup\n");
11379 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
11380 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
11381 fprintf (asm_out_file
, "\t.long\t");
11382 assemble_name (asm_out_file
, buf
);
11383 fprintf (asm_out_file
, "\n\t.previous\n");
11387 /* Remove initial .'s to turn a -mcall-aixdesc function
11388 address into the address of the descriptor, not the function
11390 else if (GET_CODE (x
) == SYMBOL_REF
11391 && XSTR (x
, 0)[0] == '.'
11392 && DEFAULT_ABI
== ABI_AIX
)
11394 const char *name
= XSTR (x
, 0);
11395 while (*name
== '.')
11398 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
11402 #endif /* RELOCATABLE_NEEDS_FIXUP */
11403 return default_assemble_integer (x
, size
, aligned_p
);
11406 #ifdef HAVE_GAS_HIDDEN
11407 /* Emit an assembler directive to set symbol visibility for DECL to
11408 VISIBILITY_TYPE. */
11411 rs6000_assemble_visibility (tree decl
, int vis
)
11413 /* Functions need to have their entry point symbol visibility set as
11414 well as their descriptor symbol visibility. */
11415 if (DEFAULT_ABI
== ABI_AIX
11417 && TREE_CODE (decl
) == FUNCTION_DECL
)
11419 static const char * const visibility_types
[] = {
11420 NULL
, "internal", "hidden", "protected"
11423 const char *name
, *type
;
11425 name
= ((* targetm
.strip_name_encoding
)
11426 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
11427 type
= visibility_types
[vis
];
11429 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
11430 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
11433 default_assemble_visibility (decl
, vis
);
11438 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
11440 /* Reversal of FP compares takes care -- an ordered compare
11441 becomes an unordered compare and vice versa. */
11442 if (mode
== CCFPmode
11443 && (!flag_finite_math_only
11444 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
11445 || code
== UNEQ
|| code
== LTGT
))
11446 return reverse_condition_maybe_unordered (code
);
11448 return reverse_condition (code
);
11451 /* Generate a compare for CODE. Return a brand-new rtx that
11452 represents the result of the compare. */
11455 rs6000_generate_compare (enum rtx_code code
)
11457 enum machine_mode comp_mode
;
11458 rtx compare_result
;
11460 if (rs6000_compare_fp_p
)
11461 comp_mode
= CCFPmode
;
11462 else if (code
== GTU
|| code
== LTU
11463 || code
== GEU
|| code
== LEU
)
11464 comp_mode
= CCUNSmode
;
11465 else if ((code
== EQ
|| code
== NE
)
11466 && GET_CODE (rs6000_compare_op0
) == SUBREG
11467 && GET_CODE (rs6000_compare_op1
) == SUBREG
11468 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
11469 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
11470 /* These are unsigned values, perhaps there will be a later
11471 ordering compare that can be shared with this one.
11472 Unfortunately we cannot detect the signedness of the operands
11473 for non-subregs. */
11474 comp_mode
= CCUNSmode
;
11476 comp_mode
= CCmode
;
11478 /* First, the compare. */
11479 compare_result
= gen_reg_rtx (comp_mode
);
11481 /* E500 FP compare instructions on the GPRs. Yuck! */
11482 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
11483 && rs6000_compare_fp_p
)
11485 rtx cmp
, or_result
, compare_result2
;
11486 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
11488 if (op_mode
== VOIDmode
)
11489 op_mode
= GET_MODE (rs6000_compare_op1
);
11491 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
11492 This explains the following mess. */
11496 case EQ
: case UNEQ
: case NE
: case LTGT
:
11500 cmp
= flag_unsafe_math_optimizations
11501 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
11502 rs6000_compare_op1
)
11503 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
11504 rs6000_compare_op1
);
11508 cmp
= flag_unsafe_math_optimizations
11509 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
11510 rs6000_compare_op1
)
11511 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
11512 rs6000_compare_op1
);
11516 cmp
= flag_unsafe_math_optimizations
11517 ? gen_tsttfeq_gpr (compare_result
, rs6000_compare_op0
,
11518 rs6000_compare_op1
)
11519 : gen_cmptfeq_gpr (compare_result
, rs6000_compare_op0
,
11520 rs6000_compare_op1
);
11524 gcc_unreachable ();
11528 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
11532 cmp
= flag_unsafe_math_optimizations
11533 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
11534 rs6000_compare_op1
)
11535 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
11536 rs6000_compare_op1
);
11540 cmp
= flag_unsafe_math_optimizations
11541 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
11542 rs6000_compare_op1
)
11543 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
11544 rs6000_compare_op1
);
11548 cmp
= flag_unsafe_math_optimizations
11549 ? gen_tsttfgt_gpr (compare_result
, rs6000_compare_op0
,
11550 rs6000_compare_op1
)
11551 : gen_cmptfgt_gpr (compare_result
, rs6000_compare_op0
,
11552 rs6000_compare_op1
);
11556 gcc_unreachable ();
11560 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
11564 cmp
= flag_unsafe_math_optimizations
11565 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
11566 rs6000_compare_op1
)
11567 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
11568 rs6000_compare_op1
);
11572 cmp
= flag_unsafe_math_optimizations
11573 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
11574 rs6000_compare_op1
)
11575 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
11576 rs6000_compare_op1
);
11580 cmp
= flag_unsafe_math_optimizations
11581 ? gen_tsttflt_gpr (compare_result
, rs6000_compare_op0
,
11582 rs6000_compare_op1
)
11583 : gen_cmptflt_gpr (compare_result
, rs6000_compare_op0
,
11584 rs6000_compare_op1
);
11588 gcc_unreachable ();
11592 gcc_unreachable ();
11595 /* Synthesize LE and GE from LT/GT || EQ. */
11596 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
11602 case LE
: code
= LT
; break;
11603 case GE
: code
= GT
; break;
11604 case LEU
: code
= LT
; break;
11605 case GEU
: code
= GT
; break;
11606 default: gcc_unreachable ();
11609 compare_result2
= gen_reg_rtx (CCFPmode
);
11615 cmp
= flag_unsafe_math_optimizations
11616 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11617 rs6000_compare_op1
)
11618 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11619 rs6000_compare_op1
);
11623 cmp
= flag_unsafe_math_optimizations
11624 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11625 rs6000_compare_op1
)
11626 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11627 rs6000_compare_op1
);
11631 cmp
= flag_unsafe_math_optimizations
11632 ? gen_tsttfeq_gpr (compare_result2
, rs6000_compare_op0
,
11633 rs6000_compare_op1
)
11634 : gen_cmptfeq_gpr (compare_result2
, rs6000_compare_op0
,
11635 rs6000_compare_op1
);
11639 gcc_unreachable ();
11643 /* OR them together. */
11644 or_result
= gen_reg_rtx (CCFPmode
);
11645 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
11647 compare_result
= or_result
;
11652 if (code
== NE
|| code
== LTGT
)
11662 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11663 CLOBBERs to match cmptf_internal2 pattern. */
11664 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
11665 && GET_MODE (rs6000_compare_op0
) == TFmode
11666 && !TARGET_IEEEQUAD
11667 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
11668 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
11670 gen_rtx_SET (VOIDmode
,
11672 gen_rtx_COMPARE (comp_mode
,
11673 rs6000_compare_op0
,
11674 rs6000_compare_op1
)),
11675 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11676 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11677 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11678 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11679 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11680 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11681 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11682 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
11683 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
11684 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
11686 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
11687 comp_mode
= CCEQmode
;
11688 compare_result
= gen_reg_rtx (CCEQmode
);
11690 emit_insn (gen_stack_protect_testdi (compare_result
,
11691 rs6000_compare_op0
, op1
));
11693 emit_insn (gen_stack_protect_testsi (compare_result
,
11694 rs6000_compare_op0
, op1
));
11697 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
11698 gen_rtx_COMPARE (comp_mode
,
11699 rs6000_compare_op0
,
11700 rs6000_compare_op1
)));
11703 /* Some kinds of FP comparisons need an OR operation;
11704 under flag_finite_math_only we don't bother. */
11705 if (rs6000_compare_fp_p
11706 && !flag_finite_math_only
11707 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
11708 && (code
== LE
|| code
== GE
11709 || code
== UNEQ
|| code
== LTGT
11710 || code
== UNGT
|| code
== UNLT
))
11712 enum rtx_code or1
, or2
;
11713 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
11714 rtx or_result
= gen_reg_rtx (CCEQmode
);
11718 case LE
: or1
= LT
; or2
= EQ
; break;
11719 case GE
: or1
= GT
; or2
= EQ
; break;
11720 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
11721 case LTGT
: or1
= LT
; or2
= GT
; break;
11722 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
11723 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
11724 default: gcc_unreachable ();
11726 validate_condition_mode (or1
, comp_mode
);
11727 validate_condition_mode (or2
, comp_mode
);
11728 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
11729 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
11730 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
11731 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
11733 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
11735 compare_result
= or_result
;
11739 validate_condition_mode (code
, GET_MODE (compare_result
));
11741 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
11745 /* Emit the RTL for an sCOND pattern. */
11748 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
11751 enum machine_mode op_mode
;
11752 enum rtx_code cond_code
;
11754 condition_rtx
= rs6000_generate_compare (code
);
11755 cond_code
= GET_CODE (condition_rtx
);
11757 if (rs6000_compare_fp_p
11758 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
11762 PUT_MODE (condition_rtx
, SImode
);
11763 t
= XEXP (condition_rtx
, 0);
11765 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
11767 if (cond_code
== NE
)
11768 emit_insn (gen_e500_flip_gt_bit (t
, t
));
11770 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
11774 if (cond_code
== NE
11775 || cond_code
== GE
|| cond_code
== LE
11776 || cond_code
== GEU
|| cond_code
== LEU
11777 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
11779 rtx not_result
= gen_reg_rtx (CCEQmode
);
11780 rtx not_op
, rev_cond_rtx
;
11781 enum machine_mode cc_mode
;
11783 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
11785 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
11786 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
11787 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
11788 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
11789 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
11792 op_mode
= GET_MODE (rs6000_compare_op0
);
11793 if (op_mode
== VOIDmode
)
11794 op_mode
= GET_MODE (rs6000_compare_op1
);
11796 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
11798 PUT_MODE (condition_rtx
, DImode
);
11799 convert_move (result
, condition_rtx
, 0);
11803 PUT_MODE (condition_rtx
, SImode
);
11804 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
11808 /* Emit a branch of kind CODE to location LOC. */
11811 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
11813 rtx condition_rtx
, loc_ref
;
11815 condition_rtx
= rs6000_generate_compare (code
);
11816 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
11817 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
11818 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
11819 loc_ref
, pc_rtx
)));
11822 /* Return the string to output a conditional branch to LABEL, which is
11823 the operand number of the label, or -1 if the branch is really a
11824 conditional return.
11826 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11827 condition code register and its mode specifies what kind of
11828 comparison we made.
11830 REVERSED is nonzero if we should reverse the sense of the comparison.
11832 INSN is the insn. */
11835 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
11837 static char string
[64];
11838 enum rtx_code code
= GET_CODE (op
);
11839 rtx cc_reg
= XEXP (op
, 0);
11840 enum machine_mode mode
= GET_MODE (cc_reg
);
11841 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
11842 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
11843 int really_reversed
= reversed
^ need_longbranch
;
11849 validate_condition_mode (code
, mode
);
11851 /* Work out which way this really branches. We could use
11852 reverse_condition_maybe_unordered here always but this
11853 makes the resulting assembler clearer. */
11854 if (really_reversed
)
11856 /* Reversal of FP compares takes care -- an ordered compare
11857 becomes an unordered compare and vice versa. */
11858 if (mode
== CCFPmode
)
11859 code
= reverse_condition_maybe_unordered (code
);
11861 code
= reverse_condition (code
);
11864 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
11866 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11871 /* Opposite of GT. */
11880 gcc_unreachable ();
11886 /* Not all of these are actually distinct opcodes, but
11887 we distinguish them for clarity of the resulting assembler. */
11888 case NE
: case LTGT
:
11889 ccode
= "ne"; break;
11890 case EQ
: case UNEQ
:
11891 ccode
= "eq"; break;
11893 ccode
= "ge"; break;
11894 case GT
: case GTU
: case UNGT
:
11895 ccode
= "gt"; break;
11897 ccode
= "le"; break;
11898 case LT
: case LTU
: case UNLT
:
11899 ccode
= "lt"; break;
11900 case UNORDERED
: ccode
= "un"; break;
11901 case ORDERED
: ccode
= "nu"; break;
11902 case UNGE
: ccode
= "nl"; break;
11903 case UNLE
: ccode
= "ng"; break;
11905 gcc_unreachable ();
11908 /* Maybe we have a guess as to how likely the branch is.
11909 The old mnemonics don't have a way to specify this information. */
11911 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
11912 if (note
!= NULL_RTX
)
11914 /* PROB is the difference from 50%. */
11915 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
11917 /* Only hint for highly probable/improbable branches on newer
11918 cpus as static prediction overrides processor dynamic
11919 prediction. For older cpus we may as well always hint, but
11920 assume not taken for branches that are very close to 50% as a
11921 mispredicted taken branch is more expensive than a
11922 mispredicted not-taken branch. */
11923 if (rs6000_always_hint
11924 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
11925 && br_prob_note_reliable_p (note
)))
11927 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
11928 && ((prob
> 0) ^ need_longbranch
))
11936 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
11938 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
11940 /* We need to escape any '%' characters in the reg_names string.
11941 Assume they'd only be the first character.... */
11942 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
11944 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
11948 /* If the branch distance was too far, we may have to use an
11949 unconditional branch to go the distance. */
11950 if (need_longbranch
)
11951 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
11953 s
+= sprintf (s
, ",%s", label
);
11959 /* Return the string to flip the GT bit on a CR. */
11961 output_e500_flip_gt_bit (rtx dst
, rtx src
)
11963 static char string
[64];
11966 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
11967 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
11970 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
11971 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
11973 sprintf (string
, "crnot %d,%d", a
, b
);
11977 /* Return insn index for the vector compare instruction for given CODE,
11978 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11982 get_vec_cmp_insn (enum rtx_code code
,
11983 enum machine_mode dest_mode
,
11984 enum machine_mode op_mode
)
11986 if (!TARGET_ALTIVEC
)
11987 return INSN_NOT_AVAILABLE
;
11992 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11993 return UNSPEC_VCMPEQUB
;
11994 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11995 return UNSPEC_VCMPEQUH
;
11996 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11997 return UNSPEC_VCMPEQUW
;
11998 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11999 return UNSPEC_VCMPEQFP
;
12002 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
12003 return UNSPEC_VCMPGEFP
;
12005 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
12006 return UNSPEC_VCMPGTSB
;
12007 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
12008 return UNSPEC_VCMPGTSH
;
12009 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
12010 return UNSPEC_VCMPGTSW
;
12011 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
12012 return UNSPEC_VCMPGTFP
;
12015 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
12016 return UNSPEC_VCMPGTUB
;
12017 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
12018 return UNSPEC_VCMPGTUH
;
12019 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
12020 return UNSPEC_VCMPGTUW
;
12025 return INSN_NOT_AVAILABLE
;
12028 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
12029 DMODE is expected destination mode. This is a recursive function. */
12032 rs6000_emit_vector_compare (enum rtx_code rcode
,
12034 enum machine_mode dmode
)
12038 enum machine_mode dest_mode
;
12039 enum machine_mode op_mode
= GET_MODE (op1
);
12041 gcc_assert (TARGET_ALTIVEC
);
12042 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
12044 /* Floating point vector compare instructions uses destination V4SImode.
12045 Move destination to appropriate mode later. */
12046 if (dmode
== V4SFmode
)
12047 dest_mode
= V4SImode
;
12051 mask
= gen_reg_rtx (dest_mode
);
12052 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
12054 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
12056 bool swap_operands
= false;
12057 bool try_again
= false;
12062 swap_operands
= true;
12067 swap_operands
= true;
12075 /* Invert condition and try again.
12076 e.g., A != B becomes ~(A==B). */
12078 enum rtx_code rev_code
;
12079 enum insn_code nor_code
;
12082 rev_code
= reverse_condition_maybe_unordered (rcode
);
12083 eq_rtx
= rs6000_emit_vector_compare (rev_code
, op0
, op1
,
12086 nor_code
= one_cmpl_optab
->handlers
[(int)dest_mode
].insn_code
;
12087 gcc_assert (nor_code
!= CODE_FOR_nothing
);
12088 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
12090 if (dmode
!= dest_mode
)
12092 rtx temp
= gen_reg_rtx (dest_mode
);
12093 convert_move (temp
, mask
, 0);
12103 /* Try GT/GTU/LT/LTU OR EQ */
12106 enum insn_code ior_code
;
12107 enum rtx_code new_code
;
12128 gcc_unreachable ();
12131 c_rtx
= rs6000_emit_vector_compare (new_code
,
12132 op0
, op1
, dest_mode
);
12133 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
12136 ior_code
= ior_optab
->handlers
[(int)dest_mode
].insn_code
;
12137 gcc_assert (ior_code
!= CODE_FOR_nothing
);
12138 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
12139 if (dmode
!= dest_mode
)
12141 rtx temp
= gen_reg_rtx (dest_mode
);
12142 convert_move (temp
, mask
, 0);
12149 gcc_unreachable ();
12154 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
12155 /* You only get two chances. */
12156 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
12168 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
12169 gen_rtx_UNSPEC (dest_mode
,
12170 gen_rtvec (2, op0
, op1
),
12172 if (dmode
!= dest_mode
)
12174 rtx temp
= gen_reg_rtx (dest_mode
);
12175 convert_move (temp
, mask
, 0);
12181 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
12182 valid insn doesn exist for given mode. */
12185 get_vsel_insn (enum machine_mode mode
)
12190 return UNSPEC_VSEL4SI
;
12193 return UNSPEC_VSEL4SF
;
12196 return UNSPEC_VSEL8HI
;
12199 return UNSPEC_VSEL16QI
;
12202 return INSN_NOT_AVAILABLE
;
12205 return INSN_NOT_AVAILABLE
;
12208 /* Emit vector select insn where DEST is destination using
12209 operands OP1, OP2 and MASK. */
12212 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
12215 enum machine_mode dest_mode
= GET_MODE (dest
);
12216 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
12218 temp
= gen_reg_rtx (dest_mode
);
12220 /* For each vector element, select op1 when mask is 1 otherwise
12222 t
= gen_rtx_SET (VOIDmode
, temp
,
12223 gen_rtx_UNSPEC (dest_mode
,
12224 gen_rtvec (3, op2
, op1
, mask
),
12227 emit_move_insn (dest
, temp
);
12231 /* Emit vector conditional expression.
12232 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
12233 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
12236 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
12237 rtx cond
, rtx cc_op0
, rtx cc_op1
)
12239 enum machine_mode dest_mode
= GET_MODE (dest
);
12240 enum rtx_code rcode
= GET_CODE (cond
);
12243 if (!TARGET_ALTIVEC
)
12246 /* Get the vector mask for the given relational operations. */
12247 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
12249 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
12254 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
12255 operands of the last comparison is nonzero/true, FALSE_COND if it
12256 is zero/false. Return 0 if the hardware has no such operation. */
12259 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
12261 enum rtx_code code
= GET_CODE (op
);
12262 rtx op0
= rs6000_compare_op0
;
12263 rtx op1
= rs6000_compare_op1
;
12264 REAL_VALUE_TYPE c1
;
12265 enum machine_mode compare_mode
= GET_MODE (op0
);
12266 enum machine_mode result_mode
= GET_MODE (dest
);
12268 bool is_against_zero
;
12270 /* These modes should always match. */
12271 if (GET_MODE (op1
) != compare_mode
12272 /* In the isel case however, we can use a compare immediate, so
12273 op1 may be a small constant. */
12274 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
12276 if (GET_MODE (true_cond
) != result_mode
)
12278 if (GET_MODE (false_cond
) != result_mode
)
12281 /* First, work out if the hardware can do this at all, or
12282 if it's too slow.... */
12283 if (! rs6000_compare_fp_p
)
12286 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
12289 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
12290 && SCALAR_FLOAT_MODE_P (compare_mode
))
12293 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
12295 /* A floating-point subtract might overflow, underflow, or produce
12296 an inexact result, thus changing the floating-point flags, so it
12297 can't be generated if we care about that. It's safe if one side
12298 of the construct is zero, since then no subtract will be
12300 if (SCALAR_FLOAT_MODE_P (compare_mode
)
12301 && flag_trapping_math
&& ! is_against_zero
)
12304 /* Eliminate half of the comparisons by switching operands, this
12305 makes the remaining code simpler. */
12306 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
12307 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
12309 code
= reverse_condition_maybe_unordered (code
);
12311 true_cond
= false_cond
;
12315 /* UNEQ and LTGT take four instructions for a comparison with zero,
12316 it'll probably be faster to use a branch here too. */
12317 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
12320 if (GET_CODE (op1
) == CONST_DOUBLE
)
12321 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
12323 /* We're going to try to implement comparisons by performing
12324 a subtract, then comparing against zero. Unfortunately,
12325 Inf - Inf is NaN which is not zero, and so if we don't
12326 know that the operand is finite and the comparison
12327 would treat EQ different to UNORDERED, we can't do it. */
12328 if (HONOR_INFINITIES (compare_mode
)
12329 && code
!= GT
&& code
!= UNGE
12330 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
12331 /* Constructs of the form (a OP b ? a : b) are safe. */
12332 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
12333 || (! rtx_equal_p (op0
, true_cond
)
12334 && ! rtx_equal_p (op1
, true_cond
))))
12337 /* At this point we know we can use fsel. */
12339 /* Reduce the comparison to a comparison against zero. */
12340 if (! is_against_zero
)
12342 temp
= gen_reg_rtx (compare_mode
);
12343 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12344 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
12346 op1
= CONST0_RTX (compare_mode
);
12349 /* If we don't care about NaNs we can reduce some of the comparisons
12350 down to faster ones. */
12351 if (! HONOR_NANS (compare_mode
))
12357 true_cond
= false_cond
;
12370 /* Now, reduce everything down to a GE. */
12377 temp
= gen_reg_rtx (compare_mode
);
12378 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
12383 temp
= gen_reg_rtx (compare_mode
);
12384 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
12389 temp
= gen_reg_rtx (compare_mode
);
12390 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12391 gen_rtx_NEG (compare_mode
,
12392 gen_rtx_ABS (compare_mode
, op0
))));
12397 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
12398 temp
= gen_reg_rtx (result_mode
);
12399 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12400 gen_rtx_IF_THEN_ELSE (result_mode
,
12401 gen_rtx_GE (VOIDmode
,
12403 true_cond
, false_cond
)));
12404 false_cond
= true_cond
;
12407 temp
= gen_reg_rtx (compare_mode
);
12408 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
12413 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
12414 temp
= gen_reg_rtx (result_mode
);
12415 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12416 gen_rtx_IF_THEN_ELSE (result_mode
,
12417 gen_rtx_GE (VOIDmode
,
12419 true_cond
, false_cond
)));
12420 true_cond
= false_cond
;
12423 temp
= gen_reg_rtx (compare_mode
);
12424 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
12429 gcc_unreachable ();
12432 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
12433 gen_rtx_IF_THEN_ELSE (result_mode
,
12434 gen_rtx_GE (VOIDmode
,
12436 true_cond
, false_cond
)));
12440 /* Same as above, but for ints (isel). */
12443 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
12445 rtx condition_rtx
, cr
;
12447 /* All isel implementations thus far are 32-bits. */
12448 if (GET_MODE (rs6000_compare_op0
) != SImode
)
12451 /* We still have to do the compare, because isel doesn't do a
12452 compare, it just looks at the CRx bits set by a previous compare
12454 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
12455 cr
= XEXP (condition_rtx
, 0);
12457 if (GET_MODE (cr
) == CCmode
)
12458 emit_insn (gen_isel_signed (dest
, condition_rtx
,
12459 true_cond
, false_cond
, cr
));
12461 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
12462 true_cond
, false_cond
, cr
));
12468 output_isel (rtx
*operands
)
12470 enum rtx_code code
;
12472 code
= GET_CODE (operands
[1]);
12473 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
12475 PUT_CODE (operands
[1], reverse_condition (code
));
12476 return "isel %0,%3,%2,%j1";
12479 return "isel %0,%2,%3,%j1";
12483 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
12485 enum machine_mode mode
= GET_MODE (op0
);
12489 if (code
== SMAX
|| code
== SMIN
)
12494 if (code
== SMAX
|| code
== UMAX
)
12495 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
12496 op0
, op1
, mode
, 0);
12498 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
12499 op1
, op0
, mode
, 0);
12500 gcc_assert (target
);
12501 if (target
!= dest
)
12502 emit_move_insn (dest
, target
);
12505 /* Emit instructions to perform a load-reserved/store-conditional operation.
12506 The operation performed is an atomic
12507 (set M (CODE:MODE M OP))
12508 If not NULL, BEFORE is atomically set to M before the operation, and
12509 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
12510 If SYNC_P then a memory barrier is emitted before the operation.
12511 Either OP or M may be wrapped in a NOT operation. */
12514 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
12515 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
12518 enum machine_mode used_mode
;
12519 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
12522 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
12523 rtx shift
= NULL_RTX
;
12526 emit_insn (gen_memory_barrier ());
12528 if (GET_CODE (m
) == NOT
)
12529 used_m
= XEXP (m
, 0);
12533 /* If this is smaller than SImode, we'll have to use SImode with
12535 if (mode
== QImode
|| mode
== HImode
)
12539 if (MEM_ALIGN (used_m
) >= 32)
12542 if (BYTES_BIG_ENDIAN
)
12543 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
12545 shift
= GEN_INT (ishift
);
12549 rtx addrSI
, aligned_addr
;
12550 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
12552 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
,
12553 XEXP (used_m
, 0)));
12554 shift
= gen_reg_rtx (SImode
);
12556 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
12557 GEN_INT (shift_mask
)));
12558 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
12560 aligned_addr
= expand_binop (Pmode
, and_optab
,
12562 GEN_INT (-4), NULL_RTX
,
12563 1, OPTAB_LIB_WIDEN
);
12564 used_m
= change_address (used_m
, SImode
, aligned_addr
);
12565 set_mem_align (used_m
, 32);
12566 /* It's safe to keep the old alias set of USED_M, because
12567 the operation is atomic and only affects the original
12569 if (GET_CODE (m
) == NOT
)
12570 m
= gen_rtx_NOT (SImode
, used_m
);
12575 if (GET_CODE (op
) == NOT
)
12577 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
12578 oldop
= gen_rtx_NOT (SImode
, oldop
);
12581 oldop
= lowpart_subreg (SImode
, op
, mode
);
12587 newop
= expand_binop (SImode
, and_optab
,
12588 oldop
, GEN_INT (imask
), NULL_RTX
,
12589 1, OPTAB_LIB_WIDEN
);
12590 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12594 newop
= expand_binop (SImode
, ior_optab
,
12595 oldop
, GEN_INT (~imask
), NULL_RTX
,
12596 1, OPTAB_LIB_WIDEN
);
12597 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
12605 newop
= expand_binop (SImode
, and_optab
,
12606 oldop
, GEN_INT (imask
), NULL_RTX
,
12607 1, OPTAB_LIB_WIDEN
);
12608 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12610 mask
= gen_reg_rtx (SImode
);
12611 emit_move_insn (mask
, GEN_INT (imask
));
12612 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12615 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
12617 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
12618 newop
= gen_rtx_AND (SImode
, newop
, mask
);
12619 newop
= gen_rtx_IOR (SImode
, newop
,
12620 gen_rtx_AND (SImode
,
12621 gen_rtx_NOT (SImode
, mask
),
12627 gcc_unreachable ();
12630 if (GET_CODE (m
) == NOT
)
12634 mask
= gen_reg_rtx (SImode
);
12635 emit_move_insn (mask
, GEN_INT (imask
));
12636 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12638 xorm
= gen_rtx_XOR (SImode
, used_m
, mask
);
12639 /* Depending on the value of 'op', the XOR or the operation might
12640 be able to be simplified away. */
12641 newop
= simplify_gen_binary (code
, SImode
, xorm
, newop
);
12644 used_mode
= SImode
;
12645 before
= gen_reg_rtx (used_mode
);
12646 after
= gen_reg_rtx (used_mode
);
12651 before
= before_param
;
12652 after
= after_param
;
12654 if (before
== NULL_RTX
)
12655 before
= gen_reg_rtx (used_mode
);
12656 if (after
== NULL_RTX
)
12657 after
= gen_reg_rtx (used_mode
);
12660 if ((code
== PLUS
|| code
== MINUS
|| GET_CODE (m
) == NOT
)
12661 && used_mode
!= mode
)
12662 the_op
= op
; /* Computed above. */
12663 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
12664 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
12666 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
12668 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
12669 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
12670 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
12671 gen_rtx_UNSPEC (used_mode
,
12672 gen_rtvec (1, the_op
),
12674 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
12676 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
12677 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
12678 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
12680 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
12681 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
12683 /* Shift and mask the return values properly. */
12684 if (used_mode
!= mode
&& before_param
)
12686 emit_insn (gen_lshrsi3 (before
, before
, shift
));
12687 convert_move (before_param
, before
, 1);
12690 if (used_mode
!= mode
&& after_param
)
12692 emit_insn (gen_lshrsi3 (after
, after
, shift
));
12693 convert_move (after_param
, after
, 1);
12696 /* The previous sequence will end with a branch that's dependent on
12697 the conditional store, so placing an isync will ensure that no
12698 other instructions (especially, no load or store instructions)
12699 can start before the atomic operation completes. */
12701 emit_insn (gen_isync ());
12704 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12705 COND is true. Mark the jump as unlikely to be taken. */
12708 emit_unlikely_jump (rtx cond
, rtx label
)
12710 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
12713 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
12714 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
12715 REG_NOTES (x
) = gen_rtx_EXPR_LIST (REG_BR_PROB
, very_unlikely
, NULL_RTX
);
12718 /* A subroutine of the atomic operation splitters. Emit a load-locked
12719 instruction in MODE. */
12722 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
12724 rtx (*fn
) (rtx
, rtx
) = NULL
;
12725 if (mode
== SImode
)
12726 fn
= gen_load_locked_si
;
12727 else if (mode
== DImode
)
12728 fn
= gen_load_locked_di
;
12729 emit_insn (fn (reg
, mem
));
12732 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12733 instruction in MODE. */
12736 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
12738 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
12739 if (mode
== SImode
)
12740 fn
= gen_store_conditional_si
;
12741 else if (mode
== DImode
)
12742 fn
= gen_store_conditional_di
;
12744 /* Emit sync before stwcx. to address PPC405 Erratum. */
12745 if (PPC405_ERRATUM77
)
12746 emit_insn (gen_memory_barrier ());
12748 emit_insn (fn (res
, mem
, val
));
12751 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
12752 to perform. MEM is the memory on which to operate. VAL is the second
12753 operand of the binary operator. BEFORE and AFTER are optional locations to
12754 return the value of MEM either before of after the operation. SCRATCH is
12755 a scratch register. */
12758 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
12759 rtx before
, rtx after
, rtx scratch
)
12761 enum machine_mode mode
= GET_MODE (mem
);
12762 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12764 emit_insn (gen_memory_barrier ());
12766 label
= gen_label_rtx ();
12767 emit_label (label
);
12768 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
12770 if (before
== NULL_RTX
)
12772 emit_load_locked (mode
, before
, mem
);
12775 x
= gen_rtx_AND (mode
, gen_rtx_NOT (mode
, before
), val
);
12776 else if (code
== AND
)
12777 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
12779 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
12781 if (after
!= NULL_RTX
)
12782 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
12783 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
12785 emit_store_conditional (mode
, cond
, mem
, scratch
);
12787 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12788 emit_unlikely_jump (x
, label
);
12790 emit_insn (gen_isync ());
12793 /* Expand an atomic compare and swap operation. MEM is the memory on which
12794 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12795 value to be stored. SCRATCH is a scratch GPR. */
12798 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
12801 enum machine_mode mode
= GET_MODE (mem
);
12802 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12804 emit_insn (gen_memory_barrier ());
12806 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12807 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12808 emit_label (XEXP (label1
, 0));
12810 emit_load_locked (mode
, retval
, mem
);
12812 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
12813 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
12815 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12816 emit_unlikely_jump (x
, label2
);
12818 emit_move_insn (scratch
, newval
);
12819 emit_store_conditional (mode
, cond
, mem
, scratch
);
12821 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12822 emit_unlikely_jump (x
, label1
);
12824 emit_insn (gen_isync ());
12825 emit_label (XEXP (label2
, 0));
12828 /* Expand an atomic test and set operation. MEM is the memory on which
12829 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12832 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
12834 enum machine_mode mode
= GET_MODE (mem
);
12835 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12837 emit_insn (gen_memory_barrier ());
12839 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12840 emit_label (XEXP (label
, 0));
12842 emit_load_locked (mode
, retval
, mem
);
12843 emit_move_insn (scratch
, val
);
12844 emit_store_conditional (mode
, cond
, mem
, scratch
);
12846 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12847 emit_unlikely_jump (x
, label
);
12849 emit_insn (gen_isync ());
12853 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
12855 enum machine_mode mode
= GET_MODE (mem
);
12856 rtx addrSI
, align
, wdst
, shift
, mask
;
12857 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
12858 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
12860 /* Shift amount for subword relative to aligned word. */
12861 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, XEXP (mem
, 0)));
12862 shift
= gen_reg_rtx (SImode
);
12863 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
12864 GEN_INT (shift_mask
)));
12865 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
12867 /* Shift and mask old value into position within word. */
12868 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
12869 oldval
= expand_binop (SImode
, and_optab
,
12870 oldval
, GEN_INT (imask
), NULL_RTX
,
12871 1, OPTAB_LIB_WIDEN
);
12872 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
12874 /* Shift and mask new value into position within word. */
12875 newval
= convert_modes (SImode
, mode
, newval
, 1);
12876 newval
= expand_binop (SImode
, and_optab
,
12877 newval
, GEN_INT (imask
), NULL_RTX
,
12878 1, OPTAB_LIB_WIDEN
);
12879 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
12881 /* Mask for insertion. */
12882 mask
= gen_reg_rtx (SImode
);
12883 emit_move_insn (mask
, GEN_INT (imask
));
12884 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12886 /* Address of aligned word containing subword. */
12887 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
12888 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
12889 mem
= change_address (mem
, SImode
, align
);
12890 set_mem_align (mem
, 32);
12891 MEM_VOLATILE_P (mem
) = 1;
12893 wdst
= gen_reg_rtx (SImode
);
12894 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
12895 oldval
, newval
, mem
));
12897 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
12901 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
12902 rtx oldval
, rtx newval
, rtx mem
,
12905 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12907 emit_insn (gen_memory_barrier ());
12908 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12909 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12910 emit_label (XEXP (label1
, 0));
12912 emit_load_locked (SImode
, scratch
, mem
);
12914 /* Mask subword within loaded value for comparison with oldval.
12915 Use UNSPEC_AND to avoid clobber.*/
12916 emit_insn (gen_rtx_SET (SImode
, dest
,
12917 gen_rtx_UNSPEC (SImode
,
12918 gen_rtvec (2, scratch
, mask
),
12921 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
12922 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
12924 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12925 emit_unlikely_jump (x
, label2
);
12927 /* Clear subword within loaded value for insertion of new value. */
12928 emit_insn (gen_rtx_SET (SImode
, scratch
,
12929 gen_rtx_AND (SImode
,
12930 gen_rtx_NOT (SImode
, mask
), scratch
)));
12931 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
12932 emit_store_conditional (SImode
, cond
, mem
, scratch
);
12934 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12935 emit_unlikely_jump (x
, label1
);
12937 emit_insn (gen_isync ());
12938 emit_label (XEXP (label2
, 0));
12942 /* Emit instructions to move SRC to DST. Called by splitters for
12943 multi-register moves. It will emit at most one instruction for
12944 each register that is accessed; that is, it won't emit li/lis pairs
12945 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12949 rs6000_split_multireg_move (rtx dst
, rtx src
)
12951 /* The register number of the first register being moved. */
12953 /* The mode that is to be moved. */
12954 enum machine_mode mode
;
12955 /* The mode that the move is being done in, and its size. */
12956 enum machine_mode reg_mode
;
12958 /* The number of registers that will be moved. */
12961 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
12962 mode
= GET_MODE (dst
);
12963 nregs
= hard_regno_nregs
[reg
][mode
];
12964 if (FP_REGNO_P (reg
))
12965 reg_mode
= DECIMAL_FLOAT_MODE_P (mode
) ? DDmode
: DFmode
;
12966 else if (ALTIVEC_REGNO_P (reg
))
12967 reg_mode
= V16QImode
;
12968 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
12971 reg_mode
= word_mode
;
12972 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
12974 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
12976 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
12978 /* Move register range backwards, if we might have destructive
12981 for (i
= nregs
- 1; i
>= 0; i
--)
12982 emit_insn (gen_rtx_SET (VOIDmode
,
12983 simplify_gen_subreg (reg_mode
, dst
, mode
,
12984 i
* reg_mode_size
),
12985 simplify_gen_subreg (reg_mode
, src
, mode
,
12986 i
* reg_mode_size
)));
12992 bool used_update
= false;
12994 if (MEM_P (src
) && INT_REGNO_P (reg
))
12998 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
12999 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
13002 breg
= XEXP (XEXP (src
, 0), 0);
13003 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
13004 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
13005 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
13006 emit_insn (TARGET_32BIT
13007 ? gen_addsi3 (breg
, breg
, delta_rtx
)
13008 : gen_adddi3 (breg
, breg
, delta_rtx
));
13009 src
= replace_equiv_address (src
, breg
);
13011 else if (! rs6000_offsettable_memref_p (src
))
13014 basereg
= gen_rtx_REG (Pmode
, reg
);
13015 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
13016 src
= replace_equiv_address (src
, basereg
);
13019 breg
= XEXP (src
, 0);
13020 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
13021 breg
= XEXP (breg
, 0);
13023 /* If the base register we are using to address memory is
13024 also a destination reg, then change that register last. */
13026 && REGNO (breg
) >= REGNO (dst
)
13027 && REGNO (breg
) < REGNO (dst
) + nregs
)
13028 j
= REGNO (breg
) - REGNO (dst
);
13031 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
13035 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
13036 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
13039 breg
= XEXP (XEXP (dst
, 0), 0);
13040 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
13041 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
13042 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
13044 /* We have to update the breg before doing the store.
13045 Use store with update, if available. */
13049 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
13050 emit_insn (TARGET_32BIT
13051 ? (TARGET_POWERPC64
13052 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
13053 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
13054 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
13055 used_update
= true;
13058 emit_insn (TARGET_32BIT
13059 ? gen_addsi3 (breg
, breg
, delta_rtx
)
13060 : gen_adddi3 (breg
, breg
, delta_rtx
));
13061 dst
= replace_equiv_address (dst
, breg
);
13064 gcc_assert (rs6000_offsettable_memref_p (dst
));
13067 for (i
= 0; i
< nregs
; i
++)
13069 /* Calculate index to next subword. */
13074 /* If compiler already emitted move of first word by
13075 store with update, no need to do anything. */
13076 if (j
== 0 && used_update
)
13079 emit_insn (gen_rtx_SET (VOIDmode
,
13080 simplify_gen_subreg (reg_mode
, dst
, mode
,
13081 j
* reg_mode_size
),
13082 simplify_gen_subreg (reg_mode
, src
, mode
,
13083 j
* reg_mode_size
)));
13089 /* This page contains routines that are used to determine what the
13090 function prologue and epilogue code will do and write them out. */
13092 /* Return the first fixed-point register that is required to be
13093 saved. 32 if none. */
13096 first_reg_to_save (void)
13100 /* Find lowest numbered live register. */
13101 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
13102 if (regs_ever_live
[first_reg
]
13103 && (! call_used_regs
[first_reg
]
13104 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
13105 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
13106 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
13107 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
13112 && current_function_uses_pic_offset_table
13113 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
13114 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
13120 /* Similar, for FP regs. */
13123 first_fp_reg_to_save (void)
13127 /* Find lowest numbered live register. */
13128 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
13129 if (regs_ever_live
[first_reg
])
13135 /* Similar, for AltiVec regs. */
13138 first_altivec_reg_to_save (void)
13142 /* Stack frame remains as is unless we are in AltiVec ABI. */
13143 if (! TARGET_ALTIVEC_ABI
)
13144 return LAST_ALTIVEC_REGNO
+ 1;
13146 /* On Darwin, the unwind routines are compiled without
13147 TARGET_ALTIVEC, and use save_world to save/restore the
13148 altivec registers when necessary. */
13149 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
13150 && ! TARGET_ALTIVEC
)
13151 return FIRST_ALTIVEC_REGNO
+ 20;
13153 /* Find lowest numbered live register. */
13154 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13155 if (regs_ever_live
[i
])
13161 /* Return a 32-bit mask of the AltiVec registers we need to set in
13162 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
13163 the 32-bit word is 0. */
13165 static unsigned int
13166 compute_vrsave_mask (void)
13168 unsigned int i
, mask
= 0;
13170 /* On Darwin, the unwind routines are compiled without
13171 TARGET_ALTIVEC, and use save_world to save/restore the
13172 call-saved altivec registers when necessary. */
13173 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
13174 && ! TARGET_ALTIVEC
)
13177 /* First, find out if we use _any_ altivec registers. */
13178 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13179 if (regs_ever_live
[i
])
13180 mask
|= ALTIVEC_REG_BIT (i
);
13185 /* Next, remove the argument registers from the set. These must
13186 be in the VRSAVE mask set by the caller, so we don't need to add
13187 them in again. More importantly, the mask we compute here is
13188 used to generate CLOBBERs in the set_vrsave insn, and we do not
13189 wish the argument registers to die. */
13190 for (i
= cfun
->args_info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
13191 mask
&= ~ALTIVEC_REG_BIT (i
);
13193 /* Similarly, remove the return value from the set. */
13196 diddle_return_value (is_altivec_return_reg
, &yes
);
13198 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
13204 /* For a very restricted set of circumstances, we can cut down the
13205 size of prologues/epilogues by calling our own save/restore-the-world
13209 compute_save_world_info (rs6000_stack_t
*info_ptr
)
13211 info_ptr
->world_save_p
= 1;
13212 info_ptr
->world_save_p
13213 = (WORLD_SAVE_P (info_ptr
)
13214 && DEFAULT_ABI
== ABI_DARWIN
13215 && ! (current_function_calls_setjmp
&& flag_exceptions
)
13216 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
13217 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
13218 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
13219 && info_ptr
->cr_save_p
);
13221 /* This will not work in conjunction with sibcalls. Make sure there
13222 are none. (This check is expensive, but seldom executed.) */
13223 if (WORLD_SAVE_P (info_ptr
))
13226 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
13227 if ( GET_CODE (insn
) == CALL_INSN
13228 && SIBLING_CALL_P (insn
))
13230 info_ptr
->world_save_p
= 0;
13235 if (WORLD_SAVE_P (info_ptr
))
13237 /* Even if we're not touching VRsave, make sure there's room on the
13238 stack for it, if it looks like we're calling SAVE_WORLD, which
13239 will attempt to save it. */
13240 info_ptr
->vrsave_size
= 4;
13242 /* "Save" the VRsave register too if we're saving the world. */
13243 if (info_ptr
->vrsave_mask
== 0)
13244 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
13246 /* Because the Darwin register save/restore routines only handle
13247 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
13249 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
13250 && (info_ptr
->first_altivec_reg_save
13251 >= FIRST_SAVED_ALTIVEC_REGNO
));
13258 is_altivec_return_reg (rtx reg
, void *xyes
)
13260 bool *yes
= (bool *) xyes
;
13261 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
13266 /* Calculate the stack information for the current function. This is
13267 complicated by having two separate calling sequences, the AIX calling
13268 sequence and the V.4 calling sequence.
13270 AIX (and Darwin/Mac OS X) stack frames look like:
13272 SP----> +---------------------------------------+
13273 | back chain to caller | 0 0
13274 +---------------------------------------+
13275 | saved CR | 4 8 (8-11)
13276 +---------------------------------------+
13278 +---------------------------------------+
13279 | reserved for compilers | 12 24
13280 +---------------------------------------+
13281 | reserved for binders | 16 32
13282 +---------------------------------------+
13283 | saved TOC pointer | 20 40
13284 +---------------------------------------+
13285 | Parameter save area (P) | 24 48
13286 +---------------------------------------+
13287 | Alloca space (A) | 24+P etc.
13288 +---------------------------------------+
13289 | Local variable space (L) | 24+P+A
13290 +---------------------------------------+
13291 | Float/int conversion temporary (X) | 24+P+A+L
13292 +---------------------------------------+
13293 | Save area for AltiVec registers (W) | 24+P+A+L+X
13294 +---------------------------------------+
13295 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
13296 +---------------------------------------+
13297 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
13298 +---------------------------------------+
13299 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
13300 +---------------------------------------+
13301 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
13302 +---------------------------------------+
13303 old SP->| back chain to caller's caller |
13304 +---------------------------------------+
13306 The required alignment for AIX configurations is two words (i.e., 8
13310 V.4 stack frames look like:
13312 SP----> +---------------------------------------+
13313 | back chain to caller | 0
13314 +---------------------------------------+
13315 | caller's saved LR | 4
13316 +---------------------------------------+
13317 | Parameter save area (P) | 8
13318 +---------------------------------------+
13319 | Alloca space (A) | 8+P
13320 +---------------------------------------+
13321 | Varargs save area (V) | 8+P+A
13322 +---------------------------------------+
13323 | Local variable space (L) | 8+P+A+V
13324 +---------------------------------------+
13325 | Float/int conversion temporary (X) | 8+P+A+V+L
13326 +---------------------------------------+
13327 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
13328 +---------------------------------------+
13329 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
13330 +---------------------------------------+
13331 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
13332 +---------------------------------------+
13333 | SPE: area for 64-bit GP registers |
13334 +---------------------------------------+
13335 | SPE alignment padding |
13336 +---------------------------------------+
13337 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
13338 +---------------------------------------+
13339 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
13340 +---------------------------------------+
13341 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
13342 +---------------------------------------+
13343 old SP->| back chain to caller's caller |
13344 +---------------------------------------+
13346 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
13347 given. (But note below and in sysv4.h that we require only 8 and
13348 may round up the size of our stack frame anyways. The historical
13349 reason is early versions of powerpc-linux which didn't properly
13350 align the stack at program startup. A happy side-effect is that
13351 -mno-eabi libraries can be used with -meabi programs.)
13353 The EABI configuration defaults to the V.4 layout. However,
13354 the stack alignment requirements may differ. If -mno-eabi is not
13355 given, the required stack alignment is 8 bytes; if -mno-eabi is
13356 given, the required alignment is 16 bytes. (But see V.4 comment
13359 #ifndef ABI_STACK_BOUNDARY
13360 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
13363 static rs6000_stack_t
*
13364 rs6000_stack_info (void)
13366 static rs6000_stack_t info
;
13367 rs6000_stack_t
*info_ptr
= &info
;
13368 int reg_size
= TARGET_32BIT
? 4 : 8;
13371 HOST_WIDE_INT non_fixed_size
;
13373 memset (&info
, 0, sizeof (info
));
13377 /* Cache value so we don't rescan instruction chain over and over. */
13378 if (cfun
->machine
->insn_chain_scanned_p
== 0)
13379 cfun
->machine
->insn_chain_scanned_p
13380 = spe_func_has_64bit_regs_p () + 1;
13381 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
13384 /* Select which calling sequence. */
13385 info_ptr
->abi
= DEFAULT_ABI
;
13387 /* Calculate which registers need to be saved & save area size. */
13388 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
13389 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
13390 even if it currently looks like we won't. */
13391 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
13392 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
13393 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
13394 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
13395 info_ptr
->gp_size
= reg_size
* (32 - RS6000_PIC_OFFSET_TABLE_REGNUM
);
13397 info_ptr
->gp_size
= reg_size
* (32 - info_ptr
->first_gp_reg_save
);
13399 /* For the SPE, we have an additional upper 32-bits on each GPR.
13400 Ideally we should save the entire 64-bits only when the upper
13401 half is used in SIMD instructions. Since we only record
13402 registers live (not the size they are used in), this proves
13403 difficult because we'd have to traverse the instruction chain at
13404 the right time, taking reload into account. This is a real pain,
13405 so we opt to save the GPRs in 64-bits always if but one register
13406 gets used in 64-bits. Otherwise, all the registers in the frame
13407 get saved in 32-bits.
13409 So... since when we save all GPRs (except the SP) in 64-bits, the
13410 traditional GP save area will be empty. */
13411 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
13412 info_ptr
->gp_size
= 0;
13414 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
13415 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
13417 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
13418 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
13419 - info_ptr
->first_altivec_reg_save
);
13421 /* Does this function call anything? */
13422 info_ptr
->calls_p
= (! current_function_is_leaf
13423 || cfun
->machine
->ra_needs_full_frame
);
13425 /* Determine if we need to save the link register. */
13426 if ((DEFAULT_ABI
== ABI_AIX
13427 && current_function_profile
13428 && !TARGET_PROFILE_KERNEL
)
13429 #ifdef TARGET_RELOCATABLE
13430 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
13432 || (info_ptr
->first_fp_reg_save
!= 64
13433 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
13434 || info_ptr
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
13435 || (DEFAULT_ABI
== ABI_V4
&& current_function_calls_alloca
)
13436 || info_ptr
->calls_p
13437 || rs6000_ra_ever_killed ())
13439 info_ptr
->lr_save_p
= 1;
13440 regs_ever_live
[LINK_REGISTER_REGNUM
] = 1;
13443 /* Determine if we need to save the condition code registers. */
13444 if (regs_ever_live
[CR2_REGNO
]
13445 || regs_ever_live
[CR3_REGNO
]
13446 || regs_ever_live
[CR4_REGNO
])
13448 info_ptr
->cr_save_p
= 1;
13449 if (DEFAULT_ABI
== ABI_V4
)
13450 info_ptr
->cr_size
= reg_size
;
13453 /* If the current function calls __builtin_eh_return, then we need
13454 to allocate stack space for registers that will hold data for
13455 the exception handler. */
13456 if (current_function_calls_eh_return
)
13459 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
13462 /* SPE saves EH registers in 64-bits. */
13463 ehrd_size
= i
* (TARGET_SPE_ABI
13464 && info_ptr
->spe_64bit_regs_used
!= 0
13465 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
13470 /* Determine various sizes. */
13471 info_ptr
->reg_size
= reg_size
;
13472 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
13473 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
13474 info_ptr
->parm_size
= RS6000_ALIGN (current_function_outgoing_args_size
,
13475 TARGET_ALTIVEC
? 16 : 8);
13476 if (FRAME_GROWS_DOWNWARD
)
13477 info_ptr
->vars_size
13478 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
13479 + info_ptr
->parm_size
,
13480 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
13481 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
13482 + info_ptr
->parm_size
);
13484 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
13485 info_ptr
->spe_gp_size
= 8 * (32 - info_ptr
->first_gp_reg_save
);
13487 info_ptr
->spe_gp_size
= 0;
13489 if (TARGET_ALTIVEC_ABI
)
13490 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
13492 info_ptr
->vrsave_mask
= 0;
13494 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
13495 info_ptr
->vrsave_size
= 4;
13497 info_ptr
->vrsave_size
= 0;
13499 compute_save_world_info (info_ptr
);
13501 /* Calculate the offsets. */
13502 switch (DEFAULT_ABI
)
13506 gcc_unreachable ();
13510 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
13511 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
13513 if (TARGET_ALTIVEC_ABI
)
13515 info_ptr
->vrsave_save_offset
13516 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
13518 /* Align stack so vector save area is on a quadword boundary.
13519 The padding goes above the vectors. */
13520 if (info_ptr
->altivec_size
!= 0)
13521 info_ptr
->altivec_padding_size
13522 = info_ptr
->vrsave_save_offset
& 0xF;
13524 info_ptr
->altivec_padding_size
= 0;
13526 info_ptr
->altivec_save_offset
13527 = info_ptr
->vrsave_save_offset
13528 - info_ptr
->altivec_padding_size
13529 - info_ptr
->altivec_size
;
13530 gcc_assert (info_ptr
->altivec_size
== 0
13531 || info_ptr
->altivec_save_offset
% 16 == 0);
13533 /* Adjust for AltiVec case. */
13534 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
13537 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
13538 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
13539 info_ptr
->lr_save_offset
= 2*reg_size
;
13543 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
13544 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
13545 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
13547 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
13549 /* Align stack so SPE GPR save area is aligned on a
13550 double-word boundary. */
13551 if (info_ptr
->spe_gp_size
!= 0)
13552 info_ptr
->spe_padding_size
13553 = 8 - (-info_ptr
->cr_save_offset
% 8);
13555 info_ptr
->spe_padding_size
= 0;
13557 info_ptr
->spe_gp_save_offset
13558 = info_ptr
->cr_save_offset
13559 - info_ptr
->spe_padding_size
13560 - info_ptr
->spe_gp_size
;
13562 /* Adjust for SPE case. */
13563 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
13565 else if (TARGET_ALTIVEC_ABI
)
13567 info_ptr
->vrsave_save_offset
13568 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
13570 /* Align stack so vector save area is on a quadword boundary. */
13571 if (info_ptr
->altivec_size
!= 0)
13572 info_ptr
->altivec_padding_size
13573 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
13575 info_ptr
->altivec_padding_size
= 0;
13577 info_ptr
->altivec_save_offset
13578 = info_ptr
->vrsave_save_offset
13579 - info_ptr
->altivec_padding_size
13580 - info_ptr
->altivec_size
;
13582 /* Adjust for AltiVec case. */
13583 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
13586 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
13587 info_ptr
->ehrd_offset
-= ehrd_size
;
13588 info_ptr
->lr_save_offset
= reg_size
;
13592 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
13593 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
13594 + info_ptr
->gp_size
13595 + info_ptr
->altivec_size
13596 + info_ptr
->altivec_padding_size
13597 + info_ptr
->spe_gp_size
13598 + info_ptr
->spe_padding_size
13600 + info_ptr
->cr_size
13601 + info_ptr
->vrsave_size
,
13604 non_fixed_size
= (info_ptr
->vars_size
13605 + info_ptr
->parm_size
13606 + info_ptr
->save_size
);
13608 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
13609 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
13611 /* Determine if we need to allocate any stack frame:
13613 For AIX we need to push the stack if a frame pointer is needed
13614 (because the stack might be dynamically adjusted), if we are
13615 debugging, if we make calls, or if the sum of fp_save, gp_save,
13616 and local variables are more than the space needed to save all
13617 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13618 + 18*8 = 288 (GPR13 reserved).
13620 For V.4 we don't have the stack cushion that AIX uses, but assume
13621 that the debugger can handle stackless frames. */
13623 if (info_ptr
->calls_p
)
13624 info_ptr
->push_p
= 1;
13626 else if (DEFAULT_ABI
== ABI_V4
)
13627 info_ptr
->push_p
= non_fixed_size
!= 0;
13629 else if (frame_pointer_needed
)
13630 info_ptr
->push_p
= 1;
13632 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
13633 info_ptr
->push_p
= 1;
13636 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
13638 /* Zero offsets if we're not saving those registers. */
13639 if (info_ptr
->fp_size
== 0)
13640 info_ptr
->fp_save_offset
= 0;
13642 if (info_ptr
->gp_size
== 0)
13643 info_ptr
->gp_save_offset
= 0;
13645 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
13646 info_ptr
->altivec_save_offset
= 0;
13648 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
13649 info_ptr
->vrsave_save_offset
= 0;
13651 if (! TARGET_SPE_ABI
13652 || info_ptr
->spe_64bit_regs_used
== 0
13653 || info_ptr
->spe_gp_size
== 0)
13654 info_ptr
->spe_gp_save_offset
= 0;
13656 if (! info_ptr
->lr_save_p
)
13657 info_ptr
->lr_save_offset
= 0;
13659 if (! info_ptr
->cr_save_p
)
13660 info_ptr
->cr_save_offset
= 0;
13665 /* Return true if the current function uses any GPRs in 64-bit SIMD
13669 spe_func_has_64bit_regs_p (void)
13673 /* Functions that save and restore all the call-saved registers will
13674 need to save/restore the registers in 64-bits. */
13675 if (current_function_calls_eh_return
13676 || current_function_calls_setjmp
13677 || current_function_has_nonlocal_goto
)
13680 insns
= get_insns ();
13682 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13688 /* FIXME: This should be implemented with attributes...
13690 (set_attr "spe64" "true")....then,
13691 if (get_spe64(insn)) return true;
13693 It's the only reliable way to do the stuff below. */
13695 i
= PATTERN (insn
);
13696 if (GET_CODE (i
) == SET
)
13698 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
13700 if (SPE_VECTOR_MODE (mode
))
13702 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
13712 debug_stack_info (rs6000_stack_t
*info
)
13714 const char *abi_string
;
13717 info
= rs6000_stack_info ();
13719 fprintf (stderr
, "\nStack information for function %s:\n",
13720 ((current_function_decl
&& DECL_NAME (current_function_decl
))
13721 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
13726 default: abi_string
= "Unknown"; break;
13727 case ABI_NONE
: abi_string
= "NONE"; break;
13728 case ABI_AIX
: abi_string
= "AIX"; break;
13729 case ABI_DARWIN
: abi_string
= "Darwin"; break;
13730 case ABI_V4
: abi_string
= "V.4"; break;
13733 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
13735 if (TARGET_ALTIVEC_ABI
)
13736 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
13738 if (TARGET_SPE_ABI
)
13739 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
13741 if (info
->first_gp_reg_save
!= 32)
13742 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
13744 if (info
->first_fp_reg_save
!= 64)
13745 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
13747 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
13748 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
13749 info
->first_altivec_reg_save
);
13751 if (info
->lr_save_p
)
13752 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
13754 if (info
->cr_save_p
)
13755 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
13757 if (info
->vrsave_mask
)
13758 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
13761 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
13764 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
13766 if (info
->gp_save_offset
)
13767 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
13769 if (info
->fp_save_offset
)
13770 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
13772 if (info
->altivec_save_offset
)
13773 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
13774 info
->altivec_save_offset
);
13776 if (info
->spe_gp_save_offset
)
13777 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
13778 info
->spe_gp_save_offset
);
13780 if (info
->vrsave_save_offset
)
13781 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
13782 info
->vrsave_save_offset
);
13784 if (info
->lr_save_offset
)
13785 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
13787 if (info
->cr_save_offset
)
13788 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
13790 if (info
->varargs_save_offset
)
13791 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
13793 if (info
->total_size
)
13794 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13797 if (info
->vars_size
)
13798 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13801 if (info
->parm_size
)
13802 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
13804 if (info
->fixed_size
)
13805 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
13808 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
13810 if (info
->spe_gp_size
)
13811 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
13814 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
13816 if (info
->altivec_size
)
13817 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
13819 if (info
->vrsave_size
)
13820 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
13822 if (info
->altivec_padding_size
)
13823 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
13824 info
->altivec_padding_size
);
13826 if (info
->spe_padding_size
)
13827 fprintf (stderr
, "\tspe_padding_size = %5d\n",
13828 info
->spe_padding_size
);
13831 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
13833 if (info
->save_size
)
13834 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
13836 if (info
->reg_size
!= 4)
13837 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
13839 fprintf (stderr
, "\n");
13843 rs6000_return_addr (int count
, rtx frame
)
13845 /* Currently we don't optimize very well between prolog and body
13846 code and for PIC code the code can be actually quite bad, so
13847 don't try to be too clever here. */
13848 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
13850 cfun
->machine
->ra_needs_full_frame
= 1;
13857 plus_constant (copy_to_reg
13858 (gen_rtx_MEM (Pmode
,
13859 memory_address (Pmode
, frame
))),
13860 RETURN_ADDRESS_OFFSET
)));
13863 cfun
->machine
->ra_need_lr
= 1;
13864 return get_hard_reg_initial_val (Pmode
, LINK_REGISTER_REGNUM
);
13867 /* Say whether a function is a candidate for sibcall handling or not.
13868 We do not allow indirect calls to be optimized into sibling calls.
13869 Also, we can't do it if there are any vector parameters; there's
13870 nowhere to put the VRsave code so it works; note that functions with
13871 vector parameters are required to have a prototype, so the argument
13872 type info must be available here. (The tail recursion case can work
13873 with vector parameters, but there's no way to distinguish here.) */
13875 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
13880 if (TARGET_ALTIVEC_VRSAVE
)
13882 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
13883 type
; type
= TREE_CHAIN (type
))
13885 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
13889 if (DEFAULT_ABI
== ABI_DARWIN
13890 || (*targetm
.binds_local_p
) (decl
))
13892 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
13894 if (!lookup_attribute ("longcall", attr_list
)
13895 || lookup_attribute ("shortcall", attr_list
))
13902 /* NULL if INSN insn is valid within a low-overhead loop.
13903 Otherwise return why doloop cannot be applied.
13904 PowerPC uses the COUNT register for branch on table instructions. */
13906 static const char *
13907 rs6000_invalid_within_doloop (rtx insn
)
13910 return "Function call in the loop.";
13913 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
13914 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
13915 return "Computed branch in the loop.";
13921 rs6000_ra_ever_killed (void)
13927 if (current_function_is_thunk
)
13930 /* regs_ever_live has LR marked as used if any sibcalls are present,
13931 but this should not force saving and restoring in the
13932 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13933 clobbers LR, so that is inappropriate. */
13935 /* Also, the prologue can generate a store into LR that
13936 doesn't really count, like this:
13939 bcl to set PIC register
13943 When we're called from the epilogue, we need to avoid counting
13944 this as a store. */
13946 push_topmost_sequence ();
13947 top
= get_insns ();
13948 pop_topmost_sequence ();
13949 reg
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13951 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13957 if (!SIBLING_CALL_P (insn
))
13960 else if (find_regno_note (insn
, REG_INC
, LINK_REGISTER_REGNUM
))
13962 else if (set_of (reg
, insn
) != NULL_RTX
13963 && !prologue_epilogue_contains (insn
))
13970 /* Add a REG_MAYBE_DEAD note to the insn. */
13972 rs6000_maybe_dead (rtx insn
)
13974 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
,
13979 /* Emit instructions needed to load the TOC register.
13980 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13981 a constant pool; or for SVR4 -fpic. */
13984 rs6000_emit_load_toc_table (int fromprolog
)
13987 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
13989 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
13992 rtx lab
, tmp1
, tmp2
, got
, tempLR
;
13994 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
13995 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13997 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
13999 got
= rs6000_got_sym ();
14000 tmp1
= tmp2
= dest
;
14003 tmp1
= gen_reg_rtx (Pmode
);
14004 tmp2
= gen_reg_rtx (Pmode
);
14006 tempLR
= (fromprolog
14007 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
14008 : gen_reg_rtx (Pmode
));
14009 insn
= emit_insn (gen_load_toc_v4_PIC_1 (tempLR
, lab
));
14011 rs6000_maybe_dead (insn
);
14012 insn
= emit_move_insn (tmp1
, tempLR
);
14014 rs6000_maybe_dead (insn
);
14015 insn
= emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
14017 rs6000_maybe_dead (insn
);
14018 insn
= emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
14020 rs6000_maybe_dead (insn
);
14022 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
14024 rtx tempLR
= (fromprolog
14025 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
14026 : gen_reg_rtx (Pmode
));
14028 insn
= emit_insn (gen_load_toc_v4_pic_si (tempLR
));
14030 rs6000_maybe_dead (insn
);
14031 insn
= emit_move_insn (dest
, tempLR
);
14033 rs6000_maybe_dead (insn
);
14035 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
14038 rtx tempLR
= (fromprolog
14039 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
14040 : gen_reg_rtx (Pmode
));
14041 rtx temp0
= (fromprolog
14042 ? gen_rtx_REG (Pmode
, 0)
14043 : gen_reg_rtx (Pmode
));
14049 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
14050 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
14052 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
14053 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
14055 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR
,
14057 rs6000_maybe_dead (emit_move_insn (dest
, tempLR
));
14058 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
,
14066 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
14067 emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, tocsym
));
14068 emit_move_insn (dest
, tempLR
);
14069 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
14071 insn
= emit_insn (gen_addsi3 (dest
, temp0
, dest
));
14073 rs6000_maybe_dead (insn
);
14075 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
14077 /* This is for AIX code running in non-PIC ELF32. */
14080 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
14081 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
14083 insn
= emit_insn (gen_elf_high (dest
, realsym
));
14085 rs6000_maybe_dead (insn
);
14086 insn
= emit_insn (gen_elf_low (dest
, dest
, realsym
));
14088 rs6000_maybe_dead (insn
);
14092 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
14095 insn
= emit_insn (gen_load_toc_aix_si (dest
));
14097 insn
= emit_insn (gen_load_toc_aix_di (dest
));
14099 rs6000_maybe_dead (insn
);
14103 /* Emit instructions to restore the link register after determining where
14104 its value has been stored. */
14107 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
14109 rs6000_stack_t
*info
= rs6000_stack_info ();
14112 operands
[0] = source
;
14113 operands
[1] = scratch
;
14115 if (info
->lr_save_p
)
14117 rtx frame_rtx
= stack_pointer_rtx
;
14118 HOST_WIDE_INT sp_offset
= 0;
14121 if (frame_pointer_needed
14122 || current_function_calls_alloca
14123 || info
->total_size
> 32767)
14125 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
14126 emit_move_insn (operands
[1], tmp
);
14127 frame_rtx
= operands
[1];
14129 else if (info
->push_p
)
14130 sp_offset
= info
->total_size
;
14132 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
14133 tmp
= gen_frame_mem (Pmode
, tmp
);
14134 emit_move_insn (tmp
, operands
[0]);
14137 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
), operands
[0]);
14140 static GTY(()) int set
= -1;
14143 get_TOC_alias_set (void)
14146 set
= new_alias_set ();
14150 /* This returns nonzero if the current function uses the TOC. This is
14151 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
14152 is generated by the ABI_V4 load_toc_* patterns. */
14159 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
14162 rtx pat
= PATTERN (insn
);
14165 if (GET_CODE (pat
) == PARALLEL
)
14166 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
14168 rtx sub
= XVECEXP (pat
, 0, i
);
14169 if (GET_CODE (sub
) == USE
)
14171 sub
= XEXP (sub
, 0);
14172 if (GET_CODE (sub
) == UNSPEC
14173 && XINT (sub
, 1) == UNSPEC_TOC
)
14183 create_TOC_reference (rtx symbol
)
14185 if (no_new_pseudos
)
14186 regs_ever_live
[TOC_REGISTER
] = 1;
14187 return gen_rtx_PLUS (Pmode
,
14188 gen_rtx_REG (Pmode
, TOC_REGISTER
),
14189 gen_rtx_CONST (Pmode
,
14190 gen_rtx_MINUS (Pmode
, symbol
,
14191 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
14194 /* If _Unwind_* has been called from within the same module,
14195 toc register is not guaranteed to be saved to 40(1) on function
14196 entry. Save it there in that case. */
14199 rs6000_aix_emit_builtin_unwind_init (void)
14202 rtx stack_top
= gen_reg_rtx (Pmode
);
14203 rtx opcode_addr
= gen_reg_rtx (Pmode
);
14204 rtx opcode
= gen_reg_rtx (SImode
);
14205 rtx tocompare
= gen_reg_rtx (SImode
);
14206 rtx no_toc_save_needed
= gen_label_rtx ();
14208 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
14209 emit_move_insn (stack_top
, mem
);
14211 mem
= gen_frame_mem (Pmode
,
14212 gen_rtx_PLUS (Pmode
, stack_top
,
14213 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
14214 emit_move_insn (opcode_addr
, mem
);
14215 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
14216 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
14217 : 0xE8410028, SImode
));
14219 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
14220 SImode
, NULL_RTX
, NULL_RTX
,
14221 no_toc_save_needed
);
14223 mem
= gen_frame_mem (Pmode
,
14224 gen_rtx_PLUS (Pmode
, stack_top
,
14225 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
14226 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
14227 emit_label (no_toc_save_needed
);
14230 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
14231 and the change to the stack pointer. */
14234 rs6000_emit_stack_tie (void)
14236 rtx mem
= gen_frame_mem (BLKmode
,
14237 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
14239 emit_insn (gen_stack_tie (mem
));
14242 /* Emit the correct code for allocating stack space, as insns.
14243 If COPY_R12, make sure a copy of the old frame is left in r12.
14244 The generated code may use hard register 0 as a temporary. */
14247 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
14250 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
14251 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
14252 rtx todec
= gen_int_mode (-size
, Pmode
);
14254 if (INTVAL (todec
) != -size
)
14256 warning (0, "stack frame too large");
14257 emit_insn (gen_trap ());
14261 if (current_function_limit_stack
)
14263 if (REG_P (stack_limit_rtx
)
14264 && REGNO (stack_limit_rtx
) > 1
14265 && REGNO (stack_limit_rtx
) <= 31)
14267 emit_insn (TARGET_32BIT
14268 ? gen_addsi3 (tmp_reg
,
14271 : gen_adddi3 (tmp_reg
,
14275 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
14278 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
14280 && DEFAULT_ABI
== ABI_V4
)
14282 rtx toload
= gen_rtx_CONST (VOIDmode
,
14283 gen_rtx_PLUS (Pmode
,
14287 emit_insn (gen_elf_high (tmp_reg
, toload
));
14288 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
14289 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
14293 warning (0, "stack limit expression is not supported");
14296 if (copy_r12
|| ! TARGET_UPDATE
)
14297 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
14303 /* Need a note here so that try_split doesn't get confused. */
14304 if (get_last_insn () == NULL_RTX
)
14305 emit_note (NOTE_INSN_DELETED
);
14306 insn
= emit_move_insn (tmp_reg
, todec
);
14307 try_split (PATTERN (insn
), insn
, 0);
14311 insn
= emit_insn (TARGET_32BIT
14312 ? gen_movsi_update (stack_reg
, stack_reg
,
14314 : gen_movdi_di_update (stack_reg
, stack_reg
,
14315 todec
, stack_reg
));
14319 insn
= emit_insn (TARGET_32BIT
14320 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
14321 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
14322 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
14323 gen_rtx_REG (Pmode
, 12));
14326 RTX_FRAME_RELATED_P (insn
) = 1;
14328 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14329 gen_rtx_SET (VOIDmode
, stack_reg
,
14330 gen_rtx_PLUS (Pmode
, stack_reg
,
14335 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
14336 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
14337 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
14338 deduce these equivalences by itself so it wasn't necessary to hold
14339 its hand so much. */
14342 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
14343 rtx reg2
, rtx rreg
)
14347 /* copy_rtx will not make unique copies of registers, so we need to
14348 ensure we don't have unwanted sharing here. */
14350 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
14353 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
14355 real
= copy_rtx (PATTERN (insn
));
14357 if (reg2
!= NULL_RTX
)
14358 real
= replace_rtx (real
, reg2
, rreg
);
14360 real
= replace_rtx (real
, reg
,
14361 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
14362 STACK_POINTER_REGNUM
),
14365 /* We expect that 'real' is either a SET or a PARALLEL containing
14366 SETs (and possibly other stuff). In a PARALLEL, all the SETs
14367 are important so they all have to be marked RTX_FRAME_RELATED_P. */
14369 if (GET_CODE (real
) == SET
)
14373 temp
= simplify_rtx (SET_SRC (set
));
14375 SET_SRC (set
) = temp
;
14376 temp
= simplify_rtx (SET_DEST (set
));
14378 SET_DEST (set
) = temp
;
14379 if (GET_CODE (SET_DEST (set
)) == MEM
)
14381 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
14383 XEXP (SET_DEST (set
), 0) = temp
;
14390 gcc_assert (GET_CODE (real
) == PARALLEL
);
14391 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
14392 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
14394 rtx set
= XVECEXP (real
, 0, i
);
14396 temp
= simplify_rtx (SET_SRC (set
));
14398 SET_SRC (set
) = temp
;
14399 temp
= simplify_rtx (SET_DEST (set
));
14401 SET_DEST (set
) = temp
;
14402 if (GET_CODE (SET_DEST (set
)) == MEM
)
14404 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
14406 XEXP (SET_DEST (set
), 0) = temp
;
14408 RTX_FRAME_RELATED_P (set
) = 1;
14413 real
= spe_synthesize_frame_save (real
);
14415 RTX_FRAME_RELATED_P (insn
) = 1;
14416 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14421 /* Given an SPE frame note, return a PARALLEL of SETs with the
14422 original note, plus a synthetic register save. */
14425 spe_synthesize_frame_save (rtx real
)
14427 rtx synth
, offset
, reg
, real2
;
14429 if (GET_CODE (real
) != SET
14430 || GET_MODE (SET_SRC (real
)) != V2SImode
)
14433 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
14434 frame related note. The parallel contains a set of the register
14435 being saved, and another set to a synthetic register (n+1200).
14436 This is so we can differentiate between 64-bit and 32-bit saves.
14437 Words cannot describe this nastiness. */
14439 gcc_assert (GET_CODE (SET_DEST (real
)) == MEM
14440 && GET_CODE (XEXP (SET_DEST (real
), 0)) == PLUS
14441 && GET_CODE (SET_SRC (real
)) == REG
);
14444 (set (mem (plus (reg x) (const y)))
14447 (set (mem (plus (reg x) (const y+4)))
14451 real2
= copy_rtx (real
);
14452 PUT_MODE (SET_DEST (real2
), SImode
);
14453 reg
= SET_SRC (real2
);
14454 real2
= replace_rtx (real2
, reg
, gen_rtx_REG (SImode
, REGNO (reg
)));
14455 synth
= copy_rtx (real2
);
14457 if (BYTES_BIG_ENDIAN
)
14459 offset
= XEXP (XEXP (SET_DEST (real2
), 0), 1);
14460 real2
= replace_rtx (real2
, offset
, GEN_INT (INTVAL (offset
) + 4));
14463 reg
= SET_SRC (synth
);
14465 synth
= replace_rtx (synth
, reg
,
14466 gen_rtx_REG (SImode
, REGNO (reg
) + 1200));
14468 offset
= XEXP (XEXP (SET_DEST (synth
), 0), 1);
14469 synth
= replace_rtx (synth
, offset
,
14470 GEN_INT (INTVAL (offset
)
14471 + (BYTES_BIG_ENDIAN
? 0 : 4)));
14473 RTX_FRAME_RELATED_P (synth
) = 1;
14474 RTX_FRAME_RELATED_P (real2
) = 1;
14475 if (BYTES_BIG_ENDIAN
)
14476 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, synth
, real2
));
14478 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, real2
, synth
));
14483 /* Returns an insn that has a vrsave set operation with the
14484 appropriate CLOBBERs. */
14487 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
14490 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
14491 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
14494 = gen_rtx_SET (VOIDmode
,
14496 gen_rtx_UNSPEC_VOLATILE (SImode
,
14497 gen_rtvec (2, reg
, vrsave
),
14498 UNSPECV_SET_VRSAVE
));
14502 /* We need to clobber the registers in the mask so the scheduler
14503 does not move sets to VRSAVE before sets of AltiVec registers.
14505 However, if the function receives nonlocal gotos, reload will set
14506 all call saved registers live. We will end up with:
14508 (set (reg 999) (mem))
14509 (parallel [ (set (reg vrsave) (unspec blah))
14510 (clobber (reg 999))])
14512 The clobber will cause the store into reg 999 to be dead, and
14513 flow will attempt to delete an epilogue insn. In this case, we
14514 need an unspec use/set of the register. */
14516 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14517 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14519 if (!epiloguep
|| call_used_regs
[i
])
14520 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
14521 gen_rtx_REG (V4SImode
, i
));
14524 rtx reg
= gen_rtx_REG (V4SImode
, i
);
14527 = gen_rtx_SET (VOIDmode
,
14529 gen_rtx_UNSPEC (V4SImode
,
14530 gen_rtvec (1, reg
), 27));
14534 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
14536 for (i
= 0; i
< nclobs
; ++i
)
14537 XVECEXP (insn
, 0, i
) = clobs
[i
];
14542 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
14543 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
14546 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
14547 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
14549 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
14550 rtx replacea
, replaceb
;
14552 int_rtx
= GEN_INT (offset
);
14554 /* Some cases that need register indexed addressing. */
14555 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
14556 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
14558 && SPE_VECTOR_MODE (mode
)
14559 && !SPE_CONST_OFFSET_OK (offset
)))
14561 /* Whomever calls us must make sure r11 is available in the
14562 flow path of instructions in the prologue. */
14563 offset_rtx
= gen_rtx_REG (Pmode
, 11);
14564 emit_move_insn (offset_rtx
, int_rtx
);
14566 replacea
= offset_rtx
;
14567 replaceb
= int_rtx
;
14571 offset_rtx
= int_rtx
;
14572 replacea
= NULL_RTX
;
14573 replaceb
= NULL_RTX
;
14576 reg
= gen_rtx_REG (mode
, regno
);
14577 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
14578 mem
= gen_frame_mem (mode
, addr
);
14580 insn
= emit_move_insn (mem
, reg
);
14582 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
14585 /* Emit an offset memory reference suitable for a frame store, while
14586 converting to a valid addressing mode. */
14589 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
14591 rtx int_rtx
, offset_rtx
;
14593 int_rtx
= GEN_INT (offset
);
14595 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
14596 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
14598 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14599 emit_move_insn (offset_rtx
, int_rtx
);
14602 offset_rtx
= int_rtx
;
14604 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
14607 /* Look for user-defined global regs. We should not save and restore these,
14608 and cannot use stmw/lmw if there are any in its range. */
14611 no_global_regs_above (int first_greg
)
14614 for (i
= 0; i
< 32 - first_greg
; i
++)
14615 if (global_regs
[first_greg
+ i
])
14620 #ifndef TARGET_FIX_AND_CONTINUE
14621 #define TARGET_FIX_AND_CONTINUE 0
14624 /* Emit function prologue as insns. */
14627 rs6000_emit_prologue (void)
14629 rs6000_stack_t
*info
= rs6000_stack_info ();
14630 enum machine_mode reg_mode
= Pmode
;
14631 int reg_size
= TARGET_32BIT
? 4 : 8;
14632 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
14633 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
14634 rtx frame_reg_rtx
= sp_reg_rtx
;
14635 rtx cr_save_rtx
= NULL_RTX
;
14637 int saving_FPRs_inline
;
14638 int using_store_multiple
;
14639 HOST_WIDE_INT sp_offset
= 0;
14641 if (TARGET_FIX_AND_CONTINUE
)
14643 /* gdb on darwin arranges to forward a function from the old
14644 address by modifying the first 5 instructions of the function
14645 to branch to the overriding function. This is necessary to
14646 permit function pointers that point to the old function to
14647 actually forward to the new function. */
14648 emit_insn (gen_nop ());
14649 emit_insn (gen_nop ());
14650 emit_insn (gen_nop ());
14651 emit_insn (gen_nop ());
14652 emit_insn (gen_nop ());
14655 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14657 reg_mode
= V2SImode
;
14661 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
14662 && (!TARGET_SPE_ABI
14663 || info
->spe_64bit_regs_used
== 0)
14664 && info
->first_gp_reg_save
< 31
14665 && no_global_regs_above (info
->first_gp_reg_save
));
14666 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
14667 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
14668 || current_function_calls_eh_return
14669 || cfun
->machine
->ra_need_lr
);
14671 /* For V.4, update stack before we do any saving and set back pointer. */
14672 if (! WORLD_SAVE_P (info
)
14674 && (DEFAULT_ABI
== ABI_V4
14675 || current_function_calls_eh_return
))
14677 if (info
->total_size
< 32767)
14678 sp_offset
= info
->total_size
;
14680 frame_reg_rtx
= frame_ptr_rtx
;
14681 rs6000_emit_allocate_stack (info
->total_size
,
14682 (frame_reg_rtx
!= sp_reg_rtx
14683 && (info
->cr_save_p
14685 || info
->first_fp_reg_save
< 64
14686 || info
->first_gp_reg_save
< 32
14688 if (frame_reg_rtx
!= sp_reg_rtx
)
14689 rs6000_emit_stack_tie ();
14692 /* Handle world saves specially here. */
14693 if (WORLD_SAVE_P (info
))
14700 /* save_world expects lr in r0. */
14701 reg0
= gen_rtx_REG (Pmode
, 0);
14702 if (info
->lr_save_p
)
14704 insn
= emit_move_insn (reg0
,
14705 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14706 RTX_FRAME_RELATED_P (insn
) = 1;
14709 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14710 assumptions about the offsets of various bits of the stack
14712 gcc_assert (info
->gp_save_offset
== -220
14713 && info
->fp_save_offset
== -144
14714 && info
->lr_save_offset
== 8
14715 && info
->cr_save_offset
== 4
14718 && (!current_function_calls_eh_return
14719 || info
->ehrd_offset
== -432)
14720 && info
->vrsave_save_offset
== -224
14721 && info
->altivec_save_offset
== -416);
14723 treg
= gen_rtx_REG (SImode
, 11);
14724 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
14726 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14727 in R11. It also clobbers R12, so beware! */
14729 /* Preserve CR2 for save_world prologues */
14731 sz
+= 32 - info
->first_gp_reg_save
;
14732 sz
+= 64 - info
->first_fp_reg_save
;
14733 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
14734 p
= rtvec_alloc (sz
);
14736 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
14737 gen_rtx_REG (Pmode
,
14738 LINK_REGISTER_REGNUM
));
14739 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
14740 gen_rtx_SYMBOL_REF (Pmode
,
14742 /* We do floats first so that the instruction pattern matches
14744 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14746 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14747 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14748 GEN_INT (info
->fp_save_offset
14749 + sp_offset
+ 8 * i
));
14750 rtx mem
= gen_frame_mem (DFmode
, addr
);
14752 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14754 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
14756 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
14757 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14758 GEN_INT (info
->altivec_save_offset
14759 + sp_offset
+ 16 * i
));
14760 rtx mem
= gen_frame_mem (V4SImode
, addr
);
14762 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14764 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14766 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14767 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14768 GEN_INT (info
->gp_save_offset
14769 + sp_offset
+ reg_size
* i
));
14770 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14772 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14776 /* CR register traditionally saved as CR2. */
14777 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
14778 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14779 GEN_INT (info
->cr_save_offset
14781 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14783 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14785 /* Explain about use of R0. */
14786 if (info
->lr_save_p
)
14788 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14789 GEN_INT (info
->lr_save_offset
14791 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14793 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
14795 /* Explain what happens to the stack pointer. */
14797 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
14798 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
14801 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14802 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14803 treg
, GEN_INT (-info
->total_size
));
14804 sp_offset
= info
->total_size
;
14807 /* Save AltiVec registers if needed. */
14808 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
14812 /* There should be a non inline version of this, for when we
14813 are saving lots of vector registers. */
14814 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14815 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14817 rtx areg
, savereg
, mem
;
14820 offset
= info
->altivec_save_offset
+ sp_offset
14821 + 16 * (i
- info
->first_altivec_reg_save
);
14823 savereg
= gen_rtx_REG (V4SImode
, i
);
14825 areg
= gen_rtx_REG (Pmode
, 0);
14826 emit_move_insn (areg
, GEN_INT (offset
));
14828 /* AltiVec addressing mode is [reg+reg]. */
14829 mem
= gen_frame_mem (V4SImode
,
14830 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
14832 insn
= emit_move_insn (mem
, savereg
);
14834 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14835 areg
, GEN_INT (offset
));
14839 /* VRSAVE is a bit vector representing which AltiVec registers
14840 are used. The OS uses this to determine which vector
14841 registers to save on a context switch. We need to save
14842 VRSAVE on the stack frame, add whatever AltiVec registers we
14843 used in this function, and do the corresponding magic in the
14846 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
14847 && info
->vrsave_mask
!= 0)
14849 rtx reg
, mem
, vrsave
;
14852 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14853 as frame_reg_rtx and r11 as the static chain pointer for
14854 nested functions. */
14855 reg
= gen_rtx_REG (SImode
, 0);
14856 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
14858 emit_insn (gen_get_vrsave_internal (reg
));
14860 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
14862 if (!WORLD_SAVE_P (info
))
14865 offset
= info
->vrsave_save_offset
+ sp_offset
;
14866 mem
= gen_frame_mem (SImode
,
14867 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14868 GEN_INT (offset
)));
14869 insn
= emit_move_insn (mem
, reg
);
14872 /* Include the registers in the mask. */
14873 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
14875 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
14878 /* If we use the link register, get it into r0. */
14879 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
14881 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
14882 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14883 RTX_FRAME_RELATED_P (insn
) = 1;
14886 /* If we need to save CR, put it into r12. */
14887 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
14891 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
14892 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
14893 RTX_FRAME_RELATED_P (insn
) = 1;
14894 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14895 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14896 But that's OK. All we have to do is specify that _one_ condition
14897 code register is saved in this stack slot. The thrower's epilogue
14898 will then restore all the call-saved registers.
14899 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14900 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
14901 gen_rtx_REG (SImode
, CR2_REGNO
));
14902 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14907 /* Do any required saving of fpr's. If only one or two to save, do
14908 it ourselves. Otherwise, call function. */
14909 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
14912 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14913 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
14914 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
14915 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
14916 info
->first_fp_reg_save
+ i
,
14917 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
14920 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
14924 const char *alloc_rname
;
14926 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
14928 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
14929 gen_rtx_REG (Pmode
,
14930 LINK_REGISTER_REGNUM
));
14931 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
14932 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
14933 alloc_rname
= ggc_strdup (rname
);
14934 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
14935 gen_rtx_SYMBOL_REF (Pmode
,
14937 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14939 rtx addr
, reg
, mem
;
14940 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14941 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14942 GEN_INT (info
->fp_save_offset
14943 + sp_offset
+ 8*i
));
14944 mem
= gen_frame_mem (DFmode
, addr
);
14946 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14948 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14949 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14950 NULL_RTX
, NULL_RTX
);
14953 /* Save GPRs. This is done as a PARALLEL if we are using
14954 the store-multiple instructions. */
14955 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
14959 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14960 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14962 rtx addr
, reg
, mem
;
14963 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14964 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14965 GEN_INT (info
->gp_save_offset
14968 mem
= gen_frame_mem (reg_mode
, addr
);
14970 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14972 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14973 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14974 NULL_RTX
, NULL_RTX
);
14976 else if (!WORLD_SAVE_P (info
))
14979 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14980 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
14981 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
14982 || (i
+ info
->first_gp_reg_save
14983 == RS6000_PIC_OFFSET_TABLE_REGNUM
14984 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14985 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14986 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14987 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14989 rtx addr
, reg
, mem
;
14990 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14992 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14994 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14997 if (!SPE_CONST_OFFSET_OK (offset
))
14999 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15000 emit_move_insn (b
, GEN_INT (offset
));
15003 b
= GEN_INT (offset
);
15005 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
15006 mem
= gen_frame_mem (V2SImode
, addr
);
15007 insn
= emit_move_insn (mem
, reg
);
15009 if (GET_CODE (b
) == CONST_INT
)
15010 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15011 NULL_RTX
, NULL_RTX
);
15013 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15014 b
, GEN_INT (offset
));
15018 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15019 GEN_INT (info
->gp_save_offset
15022 mem
= gen_frame_mem (reg_mode
, addr
);
15024 insn
= emit_move_insn (mem
, reg
);
15025 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15026 NULL_RTX
, NULL_RTX
);
15031 /* ??? There's no need to emit actual instructions here, but it's the
15032 easiest way to get the frame unwind information emitted. */
15033 if (current_function_calls_eh_return
)
15035 unsigned int i
, regno
;
15037 /* In AIX ABI we need to pretend we save r2 here. */
15040 rtx addr
, reg
, mem
;
15042 reg
= gen_rtx_REG (reg_mode
, 2);
15043 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15044 GEN_INT (sp_offset
+ 5 * reg_size
));
15045 mem
= gen_frame_mem (reg_mode
, addr
);
15047 insn
= emit_move_insn (mem
, reg
);
15048 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15049 NULL_RTX
, NULL_RTX
);
15050 PATTERN (insn
) = gen_blockage ();
15055 regno
= EH_RETURN_DATA_REGNO (i
);
15056 if (regno
== INVALID_REGNUM
)
15059 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
15060 info
->ehrd_offset
+ sp_offset
15061 + reg_size
* (int) i
,
15066 /* Save lr if we used it. */
15067 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
15069 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15070 GEN_INT (info
->lr_save_offset
+ sp_offset
));
15071 rtx reg
= gen_rtx_REG (Pmode
, 0);
15072 rtx mem
= gen_rtx_MEM (Pmode
, addr
);
15073 /* This should not be of frame_alias_set, because of
15074 __builtin_return_address. */
15076 insn
= emit_move_insn (mem
, reg
);
15077 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15078 NULL_RTX
, NULL_RTX
);
15081 /* Save CR if we use any that must be preserved. */
15082 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
15084 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15085 GEN_INT (info
->cr_save_offset
+ sp_offset
));
15086 rtx mem
= gen_frame_mem (SImode
, addr
);
15087 /* See the large comment above about why CR2_REGNO is used. */
15088 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
15090 /* If r12 was used to hold the original sp, copy cr into r0 now
15092 if (REGNO (frame_reg_rtx
) == 12)
15096 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
15097 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
15098 RTX_FRAME_RELATED_P (insn
) = 1;
15099 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
15100 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15105 insn
= emit_move_insn (mem
, cr_save_rtx
);
15107 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15108 NULL_RTX
, NULL_RTX
);
15111 /* Update stack and set back pointer unless this is V.4,
15112 for which it was done previously. */
15113 if (!WORLD_SAVE_P (info
) && info
->push_p
15114 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
15115 rs6000_emit_allocate_stack (info
->total_size
, FALSE
);
15117 /* Set frame pointer, if needed. */
15118 if (frame_pointer_needed
)
15120 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
15122 RTX_FRAME_RELATED_P (insn
) = 1;
15125 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
15126 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
15127 || (DEFAULT_ABI
== ABI_V4
15128 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
15129 && regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
]))
15131 /* If emit_load_toc_table will use the link register, we need to save
15132 it. We use R12 for this purpose because emit_load_toc_table
15133 can use register 0. This allows us to use a plain 'blr' to return
15134 from the procedure more often. */
15135 int save_LR_around_toc_setup
= (TARGET_ELF
15136 && DEFAULT_ABI
!= ABI_AIX
15138 && ! info
->lr_save_p
15139 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
15140 if (save_LR_around_toc_setup
)
15142 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
15144 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
15145 rs6000_maybe_dead (insn
);
15146 RTX_FRAME_RELATED_P (insn
) = 1;
15148 rs6000_emit_load_toc_table (TRUE
);
15150 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
15151 rs6000_maybe_dead (insn
);
15152 RTX_FRAME_RELATED_P (insn
) = 1;
15155 rs6000_emit_load_toc_table (TRUE
);
15159 if (DEFAULT_ABI
== ABI_DARWIN
15160 && flag_pic
&& current_function_uses_pic_offset_table
)
15162 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
15163 rtx src
= machopic_function_base_sym ();
15165 /* Save and restore LR locally around this call (in R0). */
15166 if (!info
->lr_save_p
)
15167 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
));
15169 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr
, src
)));
15171 insn
= emit_move_insn (gen_rtx_REG (Pmode
,
15172 RS6000_PIC_OFFSET_TABLE_REGNUM
),
15174 rs6000_maybe_dead (insn
);
15176 if (!info
->lr_save_p
)
15177 rs6000_maybe_dead (emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0)));
15182 /* Write function prologue. */
15185 rs6000_output_function_prologue (FILE *file
,
15186 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
15188 rs6000_stack_t
*info
= rs6000_stack_info ();
15190 if (TARGET_DEBUG_STACK
)
15191 debug_stack_info (info
);
15193 /* Write .extern for any function we will call to save and restore
15195 if (info
->first_fp_reg_save
< 64
15196 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
15197 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
15198 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
15199 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
15200 RESTORE_FP_SUFFIX
);
15202 /* Write .extern for AIX common mode routines, if needed. */
15203 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
15205 fputs ("\t.extern __mulh\n", file
);
15206 fputs ("\t.extern __mull\n", file
);
15207 fputs ("\t.extern __divss\n", file
);
15208 fputs ("\t.extern __divus\n", file
);
15209 fputs ("\t.extern __quoss\n", file
);
15210 fputs ("\t.extern __quous\n", file
);
15211 common_mode_defined
= 1;
15214 if (! HAVE_prologue
)
15218 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
15219 the "toplevel" insn chain. */
15220 emit_note (NOTE_INSN_DELETED
);
15221 rs6000_emit_prologue ();
15222 emit_note (NOTE_INSN_DELETED
);
15224 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15228 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
15230 INSN_ADDRESSES_NEW (insn
, addr
);
15235 if (TARGET_DEBUG_STACK
)
15236 debug_rtx_list (get_insns (), 100);
15237 final (get_insns (), file
, FALSE
);
15241 rs6000_pic_labelno
++;
15244 /* Emit function epilogue as insns.
15246 At present, dwarf2out_frame_debug_expr doesn't understand
15247 register restores, so we don't bother setting RTX_FRAME_RELATED_P
15248 anywhere in the epilogue. Most of the insns below would in any case
15249 need special notes to explain where r11 is in relation to the stack. */
15252 rs6000_emit_epilogue (int sibcall
)
15254 rs6000_stack_t
*info
;
15255 int restoring_FPRs_inline
;
15256 int using_load_multiple
;
15257 int using_mtcr_multiple
;
15258 int use_backchain_to_restore_sp
;
15260 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
15261 rtx frame_reg_rtx
= sp_reg_rtx
;
15262 enum machine_mode reg_mode
= Pmode
;
15263 int reg_size
= TARGET_32BIT
? 4 : 8;
15266 info
= rs6000_stack_info ();
15268 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
15270 reg_mode
= V2SImode
;
15274 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
15275 && (!TARGET_SPE_ABI
15276 || info
->spe_64bit_regs_used
== 0)
15277 && info
->first_gp_reg_save
< 31
15278 && no_global_regs_above (info
->first_gp_reg_save
));
15279 restoring_FPRs_inline
= (sibcall
15280 || current_function_calls_eh_return
15281 || info
->first_fp_reg_save
== 64
15282 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
15283 use_backchain_to_restore_sp
= (frame_pointer_needed
15284 || current_function_calls_alloca
15285 || info
->total_size
> 32767);
15286 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
15287 || rs6000_cpu
== PROCESSOR_PPC603
15288 || rs6000_cpu
== PROCESSOR_PPC750
15291 if (WORLD_SAVE_P (info
))
15295 const char *alloc_rname
;
15298 /* eh_rest_world_r10 will return to the location saved in the LR
15299 stack slot (which is not likely to be our caller.)
15300 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
15301 rest_world is similar, except any R10 parameter is ignored.
15302 The exception-handling stuff that was here in 2.95 is no
15303 longer necessary. */
15307 + 32 - info
->first_gp_reg_save
15308 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
15309 + 63 + 1 - info
->first_fp_reg_save
);
15311 strcpy (rname
, ((current_function_calls_eh_return
) ?
15312 "*eh_rest_world_r10" : "*rest_world"));
15313 alloc_rname
= ggc_strdup (rname
);
15316 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
15317 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
15318 gen_rtx_REG (Pmode
,
15319 LINK_REGISTER_REGNUM
));
15321 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
15322 /* The instruction pattern requires a clobber here;
15323 it is shared with the restVEC helper. */
15325 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
15328 /* CR register traditionally saved as CR2. */
15329 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
15330 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15331 GEN_INT (info
->cr_save_offset
));
15332 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15334 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15337 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15339 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15340 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15341 GEN_INT (info
->gp_save_offset
15343 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15345 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15347 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
15349 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
15350 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15351 GEN_INT (info
->altivec_save_offset
15353 rtx mem
= gen_frame_mem (V4SImode
, addr
);
15355 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15357 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
15359 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
15360 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15361 GEN_INT (info
->fp_save_offset
15363 rtx mem
= gen_frame_mem (DFmode
, addr
);
15365 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15368 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
15370 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
15372 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
15374 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
15376 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
15377 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15382 /* If we have a frame pointer, a call to alloca, or a large stack
15383 frame, restore the old stack pointer using the backchain. Otherwise,
15384 we know what size to update it with. */
15385 if (use_backchain_to_restore_sp
)
15387 /* Under V.4, don't reset the stack pointer until after we're done
15388 loading the saved registers. */
15389 if (DEFAULT_ABI
== ABI_V4
)
15390 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
15392 emit_move_insn (frame_reg_rtx
,
15393 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
15395 else if (info
->push_p
)
15397 if (DEFAULT_ABI
== ABI_V4
15398 || current_function_calls_eh_return
)
15399 sp_offset
= info
->total_size
;
15402 emit_insn (TARGET_32BIT
15403 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
15404 GEN_INT (info
->total_size
))
15405 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
15406 GEN_INT (info
->total_size
)));
15410 /* Restore AltiVec registers if needed. */
15411 if (TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
15415 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
15416 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
15418 rtx addr
, areg
, mem
;
15420 areg
= gen_rtx_REG (Pmode
, 0);
15422 (areg
, GEN_INT (info
->altivec_save_offset
15424 + 16 * (i
- info
->first_altivec_reg_save
)));
15426 /* AltiVec addressing mode is [reg+reg]. */
15427 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
15428 mem
= gen_frame_mem (V4SImode
, addr
);
15430 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
15434 /* Restore VRSAVE if needed. */
15435 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
15436 && info
->vrsave_mask
!= 0)
15438 rtx addr
, mem
, reg
;
15440 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15441 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
15442 mem
= gen_frame_mem (SImode
, addr
);
15443 reg
= gen_rtx_REG (SImode
, 12);
15444 emit_move_insn (reg
, mem
);
15446 emit_insn (generate_set_vrsave (reg
, info
, 1));
15449 /* Get the old lr if we saved it. */
15450 if (info
->lr_save_p
)
15452 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
15453 info
->lr_save_offset
+ sp_offset
);
15455 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
15458 /* Get the old cr if we saved it. */
15459 if (info
->cr_save_p
)
15461 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15462 GEN_INT (info
->cr_save_offset
+ sp_offset
));
15463 rtx mem
= gen_frame_mem (SImode
, addr
);
15465 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
15468 /* Set LR here to try to overlap restores below. */
15469 if (info
->lr_save_p
)
15470 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
),
15471 gen_rtx_REG (Pmode
, 0));
15473 /* Load exception handler data registers, if needed. */
15474 if (current_function_calls_eh_return
)
15476 unsigned int i
, regno
;
15480 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15481 GEN_INT (sp_offset
+ 5 * reg_size
));
15482 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15484 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
15491 regno
= EH_RETURN_DATA_REGNO (i
);
15492 if (regno
== INVALID_REGNUM
)
15495 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
15496 info
->ehrd_offset
+ sp_offset
15497 + reg_size
* (int) i
);
15499 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
15503 /* Restore GPRs. This is done as a PARALLEL if we are using
15504 the load-multiple instructions. */
15505 if (using_load_multiple
)
15508 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
15509 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15511 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15512 GEN_INT (info
->gp_save_offset
15515 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15518 gen_rtx_SET (VOIDmode
,
15519 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
15522 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15525 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15526 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
15527 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
15528 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
15529 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
15530 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
15531 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
15532 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
15534 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15535 GEN_INT (info
->gp_save_offset
15538 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15540 /* Restore 64-bit quantities for SPE. */
15541 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
15543 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
15546 if (!SPE_CONST_OFFSET_OK (offset
))
15548 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15549 emit_move_insn (b
, GEN_INT (offset
));
15552 b
= GEN_INT (offset
);
15554 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
15555 mem
= gen_frame_mem (V2SImode
, addr
);
15558 emit_move_insn (gen_rtx_REG (reg_mode
,
15559 info
->first_gp_reg_save
+ i
), mem
);
15562 /* Restore fpr's if we need to do it without calling a function. */
15563 if (restoring_FPRs_inline
)
15564 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15565 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
15566 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
15569 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15570 GEN_INT (info
->fp_save_offset
15573 mem
= gen_frame_mem (DFmode
, addr
);
15575 emit_move_insn (gen_rtx_REG (DFmode
,
15576 info
->first_fp_reg_save
+ i
),
15580 /* If we saved cr, restore it here. Just those that were used. */
15581 if (info
->cr_save_p
)
15583 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
15586 if (using_mtcr_multiple
)
15588 for (i
= 0; i
< 8; i
++)
15589 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15591 gcc_assert (count
);
15594 if (using_mtcr_multiple
&& count
> 1)
15599 p
= rtvec_alloc (count
);
15602 for (i
= 0; i
< 8; i
++)
15603 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15605 rtvec r
= rtvec_alloc (2);
15606 RTVEC_ELT (r
, 0) = r12_rtx
;
15607 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
15608 RTVEC_ELT (p
, ndx
) =
15609 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
15610 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
15613 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15614 gcc_assert (ndx
== count
);
15617 for (i
= 0; i
< 8; i
++)
15618 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15620 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
15626 /* If this is V.4, unwind the stack pointer after all of the loads
15628 if (frame_reg_rtx
!= sp_reg_rtx
)
15630 /* This blockage is needed so that sched doesn't decide to move
15631 the sp change before the register restores. */
15632 rs6000_emit_stack_tie ();
15633 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
15635 else if (sp_offset
!= 0)
15636 emit_insn (TARGET_32BIT
15637 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
15638 GEN_INT (sp_offset
))
15639 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
15640 GEN_INT (sp_offset
)));
15642 if (current_function_calls_eh_return
)
15644 rtx sa
= EH_RETURN_STACKADJ_RTX
;
15645 emit_insn (TARGET_32BIT
15646 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
15647 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
15653 if (! restoring_FPRs_inline
)
15654 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
15656 p
= rtvec_alloc (2);
15658 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
15659 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
15660 gen_rtx_REG (Pmode
,
15661 LINK_REGISTER_REGNUM
));
15663 /* If we have to restore more than two FP registers, branch to the
15664 restore function. It will return to our caller. */
15665 if (! restoring_FPRs_inline
)
15669 const char *alloc_rname
;
15671 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
15672 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
15673 alloc_rname
= ggc_strdup (rname
);
15674 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
15675 gen_rtx_SYMBOL_REF (Pmode
,
15678 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15681 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
15682 GEN_INT (info
->fp_save_offset
+ 8*i
));
15683 mem
= gen_frame_mem (DFmode
, addr
);
15685 RTVEC_ELT (p
, i
+3) =
15686 gen_rtx_SET (VOIDmode
,
15687 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
15692 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15696 /* Write function epilogue. */
15699 rs6000_output_function_epilogue (FILE *file
,
15700 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
15702 if (! HAVE_epilogue
)
15704 rtx insn
= get_last_insn ();
15705 /* If the last insn was a BARRIER, we don't have to write anything except
15706 the trace table. */
15707 if (GET_CODE (insn
) == NOTE
)
15708 insn
= prev_nonnote_insn (insn
);
15709 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
15711 /* This is slightly ugly, but at least we don't have two
15712 copies of the epilogue-emitting code. */
15715 /* A NOTE_INSN_DELETED is supposed to be at the start
15716 and end of the "toplevel" insn chain. */
15717 emit_note (NOTE_INSN_DELETED
);
15718 rs6000_emit_epilogue (FALSE
);
15719 emit_note (NOTE_INSN_DELETED
);
15721 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15725 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
15727 INSN_ADDRESSES_NEW (insn
, addr
);
15732 if (TARGET_DEBUG_STACK
)
15733 debug_rtx_list (get_insns (), 100);
15734 final (get_insns (), file
, FALSE
);
15740 macho_branch_islands ();
15741 /* Mach-O doesn't support labels at the end of objects, so if
15742 it looks like we might want one, insert a NOP. */
15744 rtx insn
= get_last_insn ();
15747 && NOTE_LINE_NUMBER (insn
) != NOTE_INSN_DELETED_LABEL
)
15748 insn
= PREV_INSN (insn
);
15752 && NOTE_LINE_NUMBER (insn
) == NOTE_INSN_DELETED_LABEL
)))
15753 fputs ("\tnop\n", file
);
15757 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15760 We don't output a traceback table if -finhibit-size-directive was
15761 used. The documentation for -finhibit-size-directive reads
15762 ``don't output a @code{.size} assembler directive, or anything
15763 else that would cause trouble if the function is split in the
15764 middle, and the two halves are placed at locations far apart in
15765 memory.'' The traceback table has this property, since it
15766 includes the offset from the start of the function to the
15767 traceback table itself.
15769 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15770 different traceback table. */
15771 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
15772 && rs6000_traceback
!= traceback_none
&& !current_function_is_thunk
)
15774 const char *fname
= NULL
;
15775 const char *language_string
= lang_hooks
.name
;
15776 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
15778 int optional_tbtab
;
15779 rs6000_stack_t
*info
= rs6000_stack_info ();
15781 if (rs6000_traceback
== traceback_full
)
15782 optional_tbtab
= 1;
15783 else if (rs6000_traceback
== traceback_part
)
15784 optional_tbtab
= 0;
15786 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
15788 if (optional_tbtab
)
15790 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
15791 while (*fname
== '.') /* V.4 encodes . in the name */
15794 /* Need label immediately before tbtab, so we can compute
15795 its offset from the function start. */
15796 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15797 ASM_OUTPUT_LABEL (file
, fname
);
15800 /* The .tbtab pseudo-op can only be used for the first eight
15801 expressions, since it can't handle the possibly variable
15802 length fields that follow. However, if you omit the optional
15803 fields, the assembler outputs zeros for all optional fields
15804 anyways, giving each variable length field is minimum length
15805 (as defined in sys/debug.h). Thus we can not use the .tbtab
15806 pseudo-op at all. */
15808 /* An all-zero word flags the start of the tbtab, for debuggers
15809 that have to find it by searching forward from the entry
15810 point or from the current pc. */
15811 fputs ("\t.long 0\n", file
);
15813 /* Tbtab format type. Use format type 0. */
15814 fputs ("\t.byte 0,", file
);
15816 /* Language type. Unfortunately, there does not seem to be any
15817 official way to discover the language being compiled, so we
15818 use language_string.
15819 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15820 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
15821 a number, so for now use 9. */
15822 if (! strcmp (language_string
, "GNU C"))
15824 else if (! strcmp (language_string
, "GNU F77")
15825 || ! strcmp (language_string
, "GNU F95"))
15827 else if (! strcmp (language_string
, "GNU Pascal"))
15829 else if (! strcmp (language_string
, "GNU Ada"))
15831 else if (! strcmp (language_string
, "GNU C++")
15832 || ! strcmp (language_string
, "GNU Objective-C++"))
15834 else if (! strcmp (language_string
, "GNU Java"))
15836 else if (! strcmp (language_string
, "GNU Objective-C"))
15839 gcc_unreachable ();
15840 fprintf (file
, "%d,", i
);
15842 /* 8 single bit fields: global linkage (not set for C extern linkage,
15843 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15844 from start of procedure stored in tbtab, internal function, function
15845 has controlled storage, function has no toc, function uses fp,
15846 function logs/aborts fp operations. */
15847 /* Assume that fp operations are used if any fp reg must be saved. */
15848 fprintf (file
, "%d,",
15849 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
15851 /* 6 bitfields: function is interrupt handler, name present in
15852 proc table, function calls alloca, on condition directives
15853 (controls stack walks, 3 bits), saves condition reg, saves
15855 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15856 set up as a frame pointer, even when there is no alloca call. */
15857 fprintf (file
, "%d,",
15858 ((optional_tbtab
<< 6)
15859 | ((optional_tbtab
& frame_pointer_needed
) << 5)
15860 | (info
->cr_save_p
<< 1)
15861 | (info
->lr_save_p
)));
15863 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15865 fprintf (file
, "%d,",
15866 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
15868 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15869 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
15871 if (optional_tbtab
)
15873 /* Compute the parameter info from the function decl argument
15876 int next_parm_info_bit
= 31;
15878 for (decl
= DECL_ARGUMENTS (current_function_decl
);
15879 decl
; decl
= TREE_CHAIN (decl
))
15881 rtx parameter
= DECL_INCOMING_RTL (decl
);
15882 enum machine_mode mode
= GET_MODE (parameter
);
15884 if (GET_CODE (parameter
) == REG
)
15886 if (SCALAR_FLOAT_MODE_P (mode
))
15906 gcc_unreachable ();
15909 /* If only one bit will fit, don't or in this entry. */
15910 if (next_parm_info_bit
> 0)
15911 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
15912 next_parm_info_bit
-= 2;
15916 fixed_parms
+= ((GET_MODE_SIZE (mode
)
15917 + (UNITS_PER_WORD
- 1))
15919 next_parm_info_bit
-= 1;
15925 /* Number of fixed point parameters. */
15926 /* This is actually the number of words of fixed point parameters; thus
15927 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15928 fprintf (file
, "%d,", fixed_parms
);
15930 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15932 /* This is actually the number of fp registers that hold parameters;
15933 and thus the maximum value is 13. */
15934 /* Set parameters on stack bit if parameters are not in their original
15935 registers, regardless of whether they are on the stack? Xlc
15936 seems to set the bit when not optimizing. */
15937 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
15939 if (! optional_tbtab
)
15942 /* Optional fields follow. Some are variable length. */
15944 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15945 11 double float. */
15946 /* There is an entry for each parameter in a register, in the order that
15947 they occur in the parameter list. Any intervening arguments on the
15948 stack are ignored. If the list overflows a long (max possible length
15949 34 bits) then completely leave off all elements that don't fit. */
15950 /* Only emit this long if there was at least one parameter. */
15951 if (fixed_parms
|| float_parms
)
15952 fprintf (file
, "\t.long %d\n", parm_info
);
15954 /* Offset from start of code to tb table. */
15955 fputs ("\t.long ", file
);
15956 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15958 RS6000_OUTPUT_BASENAME (file
, fname
);
15960 assemble_name (file
, fname
);
15962 rs6000_output_function_entry (file
, fname
);
15965 /* Interrupt handler mask. */
15966 /* Omit this long, since we never set the interrupt handler bit
15969 /* Number of CTL (controlled storage) anchors. */
15970 /* Omit this long, since the has_ctl bit is never set above. */
15972 /* Displacement into stack of each CTL anchor. */
15973 /* Omit this list of longs, because there are no CTL anchors. */
15975 /* Length of function name. */
15978 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
15980 /* Function name. */
15981 assemble_string (fname
, strlen (fname
));
15983 /* Register for alloca automatic storage; this is always reg 31.
15984 Only emit this if the alloca bit was set above. */
15985 if (frame_pointer_needed
)
15986 fputs ("\t.byte 31\n", file
);
15988 fputs ("\t.align 2\n", file
);
15992 /* A C compound statement that outputs the assembler code for a thunk
15993 function, used to implement C++ virtual function calls with
15994 multiple inheritance. The thunk acts as a wrapper around a virtual
15995 function, adjusting the implicit object parameter before handing
15996 control off to the real function.
15998 First, emit code to add the integer DELTA to the location that
15999 contains the incoming first argument. Assume that this argument
16000 contains a pointer, and is the one used to pass the `this' pointer
16001 in C++. This is the incoming argument *before* the function
16002 prologue, e.g. `%o0' on a sparc. The addition must preserve the
16003 values of all other incoming arguments.
16005 After the addition, emit code to jump to FUNCTION, which is a
16006 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
16007 not touch the return address. Hence returning from FUNCTION will
16008 return to whoever called the current `thunk'.
16010 The effect must be as if FUNCTION had been called directly with the
16011 adjusted first argument. This macro is responsible for emitting
16012 all of the code for a thunk function; output_function_prologue()
16013 and output_function_epilogue() are not invoked.
16015 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
16016 been extracted from it.) It might possibly be useful on some
16017 targets, but probably not.
16019 If you do not define this macro, the target-independent code in the
16020 C++ frontend will generate a less efficient heavyweight thunk that
16021 calls FUNCTION instead of jumping to it. The generic approach does
16022 not support varargs. */
16025 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
16026 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
16029 rtx
this, insn
, funexp
;
16031 reload_completed
= 1;
16032 epilogue_completed
= 1;
16033 no_new_pseudos
= 1;
16034 reset_block_changes ();
16036 /* Mark the end of the (empty) prologue. */
16037 emit_note (NOTE_INSN_PROLOGUE_END
);
16039 /* Find the "this" pointer. If the function returns a structure,
16040 the structure return pointer is in r3. */
16041 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
16042 this = gen_rtx_REG (Pmode
, 4);
16044 this = gen_rtx_REG (Pmode
, 3);
16046 /* Apply the constant offset, if required. */
16049 rtx delta_rtx
= GEN_INT (delta
);
16050 emit_insn (TARGET_32BIT
16051 ? gen_addsi3 (this, this, delta_rtx
)
16052 : gen_adddi3 (this, this, delta_rtx
));
16055 /* Apply the offset from the vtable, if required. */
16058 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
16059 rtx tmp
= gen_rtx_REG (Pmode
, 12);
16061 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
16062 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
16064 emit_insn (TARGET_32BIT
16065 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
16066 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
16067 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
16071 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
16073 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
16075 emit_insn (TARGET_32BIT
16076 ? gen_addsi3 (this, this, tmp
)
16077 : gen_adddi3 (this, this, tmp
));
16080 /* Generate a tail call to the target function. */
16081 if (!TREE_USED (function
))
16083 assemble_external (function
);
16084 TREE_USED (function
) = 1;
16086 funexp
= XEXP (DECL_RTL (function
), 0);
16087 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
16090 if (MACHOPIC_INDIRECT
)
16091 funexp
= machopic_indirect_call_target (funexp
);
16094 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
16095 generate sibcall RTL explicitly. */
16096 insn
= emit_call_insn (
16097 gen_rtx_PARALLEL (VOIDmode
,
16099 gen_rtx_CALL (VOIDmode
,
16100 funexp
, const0_rtx
),
16101 gen_rtx_USE (VOIDmode
, const0_rtx
),
16102 gen_rtx_USE (VOIDmode
,
16103 gen_rtx_REG (SImode
,
16104 LINK_REGISTER_REGNUM
)),
16105 gen_rtx_RETURN (VOIDmode
))));
16106 SIBLING_CALL_P (insn
) = 1;
16109 /* Run just enough of rest_of_compilation to get the insns emitted.
16110 There's not really enough bulk here to make other passes such as
16111 instruction scheduling worth while. Note that use_thunk calls
16112 assemble_start_function and assemble_end_function. */
16113 insn
= get_insns ();
16114 insn_locators_initialize ();
16115 shorten_branches (insn
);
16116 final_start_function (insn
, file
, 1);
16117 final (insn
, file
, 1);
16118 final_end_function ();
16120 reload_completed
= 0;
16121 epilogue_completed
= 0;
16122 no_new_pseudos
= 0;
16125 /* A quick summary of the various types of 'constant-pool tables'
16128 Target Flags Name One table per
16129 AIX (none) AIX TOC object file
16130 AIX -mfull-toc AIX TOC object file
16131 AIX -mminimal-toc AIX minimal TOC translation unit
16132 SVR4/EABI (none) SVR4 SDATA object file
16133 SVR4/EABI -fpic SVR4 pic object file
16134 SVR4/EABI -fPIC SVR4 PIC translation unit
16135 SVR4/EABI -mrelocatable EABI TOC function
16136 SVR4/EABI -maix AIX TOC object file
16137 SVR4/EABI -maix -mminimal-toc
16138 AIX minimal TOC translation unit
16140 Name Reg. Set by entries contains:
16141 made by addrs? fp? sum?
16143 AIX TOC 2 crt0 as Y option option
16144 AIX minimal TOC 30 prolog gcc Y Y option
16145 SVR4 SDATA 13 crt0 gcc N Y N
16146 SVR4 pic 30 prolog ld Y not yet N
16147 SVR4 PIC 30 prolog gcc Y option option
16148 EABI TOC 30 prolog gcc Y option option
16152 /* Hash functions for the hash table. */
16155 rs6000_hash_constant (rtx k
)
16157 enum rtx_code code
= GET_CODE (k
);
16158 enum machine_mode mode
= GET_MODE (k
);
16159 unsigned result
= (code
<< 3) ^ mode
;
16160 const char *format
;
16163 format
= GET_RTX_FORMAT (code
);
16164 flen
= strlen (format
);
16170 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
16173 if (mode
!= VOIDmode
)
16174 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
16186 for (; fidx
< flen
; fidx
++)
16187 switch (format
[fidx
])
16192 const char *str
= XSTR (k
, fidx
);
16193 len
= strlen (str
);
16194 result
= result
* 613 + len
;
16195 for (i
= 0; i
< len
; i
++)
16196 result
= result
* 613 + (unsigned) str
[i
];
16201 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
16205 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
16208 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
16209 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
16213 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
16214 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
16221 gcc_unreachable ();
16228 toc_hash_function (const void *hash_entry
)
16230 const struct toc_hash_struct
*thc
=
16231 (const struct toc_hash_struct
*) hash_entry
;
16232 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
16235 /* Compare H1 and H2 for equivalence. */
16238 toc_hash_eq (const void *h1
, const void *h2
)
16240 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
16241 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
16243 if (((const struct toc_hash_struct
*) h1
)->key_mode
16244 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
16247 return rtx_equal_p (r1
, r2
);
16250 /* These are the names given by the C++ front-end to vtables, and
16251 vtable-like objects. Ideally, this logic should not be here;
16252 instead, there should be some programmatic way of inquiring as
16253 to whether or not an object is a vtable. */
16255 #define VTABLE_NAME_P(NAME) \
16256 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
16257 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
16258 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
16259 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
16260 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
16263 rs6000_output_symbol_ref (FILE *file
, rtx x
)
16265 /* Currently C++ toc references to vtables can be emitted before it
16266 is decided whether the vtable is public or private. If this is
16267 the case, then the linker will eventually complain that there is
16268 a reference to an unknown section. Thus, for vtables only,
16269 we emit the TOC reference to reference the symbol and not the
16271 const char *name
= XSTR (x
, 0);
16273 if (VTABLE_NAME_P (name
))
16275 RS6000_OUTPUT_BASENAME (file
, name
);
16278 assemble_name (file
, name
);
16281 /* Output a TOC entry. We derive the entry name from what is being
16285 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
16288 const char *name
= buf
;
16289 const char *real_name
;
16291 HOST_WIDE_INT offset
= 0;
16293 gcc_assert (!TARGET_NO_TOC
);
16295 /* When the linker won't eliminate them, don't output duplicate
16296 TOC entries (this happens on AIX if there is any kind of TOC,
16297 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
16299 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
16301 struct toc_hash_struct
*h
;
16304 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
16305 time because GGC is not initialized at that point. */
16306 if (toc_hash_table
== NULL
)
16307 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
16308 toc_hash_eq
, NULL
);
16310 h
= ggc_alloc (sizeof (*h
));
16312 h
->key_mode
= mode
;
16313 h
->labelno
= labelno
;
16315 found
= htab_find_slot (toc_hash_table
, h
, 1);
16316 if (*found
== NULL
)
16318 else /* This is indeed a duplicate.
16319 Set this label equal to that label. */
16321 fputs ("\t.set ", file
);
16322 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
16323 fprintf (file
, "%d,", labelno
);
16324 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
16325 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
16331 /* If we're going to put a double constant in the TOC, make sure it's
16332 aligned properly when strict alignment is on. */
16333 if (GET_CODE (x
) == CONST_DOUBLE
16334 && STRICT_ALIGNMENT
16335 && GET_MODE_BITSIZE (mode
) >= 64
16336 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
16337 ASM_OUTPUT_ALIGN (file
, 3);
16340 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
16342 /* Handle FP constants specially. Note that if we have a minimal
16343 TOC, things we put here aren't actually in the TOC, so we can allow
16345 if (GET_CODE (x
) == CONST_DOUBLE
&&
16346 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
16348 REAL_VALUE_TYPE rv
;
16351 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
16352 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
16353 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
16355 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
16359 if (TARGET_MINIMAL_TOC
)
16360 fputs (DOUBLE_INT_ASM_OP
, file
);
16362 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16363 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16364 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16365 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
16366 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16367 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16372 if (TARGET_MINIMAL_TOC
)
16373 fputs ("\t.long ", file
);
16375 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16376 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16377 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16378 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
16379 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16380 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16384 else if (GET_CODE (x
) == CONST_DOUBLE
&&
16385 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
16387 REAL_VALUE_TYPE rv
;
16390 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
16392 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
16393 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
16395 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
16399 if (TARGET_MINIMAL_TOC
)
16400 fputs (DOUBLE_INT_ASM_OP
, file
);
16402 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
16403 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16404 fprintf (file
, "0x%lx%08lx\n",
16405 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16410 if (TARGET_MINIMAL_TOC
)
16411 fputs ("\t.long ", file
);
16413 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
16414 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16415 fprintf (file
, "0x%lx,0x%lx\n",
16416 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16420 else if (GET_CODE (x
) == CONST_DOUBLE
&&
16421 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
16423 REAL_VALUE_TYPE rv
;
16426 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
16427 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
16428 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
16430 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
16434 if (TARGET_MINIMAL_TOC
)
16435 fputs (DOUBLE_INT_ASM_OP
, file
);
16437 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
16438 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
16443 if (TARGET_MINIMAL_TOC
)
16444 fputs ("\t.long ", file
);
16446 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
16447 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
16451 else if (GET_MODE (x
) == VOIDmode
16452 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
16454 unsigned HOST_WIDE_INT low
;
16455 HOST_WIDE_INT high
;
16457 if (GET_CODE (x
) == CONST_DOUBLE
)
16459 low
= CONST_DOUBLE_LOW (x
);
16460 high
= CONST_DOUBLE_HIGH (x
);
16463 #if HOST_BITS_PER_WIDE_INT == 32
16466 high
= (low
& 0x80000000) ? ~0 : 0;
16470 low
= INTVAL (x
) & 0xffffffff;
16471 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
16475 /* TOC entries are always Pmode-sized, but since this
16476 is a bigendian machine then if we're putting smaller
16477 integer constants in the TOC we have to pad them.
16478 (This is still a win over putting the constants in
16479 a separate constant pool, because then we'd have
16480 to have both a TOC entry _and_ the actual constant.)
16482 For a 32-bit target, CONST_INT values are loaded and shifted
16483 entirely within `low' and can be stored in one TOC entry. */
16485 /* It would be easy to make this work, but it doesn't now. */
16486 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
16488 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
16490 #if HOST_BITS_PER_WIDE_INT == 32
16491 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
16492 POINTER_SIZE
, &low
, &high
, 0);
16495 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
16496 high
= (HOST_WIDE_INT
) low
>> 32;
16503 if (TARGET_MINIMAL_TOC
)
16504 fputs (DOUBLE_INT_ASM_OP
, file
);
16506 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
16507 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16508 fprintf (file
, "0x%lx%08lx\n",
16509 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16514 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
16516 if (TARGET_MINIMAL_TOC
)
16517 fputs ("\t.long ", file
);
16519 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
16520 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16521 fprintf (file
, "0x%lx,0x%lx\n",
16522 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16526 if (TARGET_MINIMAL_TOC
)
16527 fputs ("\t.long ", file
);
16529 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
16530 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
16536 if (GET_CODE (x
) == CONST
)
16538 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
16540 base
= XEXP (XEXP (x
, 0), 0);
16541 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
16544 switch (GET_CODE (base
))
16547 name
= XSTR (base
, 0);
16551 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
16552 CODE_LABEL_NUMBER (XEXP (base
, 0)));
16556 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
16560 gcc_unreachable ();
16563 real_name
= (*targetm
.strip_name_encoding
) (name
);
16564 if (TARGET_MINIMAL_TOC
)
16565 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
16568 fprintf (file
, "\t.tc %s", real_name
);
16571 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
16573 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
16575 fputs ("[TC],", file
);
16578 /* Currently C++ toc references to vtables can be emitted before it
16579 is decided whether the vtable is public or private. If this is
16580 the case, then the linker will eventually complain that there is
16581 a TOC reference to an unknown section. Thus, for vtables only,
16582 we emit the TOC reference to reference the symbol and not the
16584 if (VTABLE_NAME_P (name
))
16586 RS6000_OUTPUT_BASENAME (file
, name
);
16588 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
16589 else if (offset
> 0)
16590 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
16593 output_addr_const (file
, x
);
16597 /* Output an assembler pseudo-op to write an ASCII string of N characters
16598 starting at P to FILE.
16600 On the RS/6000, we have to do this using the .byte operation and
16601 write out special characters outside the quoted string.
16602 Also, the assembler is broken; very long strings are truncated,
16603 so we must artificially break them up early. */
16606 output_ascii (FILE *file
, const char *p
, int n
)
16609 int i
, count_string
;
16610 const char *for_string
= "\t.byte \"";
16611 const char *for_decimal
= "\t.byte ";
16612 const char *to_close
= NULL
;
16615 for (i
= 0; i
< n
; i
++)
16618 if (c
>= ' ' && c
< 0177)
16621 fputs (for_string
, file
);
16624 /* Write two quotes to get one. */
16632 for_decimal
= "\"\n\t.byte ";
16636 if (count_string
>= 512)
16638 fputs (to_close
, file
);
16640 for_string
= "\t.byte \"";
16641 for_decimal
= "\t.byte ";
16649 fputs (for_decimal
, file
);
16650 fprintf (file
, "%d", c
);
16652 for_string
= "\n\t.byte \"";
16653 for_decimal
= ", ";
16659 /* Now close the string if we have written one. Then end the line. */
16661 fputs (to_close
, file
);
16664 /* Generate a unique section name for FILENAME for a section type
16665 represented by SECTION_DESC. Output goes into BUF.
16667 SECTION_DESC can be any string, as long as it is different for each
16668 possible section type.
16670 We name the section in the same manner as xlc. The name begins with an
16671 underscore followed by the filename (after stripping any leading directory
16672 names) with the last period replaced by the string SECTION_DESC. If
16673 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16677 rs6000_gen_section_name (char **buf
, const char *filename
,
16678 const char *section_desc
)
16680 const char *q
, *after_last_slash
, *last_period
= 0;
16684 after_last_slash
= filename
;
16685 for (q
= filename
; *q
; q
++)
16688 after_last_slash
= q
+ 1;
16689 else if (*q
== '.')
16693 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
16694 *buf
= (char *) xmalloc (len
);
16699 for (q
= after_last_slash
; *q
; q
++)
16701 if (q
== last_period
)
16703 strcpy (p
, section_desc
);
16704 p
+= strlen (section_desc
);
16708 else if (ISALNUM (*q
))
16712 if (last_period
== 0)
16713 strcpy (p
, section_desc
);
16718 /* Emit profile function. */
16721 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
16723 /* Non-standard profiling for kernels, which just saves LR then calls
16724 _mcount without worrying about arg saves. The idea is to change
16725 the function prologue as little as possible as it isn't easy to
16726 account for arg save/restore code added just for _mcount. */
16727 if (TARGET_PROFILE_KERNEL
)
16730 if (DEFAULT_ABI
== ABI_AIX
)
16732 #ifndef NO_PROFILE_COUNTERS
16733 # define NO_PROFILE_COUNTERS 0
16735 if (NO_PROFILE_COUNTERS
)
16736 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
16740 const char *label_name
;
16743 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16744 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
16745 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
16747 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
16751 else if (DEFAULT_ABI
== ABI_DARWIN
)
16753 const char *mcount_name
= RS6000_MCOUNT
;
16754 int caller_addr_regno
= LINK_REGISTER_REGNUM
;
16756 /* Be conservative and always set this, at least for now. */
16757 current_function_uses_pic_offset_table
= 1;
16760 /* For PIC code, set up a stub and collect the caller's address
16761 from r0, which is where the prologue puts it. */
16762 if (MACHOPIC_INDIRECT
16763 && current_function_uses_pic_offset_table
)
16764 caller_addr_regno
= 0;
16766 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
16768 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
16772 /* Write function profiler code. */
16775 output_function_profiler (FILE *file
, int labelno
)
16779 switch (DEFAULT_ABI
)
16782 gcc_unreachable ();
16787 warning (0, "no profiling of 64-bit code for this ABI");
16790 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16791 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16792 if (NO_PROFILE_COUNTERS
)
16794 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16795 reg_names
[0], reg_names
[1]);
16797 else if (TARGET_SECURE_PLT
&& flag_pic
)
16799 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16800 reg_names
[0], reg_names
[1]);
16801 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16802 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
16803 reg_names
[12], reg_names
[12]);
16804 assemble_name (file
, buf
);
16805 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
16806 assemble_name (file
, buf
);
16807 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
16809 else if (flag_pic
== 1)
16811 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
16812 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16813 reg_names
[0], reg_names
[1]);
16814 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16815 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
16816 assemble_name (file
, buf
);
16817 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
16819 else if (flag_pic
> 1)
16821 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16822 reg_names
[0], reg_names
[1]);
16823 /* Now, we need to get the address of the label. */
16824 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
16825 assemble_name (file
, buf
);
16826 fputs ("-.\n1:", file
);
16827 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
16828 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
16829 reg_names
[0], reg_names
[11]);
16830 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
16831 reg_names
[0], reg_names
[0], reg_names
[11]);
16835 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
16836 assemble_name (file
, buf
);
16837 fputs ("@ha\n", file
);
16838 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16839 reg_names
[0], reg_names
[1]);
16840 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
16841 assemble_name (file
, buf
);
16842 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
16845 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16846 fprintf (file
, "\tbl %s%s\n",
16847 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
16852 if (!TARGET_PROFILE_KERNEL
)
16854 /* Don't do anything, done in output_profile_hook (). */
16858 gcc_assert (!TARGET_32BIT
);
16860 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16861 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
16863 if (cfun
->static_chain_decl
!= NULL
)
16865 asm_fprintf (file
, "\tstd %s,24(%s)\n",
16866 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16867 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16868 asm_fprintf (file
, "\tld %s,24(%s)\n",
16869 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16872 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16880 /* The following variable value is the last issued insn. */
16882 static rtx last_scheduled_insn
;
16884 /* The following variable helps to balance issuing of load and
16885 store instructions */
16887 static int load_store_pendulum
;
16889 /* Power4 load update and store update instructions are cracked into a
16890 load or store and an integer insn which are executed in the same cycle.
16891 Branches have their own dispatch slot which does not count against the
16892 GCC issue rate, but it changes the program flow so there are no other
16893 instructions to issue in this cycle. */
16896 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
16897 int verbose ATTRIBUTE_UNUSED
,
16898 rtx insn
, int more
)
16900 last_scheduled_insn
= insn
;
16901 if (GET_CODE (PATTERN (insn
)) == USE
16902 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16904 cached_can_issue_more
= more
;
16905 return cached_can_issue_more
;
16908 if (insn_terminates_group_p (insn
, current_group
))
16910 cached_can_issue_more
= 0;
16911 return cached_can_issue_more
;
16914 /* If no reservation, but reach here */
16915 if (recog_memoized (insn
) < 0)
16918 if (rs6000_sched_groups
)
16920 if (is_microcoded_insn (insn
))
16921 cached_can_issue_more
= 0;
16922 else if (is_cracked_insn (insn
))
16923 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
16925 cached_can_issue_more
= more
- 1;
16927 return cached_can_issue_more
;
16930 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
16933 cached_can_issue_more
= more
- 1;
16934 return cached_can_issue_more
;
16937 /* Adjust the cost of a scheduling dependency. Return the new cost of
16938 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16941 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
16943 enum attr_type attr_type
;
16945 if (! recog_memoized (insn
))
16948 switch (REG_NOTE_KIND (link
))
16952 /* Data dependency; DEP_INSN writes a register that INSN reads
16953 some cycles later. */
16955 /* Separate a load from a narrower, dependent store. */
16956 if (rs6000_sched_groups
16957 && GET_CODE (PATTERN (insn
)) == SET
16958 && GET_CODE (PATTERN (dep_insn
)) == SET
16959 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
16960 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
16961 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
16962 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
16965 attr_type
= get_attr_type (insn
);
16970 /* Tell the first scheduling pass about the latency between
16971 a mtctr and bctr (and mtlr and br/blr). The first
16972 scheduling pass will not know about this latency since
16973 the mtctr instruction, which has the latency associated
16974 to it, will be generated by reload. */
16975 return TARGET_POWER
? 5 : 4;
16977 /* Leave some extra cycles between a compare and its
16978 dependent branch, to inhibit expensive mispredicts. */
16979 if ((rs6000_cpu_attr
== CPU_PPC603
16980 || rs6000_cpu_attr
== CPU_PPC604
16981 || rs6000_cpu_attr
== CPU_PPC604E
16982 || rs6000_cpu_attr
== CPU_PPC620
16983 || rs6000_cpu_attr
== CPU_PPC630
16984 || rs6000_cpu_attr
== CPU_PPC750
16985 || rs6000_cpu_attr
== CPU_PPC7400
16986 || rs6000_cpu_attr
== CPU_PPC7450
16987 || rs6000_cpu_attr
== CPU_POWER4
16988 || rs6000_cpu_attr
== CPU_POWER5
16989 || rs6000_cpu_attr
== CPU_CELL
)
16990 && recog_memoized (dep_insn
)
16991 && (INSN_CODE (dep_insn
) >= 0))
16993 switch (get_attr_type (dep_insn
))
16997 case TYPE_DELAYED_COMPARE
:
16998 case TYPE_IMUL_COMPARE
:
16999 case TYPE_LMUL_COMPARE
:
17000 case TYPE_FPCOMPARE
:
17001 case TYPE_CR_LOGICAL
:
17002 case TYPE_DELAYED_CR
:
17011 case TYPE_STORE_UX
:
17013 case TYPE_FPSTORE_U
:
17014 case TYPE_FPSTORE_UX
:
17015 if ((rs6000_cpu
== PROCESSOR_POWER6
)
17016 && recog_memoized (dep_insn
)
17017 && (INSN_CODE (dep_insn
) >= 0))
17020 if (GET_CODE (PATTERN (insn
)) != SET
)
17021 /* If this happens, we have to extend this to schedule
17022 optimally. Return default for now. */
17025 /* Adjust the cost for the case where the value written
17026 by a fixed point operation is used as the address
17027 gen value on a store. */
17028 switch (get_attr_type (dep_insn
))
17035 if (! store_data_bypass_p (dep_insn
, insn
))
17039 case TYPE_LOAD_EXT
:
17040 case TYPE_LOAD_EXT_U
:
17041 case TYPE_LOAD_EXT_UX
:
17042 case TYPE_VAR_SHIFT_ROTATE
:
17043 case TYPE_VAR_DELAYED_COMPARE
:
17045 if (! store_data_bypass_p (dep_insn
, insn
))
17051 case TYPE_FAST_COMPARE
:
17054 case TYPE_INSERT_WORD
:
17055 case TYPE_INSERT_DWORD
:
17056 case TYPE_FPLOAD_U
:
17057 case TYPE_FPLOAD_UX
:
17059 case TYPE_STORE_UX
:
17060 case TYPE_FPSTORE_U
:
17061 case TYPE_FPSTORE_UX
:
17063 if (! store_data_bypass_p (dep_insn
, insn
))
17071 case TYPE_IMUL_COMPARE
:
17072 case TYPE_LMUL_COMPARE
:
17074 if (! store_data_bypass_p (dep_insn
, insn
))
17080 if (! store_data_bypass_p (dep_insn
, insn
))
17086 if (! store_data_bypass_p (dep_insn
, insn
))
17099 case TYPE_LOAD_EXT
:
17100 case TYPE_LOAD_EXT_U
:
17101 case TYPE_LOAD_EXT_UX
:
17102 if ((rs6000_cpu
== PROCESSOR_POWER6
)
17103 && recog_memoized (dep_insn
)
17104 && (INSN_CODE (dep_insn
) >= 0))
17107 /* Adjust the cost for the case where the value written
17108 by a fixed point instruction is used within the address
17109 gen portion of a subsequent load(u)(x) */
17110 switch (get_attr_type (dep_insn
))
17117 if (set_to_load_agen (dep_insn
, insn
))
17121 case TYPE_LOAD_EXT
:
17122 case TYPE_LOAD_EXT_U
:
17123 case TYPE_LOAD_EXT_UX
:
17124 case TYPE_VAR_SHIFT_ROTATE
:
17125 case TYPE_VAR_DELAYED_COMPARE
:
17127 if (set_to_load_agen (dep_insn
, insn
))
17133 case TYPE_FAST_COMPARE
:
17136 case TYPE_INSERT_WORD
:
17137 case TYPE_INSERT_DWORD
:
17138 case TYPE_FPLOAD_U
:
17139 case TYPE_FPLOAD_UX
:
17141 case TYPE_STORE_UX
:
17142 case TYPE_FPSTORE_U
:
17143 case TYPE_FPSTORE_UX
:
17145 if (set_to_load_agen (dep_insn
, insn
))
17153 case TYPE_IMUL_COMPARE
:
17154 case TYPE_LMUL_COMPARE
:
17156 if (set_to_load_agen (dep_insn
, insn
))
17162 if (set_to_load_agen (dep_insn
, insn
))
17168 if (set_to_load_agen (dep_insn
, insn
))
17179 if ((rs6000_cpu
== PROCESSOR_POWER6
)
17180 && recog_memoized (dep_insn
)
17181 && (INSN_CODE (dep_insn
) >= 0)
17182 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
17189 /* Fall out to return default cost. */
17193 case REG_DEP_OUTPUT
:
17194 /* Output dependency; DEP_INSN writes a register that INSN writes some
17196 if ((rs6000_cpu
== PROCESSOR_POWER6
)
17197 && recog_memoized (dep_insn
)
17198 && (INSN_CODE (dep_insn
) >= 0))
17200 attr_type
= get_attr_type (insn
);
17205 if (get_attr_type (dep_insn
) == TYPE_FP
)
17209 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
17217 /* Anti dependency; DEP_INSN reads a register that INSN writes some
17222 gcc_unreachable ();
17228 /* The function returns a true if INSN is microcoded.
17229 Return false otherwise. */
17232 is_microcoded_insn (rtx insn
)
17234 if (!insn
|| !INSN_P (insn
)
17235 || GET_CODE (PATTERN (insn
)) == USE
17236 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17239 if (rs6000_cpu_attr
== CPU_CELL
)
17240 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
17242 if (rs6000_sched_groups
)
17244 enum attr_type type
= get_attr_type (insn
);
17245 if (type
== TYPE_LOAD_EXT_U
17246 || type
== TYPE_LOAD_EXT_UX
17247 || type
== TYPE_LOAD_UX
17248 || type
== TYPE_STORE_UX
17249 || type
== TYPE_MFCR
)
17256 /* The function returns true if INSN is cracked into 2 instructions
17257 by the processor (and therefore occupies 2 issue slots). */
17260 is_cracked_insn (rtx insn
)
17262 if (!insn
|| !INSN_P (insn
)
17263 || GET_CODE (PATTERN (insn
)) == USE
17264 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17267 if (rs6000_sched_groups
)
17269 enum attr_type type
= get_attr_type (insn
);
17270 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
17271 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
17272 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
17273 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
17274 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
17275 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
17276 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
17277 || type
== TYPE_INSERT_WORD
)
17284 /* The function returns true if INSN can be issued only from
17285 the branch slot. */
17288 is_branch_slot_insn (rtx insn
)
17290 if (!insn
|| !INSN_P (insn
)
17291 || GET_CODE (PATTERN (insn
)) == USE
17292 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17295 if (rs6000_sched_groups
)
17297 enum attr_type type
= get_attr_type (insn
);
17298 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
17306 /* The function returns true if out_inst sets a value that is
17307 used in the address generation computation of in_insn */
17309 set_to_load_agen (rtx out_insn
, rtx in_insn
)
17311 rtx out_set
, in_set
;
17313 /* For performance reasons, only handle the simple case where
17314 both loads are a single_set. */
17315 out_set
= single_set (out_insn
);
17318 in_set
= single_set (in_insn
);
17320 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
17326 /* The function returns true if the target storage location of
17327 out_insn is adjacent to the target storage location of in_insn */
17328 /* Return 1 if memory locations are adjacent. */
17331 adjacent_mem_locations (rtx insn1
, rtx insn2
)
17334 rtx a
= get_store_dest (PATTERN (insn1
));
17335 rtx b
= get_store_dest (PATTERN (insn2
));
17337 if ((GET_CODE (XEXP (a
, 0)) == REG
17338 || (GET_CODE (XEXP (a
, 0)) == PLUS
17339 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
17340 && (GET_CODE (XEXP (b
, 0)) == REG
17341 || (GET_CODE (XEXP (b
, 0)) == PLUS
17342 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
17344 HOST_WIDE_INT val0
= 0, val1
= 0;
17348 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
17350 reg0
= XEXP (XEXP (a
, 0), 0);
17351 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
17354 reg0
= XEXP (a
, 0);
17356 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
17358 reg1
= XEXP (XEXP (b
, 0), 0);
17359 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
17362 reg1
= XEXP (b
, 0);
17364 val_diff
= val1
- val0
;
17366 return ((REGNO (reg0
) == REGNO (reg1
))
17367 && (val_diff
== INTVAL (MEM_SIZE (a
))
17368 || val_diff
== -INTVAL (MEM_SIZE (b
))));
17374 /* A C statement (sans semicolon) to update the integer scheduling
17375 priority INSN_PRIORITY (INSN). Increase the priority to execute the
17376 INSN earlier, reduce the priority to execute INSN later. Do not
17377 define this macro if you do not need to adjust the scheduling
17378 priorities of insns. */
17381 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
17383 /* On machines (like the 750) which have asymmetric integer units,
17384 where one integer unit can do multiply and divides and the other
17385 can't, reduce the priority of multiply/divide so it is scheduled
17386 before other integer operations. */
17389 if (! INSN_P (insn
))
17392 if (GET_CODE (PATTERN (insn
)) == USE
)
17395 switch (rs6000_cpu_attr
) {
17397 switch (get_attr_type (insn
))
17404 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
17405 priority
, priority
);
17406 if (priority
>= 0 && priority
< 0x01000000)
17413 if (insn_must_be_first_in_group (insn
)
17414 && reload_completed
17415 && current_sched_info
->sched_max_insns_priority
17416 && rs6000_sched_restricted_insns_priority
)
17419 /* Prioritize insns that can be dispatched only in the first
17421 if (rs6000_sched_restricted_insns_priority
== 1)
17422 /* Attach highest priority to insn. This means that in
17423 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
17424 precede 'priority' (critical path) considerations. */
17425 return current_sched_info
->sched_max_insns_priority
;
17426 else if (rs6000_sched_restricted_insns_priority
== 2)
17427 /* Increase priority of insn by a minimal amount. This means that in
17428 haifa-sched.c:ready_sort(), only 'priority' (critical path)
17429 considerations precede dispatch-slot restriction considerations. */
17430 return (priority
+ 1);
17433 if (rs6000_cpu
== PROCESSOR_POWER6
17434 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
17435 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
17436 /* Attach highest priority to insn if the scheduler has just issued two
17437 stores and this instruction is a load, or two loads and this instruction
17438 is a store. Power6 wants loads and stores scheduled alternately
17440 return current_sched_info
->sched_max_insns_priority
;
17445 /* Return true if the instruction is nonpipelined on the Cell. */
17447 is_nonpipeline_insn (rtx insn
)
17449 enum attr_type type
;
17450 if (!insn
|| !INSN_P (insn
)
17451 || GET_CODE (PATTERN (insn
)) == USE
17452 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17455 type
= get_attr_type (insn
);
17456 if (type
== TYPE_IMUL
17457 || type
== TYPE_IMUL2
17458 || type
== TYPE_IMUL3
17459 || type
== TYPE_LMUL
17460 || type
== TYPE_IDIV
17461 || type
== TYPE_LDIV
17462 || type
== TYPE_SDIV
17463 || type
== TYPE_DDIV
17464 || type
== TYPE_SSQRT
17465 || type
== TYPE_DSQRT
17466 || type
== TYPE_MFCR
17467 || type
== TYPE_MFCRF
17468 || type
== TYPE_MFJMPR
)
17476 /* Return how many instructions the machine can issue per cycle. */
17479 rs6000_issue_rate (void)
17481 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
17482 if (!reload_completed
)
17485 switch (rs6000_cpu_attr
) {
17486 case CPU_RIOS1
: /* ? */
17488 case CPU_PPC601
: /* ? */
17513 /* Return how many instructions to look ahead for better insn
17517 rs6000_use_sched_lookahead (void)
17519 if (rs6000_cpu_attr
== CPU_PPC8540
)
17521 if (rs6000_cpu_attr
== CPU_CELL
)
17522 return (reload_completed
? 8 : 0);
17526 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
17528 rs6000_use_sched_lookahead_guard (rtx insn
)
17530 if (rs6000_cpu_attr
!= CPU_CELL
)
17533 if (insn
== NULL_RTX
|| !INSN_P (insn
))
17536 if (!reload_completed
17537 || is_nonpipeline_insn (insn
)
17538 || is_microcoded_insn (insn
))
17544 /* Determine is PAT refers to memory. */
17547 is_mem_ref (rtx pat
)
17553 if (GET_CODE (pat
) == MEM
)
17556 /* Recursively process the pattern. */
17557 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
17559 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
17562 ret
|= is_mem_ref (XEXP (pat
, i
));
17563 else if (fmt
[i
] == 'E')
17564 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
17565 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
17571 /* Determine if PAT is a PATTERN of a load insn. */
17574 is_load_insn1 (rtx pat
)
17576 if (!pat
|| pat
== NULL_RTX
)
17579 if (GET_CODE (pat
) == SET
)
17580 return is_mem_ref (SET_SRC (pat
));
17582 if (GET_CODE (pat
) == PARALLEL
)
17586 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
17587 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
17594 /* Determine if INSN loads from memory. */
17597 is_load_insn (rtx insn
)
17599 if (!insn
|| !INSN_P (insn
))
17602 if (GET_CODE (insn
) == CALL_INSN
)
17605 return is_load_insn1 (PATTERN (insn
));
17608 /* Determine if PAT is a PATTERN of a store insn. */
17611 is_store_insn1 (rtx pat
)
17613 if (!pat
|| pat
== NULL_RTX
)
17616 if (GET_CODE (pat
) == SET
)
17617 return is_mem_ref (SET_DEST (pat
));
17619 if (GET_CODE (pat
) == PARALLEL
)
17623 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
17624 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
17631 /* Determine if INSN stores to memory. */
17634 is_store_insn (rtx insn
)
17636 if (!insn
|| !INSN_P (insn
))
17639 return is_store_insn1 (PATTERN (insn
));
17642 /* Return the dest of a store insn. */
17645 get_store_dest (rtx pat
)
17647 gcc_assert (is_store_insn1 (pat
));
17649 if (GET_CODE (pat
) == SET
)
17650 return SET_DEST (pat
);
17651 else if (GET_CODE (pat
) == PARALLEL
)
17655 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
17657 rtx inner_pat
= XVECEXP (pat
, 0, i
);
17658 if (GET_CODE (inner_pat
) == SET
17659 && is_mem_ref (SET_DEST (inner_pat
)))
17663 /* We shouldn't get here, because we should have either a simple
17664 store insn or a store with update which are covered above. */
17668 /* Returns whether the dependence between INSN and NEXT is considered
17669 costly by the given target. */
17672 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
17677 /* If the flag is not enabled - no dependence is considered costly;
17678 allow all dependent insns in the same group.
17679 This is the most aggressive option. */
17680 if (rs6000_sched_costly_dep
== no_dep_costly
)
17683 /* If the flag is set to 1 - a dependence is always considered costly;
17684 do not allow dependent instructions in the same group.
17685 This is the most conservative option. */
17686 if (rs6000_sched_costly_dep
== all_deps_costly
)
17689 insn
= DEP_PRO (dep
);
17690 next
= DEP_CON (dep
);
17692 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
17693 && is_load_insn (next
)
17694 && is_store_insn (insn
))
17695 /* Prevent load after store in the same group. */
17698 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
17699 && is_load_insn (next
)
17700 && is_store_insn (insn
)
17701 && DEP_KIND (dep
) == REG_DEP_TRUE
)
17702 /* Prevent load after store in the same group if it is a true
17706 /* The flag is set to X; dependences with latency >= X are considered costly,
17707 and will not be scheduled in the same group. */
17708 if (rs6000_sched_costly_dep
<= max_dep_latency
17709 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
17715 /* Return the next insn after INSN that is found before TAIL is reached,
17716 skipping any "non-active" insns - insns that will not actually occupy
17717 an issue slot. Return NULL_RTX if such an insn is not found. */
17720 get_next_active_insn (rtx insn
, rtx tail
)
17722 if (insn
== NULL_RTX
|| insn
== tail
)
17727 insn
= NEXT_INSN (insn
);
17728 if (insn
== NULL_RTX
|| insn
== tail
)
17733 || (NONJUMP_INSN_P (insn
)
17734 && GET_CODE (PATTERN (insn
)) != USE
17735 && GET_CODE (PATTERN (insn
)) != CLOBBER
17736 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
17742 /* We are about to begin issuing insns for this clock cycle. */
17745 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
17746 rtx
*ready ATTRIBUTE_UNUSED
,
17747 int *pn_ready ATTRIBUTE_UNUSED
,
17748 int clock_var ATTRIBUTE_UNUSED
)
17750 int n_ready
= *pn_ready
;
17753 fprintf (dump
, "// rs6000_sched_reorder :\n");
17755 /* Reorder the ready list, if the second to last ready insn
17756 is a nonepipeline insn. */
17757 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
17759 if (is_nonpipeline_insn (ready
[n_ready
- 1])
17760 && (recog_memoized (ready
[n_ready
- 2]) > 0))
17761 /* Simply swap first two insns. */
17763 rtx tmp
= ready
[n_ready
- 1];
17764 ready
[n_ready
- 1] = ready
[n_ready
- 2];
17765 ready
[n_ready
- 2] = tmp
;
17769 if (rs6000_cpu
== PROCESSOR_POWER6
)
17770 load_store_pendulum
= 0;
17772 return rs6000_issue_rate ();
17775 /* Like rs6000_sched_reorder, but called after issuing each insn. */
17778 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
17779 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
17782 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
17784 /* For Power6, we need to handle some special cases to try and keep the
17785 store queue from overflowing and triggering expensive flushes.
17787 This code monitors how load and store instructions are being issued
17788 and skews the ready list one way or the other to increase the likelihood
17789 that a desired instruction is issued at the proper time.
17791 A couple of things are done. First, we maintain a "load_store_pendulum"
17792 to track the current state of load/store issue.
17794 - If the pendulum is at zero, then no loads or stores have been
17795 issued in the current cycle so we do nothing.
17797 - If the pendulum is 1, then a single load has been issued in this
17798 cycle and we attempt to locate another load in the ready list to
17801 - If the pendulum is -2, then two stores have already been
17802 issued in this cycle, so we increase the priority of the first load
17803 in the ready list to increase it's likelihood of being chosen first
17806 - If the pendulum is -1, then a single store has been issued in this
17807 cycle and we attempt to locate another store in the ready list to
17808 issue with it, preferring a store to an adjacent memory location to
17809 facilitate store pairing in the store queue.
17811 - If the pendulum is 2, then two loads have already been
17812 issued in this cycle, so we increase the priority of the first store
17813 in the ready list to increase it's likelihood of being chosen first
17816 - If the pendulum < -2 or > 2, then do nothing.
17818 Note: This code covers the most common scenarios. There exist non
17819 load/store instructions which make use of the LSU and which
17820 would need to be accounted for to strictly model the behavior
17821 of the machine. Those instructions are currently unaccounted
17822 for to help minimize compile time overhead of this code.
17824 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
17830 if (is_store_insn (last_scheduled_insn
))
17831 /* Issuing a store, swing the load_store_pendulum to the left */
17832 load_store_pendulum
--;
17833 else if (is_load_insn (last_scheduled_insn
))
17834 /* Issuing a load, swing the load_store_pendulum to the right */
17835 load_store_pendulum
++;
17837 return cached_can_issue_more
;
17839 /* If the pendulum is balanced, or there is only one instruction on
17840 the ready list, then all is well, so return. */
17841 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
17842 return cached_can_issue_more
;
17844 if (load_store_pendulum
== 1)
17846 /* A load has been issued in this cycle. Scan the ready list
17847 for another load to issue with it */
17852 if (is_load_insn (ready
[pos
]))
17854 /* Found a load. Move it to the head of the ready list,
17855 and adjust it's priority so that it is more likely to
17858 for (i
=pos
; i
<*pn_ready
-1; i
++)
17859 ready
[i
] = ready
[i
+ 1];
17860 ready
[*pn_ready
-1] = tmp
;
17861 if INSN_PRIORITY_KNOWN (tmp
)
17862 INSN_PRIORITY (tmp
)++;
17868 else if (load_store_pendulum
== -2)
17870 /* Two stores have been issued in this cycle. Increase the
17871 priority of the first load in the ready list to favor it for
17872 issuing in the next cycle. */
17877 if (is_load_insn (ready
[pos
])
17878 && INSN_PRIORITY_KNOWN (ready
[pos
]))
17880 INSN_PRIORITY (ready
[pos
])++;
17882 /* Adjust the pendulum to account for the fact that a load
17883 was found and increased in priority. This is to prevent
17884 increasing the priority of multiple loads */
17885 load_store_pendulum
--;
17892 else if (load_store_pendulum
== -1)
17894 /* A store has been issued in this cycle. Scan the ready list for
17895 another store to issue with it, preferring a store to an adjacent
17897 int first_store_pos
= -1;
17903 if (is_store_insn (ready
[pos
]))
17905 /* Maintain the index of the first store found on the
17907 if (first_store_pos
== -1)
17908 first_store_pos
= pos
;
17910 if (is_store_insn (last_scheduled_insn
)
17911 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
17913 /* Found an adjacent store. Move it to the head of the
17914 ready list, and adjust it's priority so that it is
17915 more likely to stay there */
17917 for (i
=pos
; i
<*pn_ready
-1; i
++)
17918 ready
[i
] = ready
[i
+ 1];
17919 ready
[*pn_ready
-1] = tmp
;
17920 if INSN_PRIORITY_KNOWN (tmp
)
17921 INSN_PRIORITY (tmp
)++;
17922 first_store_pos
= -1;
17930 if (first_store_pos
>= 0)
17932 /* An adjacent store wasn't found, but a non-adjacent store was,
17933 so move the non-adjacent store to the front of the ready
17934 list, and adjust its priority so that it is more likely to
17936 tmp
= ready
[first_store_pos
];
17937 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
17938 ready
[i
] = ready
[i
+ 1];
17939 ready
[*pn_ready
-1] = tmp
;
17940 if INSN_PRIORITY_KNOWN (tmp
)
17941 INSN_PRIORITY (tmp
)++;
17944 else if (load_store_pendulum
== 2)
17946 /* Two loads have been issued in this cycle. Increase the priority
17947 of the first store in the ready list to favor it for issuing in
17953 if (is_store_insn (ready
[pos
])
17954 && INSN_PRIORITY_KNOWN (ready
[pos
]))
17956 INSN_PRIORITY (ready
[pos
])++;
17958 /* Adjust the pendulum to account for the fact that a store
17959 was found and increased in priority. This is to prevent
17960 increasing the priority of multiple stores */
17961 load_store_pendulum
++;
17970 return cached_can_issue_more
;
17973 /* Return whether the presence of INSN causes a dispatch group termination
17974 of group WHICH_GROUP.
17976 If WHICH_GROUP == current_group, this function will return true if INSN
17977 causes the termination of the current group (i.e, the dispatch group to
17978 which INSN belongs). This means that INSN will be the last insn in the
17979 group it belongs to.
17981 If WHICH_GROUP == previous_group, this function will return true if INSN
17982 causes the termination of the previous group (i.e, the dispatch group that
17983 precedes the group to which INSN belongs). This means that INSN will be
17984 the first insn in the group it belongs to). */
17987 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
17994 first
= insn_must_be_first_in_group (insn
);
17995 last
= insn_must_be_last_in_group (insn
);
18000 if (which_group
== current_group
)
18002 else if (which_group
== previous_group
)
18010 insn_must_be_first_in_group (rtx insn
)
18012 enum attr_type type
;
18015 || insn
== NULL_RTX
18016 || GET_CODE (insn
) == NOTE
18017 || GET_CODE (PATTERN (insn
)) == USE
18018 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18021 switch (rs6000_cpu
)
18023 case PROCESSOR_POWER5
:
18024 if (is_cracked_insn (insn
))
18026 case PROCESSOR_POWER4
:
18027 if (is_microcoded_insn (insn
))
18030 if (!rs6000_sched_groups
)
18033 type
= get_attr_type (insn
);
18040 case TYPE_DELAYED_CR
:
18041 case TYPE_CR_LOGICAL
:
18055 case PROCESSOR_POWER6
:
18056 type
= get_attr_type (insn
);
18060 case TYPE_INSERT_DWORD
:
18064 case TYPE_VAR_SHIFT_ROTATE
:
18071 case TYPE_INSERT_WORD
:
18072 case TYPE_DELAYED_COMPARE
:
18073 case TYPE_IMUL_COMPARE
:
18074 case TYPE_LMUL_COMPARE
:
18075 case TYPE_FPCOMPARE
:
18086 case TYPE_LOAD_EXT_UX
:
18088 case TYPE_STORE_UX
:
18089 case TYPE_FPLOAD_U
:
18090 case TYPE_FPLOAD_UX
:
18091 case TYPE_FPSTORE_U
:
18092 case TYPE_FPSTORE_UX
:
18106 insn_must_be_last_in_group (rtx insn
)
18108 enum attr_type type
;
18111 || insn
== NULL_RTX
18112 || GET_CODE (insn
) == NOTE
18113 || GET_CODE (PATTERN (insn
)) == USE
18114 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18117 switch (rs6000_cpu
) {
18118 case PROCESSOR_POWER4
:
18119 case PROCESSOR_POWER5
:
18120 if (is_microcoded_insn (insn
))
18123 if (is_branch_slot_insn (insn
))
18127 case PROCESSOR_POWER6
:
18128 type
= get_attr_type (insn
);
18135 case TYPE_VAR_SHIFT_ROTATE
:
18142 case TYPE_DELAYED_COMPARE
:
18143 case TYPE_IMUL_COMPARE
:
18144 case TYPE_LMUL_COMPARE
:
18145 case TYPE_FPCOMPARE
:
18166 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
18167 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
18170 is_costly_group (rtx
*group_insns
, rtx next_insn
)
18173 int issue_rate
= rs6000_issue_rate ();
18175 for (i
= 0; i
< issue_rate
; i
++)
18178 rtx insn
= group_insns
[i
];
18183 FOR_EACH_DEP_LINK (link
, INSN_FORW_DEPS (insn
))
18185 dep_t dep
= DEP_LINK_DEP (link
);
18186 rtx next
= DEP_CON (dep
);
18188 if (next
== next_insn
18189 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
18197 /* Utility of the function redefine_groups.
18198 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
18199 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
18200 to keep it "far" (in a separate group) from GROUP_INSNS, following
18201 one of the following schemes, depending on the value of the flag
18202 -minsert_sched_nops = X:
18203 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
18204 in order to force NEXT_INSN into a separate group.
18205 (2) X < sched_finish_regroup_exact: insert exactly X nops.
18206 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
18207 insertion (has a group just ended, how many vacant issue slots remain in the
18208 last group, and how many dispatch groups were encountered so far). */
18211 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
18212 rtx next_insn
, bool *group_end
, int can_issue_more
,
18217 int issue_rate
= rs6000_issue_rate ();
18218 bool end
= *group_end
;
18221 if (next_insn
== NULL_RTX
)
18222 return can_issue_more
;
18224 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
18225 return can_issue_more
;
18227 force
= is_costly_group (group_insns
, next_insn
);
18229 return can_issue_more
;
18231 if (sched_verbose
> 6)
18232 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
18233 *group_count
,can_issue_more
);
18235 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
18238 can_issue_more
= 0;
18240 /* Since only a branch can be issued in the last issue_slot, it is
18241 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
18242 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
18243 in this case the last nop will start a new group and the branch
18244 will be forced to the new group. */
18245 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
18248 while (can_issue_more
> 0)
18251 emit_insn_before (nop
, next_insn
);
18259 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
18261 int n_nops
= rs6000_sched_insert_nops
;
18263 /* Nops can't be issued from the branch slot, so the effective
18264 issue_rate for nops is 'issue_rate - 1'. */
18265 if (can_issue_more
== 0)
18266 can_issue_more
= issue_rate
;
18268 if (can_issue_more
== 0)
18270 can_issue_more
= issue_rate
- 1;
18273 for (i
= 0; i
< issue_rate
; i
++)
18275 group_insns
[i
] = 0;
18282 emit_insn_before (nop
, next_insn
);
18283 if (can_issue_more
== issue_rate
- 1) /* new group begins */
18286 if (can_issue_more
== 0)
18288 can_issue_more
= issue_rate
- 1;
18291 for (i
= 0; i
< issue_rate
; i
++)
18293 group_insns
[i
] = 0;
18299 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
18302 /* Is next_insn going to start a new group? */
18305 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
18306 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
18307 || (can_issue_more
< issue_rate
&&
18308 insn_terminates_group_p (next_insn
, previous_group
)));
18309 if (*group_end
&& end
)
18312 if (sched_verbose
> 6)
18313 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
18314 *group_count
, can_issue_more
);
18315 return can_issue_more
;
18318 return can_issue_more
;
18321 /* This function tries to synch the dispatch groups that the compiler "sees"
18322 with the dispatch groups that the processor dispatcher is expected to
18323 form in practice. It tries to achieve this synchronization by forcing the
18324 estimated processor grouping on the compiler (as opposed to the function
18325 'pad_goups' which tries to force the scheduler's grouping on the processor).
18327 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
18328 examines the (estimated) dispatch groups that will be formed by the processor
18329 dispatcher. It marks these group boundaries to reflect the estimated
18330 processor grouping, overriding the grouping that the scheduler had marked.
18331 Depending on the value of the flag '-minsert-sched-nops' this function can
18332 force certain insns into separate groups or force a certain distance between
18333 them by inserting nops, for example, if there exists a "costly dependence"
18336 The function estimates the group boundaries that the processor will form as
18337 follows: It keeps track of how many vacant issue slots are available after
18338 each insn. A subsequent insn will start a new group if one of the following
18340 - no more vacant issue slots remain in the current dispatch group.
18341 - only the last issue slot, which is the branch slot, is vacant, but the next
18342 insn is not a branch.
18343 - only the last 2 or less issue slots, including the branch slot, are vacant,
18344 which means that a cracked insn (which occupies two issue slots) can't be
18345 issued in this group.
18346 - less than 'issue_rate' slots are vacant, and the next insn always needs to
18347 start a new group. */
18350 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
18352 rtx insn
, next_insn
;
18354 int can_issue_more
;
18357 int group_count
= 0;
18361 issue_rate
= rs6000_issue_rate ();
18362 group_insns
= alloca (issue_rate
* sizeof (rtx
));
18363 for (i
= 0; i
< issue_rate
; i
++)
18365 group_insns
[i
] = 0;
18367 can_issue_more
= issue_rate
;
18369 insn
= get_next_active_insn (prev_head_insn
, tail
);
18372 while (insn
!= NULL_RTX
)
18374 slot
= (issue_rate
- can_issue_more
);
18375 group_insns
[slot
] = insn
;
18377 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
18378 if (insn_terminates_group_p (insn
, current_group
))
18379 can_issue_more
= 0;
18381 next_insn
= get_next_active_insn (insn
, tail
);
18382 if (next_insn
== NULL_RTX
)
18383 return group_count
+ 1;
18385 /* Is next_insn going to start a new group? */
18387 = (can_issue_more
== 0
18388 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
18389 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
18390 || (can_issue_more
< issue_rate
&&
18391 insn_terminates_group_p (next_insn
, previous_group
)));
18393 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
18394 next_insn
, &group_end
, can_issue_more
,
18400 can_issue_more
= 0;
18401 for (i
= 0; i
< issue_rate
; i
++)
18403 group_insns
[i
] = 0;
18407 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
18408 PUT_MODE (next_insn
, VOIDmode
);
18409 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
18410 PUT_MODE (next_insn
, TImode
);
18413 if (can_issue_more
== 0)
18414 can_issue_more
= issue_rate
;
18417 return group_count
;
18420 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
18421 dispatch group boundaries that the scheduler had marked. Pad with nops
18422 any dispatch groups which have vacant issue slots, in order to force the
18423 scheduler's grouping on the processor dispatcher. The function
18424 returns the number of dispatch groups found. */
18427 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
18429 rtx insn
, next_insn
;
18432 int can_issue_more
;
18434 int group_count
= 0;
18436 /* Initialize issue_rate. */
18437 issue_rate
= rs6000_issue_rate ();
18438 can_issue_more
= issue_rate
;
18440 insn
= get_next_active_insn (prev_head_insn
, tail
);
18441 next_insn
= get_next_active_insn (insn
, tail
);
18443 while (insn
!= NULL_RTX
)
18446 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
18448 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
18450 if (next_insn
== NULL_RTX
)
18455 /* If the scheduler had marked group termination at this location
18456 (between insn and next_indn), and neither insn nor next_insn will
18457 force group termination, pad the group with nops to force group
18460 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
18461 && !insn_terminates_group_p (insn
, current_group
)
18462 && !insn_terminates_group_p (next_insn
, previous_group
))
18464 if (!is_branch_slot_insn (next_insn
))
18467 while (can_issue_more
)
18470 emit_insn_before (nop
, next_insn
);
18475 can_issue_more
= issue_rate
;
18480 next_insn
= get_next_active_insn (insn
, tail
);
18483 return group_count
;
18486 /* We're beginning a new block. Initialize data structures as necessary. */
18489 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
18490 int sched_verbose ATTRIBUTE_UNUSED
,
18491 int max_ready ATTRIBUTE_UNUSED
)
18493 last_scheduled_insn
= NULL_RTX
;
18494 load_store_pendulum
= 0;
18497 /* The following function is called at the end of scheduling BB.
18498 After reload, it inserts nops at insn group bundling. */
18501 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
18506 fprintf (dump
, "=== Finishing schedule.\n");
18508 if (reload_completed
&& rs6000_sched_groups
)
18510 if (rs6000_sched_insert_nops
== sched_finish_none
)
18513 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
18514 n_groups
= pad_groups (dump
, sched_verbose
,
18515 current_sched_info
->prev_head
,
18516 current_sched_info
->next_tail
);
18518 n_groups
= redefine_groups (dump
, sched_verbose
,
18519 current_sched_info
->prev_head
,
18520 current_sched_info
->next_tail
);
18522 if (sched_verbose
>= 6)
18524 fprintf (dump
, "ngroups = %d\n", n_groups
);
18525 print_rtl (dump
, current_sched_info
->prev_head
);
18526 fprintf (dump
, "Done finish_sched\n");
18531 /* Length in units of the trampoline for entering a nested function. */
18534 rs6000_trampoline_size (void)
18538 switch (DEFAULT_ABI
)
18541 gcc_unreachable ();
18544 ret
= (TARGET_32BIT
) ? 12 : 24;
18549 ret
= (TARGET_32BIT
) ? 40 : 48;
18556 /* Emit RTL insns to initialize the variable parts of a trampoline.
18557 FNADDR is an RTX for the address of the function's pure code.
18558 CXT is an RTX for the static chain value for the function. */
18561 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
18563 int regsize
= (TARGET_32BIT
) ? 4 : 8;
18564 rtx ctx_reg
= force_reg (Pmode
, cxt
);
18566 switch (DEFAULT_ABI
)
18569 gcc_unreachable ();
18571 /* Macros to shorten the code expansions below. */
18572 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
18573 #define MEM_PLUS(addr,offset) \
18574 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
18576 /* Under AIX, just build the 3 word function descriptor */
18579 rtx fn_reg
= gen_reg_rtx (Pmode
);
18580 rtx toc_reg
= gen_reg_rtx (Pmode
);
18581 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
18582 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
18583 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
18584 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
18585 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
18589 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
18592 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
18593 FALSE
, VOIDmode
, 4,
18595 GEN_INT (rs6000_trampoline_size ()), SImode
,
18605 /* Table of valid machine attributes. */
18607 const struct attribute_spec rs6000_attribute_table
[] =
18609 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
18610 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
18611 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
18612 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
18613 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
18614 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
18615 #ifdef SUBTARGET_ATTRIBUTE_TABLE
18616 SUBTARGET_ATTRIBUTE_TABLE
,
18618 { NULL
, 0, 0, false, false, false, NULL
}
18621 /* Handle the "altivec" attribute. The attribute may have
18622 arguments as follows:
18624 __attribute__((altivec(vector__)))
18625 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
18626 __attribute__((altivec(bool__))) (always followed by 'unsigned')
18628 and may appear more than once (e.g., 'vector bool char') in a
18629 given declaration. */
18632 rs6000_handle_altivec_attribute (tree
*node
,
18633 tree name ATTRIBUTE_UNUSED
,
18635 int flags ATTRIBUTE_UNUSED
,
18636 bool *no_add_attrs
)
18638 tree type
= *node
, result
= NULL_TREE
;
18639 enum machine_mode mode
;
18642 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
18643 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
18644 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
18647 while (POINTER_TYPE_P (type
)
18648 || TREE_CODE (type
) == FUNCTION_TYPE
18649 || TREE_CODE (type
) == METHOD_TYPE
18650 || TREE_CODE (type
) == ARRAY_TYPE
)
18651 type
= TREE_TYPE (type
);
18653 mode
= TYPE_MODE (type
);
18655 /* Check for invalid AltiVec type qualifiers. */
18656 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
18659 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
18660 else if (rs6000_warn_altivec_long
)
18661 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
18663 else if (type
== long_long_unsigned_type_node
18664 || type
== long_long_integer_type_node
)
18665 error ("use of %<long long%> in AltiVec types is invalid");
18666 else if (type
== double_type_node
)
18667 error ("use of %<double%> in AltiVec types is invalid");
18668 else if (type
== long_double_type_node
)
18669 error ("use of %<long double%> in AltiVec types is invalid");
18670 else if (type
== boolean_type_node
)
18671 error ("use of boolean types in AltiVec types is invalid");
18672 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
18673 error ("use of %<complex%> in AltiVec types is invalid");
18674 else if (DECIMAL_FLOAT_MODE_P (mode
))
18675 error ("use of decimal floating point types in AltiVec types is invalid");
18677 switch (altivec_type
)
18680 unsigned_p
= TYPE_UNSIGNED (type
);
18684 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
18687 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
18690 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
18692 case SFmode
: result
= V4SF_type_node
; break;
18693 /* If the user says 'vector int bool', we may be handed the 'bool'
18694 attribute _before_ the 'vector' attribute, and so select the
18695 proper type in the 'b' case below. */
18696 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
18704 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
18705 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
18706 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
18713 case V8HImode
: result
= pixel_V8HI_type_node
;
18719 if (result
&& result
!= type
&& TYPE_READONLY (type
))
18720 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
18722 *no_add_attrs
= true; /* No need to hang on to the attribute. */
18725 *node
= reconstruct_complex_type (*node
, result
);
18730 /* AltiVec defines four built-in scalar types that serve as vector
18731 elements; we must teach the compiler how to mangle them. */
18733 static const char *
18734 rs6000_mangle_fundamental_type (tree type
)
18736 if (type
== bool_char_type_node
) return "U6__boolc";
18737 if (type
== bool_short_type_node
) return "U6__bools";
18738 if (type
== pixel_type_node
) return "u7__pixel";
18739 if (type
== bool_int_type_node
) return "U6__booli";
18741 /* Mangle IBM extended float long double as `g' (__float128) on
18742 powerpc*-linux where long-double-64 previously was the default. */
18743 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
18745 && TARGET_LONG_DOUBLE_128
18746 && !TARGET_IEEEQUAD
)
18749 /* For all other types, use normal C++ mangling. */
18753 /* Handle a "longcall" or "shortcall" attribute; arguments as in
18754 struct attribute_spec.handler. */
18757 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
18758 tree args ATTRIBUTE_UNUSED
,
18759 int flags ATTRIBUTE_UNUSED
,
18760 bool *no_add_attrs
)
18762 if (TREE_CODE (*node
) != FUNCTION_TYPE
18763 && TREE_CODE (*node
) != FIELD_DECL
18764 && TREE_CODE (*node
) != TYPE_DECL
)
18766 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
18767 IDENTIFIER_POINTER (name
));
18768 *no_add_attrs
= true;
18774 /* Set longcall attributes on all functions declared when
18775 rs6000_default_long_calls is true. */
18777 rs6000_set_default_type_attributes (tree type
)
18779 if (rs6000_default_long_calls
18780 && (TREE_CODE (type
) == FUNCTION_TYPE
18781 || TREE_CODE (type
) == METHOD_TYPE
))
18782 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
18784 TYPE_ATTRIBUTES (type
));
18787 darwin_set_default_type_attributes (type
);
18791 /* Return a reference suitable for calling a function with the
18792 longcall attribute. */
18795 rs6000_longcall_ref (rtx call_ref
)
18797 const char *call_name
;
18800 if (GET_CODE (call_ref
) != SYMBOL_REF
)
18803 /* System V adds '.' to the internal name, so skip them. */
18804 call_name
= XSTR (call_ref
, 0);
18805 if (*call_name
== '.')
18807 while (*call_name
== '.')
18810 node
= get_identifier (call_name
);
18811 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
18814 return force_reg (Pmode
, call_ref
);
18817 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
18818 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
18821 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
18822 struct attribute_spec.handler. */
18824 rs6000_handle_struct_attribute (tree
*node
, tree name
,
18825 tree args ATTRIBUTE_UNUSED
,
18826 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
18829 if (DECL_P (*node
))
18831 if (TREE_CODE (*node
) == TYPE_DECL
)
18832 type
= &TREE_TYPE (*node
);
18837 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
18838 || TREE_CODE (*type
) == UNION_TYPE
)))
18840 warning (OPT_Wattributes
, "%qs attribute ignored", IDENTIFIER_POINTER (name
));
18841 *no_add_attrs
= true;
18844 else if ((is_attribute_p ("ms_struct", name
)
18845 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
18846 || ((is_attribute_p ("gcc_struct", name
)
18847 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
18849 warning (OPT_Wattributes
, "%qs incompatible attribute ignored",
18850 IDENTIFIER_POINTER (name
));
18851 *no_add_attrs
= true;
18858 rs6000_ms_bitfield_layout_p (tree record_type
)
18860 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
18861 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
18862 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
18865 #ifdef USING_ELFOS_H
18867 /* A get_unnamed_section callback, used for switching to toc_section. */
18870 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
18872 if (DEFAULT_ABI
== ABI_AIX
18873 && TARGET_MINIMAL_TOC
18874 && !TARGET_RELOCATABLE
)
18876 if (!toc_initialized
)
18878 toc_initialized
= 1;
18879 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
18880 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
18881 fprintf (asm_out_file
, "\t.tc ");
18882 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
18883 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
18884 fprintf (asm_out_file
, "\n");
18886 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18887 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
18888 fprintf (asm_out_file
, " = .+32768\n");
18891 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18893 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
18894 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
18897 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18898 if (!toc_initialized
)
18900 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
18901 fprintf (asm_out_file
, " = .+32768\n");
18902 toc_initialized
= 1;
18907 /* Implement TARGET_ASM_INIT_SECTIONS. */
18910 rs6000_elf_asm_init_sections (void)
18913 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
18916 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
18917 SDATA2_SECTION_ASM_OP
);
18920 /* Implement TARGET_SELECT_RTX_SECTION. */
18923 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
18924 unsigned HOST_WIDE_INT align
)
18926 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
18927 return toc_section
;
18929 return default_elf_select_rtx_section (mode
, x
, align
);
18932 /* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */
18935 rs6000_elf_select_section (tree decl
, int reloc
,
18936 unsigned HOST_WIDE_INT align
)
18938 /* Pretend that we're always building for a shared library when
18939 ABI_AIX, because otherwise we end up with dynamic relocations
18940 in read-only sections. This happens for function pointers,
18941 references to vtables in typeinfo, and probably other cases. */
18942 return default_elf_select_section_1 (decl
, reloc
, align
,
18943 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
18946 /* A C statement to build up a unique section name, expressed as a
18947 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
18948 RELOC indicates whether the initial value of EXP requires
18949 link-time relocations. If you do not define this macro, GCC will use
18950 the symbol name prefixed by `.' as the section name. Note - this
18951 macro can now be called for uninitialized data items as well as
18952 initialized data and functions. */
18955 rs6000_elf_unique_section (tree decl
, int reloc
)
18957 /* As above, pretend that we're always building for a shared library
18958 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
18959 default_unique_section_1 (decl
, reloc
,
18960 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
18963 /* For a SYMBOL_REF, set generic flags and then perform some
18964 target-specific processing.
18966 When the AIX ABI is requested on a non-AIX system, replace the
18967 function name with the real name (with a leading .) rather than the
18968 function descriptor name. This saves a lot of overriding code to
18969 read the prefixes. */
18972 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
18974 default_encode_section_info (decl
, rtl
, first
);
18977 && TREE_CODE (decl
) == FUNCTION_DECL
18979 && DEFAULT_ABI
== ABI_AIX
)
18981 rtx sym_ref
= XEXP (rtl
, 0);
18982 size_t len
= strlen (XSTR (sym_ref
, 0));
18983 char *str
= alloca (len
+ 2);
18985 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
18986 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
18991 rs6000_elf_in_small_data_p (tree decl
)
18993 if (rs6000_sdata
== SDATA_NONE
)
18996 /* We want to merge strings, so we never consider them small data. */
18997 if (TREE_CODE (decl
) == STRING_CST
)
19000 /* Functions are never in the small data area. */
19001 if (TREE_CODE (decl
) == FUNCTION_DECL
)
19004 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
19006 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
19007 if (strcmp (section
, ".sdata") == 0
19008 || strcmp (section
, ".sdata2") == 0
19009 || strcmp (section
, ".sbss") == 0
19010 || strcmp (section
, ".sbss2") == 0
19011 || strcmp (section
, ".PPC.EMB.sdata0") == 0
19012 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
19017 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
19020 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
19021 /* If it's not public, and we're not going to reference it there,
19022 there's no need to put it in the small data section. */
19023 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
19030 #endif /* USING_ELFOS_H */
19032 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
19035 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, rtx x
)
19037 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
19040 /* Return a REG that occurs in ADDR with coefficient 1.
19041 ADDR can be effectively incremented by incrementing REG.
19043 r0 is special and we must not select it as an address
19044 register by this routine since our caller will try to
19045 increment the returned register via an "la" instruction. */
19048 find_addr_reg (rtx addr
)
19050 while (GET_CODE (addr
) == PLUS
)
19052 if (GET_CODE (XEXP (addr
, 0)) == REG
19053 && REGNO (XEXP (addr
, 0)) != 0)
19054 addr
= XEXP (addr
, 0);
19055 else if (GET_CODE (XEXP (addr
, 1)) == REG
19056 && REGNO (XEXP (addr
, 1)) != 0)
19057 addr
= XEXP (addr
, 1);
19058 else if (CONSTANT_P (XEXP (addr
, 0)))
19059 addr
= XEXP (addr
, 1);
19060 else if (CONSTANT_P (XEXP (addr
, 1)))
19061 addr
= XEXP (addr
, 0);
19063 gcc_unreachable ();
19065 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
19070 rs6000_fatal_bad_address (rtx op
)
19072 fatal_insn ("bad address", op
);
19077 static tree branch_island_list
= 0;
19079 /* Remember to generate a branch island for far calls to the given
19083 add_compiler_branch_island (tree label_name
, tree function_name
,
19086 tree branch_island
= build_tree_list (function_name
, label_name
);
19087 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
19088 TREE_CHAIN (branch_island
) = branch_island_list
;
19089 branch_island_list
= branch_island
;
19092 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
19093 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
19094 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
19095 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
19097 /* Generate far-jump branch islands for everything on the
19098 branch_island_list. Invoked immediately after the last instruction
19099 of the epilogue has been emitted; the branch-islands must be
19100 appended to, and contiguous with, the function body. Mach-O stubs
19101 are generated in machopic_output_stub(). */
19104 macho_branch_islands (void)
19107 tree branch_island
;
19109 for (branch_island
= branch_island_list
;
19111 branch_island
= TREE_CHAIN (branch_island
))
19113 const char *label
=
19114 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
19116 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
19117 char name_buf
[512];
19118 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
19119 if (name
[0] == '*' || name
[0] == '&')
19120 strcpy (name_buf
, name
+1);
19124 strcpy (name_buf
+1, name
);
19126 strcpy (tmp_buf
, "\n");
19127 strcat (tmp_buf
, label
);
19128 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
19129 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
19130 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
19131 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
19134 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
19135 strcat (tmp_buf
, label
);
19136 strcat (tmp_buf
, "_pic\n");
19137 strcat (tmp_buf
, label
);
19138 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
19140 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
19141 strcat (tmp_buf
, name_buf
);
19142 strcat (tmp_buf
, " - ");
19143 strcat (tmp_buf
, label
);
19144 strcat (tmp_buf
, "_pic)\n");
19146 strcat (tmp_buf
, "\tmtlr r0\n");
19148 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
19149 strcat (tmp_buf
, name_buf
);
19150 strcat (tmp_buf
, " - ");
19151 strcat (tmp_buf
, label
);
19152 strcat (tmp_buf
, "_pic)\n");
19154 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
19158 strcat (tmp_buf
, ":\nlis r12,hi16(");
19159 strcat (tmp_buf
, name_buf
);
19160 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
19161 strcat (tmp_buf
, name_buf
);
19162 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
19164 output_asm_insn (tmp_buf
, 0);
19165 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
19166 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
19167 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
19168 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
19171 branch_island_list
= 0;
19174 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
19175 already there or not. */
19178 no_previous_def (tree function_name
)
19180 tree branch_island
;
19181 for (branch_island
= branch_island_list
;
19183 branch_island
= TREE_CHAIN (branch_island
))
19184 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
19189 /* GET_PREV_LABEL gets the label name from the previous definition of
19193 get_prev_label (tree function_name
)
19195 tree branch_island
;
19196 for (branch_island
= branch_island_list
;
19198 branch_island
= TREE_CHAIN (branch_island
))
19199 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
19200 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
19204 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
19205 #define DARWIN_LINKER_GENERATES_ISLANDS 0
19208 /* KEXTs still need branch islands. */
19209 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
19210 || flag_mkernel || flag_apple_kext)
19212 /* INSN is either a function call or a millicode call. It may have an
19213 unconditional jump in its delay slot.
19215 CALL_DEST is the routine we are calling. */
19218 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
19219 int cookie_operand_number
)
19221 static char buf
[256];
19222 if (DARWIN_GENERATE_ISLANDS
19223 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
19224 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
19227 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
19229 if (no_previous_def (funname
))
19231 int line_number
= 0;
19232 rtx label_rtx
= gen_label_rtx ();
19233 char *label_buf
, temp_buf
[256];
19234 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
19235 CODE_LABEL_NUMBER (label_rtx
));
19236 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
19237 labelname
= get_identifier (label_buf
);
19238 for (; insn
&& GET_CODE (insn
) != NOTE
; insn
= PREV_INSN (insn
));
19240 line_number
= NOTE_LINE_NUMBER (insn
);
19241 add_compiler_branch_island (labelname
, funname
, line_number
);
19244 labelname
= get_prev_label (funname
);
19246 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
19247 instruction will reach 'foo', otherwise link as 'bl L42'".
19248 "L42" should be a 'branch island', that will do a far jump to
19249 'foo'. Branch islands are generated in
19250 macho_branch_islands(). */
19251 sprintf (buf
, "jbsr %%z%d,%.246s",
19252 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
19255 sprintf (buf
, "bl %%z%d", dest_operand_number
);
19259 /* Generate PIC and indirect symbol stubs. */
19262 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
19264 unsigned int length
;
19265 char *symbol_name
, *lazy_ptr_name
;
19266 char *local_label_0
;
19267 static int label
= 0;
19269 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
19270 symb
= (*targetm
.strip_name_encoding
) (symb
);
19273 length
= strlen (symb
);
19274 symbol_name
= alloca (length
+ 32);
19275 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
19277 lazy_ptr_name
= alloca (length
+ 32);
19278 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
19281 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
19283 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
19287 fprintf (file
, "\t.align 5\n");
19289 fprintf (file
, "%s:\n", stub
);
19290 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
19293 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
19294 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
19296 fprintf (file
, "\tmflr r0\n");
19297 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
19298 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
19299 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
19300 lazy_ptr_name
, local_label_0
);
19301 fprintf (file
, "\tmtlr r0\n");
19302 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
19303 (TARGET_64BIT
? "ldu" : "lwzu"),
19304 lazy_ptr_name
, local_label_0
);
19305 fprintf (file
, "\tmtctr r12\n");
19306 fprintf (file
, "\tbctr\n");
19310 fprintf (file
, "\t.align 4\n");
19312 fprintf (file
, "%s:\n", stub
);
19313 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
19315 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
19316 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
19317 (TARGET_64BIT
? "ldu" : "lwzu"),
19319 fprintf (file
, "\tmtctr r12\n");
19320 fprintf (file
, "\tbctr\n");
19323 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
19324 fprintf (file
, "%s:\n", lazy_ptr_name
);
19325 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
19326 fprintf (file
, "%sdyld_stub_binding_helper\n",
19327 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
19330 /* Legitimize PIC addresses. If the address is already
19331 position-independent, we return ORIG. Newly generated
19332 position-independent addresses go into a reg. This is REG if non
19333 zero, otherwise we allocate register(s) as necessary. */
19335 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
19338 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
19343 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
19344 reg
= gen_reg_rtx (Pmode
);
19346 if (GET_CODE (orig
) == CONST
)
19350 if (GET_CODE (XEXP (orig
, 0)) == PLUS
19351 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
19354 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
19356 /* Use a different reg for the intermediate value, as
19357 it will be marked UNCHANGING. */
19358 reg_temp
= no_new_pseudos
? reg
: gen_reg_rtx (Pmode
);
19359 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
19362 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
19365 if (GET_CODE (offset
) == CONST_INT
)
19367 if (SMALL_INT (offset
))
19368 return plus_constant (base
, INTVAL (offset
));
19369 else if (! reload_in_progress
&& ! reload_completed
)
19370 offset
= force_reg (Pmode
, offset
);
19373 rtx mem
= force_const_mem (Pmode
, orig
);
19374 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
19377 return gen_rtx_PLUS (Pmode
, base
, offset
);
19380 /* Fall back on generic machopic code. */
19381 return machopic_legitimize_pic_address (orig
, mode
, reg
);
19384 /* Output a .machine directive for the Darwin assembler, and call
19385 the generic start_file routine. */
19388 rs6000_darwin_file_start (void)
19390 static const struct
19396 { "ppc64", "ppc64", MASK_64BIT
},
19397 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
19398 { "power4", "ppc970", 0 },
19399 { "G5", "ppc970", 0 },
19400 { "7450", "ppc7450", 0 },
19401 { "7400", "ppc7400", MASK_ALTIVEC
},
19402 { "G4", "ppc7400", 0 },
19403 { "750", "ppc750", 0 },
19404 { "740", "ppc750", 0 },
19405 { "G3", "ppc750", 0 },
19406 { "604e", "ppc604e", 0 },
19407 { "604", "ppc604", 0 },
19408 { "603e", "ppc603", 0 },
19409 { "603", "ppc603", 0 },
19410 { "601", "ppc601", 0 },
19411 { NULL
, "ppc", 0 } };
19412 const char *cpu_id
= "";
19415 rs6000_file_start ();
19416 darwin_file_start ();
19418 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
19419 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
19420 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
19421 && rs6000_select
[i
].string
[0] != '\0')
19422 cpu_id
= rs6000_select
[i
].string
;
19424 /* Look through the mapping array. Pick the first name that either
19425 matches the argument, has a bit set in IF_SET that is also set
19426 in the target flags, or has a NULL name. */
19429 while (mapping
[i
].arg
!= NULL
19430 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
19431 && (mapping
[i
].if_set
& target_flags
) == 0)
19434 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
19437 #endif /* TARGET_MACHO */
19440 static unsigned int
19441 rs6000_elf_section_type_flags (tree decl
, const char *name
, int reloc
)
19443 return default_section_type_flags_1 (decl
, name
, reloc
,
19444 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
19447 /* Record an element in the table of global constructors. SYMBOL is
19448 a SYMBOL_REF of the function to be called; PRIORITY is a number
19449 between 0 and MAX_INIT_PRIORITY.
19451 This differs from default_named_section_asm_out_constructor in
19452 that we have special handling for -mrelocatable. */
19455 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
19457 const char *section
= ".ctors";
19460 if (priority
!= DEFAULT_INIT_PRIORITY
)
19462 sprintf (buf
, ".ctors.%.5u",
19463 /* Invert the numbering so the linker puts us in the proper
19464 order; constructors are run from right to left, and the
19465 linker sorts in increasing order. */
19466 MAX_INIT_PRIORITY
- priority
);
19470 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
19471 assemble_align (POINTER_SIZE
);
19473 if (TARGET_RELOCATABLE
)
19475 fputs ("\t.long (", asm_out_file
);
19476 output_addr_const (asm_out_file
, symbol
);
19477 fputs (")@fixup\n", asm_out_file
);
19480 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
19484 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
19486 const char *section
= ".dtors";
19489 if (priority
!= DEFAULT_INIT_PRIORITY
)
19491 sprintf (buf
, ".dtors.%.5u",
19492 /* Invert the numbering so the linker puts us in the proper
19493 order; constructors are run from right to left, and the
19494 linker sorts in increasing order. */
19495 MAX_INIT_PRIORITY
- priority
);
19499 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
19500 assemble_align (POINTER_SIZE
);
19502 if (TARGET_RELOCATABLE
)
19504 fputs ("\t.long (", asm_out_file
);
19505 output_addr_const (asm_out_file
, symbol
);
19506 fputs (")@fixup\n", asm_out_file
);
19509 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
19513 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
19517 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
19518 ASM_OUTPUT_LABEL (file
, name
);
19519 fputs (DOUBLE_INT_ASM_OP
, file
);
19520 rs6000_output_function_entry (file
, name
);
19521 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
19524 fputs ("\t.size\t", file
);
19525 assemble_name (file
, name
);
19526 fputs (",24\n\t.type\t.", file
);
19527 assemble_name (file
, name
);
19528 fputs (",@function\n", file
);
19529 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
19531 fputs ("\t.globl\t.", file
);
19532 assemble_name (file
, name
);
19537 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
19538 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
19539 rs6000_output_function_entry (file
, name
);
19540 fputs (":\n", file
);
19544 if (TARGET_RELOCATABLE
19545 && !TARGET_SECURE_PLT
19546 && (get_pool_size () != 0 || current_function_profile
)
19551 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
19553 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
19554 fprintf (file
, "\t.long ");
19555 assemble_name (file
, buf
);
19557 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
19558 assemble_name (file
, buf
);
19562 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
19563 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
19565 if (DEFAULT_ABI
== ABI_AIX
)
19567 const char *desc_name
, *orig_name
;
19569 orig_name
= (*targetm
.strip_name_encoding
) (name
);
19570 desc_name
= orig_name
;
19571 while (*desc_name
== '.')
19574 if (TREE_PUBLIC (decl
))
19575 fprintf (file
, "\t.globl %s\n", desc_name
);
19577 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
19578 fprintf (file
, "%s:\n", desc_name
);
19579 fprintf (file
, "\t.long %s\n", orig_name
);
19580 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
19581 if (DEFAULT_ABI
== ABI_AIX
)
19582 fputs ("\t.long 0\n", file
);
19583 fprintf (file
, "\t.previous\n");
19585 ASM_OUTPUT_LABEL (file
, name
);
19589 rs6000_elf_end_indicate_exec_stack (void)
19592 file_end_indicate_exec_stack ();
19598 rs6000_xcoff_asm_output_anchor (rtx symbol
)
19602 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
19603 SYMBOL_REF_BLOCK_OFFSET (symbol
));
19604 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
19608 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
19610 fputs (GLOBAL_ASM_OP
, stream
);
19611 RS6000_OUTPUT_BASENAME (stream
, name
);
19612 putc ('\n', stream
);
19615 /* A get_unnamed_decl callback, used for read-only sections. PTR
19616 points to the section string variable. */
19619 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
19621 fprintf (asm_out_file
, "\t.csect %s[RO],3\n",
19622 *(const char *const *) directive
);
19625 /* Likewise for read-write sections. */
19628 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
19630 fprintf (asm_out_file
, "\t.csect %s[RW],3\n",
19631 *(const char *const *) directive
);
19634 /* A get_unnamed_section callback, used for switching to toc_section. */
19637 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
19639 if (TARGET_MINIMAL_TOC
)
19641 /* toc_section is always selected at least once from
19642 rs6000_xcoff_file_start, so this is guaranteed to
19643 always be defined once and only once in each file. */
19644 if (!toc_initialized
)
19646 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
19647 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
19648 toc_initialized
= 1;
19650 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
19651 (TARGET_32BIT
? "" : ",3"));
19654 fputs ("\t.toc\n", asm_out_file
);
19657 /* Implement TARGET_ASM_INIT_SECTIONS. */
19660 rs6000_xcoff_asm_init_sections (void)
19662 read_only_data_section
19663 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
19664 &xcoff_read_only_section_name
);
19666 private_data_section
19667 = get_unnamed_section (SECTION_WRITE
,
19668 rs6000_xcoff_output_readwrite_section_asm_op
,
19669 &xcoff_private_data_section_name
);
19671 read_only_private_data_section
19672 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
19673 &xcoff_private_data_section_name
);
19676 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
19678 readonly_data_section
= read_only_data_section
;
19679 exception_section
= data_section
;
19683 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
19684 tree decl ATTRIBUTE_UNUSED
)
19687 static const char * const suffix
[3] = { "PR", "RO", "RW" };
19689 if (flags
& SECTION_CODE
)
19691 else if (flags
& SECTION_WRITE
)
19696 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
19697 (flags
& SECTION_CODE
) ? "." : "",
19698 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
19702 rs6000_xcoff_select_section (tree decl
, int reloc
,
19703 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
19705 if (decl_readonly_section_1 (decl
, reloc
, 1))
19707 if (TREE_PUBLIC (decl
))
19708 return read_only_data_section
;
19710 return read_only_private_data_section
;
19714 if (TREE_PUBLIC (decl
))
19715 return data_section
;
19717 return private_data_section
;
19722 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
19726 /* Use select_section for private and uninitialized data. */
19727 if (!TREE_PUBLIC (decl
)
19728 || DECL_COMMON (decl
)
19729 || DECL_INITIAL (decl
) == NULL_TREE
19730 || DECL_INITIAL (decl
) == error_mark_node
19731 || (flag_zero_initialized_in_bss
19732 && initializer_zerop (DECL_INITIAL (decl
))))
19735 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
19736 name
= (*targetm
.strip_name_encoding
) (name
);
19737 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
19740 /* Select section for constant in constant pool.
19742 On RS/6000, all constants are in the private read-only data area.
19743 However, if this is being placed in the TOC it must be output as a
19747 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
19748 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
19750 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
19751 return toc_section
;
19753 return read_only_private_data_section
;
19756 /* Remove any trailing [DS] or the like from the symbol name. */
19758 static const char *
19759 rs6000_xcoff_strip_name_encoding (const char *name
)
19764 len
= strlen (name
);
19765 if (name
[len
- 1] == ']')
19766 return ggc_alloc_string (name
, len
- 4);
19771 /* Section attributes. AIX is always PIC. */
19773 static unsigned int
19774 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
19776 unsigned int align
;
19777 unsigned int flags
= default_section_type_flags_1 (decl
, name
, reloc
, 1);
19779 /* Align to at least UNIT size. */
19780 if (flags
& SECTION_CODE
)
19781 align
= MIN_UNITS_PER_WORD
;
19783 /* Increase alignment of large objects if not already stricter. */
19784 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
19785 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
19786 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
19788 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
19791 /* Output at beginning of assembler file.
19793 Initialize the section names for the RS/6000 at this point.
19795 Specify filename, including full path, to assembler.
19797 We want to go into the TOC section so at least one .toc will be emitted.
19798 Also, in order to output proper .bs/.es pairs, we need at least one static
19799 [RW] section emitted.
19801 Finally, declare mcount when profiling to make the assembler happy. */
19804 rs6000_xcoff_file_start (void)
19806 rs6000_gen_section_name (&xcoff_bss_section_name
,
19807 main_input_filename
, ".bss_");
19808 rs6000_gen_section_name (&xcoff_private_data_section_name
,
19809 main_input_filename
, ".rw_");
19810 rs6000_gen_section_name (&xcoff_read_only_section_name
,
19811 main_input_filename
, ".ro_");
19813 fputs ("\t.file\t", asm_out_file
);
19814 output_quoted_string (asm_out_file
, main_input_filename
);
19815 fputc ('\n', asm_out_file
);
19816 if (write_symbols
!= NO_DEBUG
)
19817 switch_to_section (private_data_section
);
19818 switch_to_section (text_section
);
19820 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
19821 rs6000_file_start ();
19824 /* Output at end of assembler file.
19825 On the RS/6000, referencing data should automatically pull in text. */
19828 rs6000_xcoff_file_end (void)
19830 switch_to_section (text_section
);
19831 fputs ("_section_.text:\n", asm_out_file
);
19832 switch_to_section (data_section
);
19833 fputs (TARGET_32BIT
19834 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
19837 #endif /* TARGET_XCOFF */
19839 /* Compute a (partial) cost for rtx X. Return true if the complete
19840 cost has been computed, and false if subexpressions should be
19841 scanned. In either case, *TOTAL contains the cost result. */
19844 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
19846 enum machine_mode mode
= GET_MODE (x
);
19850 /* On the RS/6000, if it is valid in the insn, it is free. */
19852 if (((outer_code
== SET
19853 || outer_code
== PLUS
19854 || outer_code
== MINUS
)
19855 && (satisfies_constraint_I (x
)
19856 || satisfies_constraint_L (x
)))
19857 || (outer_code
== AND
19858 && (satisfies_constraint_K (x
)
19860 ? satisfies_constraint_L (x
)
19861 : satisfies_constraint_J (x
))
19862 || mask_operand (x
, mode
)
19864 && mask64_operand (x
, DImode
))))
19865 || ((outer_code
== IOR
|| outer_code
== XOR
)
19866 && (satisfies_constraint_K (x
)
19868 ? satisfies_constraint_L (x
)
19869 : satisfies_constraint_J (x
))))
19870 || outer_code
== ASHIFT
19871 || outer_code
== ASHIFTRT
19872 || outer_code
== LSHIFTRT
19873 || outer_code
== ROTATE
19874 || outer_code
== ROTATERT
19875 || outer_code
== ZERO_EXTRACT
19876 || (outer_code
== MULT
19877 && satisfies_constraint_I (x
))
19878 || ((outer_code
== DIV
|| outer_code
== UDIV
19879 || outer_code
== MOD
|| outer_code
== UMOD
)
19880 && exact_log2 (INTVAL (x
)) >= 0)
19881 || (outer_code
== COMPARE
19882 && (satisfies_constraint_I (x
)
19883 || satisfies_constraint_K (x
)))
19884 || (outer_code
== EQ
19885 && (satisfies_constraint_I (x
)
19886 || satisfies_constraint_K (x
)
19888 ? satisfies_constraint_L (x
)
19889 : satisfies_constraint_J (x
))))
19890 || (outer_code
== GTU
19891 && satisfies_constraint_I (x
))
19892 || (outer_code
== LTU
19893 && satisfies_constraint_P (x
)))
19898 else if ((outer_code
== PLUS
19899 && reg_or_add_cint_operand (x
, VOIDmode
))
19900 || (outer_code
== MINUS
19901 && reg_or_sub_cint_operand (x
, VOIDmode
))
19902 || ((outer_code
== SET
19903 || outer_code
== IOR
19904 || outer_code
== XOR
)
19906 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
19908 *total
= COSTS_N_INSNS (1);
19914 if (mode
== DImode
&& code
== CONST_DOUBLE
)
19916 if ((outer_code
== IOR
|| outer_code
== XOR
)
19917 && CONST_DOUBLE_HIGH (x
) == 0
19918 && (CONST_DOUBLE_LOW (x
)
19919 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
19924 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
19925 || ((outer_code
== SET
19926 || outer_code
== IOR
19927 || outer_code
== XOR
)
19928 && CONST_DOUBLE_HIGH (x
) == 0))
19930 *total
= COSTS_N_INSNS (1);
19940 /* When optimizing for size, MEM should be slightly more expensive
19941 than generating address, e.g., (plus (reg) (const)).
19942 L1 cache latency is about two instructions. */
19943 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
19951 if (mode
== DFmode
)
19953 if (GET_CODE (XEXP (x
, 0)) == MULT
)
19955 /* FNMA accounted in outer NEG. */
19956 if (outer_code
== NEG
)
19957 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
19959 *total
= rs6000_cost
->dmul
;
19962 *total
= rs6000_cost
->fp
;
19964 else if (mode
== SFmode
)
19966 /* FNMA accounted in outer NEG. */
19967 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
19970 *total
= rs6000_cost
->fp
;
19973 *total
= COSTS_N_INSNS (1);
19977 if (mode
== DFmode
)
19979 if (GET_CODE (XEXP (x
, 0)) == MULT
19980 || GET_CODE (XEXP (x
, 1)) == MULT
)
19982 /* FNMA accounted in outer NEG. */
19983 if (outer_code
== NEG
)
19984 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
19986 *total
= rs6000_cost
->dmul
;
19989 *total
= rs6000_cost
->fp
;
19991 else if (mode
== SFmode
)
19993 /* FNMA accounted in outer NEG. */
19994 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
19997 *total
= rs6000_cost
->fp
;
20000 *total
= COSTS_N_INSNS (1);
20004 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
20005 && satisfies_constraint_I (XEXP (x
, 1)))
20007 if (INTVAL (XEXP (x
, 1)) >= -256
20008 && INTVAL (XEXP (x
, 1)) <= 255)
20009 *total
= rs6000_cost
->mulsi_const9
;
20011 *total
= rs6000_cost
->mulsi_const
;
20013 /* FMA accounted in outer PLUS/MINUS. */
20014 else if ((mode
== DFmode
|| mode
== SFmode
)
20015 && (outer_code
== PLUS
|| outer_code
== MINUS
))
20017 else if (mode
== DFmode
)
20018 *total
= rs6000_cost
->dmul
;
20019 else if (mode
== SFmode
)
20020 *total
= rs6000_cost
->fp
;
20021 else if (mode
== DImode
)
20022 *total
= rs6000_cost
->muldi
;
20024 *total
= rs6000_cost
->mulsi
;
20029 if (FLOAT_MODE_P (mode
))
20031 *total
= mode
== DFmode
? rs6000_cost
->ddiv
20032 : rs6000_cost
->sdiv
;
20039 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
20040 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
20042 if (code
== DIV
|| code
== MOD
)
20044 *total
= COSTS_N_INSNS (2);
20047 *total
= COSTS_N_INSNS (1);
20051 if (GET_MODE (XEXP (x
, 1)) == DImode
)
20052 *total
= rs6000_cost
->divdi
;
20054 *total
= rs6000_cost
->divsi
;
20056 /* Add in shift and subtract for MOD. */
20057 if (code
== MOD
|| code
== UMOD
)
20058 *total
+= COSTS_N_INSNS (2);
20062 *total
= COSTS_N_INSNS (4);
20066 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
20077 *total
= COSTS_N_INSNS (1);
20085 /* Handle mul_highpart. */
20086 if (outer_code
== TRUNCATE
20087 && GET_CODE (XEXP (x
, 0)) == MULT
)
20089 if (mode
== DImode
)
20090 *total
= rs6000_cost
->muldi
;
20092 *total
= rs6000_cost
->mulsi
;
20095 else if (outer_code
== AND
)
20098 *total
= COSTS_N_INSNS (1);
20103 if (GET_CODE (XEXP (x
, 0)) == MEM
)
20106 *total
= COSTS_N_INSNS (1);
20112 if (!FLOAT_MODE_P (mode
))
20114 *total
= COSTS_N_INSNS (1);
20120 case UNSIGNED_FLOAT
:
20123 case FLOAT_TRUNCATE
:
20124 *total
= rs6000_cost
->fp
;
20128 if (mode
== DFmode
)
20131 *total
= rs6000_cost
->fp
;
20135 switch (XINT (x
, 1))
20138 *total
= rs6000_cost
->fp
;
20150 *total
= COSTS_N_INSNS (1);
20153 else if (FLOAT_MODE_P (mode
)
20154 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20156 *total
= rs6000_cost
->fp
;
20164 /* Carry bit requires mode == Pmode.
20165 NEG or PLUS already counted so only add one. */
20167 && (outer_code
== NEG
|| outer_code
== PLUS
))
20169 *total
= COSTS_N_INSNS (1);
20172 if (outer_code
== SET
)
20174 if (XEXP (x
, 1) == const0_rtx
)
20176 *total
= COSTS_N_INSNS (2);
20179 else if (mode
== Pmode
)
20181 *total
= COSTS_N_INSNS (3);
20190 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
20192 *total
= COSTS_N_INSNS (2);
20196 if (outer_code
== COMPARE
)
20210 /* A C expression returning the cost of moving data from a register of class
20211 CLASS1 to one of CLASS2. */
20214 rs6000_register_move_cost (enum machine_mode mode
,
20215 enum reg_class from
, enum reg_class to
)
20217 /* Moves from/to GENERAL_REGS. */
20218 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
20219 || reg_classes_intersect_p (from
, GENERAL_REGS
))
20221 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
20224 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
20225 return (rs6000_memory_move_cost (mode
, from
, 0)
20226 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
20228 /* It's more expensive to move CR_REGS than CR0_REGS because of the
20230 else if (from
== CR_REGS
)
20234 /* A move will cost one instruction per GPR moved. */
20235 return 2 * hard_regno_nregs
[0][mode
];
20238 /* Moving between two similar registers is just one instruction. */
20239 else if (reg_classes_intersect_p (to
, from
))
20240 return (mode
== TFmode
|| mode
== TDmode
) ? 4 : 2;
20242 /* Everything else has to go through GENERAL_REGS. */
20244 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
20245 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
20248 /* A C expressions returning the cost of moving data of MODE from a register to
20252 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
20253 int in ATTRIBUTE_UNUSED
)
20255 if (reg_classes_intersect_p (class, GENERAL_REGS
))
20256 return 4 * hard_regno_nregs
[0][mode
];
20257 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
20258 return 4 * hard_regno_nregs
[32][mode
];
20259 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
20260 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
20262 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
20265 /* Newton-Raphson approximation of single-precision floating point divide n/d.
20266 Assumes no trapping math and finite arguments. */
20269 rs6000_emit_swdivsf (rtx res
, rtx n
, rtx d
)
20271 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
20273 x0
= gen_reg_rtx (SFmode
);
20274 e0
= gen_reg_rtx (SFmode
);
20275 e1
= gen_reg_rtx (SFmode
);
20276 y1
= gen_reg_rtx (SFmode
);
20277 u0
= gen_reg_rtx (SFmode
);
20278 v0
= gen_reg_rtx (SFmode
);
20279 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
20281 /* x0 = 1./d estimate */
20282 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
20283 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
20285 /* e0 = 1. - d * x0 */
20286 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
20287 gen_rtx_MINUS (SFmode
, one
,
20288 gen_rtx_MULT (SFmode
, d
, x0
))));
20289 /* e1 = e0 + e0 * e0 */
20290 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
20291 gen_rtx_PLUS (SFmode
,
20292 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
20293 /* y1 = x0 + e1 * x0 */
20294 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
20295 gen_rtx_PLUS (SFmode
,
20296 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
20298 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
20299 gen_rtx_MULT (SFmode
, n
, y1
)));
20300 /* v0 = n - d * u0 */
20301 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
20302 gen_rtx_MINUS (SFmode
, n
,
20303 gen_rtx_MULT (SFmode
, d
, u0
))));
20304 /* res = u0 + v0 * y1 */
20305 emit_insn (gen_rtx_SET (VOIDmode
, res
,
20306 gen_rtx_PLUS (SFmode
,
20307 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
20310 /* Newton-Raphson approximation of double-precision floating point divide n/d.
20311 Assumes no trapping math and finite arguments. */
20314 rs6000_emit_swdivdf (rtx res
, rtx n
, rtx d
)
20316 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
20318 x0
= gen_reg_rtx (DFmode
);
20319 e0
= gen_reg_rtx (DFmode
);
20320 e1
= gen_reg_rtx (DFmode
);
20321 e2
= gen_reg_rtx (DFmode
);
20322 y1
= gen_reg_rtx (DFmode
);
20323 y2
= gen_reg_rtx (DFmode
);
20324 y3
= gen_reg_rtx (DFmode
);
20325 u0
= gen_reg_rtx (DFmode
);
20326 v0
= gen_reg_rtx (DFmode
);
20327 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
20329 /* x0 = 1./d estimate */
20330 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
20331 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
20333 /* e0 = 1. - d * x0 */
20334 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
20335 gen_rtx_MINUS (DFmode
, one
,
20336 gen_rtx_MULT (SFmode
, d
, x0
))));
20337 /* y1 = x0 + e0 * x0 */
20338 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
20339 gen_rtx_PLUS (DFmode
,
20340 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
20342 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
20343 gen_rtx_MULT (DFmode
, e0
, e0
)));
20344 /* y2 = y1 + e1 * y1 */
20345 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
20346 gen_rtx_PLUS (DFmode
,
20347 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
20349 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
20350 gen_rtx_MULT (DFmode
, e1
, e1
)));
20351 /* y3 = y2 + e2 * y2 */
20352 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
20353 gen_rtx_PLUS (DFmode
,
20354 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
20356 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
20357 gen_rtx_MULT (DFmode
, n
, y3
)));
20358 /* v0 = n - d * u0 */
20359 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
20360 gen_rtx_MINUS (DFmode
, n
,
20361 gen_rtx_MULT (DFmode
, d
, u0
))));
20362 /* res = u0 + v0 * y3 */
20363 emit_insn (gen_rtx_SET (VOIDmode
, res
,
20364 gen_rtx_PLUS (DFmode
,
20365 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
20369 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
20370 target, and SRC is the argument operand. */
20373 rs6000_emit_popcount (rtx dst
, rtx src
)
20375 enum machine_mode mode
= GET_MODE (dst
);
20378 tmp1
= gen_reg_rtx (mode
);
20380 if (mode
== SImode
)
20382 emit_insn (gen_popcntbsi2 (tmp1
, src
));
20383 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
20385 tmp2
= force_reg (SImode
, tmp2
);
20386 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
20390 emit_insn (gen_popcntbdi2 (tmp1
, src
));
20391 tmp2
= expand_mult (DImode
, tmp1
,
20392 GEN_INT ((HOST_WIDE_INT
)
20393 0x01010101 << 32 | 0x01010101),
20395 tmp2
= force_reg (DImode
, tmp2
);
20396 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
20401 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
20402 target, and SRC is the argument operand. */
20405 rs6000_emit_parity (rtx dst
, rtx src
)
20407 enum machine_mode mode
= GET_MODE (dst
);
20410 tmp
= gen_reg_rtx (mode
);
20411 if (mode
== SImode
)
20413 /* Is mult+shift >= shift+xor+shift+xor? */
20414 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
20416 rtx tmp1
, tmp2
, tmp3
, tmp4
;
20418 tmp1
= gen_reg_rtx (SImode
);
20419 emit_insn (gen_popcntbsi2 (tmp1
, src
));
20421 tmp2
= gen_reg_rtx (SImode
);
20422 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
20423 tmp3
= gen_reg_rtx (SImode
);
20424 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
20426 tmp4
= gen_reg_rtx (SImode
);
20427 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
20428 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
20431 rs6000_emit_popcount (tmp
, src
);
20432 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
20436 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
20437 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
20439 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
20441 tmp1
= gen_reg_rtx (DImode
);
20442 emit_insn (gen_popcntbdi2 (tmp1
, src
));
20444 tmp2
= gen_reg_rtx (DImode
);
20445 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
20446 tmp3
= gen_reg_rtx (DImode
);
20447 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
20449 tmp4
= gen_reg_rtx (DImode
);
20450 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
20451 tmp5
= gen_reg_rtx (DImode
);
20452 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
20454 tmp6
= gen_reg_rtx (DImode
);
20455 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
20456 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
20459 rs6000_emit_popcount (tmp
, src
);
20460 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
20464 /* Return an RTX representing where to find the function value of a
20465 function returning MODE. */
20467 rs6000_complex_function_value (enum machine_mode mode
)
20469 unsigned int regno
;
20471 enum machine_mode inner
= GET_MODE_INNER (mode
);
20472 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
20474 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20475 regno
= FP_ARG_RETURN
;
20478 regno
= GP_ARG_RETURN
;
20480 /* 32-bit is OK since it'll go in r3/r4. */
20481 if (TARGET_32BIT
&& inner_bytes
>= 4)
20482 return gen_rtx_REG (mode
, regno
);
20485 if (inner_bytes
>= 8)
20486 return gen_rtx_REG (mode
, regno
);
20488 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
20490 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
20491 GEN_INT (inner_bytes
));
20492 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
20495 /* Define how to find the value returned by a function.
20496 VALTYPE is the data type of the value (as a tree).
20497 If the precise function being called is known, FUNC is its FUNCTION_DECL;
20498 otherwise, FUNC is 0.
20500 On the SPE, both FPs and vectors are returned in r3.
20502 On RS/6000 an integer value is in r3 and a floating-point value is in
20503 fp1, unless -msoft-float. */
20506 rs6000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
20508 enum machine_mode mode
;
20509 unsigned int regno
;
20511 /* Special handling for structs in darwin64. */
20512 if (rs6000_darwin64_abi
20513 && TYPE_MODE (valtype
) == BLKmode
20514 && TREE_CODE (valtype
) == RECORD_TYPE
20515 && int_size_in_bytes (valtype
) > 0)
20517 CUMULATIVE_ARGS valcum
;
20521 valcum
.fregno
= FP_ARG_MIN_REG
;
20522 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
20523 /* Do a trial code generation as if this were going to be passed as
20524 an argument; if any part goes in memory, we return NULL. */
20525 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
20528 /* Otherwise fall through to standard ABI rules. */
20531 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
20533 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20534 return gen_rtx_PARALLEL (DImode
,
20536 gen_rtx_EXPR_LIST (VOIDmode
,
20537 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
20539 gen_rtx_EXPR_LIST (VOIDmode
,
20540 gen_rtx_REG (SImode
,
20541 GP_ARG_RETURN
+ 1),
20544 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
20546 return gen_rtx_PARALLEL (DCmode
,
20548 gen_rtx_EXPR_LIST (VOIDmode
,
20549 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
20551 gen_rtx_EXPR_LIST (VOIDmode
,
20552 gen_rtx_REG (SImode
,
20553 GP_ARG_RETURN
+ 1),
20555 gen_rtx_EXPR_LIST (VOIDmode
,
20556 gen_rtx_REG (SImode
,
20557 GP_ARG_RETURN
+ 2),
20559 gen_rtx_EXPR_LIST (VOIDmode
,
20560 gen_rtx_REG (SImode
,
20561 GP_ARG_RETURN
+ 3),
20565 if ((INTEGRAL_TYPE_P (valtype
)
20566 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
20567 || POINTER_TYPE_P (valtype
))
20568 mode
= TARGET_32BIT
? SImode
: DImode
;
20570 mode
= TYPE_MODE (valtype
);
20572 if (DECIMAL_FLOAT_MODE_P (mode
))
20574 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20579 gcc_unreachable ();
20581 regno
= GP_ARG_RETURN
;
20584 regno
= FP_ARG_RETURN
;
20587 /* Use f2:f3 specified by the ABI. */
20588 regno
= FP_ARG_RETURN
+ 1;
20593 regno
= GP_ARG_RETURN
;
20595 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20596 regno
= FP_ARG_RETURN
;
20597 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
20598 && targetm
.calls
.split_complex_arg
)
20599 return rs6000_complex_function_value (mode
);
20600 else if (TREE_CODE (valtype
) == VECTOR_TYPE
20601 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
20602 && ALTIVEC_VECTOR_MODE (mode
))
20603 regno
= ALTIVEC_ARG_RETURN
;
20604 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
20605 && (mode
== DFmode
|| mode
== DCmode
20606 || mode
== TFmode
|| mode
== TCmode
))
20607 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
20609 regno
= GP_ARG_RETURN
;
20611 return gen_rtx_REG (mode
, regno
);
20614 /* Define how to find the value returned by a library function
20615 assuming the value has mode MODE. */
20617 rs6000_libcall_value (enum machine_mode mode
)
20619 unsigned int regno
;
20621 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
20623 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20624 return gen_rtx_PARALLEL (DImode
,
20626 gen_rtx_EXPR_LIST (VOIDmode
,
20627 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
20629 gen_rtx_EXPR_LIST (VOIDmode
,
20630 gen_rtx_REG (SImode
,
20631 GP_ARG_RETURN
+ 1),
20635 if (DECIMAL_FLOAT_MODE_P (mode
))
20637 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20642 gcc_unreachable ();
20644 regno
= GP_ARG_RETURN
;
20647 regno
= FP_ARG_RETURN
;
20650 /* Use f2:f3 specified by the ABI. */
20651 regno
= FP_ARG_RETURN
+ 1;
20656 regno
= GP_ARG_RETURN
;
20658 else if (SCALAR_FLOAT_MODE_P (mode
)
20659 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20660 regno
= FP_ARG_RETURN
;
20661 else if (ALTIVEC_VECTOR_MODE (mode
)
20662 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
20663 regno
= ALTIVEC_ARG_RETURN
;
20664 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
20665 return rs6000_complex_function_value (mode
);
20666 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
20667 && (mode
== DFmode
|| mode
== DCmode
20668 || mode
== TFmode
|| mode
== TCmode
))
20669 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
20671 regno
= GP_ARG_RETURN
;
20673 return gen_rtx_REG (mode
, regno
);
20676 /* Define the offset between two registers, FROM to be eliminated and its
20677 replacement TO, at the start of a routine. */
20679 rs6000_initial_elimination_offset (int from
, int to
)
20681 rs6000_stack_t
*info
= rs6000_stack_info ();
20682 HOST_WIDE_INT offset
;
20684 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
20685 offset
= info
->push_p
? 0 : -info
->total_size
;
20686 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
20688 offset
= info
->push_p
? 0 : -info
->total_size
;
20689 if (FRAME_GROWS_DOWNWARD
)
20690 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
20692 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
20693 offset
= FRAME_GROWS_DOWNWARD
20694 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
20696 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
20697 offset
= info
->total_size
;
20698 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
20699 offset
= info
->push_p
? info
->total_size
: 0;
20700 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
20703 gcc_unreachable ();
20708 /* Return true if TYPE is a SPE or AltiVec opaque type. */
20711 rs6000_is_opaque_type (tree type
)
20713 return (type
== opaque_V2SI_type_node
20714 || type
== opaque_V2SF_type_node
20715 || type
== opaque_p_V2SI_type_node
20716 || type
== opaque_V4SI_type_node
);
20720 rs6000_dwarf_register_span (rtx reg
)
20725 && (SPE_VECTOR_MODE (GET_MODE (reg
))
20726 || (TARGET_E500_DOUBLE
&& GET_MODE (reg
) == DFmode
)))
20731 regno
= REGNO (reg
);
20733 /* The duality of the SPE register size wreaks all kinds of havoc.
20734 This is a way of distinguishing r0 in 32-bits from r0 in
20737 gen_rtx_PARALLEL (VOIDmode
,
20740 gen_rtx_REG (SImode
, regno
+ 1200),
20741 gen_rtx_REG (SImode
, regno
))
20743 gen_rtx_REG (SImode
, regno
),
20744 gen_rtx_REG (SImode
, regno
+ 1200)));
20747 /* Fill in sizes for SPE register high parts in table used by unwinder. */
20750 rs6000_init_dwarf_reg_sizes_extra (tree address
)
20755 enum machine_mode mode
= TYPE_MODE (char_type_node
);
20756 rtx addr
= expand_expr (address
, NULL_RTX
, VOIDmode
, 0);
20757 rtx mem
= gen_rtx_MEM (BLKmode
, addr
);
20758 rtx value
= gen_int_mode (4, mode
);
20760 for (i
= 1201; i
< 1232; i
++)
20762 int column
= DWARF_REG_TO_UNWIND_COLUMN (i
);
20763 HOST_WIDE_INT offset
20764 = DWARF_FRAME_REGNUM (column
) * GET_MODE_SIZE (mode
);
20766 emit_move_insn (adjust_address (mem
, mode
, offset
), value
);
20771 /* Map internal gcc register numbers to DWARF2 register numbers. */
20774 rs6000_dbx_register_number (unsigned int regno
)
20776 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
20778 if (regno
== MQ_REGNO
)
20780 if (regno
== LINK_REGISTER_REGNUM
)
20782 if (regno
== COUNT_REGISTER_REGNUM
)
20784 if (CR_REGNO_P (regno
))
20785 return regno
- CR0_REGNO
+ 86;
20786 if (regno
== XER_REGNO
)
20788 if (ALTIVEC_REGNO_P (regno
))
20789 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
20790 if (regno
== VRSAVE_REGNO
)
20792 if (regno
== VSCR_REGNO
)
20794 if (regno
== SPE_ACC_REGNO
)
20796 if (regno
== SPEFSCR_REGNO
)
20798 /* SPE high reg number. We get these values of regno from
20799 rs6000_dwarf_register_span. */
20800 gcc_assert (regno
>= 1200 && regno
< 1232);
20804 /* target hook eh_return_filter_mode */
20805 static enum machine_mode
20806 rs6000_eh_return_filter_mode (void)
20808 return TARGET_32BIT
? SImode
: word_mode
;
20811 /* Target hook for scalar_mode_supported_p. */
20813 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
20815 if (DECIMAL_FLOAT_MODE_P (mode
))
20818 return default_scalar_mode_supported_p (mode
);
20821 /* Target hook for vector_mode_supported_p. */
20823 rs6000_vector_mode_supported_p (enum machine_mode mode
)
20826 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
20829 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
20836 /* Target hook for invalid_arg_for_unprototyped_fn. */
20837 static const char *
20838 invalid_arg_for_unprototyped_fn (tree typelist
, tree funcdecl
, tree val
)
20840 return (!rs6000_darwin64_abi
20842 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
20843 && (funcdecl
== NULL_TREE
20844 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
20845 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
20846 ? N_("AltiVec argument passed to unprototyped function")
20850 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
20851 setup by using __stack_chk_fail_local hidden function instead of
20852 calling __stack_chk_fail directly. Otherwise it is better to call
20853 __stack_chk_fail directly. */
20856 rs6000_stack_protect_fail (void)
20858 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
20859 ? default_hidden_stack_protect_fail ()
20860 : default_external_stack_protect_fail ();
20863 #include "gt-rs6000.h"