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 rtx
rs6000_legitimize_tls_address (rtx
, enum tls_model
);
769 static void rs6000_output_dwarf_dtprel (FILE *, int, rtx
) ATTRIBUTE_UNUSED
;
770 static rtx
rs6000_tls_get_addr (void);
771 static rtx
rs6000_got_sym (void);
772 static int rs6000_tls_symbol_ref_1 (rtx
*, void *);
773 static const char *rs6000_get_some_local_dynamic_name (void);
774 static int rs6000_get_some_local_dynamic_name_1 (rtx
*, void *);
775 static rtx
rs6000_complex_function_value (enum machine_mode
);
776 static rtx
rs6000_spe_function_arg (CUMULATIVE_ARGS
*,
777 enum machine_mode
, tree
);
778 static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*,
780 static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*,
781 tree
, HOST_WIDE_INT
);
782 static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*,
785 static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*,
788 static rtx
rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*, tree
, int, bool);
789 static rtx
rs6000_mixed_function_arg (enum machine_mode
, tree
, int);
790 static void rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
);
791 static void setup_incoming_varargs (CUMULATIVE_ARGS
*,
792 enum machine_mode
, tree
,
794 static bool rs6000_pass_by_reference (CUMULATIVE_ARGS
*, enum machine_mode
,
796 static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*, enum machine_mode
,
798 static const char *invalid_arg_for_unprototyped_fn (tree
, tree
, tree
);
800 static void macho_branch_islands (void);
801 static int no_previous_def (tree function_name
);
802 static tree
get_prev_label (tree function_name
);
803 static void rs6000_darwin_file_start (void);
806 static tree
rs6000_build_builtin_va_list (void);
807 static tree
rs6000_gimplify_va_arg (tree
, tree
, tree
*, tree
*);
808 static bool rs6000_must_pass_in_stack (enum machine_mode
, tree
);
809 static bool rs6000_scalar_mode_supported_p (enum machine_mode
);
810 static bool rs6000_vector_mode_supported_p (enum machine_mode
);
811 static int get_vec_cmp_insn (enum rtx_code
, enum machine_mode
,
813 static rtx
rs6000_emit_vector_compare (enum rtx_code
, rtx
, rtx
,
815 static int get_vsel_insn (enum machine_mode
);
816 static void rs6000_emit_vector_select (rtx
, rtx
, rtx
, rtx
);
817 static tree
rs6000_stack_protect_fail (void);
819 const int INSN_NOT_AVAILABLE
= -1;
820 static enum machine_mode
rs6000_eh_return_filter_mode (void);
822 /* Hash table stuff for keeping track of TOC entries. */
824 struct toc_hash_struct
GTY(())
826 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
827 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
829 enum machine_mode key_mode
;
833 static GTY ((param_is (struct toc_hash_struct
))) htab_t toc_hash_table
;
835 /* Default register names. */
836 char rs6000_reg_names
[][8] =
838 "0", "1", "2", "3", "4", "5", "6", "7",
839 "8", "9", "10", "11", "12", "13", "14", "15",
840 "16", "17", "18", "19", "20", "21", "22", "23",
841 "24", "25", "26", "27", "28", "29", "30", "31",
842 "0", "1", "2", "3", "4", "5", "6", "7",
843 "8", "9", "10", "11", "12", "13", "14", "15",
844 "16", "17", "18", "19", "20", "21", "22", "23",
845 "24", "25", "26", "27", "28", "29", "30", "31",
846 "mq", "lr", "ctr","ap",
847 "0", "1", "2", "3", "4", "5", "6", "7",
849 /* AltiVec registers. */
850 "0", "1", "2", "3", "4", "5", "6", "7",
851 "8", "9", "10", "11", "12", "13", "14", "15",
852 "16", "17", "18", "19", "20", "21", "22", "23",
853 "24", "25", "26", "27", "28", "29", "30", "31",
856 "spe_acc", "spefscr",
857 /* Soft frame pointer. */
861 #ifdef TARGET_REGNAMES
862 static const char alt_reg_names
[][8] =
864 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
865 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
866 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
867 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
868 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
869 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
870 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
871 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
872 "mq", "lr", "ctr", "ap",
873 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
875 /* AltiVec registers. */
876 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
877 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
878 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
879 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
882 "spe_acc", "spefscr",
883 /* Soft frame pointer. */
888 #ifndef MASK_STRICT_ALIGN
889 #define MASK_STRICT_ALIGN 0
891 #ifndef TARGET_PROFILE_KERNEL
892 #define TARGET_PROFILE_KERNEL 0
895 /* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
896 #define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
898 /* Initialize the GCC target structure. */
899 #undef TARGET_ATTRIBUTE_TABLE
900 #define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
901 #undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
902 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
904 #undef TARGET_ASM_ALIGNED_DI_OP
905 #define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
907 /* Default unaligned ops are only provided for ELF. Find the ops needed
908 for non-ELF systems. */
909 #ifndef OBJECT_FORMAT_ELF
911 /* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
913 #undef TARGET_ASM_UNALIGNED_HI_OP
914 #define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
915 #undef TARGET_ASM_UNALIGNED_SI_OP
916 #define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
917 #undef TARGET_ASM_UNALIGNED_DI_OP
918 #define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
921 #undef TARGET_ASM_UNALIGNED_HI_OP
922 #define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
923 #undef TARGET_ASM_UNALIGNED_SI_OP
924 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
925 #undef TARGET_ASM_UNALIGNED_DI_OP
926 #define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
927 #undef TARGET_ASM_ALIGNED_DI_OP
928 #define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
932 /* This hook deals with fixups for relocatable code and DI-mode objects
934 #undef TARGET_ASM_INTEGER
935 #define TARGET_ASM_INTEGER rs6000_assemble_integer
937 #ifdef HAVE_GAS_HIDDEN
938 #undef TARGET_ASM_ASSEMBLE_VISIBILITY
939 #define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
942 #undef TARGET_HAVE_TLS
943 #define TARGET_HAVE_TLS HAVE_AS_TLS
945 #undef TARGET_CANNOT_FORCE_CONST_MEM
946 #define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
948 #undef TARGET_ASM_FUNCTION_PROLOGUE
949 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
950 #undef TARGET_ASM_FUNCTION_EPILOGUE
951 #define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
953 #undef TARGET_SCHED_VARIABLE_ISSUE
954 #define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
956 #undef TARGET_SCHED_ISSUE_RATE
957 #define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
958 #undef TARGET_SCHED_ADJUST_COST
959 #define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
960 #undef TARGET_SCHED_ADJUST_PRIORITY
961 #define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
962 #undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
963 #define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
964 #undef TARGET_SCHED_INIT
965 #define TARGET_SCHED_INIT rs6000_sched_init
966 #undef TARGET_SCHED_FINISH
967 #define TARGET_SCHED_FINISH rs6000_sched_finish
968 #undef TARGET_SCHED_REORDER
969 #define TARGET_SCHED_REORDER rs6000_sched_reorder
970 #undef TARGET_SCHED_REORDER2
971 #define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
973 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
974 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
976 #undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
977 #define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
979 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
980 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
981 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
982 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
983 #undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
984 #define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
985 #undef TARGET_VECTORIZE_BUILTIN_CONVERSION
986 #define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
988 #undef TARGET_INIT_BUILTINS
989 #define TARGET_INIT_BUILTINS rs6000_init_builtins
991 #undef TARGET_EXPAND_BUILTIN
992 #define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
994 #undef TARGET_MANGLE_FUNDAMENTAL_TYPE
995 #define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
997 #undef TARGET_INIT_LIBFUNCS
998 #define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1001 #undef TARGET_BINDS_LOCAL_P
1002 #define TARGET_BINDS_LOCAL_P darwin_binds_local_p
1005 #undef TARGET_MS_BITFIELD_LAYOUT_P
1006 #define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1008 #undef TARGET_ASM_OUTPUT_MI_THUNK
1009 #define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1011 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
1012 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
1014 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
1015 #define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1017 #undef TARGET_INVALID_WITHIN_DOLOOP
1018 #define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
1020 #undef TARGET_RTX_COSTS
1021 #define TARGET_RTX_COSTS rs6000_rtx_costs
1022 #undef TARGET_ADDRESS_COST
1023 #define TARGET_ADDRESS_COST hook_int_rtx_0
1025 #undef TARGET_VECTOR_OPAQUE_P
1026 #define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
1028 #undef TARGET_DWARF_REGISTER_SPAN
1029 #define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1031 /* On rs6000, function arguments are promoted, as are function return
1033 #undef TARGET_PROMOTE_FUNCTION_ARGS
1034 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
1035 #undef TARGET_PROMOTE_FUNCTION_RETURN
1036 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
1038 #undef TARGET_RETURN_IN_MEMORY
1039 #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1041 #undef TARGET_SETUP_INCOMING_VARARGS
1042 #define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1044 /* Always strict argument naming on rs6000. */
1045 #undef TARGET_STRICT_ARGUMENT_NAMING
1046 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1047 #undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1048 #define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
1049 #undef TARGET_SPLIT_COMPLEX_ARG
1050 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
1051 #undef TARGET_MUST_PASS_IN_STACK
1052 #define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
1053 #undef TARGET_PASS_BY_REFERENCE
1054 #define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
1055 #undef TARGET_ARG_PARTIAL_BYTES
1056 #define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
1058 #undef TARGET_BUILD_BUILTIN_VA_LIST
1059 #define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1061 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
1062 #define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1064 #undef TARGET_EH_RETURN_FILTER_MODE
1065 #define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1067 #undef TARGET_SCALAR_MODE_SUPPORTED_P
1068 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1070 #undef TARGET_VECTOR_MODE_SUPPORTED_P
1071 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1073 #undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1074 #define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1076 #undef TARGET_HANDLE_OPTION
1077 #define TARGET_HANDLE_OPTION rs6000_handle_option
1079 #undef TARGET_DEFAULT_TARGET_FLAGS
1080 #define TARGET_DEFAULT_TARGET_FLAGS \
1083 #undef TARGET_STACK_PROTECT_FAIL
1084 #define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1086 /* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1087 The PowerPC architecture requires only weak consistency among
1088 processors--that is, memory accesses between processors need not be
1089 sequentially consistent and memory accesses among processors can occur
1090 in any order. The ability to order memory accesses weakly provides
1091 opportunities for more efficient use of the system bus. Unless a
1092 dependency exists, the 604e allows read operations to precede store
1094 #undef TARGET_RELAXED_ORDERING
1095 #define TARGET_RELAXED_ORDERING true
1098 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1099 #define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1102 /* Use a 32-bit anchor range. This leads to sequences like:
1104 addis tmp,anchor,high
1107 where tmp itself acts as an anchor, and can be shared between
1108 accesses to the same 64k page. */
1109 #undef TARGET_MIN_ANCHOR_OFFSET
1110 #define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1111 #undef TARGET_MAX_ANCHOR_OFFSET
1112 #define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1113 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1114 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1116 struct gcc_target targetm
= TARGET_INITIALIZER
;
1119 /* Value is 1 if hard register REGNO can hold a value of machine-mode
1122 rs6000_hard_regno_mode_ok (int regno
, enum machine_mode mode
)
1124 /* The GPRs can hold any mode, but values bigger than one register
1125 cannot go past R31. */
1126 if (INT_REGNO_P (regno
))
1127 return INT_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1);
1129 /* The float registers can only hold floating modes and DImode.
1130 This also excludes decimal float modes. */
1131 if (FP_REGNO_P (regno
))
1133 (SCALAR_FLOAT_MODE_P (mode
)
1134 && !DECIMAL_FLOAT_MODE_P (mode
)
1135 && FP_REGNO_P (regno
+ HARD_REGNO_NREGS (regno
, mode
) - 1))
1136 || (GET_MODE_CLASS (mode
) == MODE_INT
1137 && GET_MODE_SIZE (mode
) == UNITS_PER_FP_WORD
);
1139 /* The CR register can only hold CC modes. */
1140 if (CR_REGNO_P (regno
))
1141 return GET_MODE_CLASS (mode
) == MODE_CC
;
1143 if (XER_REGNO_P (regno
))
1144 return mode
== PSImode
;
1146 /* AltiVec only in AldyVec registers. */
1147 if (ALTIVEC_REGNO_P (regno
))
1148 return ALTIVEC_VECTOR_MODE (mode
);
1150 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1151 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
1154 /* We cannot put TImode anywhere except general register and it must be
1155 able to fit within the register set. */
1157 return GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
;
1160 /* Initialize rs6000_hard_regno_mode_ok_p table. */
1162 rs6000_init_hard_regno_mode_ok (void)
1166 for (r
= 0; r
< FIRST_PSEUDO_REGISTER
; ++r
)
1167 for (m
= 0; m
< NUM_MACHINE_MODES
; ++m
)
1168 if (rs6000_hard_regno_mode_ok (r
, m
))
1169 rs6000_hard_regno_mode_ok_p
[m
][r
] = true;
1172 /* If not otherwise specified by a target, make 'long double' equivalent to
1175 #ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1176 #define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1179 /* Override command line options. Mostly we process the processor
1180 type and sometimes adjust other TARGET_ options. */
1183 rs6000_override_options (const char *default_cpu
)
1186 struct rs6000_cpu_select
*ptr
;
1189 /* Simplifications for entries below. */
1192 POWERPC_BASE_MASK
= MASK_POWERPC
| MASK_NEW_MNEMONICS
,
1193 POWERPC_7400_MASK
= POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_ALTIVEC
1196 /* This table occasionally claims that a processor does not support
1197 a particular feature even though it does, but the feature is slower
1198 than the alternative. Thus, it shouldn't be relied on as a
1199 complete description of the processor's support.
1201 Please keep this list in order, and don't forget to update the
1202 documentation in invoke.texi when adding a new processor or
1206 const char *const name
; /* Canonical processor name. */
1207 const enum processor_type processor
; /* Processor type enum value. */
1208 const int target_enable
; /* Target flags to enable. */
1209 } const processor_target_table
[]
1210 = {{"401", PROCESSOR_PPC403
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1211 {"403", PROCESSOR_PPC403
,
1212 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_STRICT_ALIGN
},
1213 {"405", PROCESSOR_PPC405
,
1214 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1215 {"405fp", PROCESSOR_PPC405
,
1216 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1217 {"440", PROCESSOR_PPC440
,
1218 POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
| MASK_MULHW
| MASK_DLMZB
},
1219 {"440fp", PROCESSOR_PPC440
,
1220 POWERPC_BASE_MASK
| MASK_MULHW
| MASK_DLMZB
},
1221 {"505", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
},
1222 {"601", PROCESSOR_PPC601
,
1223 MASK_POWER
| POWERPC_BASE_MASK
| MASK_MULTIPLE
| MASK_STRING
},
1224 {"602", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1225 {"603", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1226 {"603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1227 {"604", PROCESSOR_PPC604
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1228 {"604e", PROCESSOR_PPC604e
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1229 {"620", PROCESSOR_PPC620
,
1230 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1231 {"630", PROCESSOR_PPC630
,
1232 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1233 {"740", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1234 {"7400", PROCESSOR_PPC7400
, POWERPC_7400_MASK
},
1235 {"7450", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1236 {"750", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1237 {"801", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1238 {"821", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1239 {"823", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1240 {"8540", PROCESSOR_PPC8540
,
1241 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_STRICT_ALIGN
},
1242 /* 8548 has a dummy entry for now. */
1243 {"8548", PROCESSOR_PPC8540
,
1244 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_STRICT_ALIGN
},
1245 {"860", PROCESSOR_MPCCORE
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1246 {"970", PROCESSOR_POWER4
,
1247 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1248 {"cell", PROCESSOR_CELL
,
1249 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1250 {"common", PROCESSOR_COMMON
, MASK_NEW_MNEMONICS
},
1251 {"ec603e", PROCESSOR_PPC603
, POWERPC_BASE_MASK
| MASK_SOFT_FLOAT
},
1252 {"G3", PROCESSOR_PPC750
, POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
},
1253 {"G4", PROCESSOR_PPC7450
, POWERPC_7400_MASK
},
1254 {"G5", PROCESSOR_POWER4
,
1255 POWERPC_7400_MASK
| MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1256 {"power", PROCESSOR_POWER
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1257 {"power2", PROCESSOR_POWER
,
1258 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1259 {"power3", PROCESSOR_PPC630
,
1260 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1261 {"power4", PROCESSOR_POWER4
,
1262 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_MFCRF
| MASK_POWERPC64
},
1263 {"power5", PROCESSOR_POWER5
,
1264 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1265 | MASK_MFCRF
| MASK_POPCNTB
},
1266 {"power5+", PROCESSOR_POWER5
,
1267 POWERPC_BASE_MASK
| MASK_POWERPC64
| MASK_PPC_GFXOPT
1268 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
},
1269 {"power6", PROCESSOR_POWER6
,
1270 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1272 {"power6x", PROCESSOR_POWER6
,
1273 POWERPC_7400_MASK
| MASK_POWERPC64
| MASK_MFCRF
| MASK_POPCNTB
1274 | MASK_FPRND
| MASK_MFPGPR
},
1275 {"powerpc", PROCESSOR_POWERPC
, POWERPC_BASE_MASK
},
1276 {"powerpc64", PROCESSOR_POWERPC64
,
1277 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
},
1278 {"rios", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1279 {"rios1", PROCESSOR_RIOS1
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1280 {"rios2", PROCESSOR_RIOS2
,
1281 MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
},
1282 {"rsc", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1283 {"rsc1", PROCESSOR_PPC601
, MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
},
1284 {"rs64", PROCESSOR_RS64A
,
1285 POWERPC_BASE_MASK
| MASK_PPC_GFXOPT
| MASK_POWERPC64
}
1288 const size_t ptt_size
= ARRAY_SIZE (processor_target_table
);
1290 /* Some OSs don't support saving the high part of 64-bit registers on
1291 context switch. Other OSs don't support saving Altivec registers.
1292 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1293 settings; if the user wants either, the user must explicitly specify
1294 them and we won't interfere with the user's specification. */
1297 POWER_MASKS
= MASK_POWER
| MASK_POWER2
| MASK_MULTIPLE
| MASK_STRING
,
1298 POWERPC_MASKS
= (POWERPC_BASE_MASK
| MASK_PPC_GPOPT
| MASK_STRICT_ALIGN
1299 | MASK_PPC_GFXOPT
| MASK_POWERPC64
| MASK_ALTIVEC
1300 | MASK_MFCRF
| MASK_POPCNTB
| MASK_FPRND
| MASK_MULHW
1301 | MASK_DLMZB
| MASK_MFPGPR
)
1304 rs6000_init_hard_regno_mode_ok ();
1306 set_masks
= POWER_MASKS
| POWERPC_MASKS
| MASK_SOFT_FLOAT
;
1307 #ifdef OS_MISSING_POWERPC64
1308 if (OS_MISSING_POWERPC64
)
1309 set_masks
&= ~MASK_POWERPC64
;
1311 #ifdef OS_MISSING_ALTIVEC
1312 if (OS_MISSING_ALTIVEC
)
1313 set_masks
&= ~MASK_ALTIVEC
;
1316 /* Don't override by the processor default if given explicitly. */
1317 set_masks
&= ~target_flags_explicit
;
1319 /* Identify the processor type. */
1320 rs6000_select
[0].string
= default_cpu
;
1321 rs6000_cpu
= TARGET_POWERPC64
? PROCESSOR_DEFAULT64
: PROCESSOR_DEFAULT
;
1323 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
1325 ptr
= &rs6000_select
[i
];
1326 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
1328 for (j
= 0; j
< ptt_size
; j
++)
1329 if (! strcmp (ptr
->string
, processor_target_table
[j
].name
))
1331 if (ptr
->set_tune_p
)
1332 rs6000_cpu
= processor_target_table
[j
].processor
;
1334 if (ptr
->set_arch_p
)
1336 target_flags
&= ~set_masks
;
1337 target_flags
|= (processor_target_table
[j
].target_enable
1344 error ("bad value (%s) for %s switch", ptr
->string
, ptr
->name
);
1351 /* If we are optimizing big endian systems for space, use the load/store
1352 multiple and string instructions. */
1353 if (BYTES_BIG_ENDIAN
&& optimize_size
)
1354 target_flags
|= ~target_flags_explicit
& (MASK_MULTIPLE
| MASK_STRING
);
1356 /* Don't allow -mmultiple or -mstring on little endian systems
1357 unless the cpu is a 750, because the hardware doesn't support the
1358 instructions used in little endian mode, and causes an alignment
1359 trap. The 750 does not cause an alignment trap (except when the
1360 target is unaligned). */
1362 if (!BYTES_BIG_ENDIAN
&& rs6000_cpu
!= PROCESSOR_PPC750
)
1364 if (TARGET_MULTIPLE
)
1366 target_flags
&= ~MASK_MULTIPLE
;
1367 if ((target_flags_explicit
& MASK_MULTIPLE
) != 0)
1368 warning (0, "-mmultiple is not supported on little endian systems");
1373 target_flags
&= ~MASK_STRING
;
1374 if ((target_flags_explicit
& MASK_STRING
) != 0)
1375 warning (0, "-mstring is not supported on little endian systems");
1379 /* Set debug flags */
1380 if (rs6000_debug_name
)
1382 if (! strcmp (rs6000_debug_name
, "all"))
1383 rs6000_debug_stack
= rs6000_debug_arg
= 1;
1384 else if (! strcmp (rs6000_debug_name
, "stack"))
1385 rs6000_debug_stack
= 1;
1386 else if (! strcmp (rs6000_debug_name
, "arg"))
1387 rs6000_debug_arg
= 1;
1389 error ("unknown -mdebug-%s switch", rs6000_debug_name
);
1392 if (rs6000_traceback_name
)
1394 if (! strncmp (rs6000_traceback_name
, "full", 4))
1395 rs6000_traceback
= traceback_full
;
1396 else if (! strncmp (rs6000_traceback_name
, "part", 4))
1397 rs6000_traceback
= traceback_part
;
1398 else if (! strncmp (rs6000_traceback_name
, "no", 2))
1399 rs6000_traceback
= traceback_none
;
1401 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
1402 rs6000_traceback_name
);
1405 if (!rs6000_explicit_options
.long_double
)
1406 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
1408 #ifndef POWERPC_LINUX
1409 if (!rs6000_explicit_options
.ieee
)
1410 rs6000_ieeequad
= 1;
1413 /* Set Altivec ABI as default for powerpc64 linux. */
1414 if (TARGET_ELF
&& TARGET_64BIT
)
1416 rs6000_altivec_abi
= 1;
1417 TARGET_ALTIVEC_VRSAVE
= 1;
1420 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1421 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
1423 rs6000_darwin64_abi
= 1;
1425 darwin_one_byte_bool
= 1;
1427 /* Default to natural alignment, for better performance. */
1428 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
1431 /* Place FP constants in the constant pool instead of TOC
1432 if section anchors enabled. */
1433 if (flag_section_anchors
)
1434 TARGET_NO_FP_IN_TOC
= 1;
1436 /* Handle -mtls-size option. */
1437 rs6000_parse_tls_size_option ();
1439 #ifdef SUBTARGET_OVERRIDE_OPTIONS
1440 SUBTARGET_OVERRIDE_OPTIONS
;
1442 #ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1443 SUBSUBTARGET_OVERRIDE_OPTIONS
;
1445 #ifdef SUB3TARGET_OVERRIDE_OPTIONS
1446 SUB3TARGET_OVERRIDE_OPTIONS
;
1451 /* The e500 does not have string instructions, and we set
1452 MASK_STRING above when optimizing for size. */
1453 if ((target_flags
& MASK_STRING
) != 0)
1454 target_flags
= target_flags
& ~MASK_STRING
;
1456 else if (rs6000_select
[1].string
!= NULL
)
1458 /* For the powerpc-eabispe configuration, we set all these by
1459 default, so let's unset them if we manually set another
1460 CPU that is not the E500. */
1461 if (!rs6000_explicit_options
.abi
)
1463 if (!rs6000_explicit_options
.spe
)
1465 if (!rs6000_explicit_options
.float_gprs
)
1466 rs6000_float_gprs
= 0;
1467 if (!rs6000_explicit_options
.isel
)
1471 /* Detect invalid option combinations with E500. */
1474 rs6000_always_hint
= (rs6000_cpu
!= PROCESSOR_POWER4
1475 && rs6000_cpu
!= PROCESSOR_POWER5
1476 && rs6000_cpu
!= PROCESSOR_POWER6
1477 && rs6000_cpu
!= PROCESSOR_CELL
);
1478 rs6000_sched_groups
= (rs6000_cpu
== PROCESSOR_POWER4
1479 || rs6000_cpu
== PROCESSOR_POWER5
);
1480 rs6000_align_branch_targets
= (rs6000_cpu
== PROCESSOR_POWER4
1481 || rs6000_cpu
== PROCESSOR_POWER5
1482 || rs6000_cpu
== PROCESSOR_POWER6
);
1484 rs6000_sched_restricted_insns_priority
1485 = (rs6000_sched_groups
? 1 : 0);
1487 /* Handle -msched-costly-dep option. */
1488 rs6000_sched_costly_dep
1489 = (rs6000_sched_groups
? store_to_load_dep_costly
: no_dep_costly
);
1491 if (rs6000_sched_costly_dep_str
)
1493 if (! strcmp (rs6000_sched_costly_dep_str
, "no"))
1494 rs6000_sched_costly_dep
= no_dep_costly
;
1495 else if (! strcmp (rs6000_sched_costly_dep_str
, "all"))
1496 rs6000_sched_costly_dep
= all_deps_costly
;
1497 else if (! strcmp (rs6000_sched_costly_dep_str
, "true_store_to_load"))
1498 rs6000_sched_costly_dep
= true_store_to_load_dep_costly
;
1499 else if (! strcmp (rs6000_sched_costly_dep_str
, "store_to_load"))
1500 rs6000_sched_costly_dep
= store_to_load_dep_costly
;
1502 rs6000_sched_costly_dep
= atoi (rs6000_sched_costly_dep_str
);
1505 /* Handle -minsert-sched-nops option. */
1506 rs6000_sched_insert_nops
1507 = (rs6000_sched_groups
? sched_finish_regroup_exact
: sched_finish_none
);
1509 if (rs6000_sched_insert_nops_str
)
1511 if (! strcmp (rs6000_sched_insert_nops_str
, "no"))
1512 rs6000_sched_insert_nops
= sched_finish_none
;
1513 else if (! strcmp (rs6000_sched_insert_nops_str
, "pad"))
1514 rs6000_sched_insert_nops
= sched_finish_pad_groups
;
1515 else if (! strcmp (rs6000_sched_insert_nops_str
, "regroup_exact"))
1516 rs6000_sched_insert_nops
= sched_finish_regroup_exact
;
1518 rs6000_sched_insert_nops
= atoi (rs6000_sched_insert_nops_str
);
1521 #ifdef TARGET_REGNAMES
1522 /* If the user desires alternate register names, copy in the
1523 alternate names now. */
1524 if (TARGET_REGNAMES
)
1525 memcpy (rs6000_reg_names
, alt_reg_names
, sizeof (rs6000_reg_names
));
1528 /* Set aix_struct_return last, after the ABI is determined.
1529 If -maix-struct-return or -msvr4-struct-return was explicitly
1530 used, don't override with the ABI default. */
1531 if (!rs6000_explicit_options
.aix_struct_ret
)
1532 aix_struct_return
= (DEFAULT_ABI
!= ABI_V4
|| DRAFT_V4_STRUCT_RET
);
1534 if (TARGET_LONG_DOUBLE_128
&& !TARGET_IEEEQUAD
)
1535 REAL_MODE_FORMAT (TFmode
) = &ibm_extended_format
;
1538 ASM_GENERATE_INTERNAL_LABEL (toc_label_name
, "LCTOC", 1);
1540 /* We can only guarantee the availability of DI pseudo-ops when
1541 assembling for 64-bit targets. */
1544 targetm
.asm_out
.aligned_op
.di
= NULL
;
1545 targetm
.asm_out
.unaligned_op
.di
= NULL
;
1548 /* Set branch target alignment, if not optimizing for size. */
1551 /* Cell wants to be aligned 8byte for dual issue. */
1552 if (rs6000_cpu
== PROCESSOR_CELL
)
1554 if (align_functions
<= 0)
1555 align_functions
= 8;
1556 if (align_jumps
<= 0)
1558 if (align_loops
<= 0)
1561 if (rs6000_align_branch_targets
)
1563 if (align_functions
<= 0)
1564 align_functions
= 16;
1565 if (align_jumps
<= 0)
1567 if (align_loops
<= 0)
1570 if (align_jumps_max_skip
<= 0)
1571 align_jumps_max_skip
= 15;
1572 if (align_loops_max_skip
<= 0)
1573 align_loops_max_skip
= 15;
1576 /* Arrange to save and restore machine status around nested functions. */
1577 init_machine_status
= rs6000_init_machine_status
;
1579 /* We should always be splitting complex arguments, but we can't break
1580 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
1581 if (DEFAULT_ABI
!= ABI_AIX
)
1582 targetm
.calls
.split_complex_arg
= NULL
;
1584 /* Initialize rs6000_cost with the appropriate target costs. */
1586 rs6000_cost
= TARGET_POWERPC64
? &size64_cost
: &size32_cost
;
1590 case PROCESSOR_RIOS1
:
1591 rs6000_cost
= &rios1_cost
;
1594 case PROCESSOR_RIOS2
:
1595 rs6000_cost
= &rios2_cost
;
1598 case PROCESSOR_RS64A
:
1599 rs6000_cost
= &rs64a_cost
;
1602 case PROCESSOR_MPCCORE
:
1603 rs6000_cost
= &mpccore_cost
;
1606 case PROCESSOR_PPC403
:
1607 rs6000_cost
= &ppc403_cost
;
1610 case PROCESSOR_PPC405
:
1611 rs6000_cost
= &ppc405_cost
;
1614 case PROCESSOR_PPC440
:
1615 rs6000_cost
= &ppc440_cost
;
1618 case PROCESSOR_PPC601
:
1619 rs6000_cost
= &ppc601_cost
;
1622 case PROCESSOR_PPC603
:
1623 rs6000_cost
= &ppc603_cost
;
1626 case PROCESSOR_PPC604
:
1627 rs6000_cost
= &ppc604_cost
;
1630 case PROCESSOR_PPC604e
:
1631 rs6000_cost
= &ppc604e_cost
;
1634 case PROCESSOR_PPC620
:
1635 rs6000_cost
= &ppc620_cost
;
1638 case PROCESSOR_PPC630
:
1639 rs6000_cost
= &ppc630_cost
;
1642 case PROCESSOR_CELL
:
1643 rs6000_cost
= &ppccell_cost
;
1646 case PROCESSOR_PPC750
:
1647 case PROCESSOR_PPC7400
:
1648 rs6000_cost
= &ppc750_cost
;
1651 case PROCESSOR_PPC7450
:
1652 rs6000_cost
= &ppc7450_cost
;
1655 case PROCESSOR_PPC8540
:
1656 rs6000_cost
= &ppc8540_cost
;
1659 case PROCESSOR_POWER4
:
1660 case PROCESSOR_POWER5
:
1661 rs6000_cost
= &power4_cost
;
1664 case PROCESSOR_POWER6
:
1665 rs6000_cost
= &power6_cost
;
1673 /* Implement targetm.vectorize.builtin_mask_for_load. */
1675 rs6000_builtin_mask_for_load (void)
1678 return altivec_builtin_mask_for_load
;
1683 /* Implement targetm.vectorize.builtin_conversion. */
1685 rs6000_builtin_conversion (enum tree_code code
, tree type
)
1687 if (!TARGET_ALTIVEC
)
1693 switch (TYPE_MODE (type
))
1696 return TYPE_UNSIGNED (type
) ?
1697 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFUX
] :
1698 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VCFSX
];
1707 /* Implement targetm.vectorize.builtin_mul_widen_even. */
1709 rs6000_builtin_mul_widen_even (tree type
)
1711 if (!TARGET_ALTIVEC
)
1714 switch (TYPE_MODE (type
))
1717 return TYPE_UNSIGNED (type
) ?
1718 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUH
] :
1719 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESH
];
1722 return TYPE_UNSIGNED (type
) ?
1723 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULEUB
] :
1724 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULESB
];
1730 /* Implement targetm.vectorize.builtin_mul_widen_odd. */
1732 rs6000_builtin_mul_widen_odd (tree type
)
1734 if (!TARGET_ALTIVEC
)
1737 switch (TYPE_MODE (type
))
1740 return TYPE_UNSIGNED (type
) ?
1741 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUH
] :
1742 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSH
];
1745 return TYPE_UNSIGNED (type
) ?
1746 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOUB
] :
1747 rs6000_builtin_decls
[ALTIVEC_BUILTIN_VMULOSB
];
1753 /* Handle generic options of the form -mfoo=yes/no.
1754 NAME is the option name.
1755 VALUE is the option value.
1756 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1757 whether the option value is 'yes' or 'no' respectively. */
1759 rs6000_parse_yes_no_option (const char *name
, const char *value
, int *flag
)
1763 else if (!strcmp (value
, "yes"))
1765 else if (!strcmp (value
, "no"))
1768 error ("unknown -m%s= option specified: '%s'", name
, value
);
1771 /* Validate and record the size specified with the -mtls-size option. */
1774 rs6000_parse_tls_size_option (void)
1776 if (rs6000_tls_size_string
== 0)
1778 else if (strcmp (rs6000_tls_size_string
, "16") == 0)
1779 rs6000_tls_size
= 16;
1780 else if (strcmp (rs6000_tls_size_string
, "32") == 0)
1781 rs6000_tls_size
= 32;
1782 else if (strcmp (rs6000_tls_size_string
, "64") == 0)
1783 rs6000_tls_size
= 64;
1785 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string
);
1789 optimization_options (int level ATTRIBUTE_UNUSED
, int size ATTRIBUTE_UNUSED
)
1791 if (DEFAULT_ABI
== ABI_DARWIN
)
1792 /* The Darwin libraries never set errno, so we might as well
1793 avoid calling them when that's the only reason we would. */
1794 flag_errno_math
= 0;
1796 /* Double growth factor to counter reduced min jump length. */
1797 set_param_value ("max-grow-copy-bb-insns", 16);
1799 /* Enable section anchors by default.
1800 Skip section anchors for Objective C and Objective C++
1801 until front-ends fixed. */
1802 if (!TARGET_MACHO
&& lang_hooks
.name
[4] != 'O')
1803 flag_section_anchors
= 1;
1806 /* Implement TARGET_HANDLE_OPTION. */
1809 rs6000_handle_option (size_t code
, const char *arg
, int value
)
1814 target_flags
&= ~(MASK_POWER
| MASK_POWER2
1815 | MASK_MULTIPLE
| MASK_STRING
);
1816 target_flags_explicit
|= (MASK_POWER
| MASK_POWER2
1817 | MASK_MULTIPLE
| MASK_STRING
);
1819 case OPT_mno_powerpc
:
1820 target_flags
&= ~(MASK_POWERPC
| MASK_PPC_GPOPT
1821 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1822 target_flags_explicit
|= (MASK_POWERPC
| MASK_PPC_GPOPT
1823 | MASK_PPC_GFXOPT
| MASK_POWERPC64
);
1826 target_flags
&= ~MASK_MINIMAL_TOC
;
1827 TARGET_NO_FP_IN_TOC
= 0;
1828 TARGET_NO_SUM_IN_TOC
= 0;
1829 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1830 #ifdef TARGET_USES_SYSV4_OPT
1831 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1832 just the same as -mminimal-toc. */
1833 target_flags
|= MASK_MINIMAL_TOC
;
1834 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1838 #ifdef TARGET_USES_SYSV4_OPT
1840 /* Make -mtoc behave like -mminimal-toc. */
1841 target_flags
|= MASK_MINIMAL_TOC
;
1842 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1846 #ifdef TARGET_USES_AIX64_OPT
1851 target_flags
|= MASK_POWERPC64
| MASK_POWERPC
;
1852 target_flags
|= ~target_flags_explicit
& MASK_PPC_GFXOPT
;
1853 target_flags_explicit
|= MASK_POWERPC64
| MASK_POWERPC
;
1856 #ifdef TARGET_USES_AIX64_OPT
1861 target_flags
&= ~MASK_POWERPC64
;
1862 target_flags_explicit
|= MASK_POWERPC64
;
1865 case OPT_minsert_sched_nops_
:
1866 rs6000_sched_insert_nops_str
= arg
;
1869 case OPT_mminimal_toc
:
1872 TARGET_NO_FP_IN_TOC
= 0;
1873 TARGET_NO_SUM_IN_TOC
= 0;
1880 target_flags
|= (MASK_MULTIPLE
| MASK_STRING
);
1881 target_flags_explicit
|= (MASK_MULTIPLE
| MASK_STRING
);
1888 target_flags
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1889 target_flags_explicit
|= (MASK_POWER
| MASK_MULTIPLE
| MASK_STRING
);
1893 case OPT_mpowerpc_gpopt
:
1894 case OPT_mpowerpc_gfxopt
:
1897 target_flags
|= MASK_POWERPC
;
1898 target_flags_explicit
|= MASK_POWERPC
;
1902 case OPT_maix_struct_return
:
1903 case OPT_msvr4_struct_return
:
1904 rs6000_explicit_options
.aix_struct_ret
= true;
1908 rs6000_parse_yes_no_option ("vrsave", arg
, &(TARGET_ALTIVEC_VRSAVE
));
1912 rs6000_explicit_options
.isel
= true;
1913 rs6000_parse_yes_no_option ("isel", arg
, &(rs6000_isel
));
1917 rs6000_explicit_options
.spe
= true;
1918 rs6000_parse_yes_no_option ("spe", arg
, &(rs6000_spe
));
1922 rs6000_debug_name
= arg
;
1925 #ifdef TARGET_USES_SYSV4_OPT
1927 rs6000_abi_name
= arg
;
1931 rs6000_sdata_name
= arg
;
1934 case OPT_mtls_size_
:
1935 rs6000_tls_size_string
= arg
;
1938 case OPT_mrelocatable
:
1941 target_flags
|= MASK_MINIMAL_TOC
;
1942 target_flags_explicit
|= MASK_MINIMAL_TOC
;
1943 TARGET_NO_FP_IN_TOC
= 1;
1947 case OPT_mrelocatable_lib
:
1950 target_flags
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
1951 target_flags_explicit
|= MASK_RELOCATABLE
| MASK_MINIMAL_TOC
;
1952 TARGET_NO_FP_IN_TOC
= 1;
1956 target_flags
&= ~MASK_RELOCATABLE
;
1957 target_flags_explicit
|= MASK_RELOCATABLE
;
1963 if (!strcmp (arg
, "altivec"))
1965 rs6000_explicit_options
.abi
= true;
1966 rs6000_altivec_abi
= 1;
1969 else if (! strcmp (arg
, "no-altivec"))
1971 /* ??? Don't set rs6000_explicit_options.abi here, to allow
1972 the default for rs6000_spe_abi to be chosen later. */
1973 rs6000_altivec_abi
= 0;
1975 else if (! strcmp (arg
, "spe"))
1977 rs6000_explicit_options
.abi
= true;
1979 rs6000_altivec_abi
= 0;
1980 if (!TARGET_SPE_ABI
)
1981 error ("not configured for ABI: '%s'", arg
);
1983 else if (! strcmp (arg
, "no-spe"))
1985 rs6000_explicit_options
.abi
= true;
1989 /* These are here for testing during development only, do not
1990 document in the manual please. */
1991 else if (! strcmp (arg
, "d64"))
1993 rs6000_darwin64_abi
= 1;
1994 warning (0, "Using darwin64 ABI");
1996 else if (! strcmp (arg
, "d32"))
1998 rs6000_darwin64_abi
= 0;
1999 warning (0, "Using old darwin ABI");
2002 else if (! strcmp (arg
, "ibmlongdouble"))
2004 rs6000_explicit_options
.ieee
= true;
2005 rs6000_ieeequad
= 0;
2006 warning (0, "Using IBM extended precision long double");
2008 else if (! strcmp (arg
, "ieeelongdouble"))
2010 rs6000_explicit_options
.ieee
= true;
2011 rs6000_ieeequad
= 1;
2012 warning (0, "Using IEEE extended precision long double");
2017 error ("unknown ABI specified: '%s'", arg
);
2023 rs6000_select
[1].string
= arg
;
2027 rs6000_select
[2].string
= arg
;
2030 case OPT_mtraceback_
:
2031 rs6000_traceback_name
= arg
;
2034 case OPT_mfloat_gprs_
:
2035 rs6000_explicit_options
.float_gprs
= true;
2036 if (! strcmp (arg
, "yes") || ! strcmp (arg
, "single"))
2037 rs6000_float_gprs
= 1;
2038 else if (! strcmp (arg
, "double"))
2039 rs6000_float_gprs
= 2;
2040 else if (! strcmp (arg
, "no"))
2041 rs6000_float_gprs
= 0;
2044 error ("invalid option for -mfloat-gprs: '%s'", arg
);
2049 case OPT_mlong_double_
:
2050 rs6000_explicit_options
.long_double
= true;
2051 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2052 if (value
!= 64 && value
!= 128)
2054 error ("Unknown switch -mlong-double-%s", arg
);
2055 rs6000_long_double_type_size
= RS6000_DEFAULT_LONG_DOUBLE_SIZE
;
2059 rs6000_long_double_type_size
= value
;
2062 case OPT_msched_costly_dep_
:
2063 rs6000_sched_costly_dep_str
= arg
;
2067 rs6000_explicit_options
.alignment
= true;
2068 if (! strcmp (arg
, "power"))
2070 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2071 some C library functions, so warn about it. The flag may be
2072 useful for performance studies from time to time though, so
2073 don't disable it entirely. */
2074 if (DEFAULT_ABI
== ABI_DARWIN
&& TARGET_64BIT
)
2075 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2076 " it is incompatible with the installed C and C++ libraries");
2077 rs6000_alignment_flags
= MASK_ALIGN_POWER
;
2079 else if (! strcmp (arg
, "natural"))
2080 rs6000_alignment_flags
= MASK_ALIGN_NATURAL
;
2083 error ("unknown -malign-XXXXX option specified: '%s'", arg
);
2091 /* Do anything needed at the start of the asm file. */
2094 rs6000_file_start (void)
2098 const char *start
= buffer
;
2099 struct rs6000_cpu_select
*ptr
;
2100 const char *default_cpu
= TARGET_CPU_DEFAULT
;
2101 FILE *file
= asm_out_file
;
2103 default_file_start ();
2105 #ifdef TARGET_BI_ARCH
2106 if ((TARGET_DEFAULT
^ target_flags
) & MASK_64BIT
)
2110 if (flag_verbose_asm
)
2112 sprintf (buffer
, "\n%s rs6000/powerpc options:", ASM_COMMENT_START
);
2113 rs6000_select
[0].string
= default_cpu
;
2115 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
2117 ptr
= &rs6000_select
[i
];
2118 if (ptr
->string
!= (char *)0 && ptr
->string
[0] != '\0')
2120 fprintf (file
, "%s %s%s", start
, ptr
->name
, ptr
->string
);
2125 if (PPC405_ERRATUM77
)
2127 fprintf (file
, "%s PPC405CR_ERRATUM77", start
);
2131 #ifdef USING_ELFOS_H
2132 switch (rs6000_sdata
)
2134 case SDATA_NONE
: fprintf (file
, "%s -msdata=none", start
); start
= ""; break;
2135 case SDATA_DATA
: fprintf (file
, "%s -msdata=data", start
); start
= ""; break;
2136 case SDATA_SYSV
: fprintf (file
, "%s -msdata=sysv", start
); start
= ""; break;
2137 case SDATA_EABI
: fprintf (file
, "%s -msdata=eabi", start
); start
= ""; break;
2140 if (rs6000_sdata
&& g_switch_value
)
2142 fprintf (file
, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED
, start
,
2152 if (DEFAULT_ABI
== ABI_AIX
|| (TARGET_ELF
&& flag_pic
== 2))
2154 switch_to_section (toc_section
);
2155 switch_to_section (text_section
);
2160 /* Return nonzero if this function is known to have a null epilogue. */
2163 direct_return (void)
2165 if (reload_completed
)
2167 rs6000_stack_t
*info
= rs6000_stack_info ();
2169 if (info
->first_gp_reg_save
== 32
2170 && info
->first_fp_reg_save
== 64
2171 && info
->first_altivec_reg_save
== LAST_ALTIVEC_REGNO
+ 1
2172 && ! info
->lr_save_p
2173 && ! info
->cr_save_p
2174 && info
->vrsave_mask
== 0
2182 /* Return the number of instructions it takes to form a constant in an
2183 integer register. */
2186 num_insns_constant_wide (HOST_WIDE_INT value
)
2188 /* signed constant loadable with {cal|addi} */
2189 if ((unsigned HOST_WIDE_INT
) (value
+ 0x8000) < 0x10000)
2192 /* constant loadable with {cau|addis} */
2193 else if ((value
& 0xffff) == 0
2194 && (value
>> 31 == -1 || value
>> 31 == 0))
2197 #if HOST_BITS_PER_WIDE_INT == 64
2198 else if (TARGET_POWERPC64
)
2200 HOST_WIDE_INT low
= ((value
& 0xffffffff) ^ 0x80000000) - 0x80000000;
2201 HOST_WIDE_INT high
= value
>> 31;
2203 if (high
== 0 || high
== -1)
2209 return num_insns_constant_wide (high
) + 1;
2211 return (num_insns_constant_wide (high
)
2212 + num_insns_constant_wide (low
) + 1);
2221 num_insns_constant (rtx op
, enum machine_mode mode
)
2223 HOST_WIDE_INT low
, high
;
2225 switch (GET_CODE (op
))
2228 #if HOST_BITS_PER_WIDE_INT == 64
2229 if ((INTVAL (op
) >> 31) != 0 && (INTVAL (op
) >> 31) != -1
2230 && mask64_operand (op
, mode
))
2234 return num_insns_constant_wide (INTVAL (op
));
2242 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2243 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
2244 return num_insns_constant_wide ((HOST_WIDE_INT
) l
);
2247 if (mode
== VOIDmode
|| mode
== DImode
)
2249 high
= CONST_DOUBLE_HIGH (op
);
2250 low
= CONST_DOUBLE_LOW (op
);
2257 REAL_VALUE_FROM_CONST_DOUBLE (rv
, op
);
2258 REAL_VALUE_TO_TARGET_DOUBLE (rv
, l
);
2259 high
= l
[WORDS_BIG_ENDIAN
== 0];
2260 low
= l
[WORDS_BIG_ENDIAN
!= 0];
2264 return (num_insns_constant_wide (low
)
2265 + num_insns_constant_wide (high
));
2268 if ((high
== 0 && low
>= 0)
2269 || (high
== -1 && low
< 0))
2270 return num_insns_constant_wide (low
);
2272 else if (mask64_operand (op
, mode
))
2276 return num_insns_constant_wide (high
) + 1;
2279 return (num_insns_constant_wide (high
)
2280 + num_insns_constant_wide (low
) + 1);
2288 /* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2289 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2290 corresponding element of the vector, but for V4SFmode and V2SFmode,
2291 the corresponding "float" is interpreted as an SImode integer. */
2293 static HOST_WIDE_INT
2294 const_vector_elt_as_int (rtx op
, unsigned int elt
)
2296 rtx tmp
= CONST_VECTOR_ELT (op
, elt
);
2297 if (GET_MODE (op
) == V4SFmode
2298 || GET_MODE (op
) == V2SFmode
)
2299 tmp
= gen_lowpart (SImode
, tmp
);
2300 return INTVAL (tmp
);
2303 /* Return true if OP can be synthesized with a particular vspltisb, vspltish
2304 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2305 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2306 all items are set to the same value and contain COPIES replicas of the
2307 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2308 operand and the others are set to the value of the operand's msb. */
2311 vspltis_constant (rtx op
, unsigned step
, unsigned copies
)
2313 enum machine_mode mode
= GET_MODE (op
);
2314 enum machine_mode inner
= GET_MODE_INNER (mode
);
2317 unsigned nunits
= GET_MODE_NUNITS (mode
);
2318 unsigned bitsize
= GET_MODE_BITSIZE (inner
);
2319 unsigned mask
= GET_MODE_MASK (inner
);
2321 HOST_WIDE_INT val
= const_vector_elt_as_int (op
, nunits
- 1);
2322 HOST_WIDE_INT splat_val
= val
;
2323 HOST_WIDE_INT msb_val
= val
> 0 ? 0 : -1;
2325 /* Construct the value to be splatted, if possible. If not, return 0. */
2326 for (i
= 2; i
<= copies
; i
*= 2)
2328 HOST_WIDE_INT small_val
;
2330 small_val
= splat_val
>> bitsize
;
2332 if (splat_val
!= ((small_val
<< bitsize
) | (small_val
& mask
)))
2334 splat_val
= small_val
;
2337 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2338 if (EASY_VECTOR_15 (splat_val
))
2341 /* Also check if we can splat, and then add the result to itself. Do so if
2342 the value is positive, of if the splat instruction is using OP's mode;
2343 for splat_val < 0, the splat and the add should use the same mode. */
2344 else if (EASY_VECTOR_15_ADD_SELF (splat_val
)
2345 && (splat_val
>= 0 || (step
== 1 && copies
== 1)))
2351 /* Check if VAL is present in every STEP-th element, and the
2352 other elements are filled with its most significant bit. */
2353 for (i
= 0; i
< nunits
- 1; ++i
)
2355 HOST_WIDE_INT desired_val
;
2356 if (((i
+ 1) & (step
- 1)) == 0)
2359 desired_val
= msb_val
;
2361 if (desired_val
!= const_vector_elt_as_int (op
, i
))
2369 /* Return true if OP is of the given MODE and can be synthesized
2370 with a vspltisb, vspltish or vspltisw. */
2373 easy_altivec_constant (rtx op
, enum machine_mode mode
)
2375 unsigned step
, copies
;
2377 if (mode
== VOIDmode
)
2378 mode
= GET_MODE (op
);
2379 else if (mode
!= GET_MODE (op
))
2382 /* Start with a vspltisw. */
2383 step
= GET_MODE_NUNITS (mode
) / 4;
2386 if (vspltis_constant (op
, step
, copies
))
2389 /* Then try with a vspltish. */
2395 if (vspltis_constant (op
, step
, copies
))
2398 /* And finally a vspltisb. */
2404 if (vspltis_constant (op
, step
, copies
))
2410 /* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2411 result is OP. Abort if it is not possible. */
2414 gen_easy_altivec_constant (rtx op
)
2416 enum machine_mode mode
= GET_MODE (op
);
2417 int nunits
= GET_MODE_NUNITS (mode
);
2418 rtx last
= CONST_VECTOR_ELT (op
, nunits
- 1);
2419 unsigned step
= nunits
/ 4;
2420 unsigned copies
= 1;
2422 /* Start with a vspltisw. */
2423 if (vspltis_constant (op
, step
, copies
))
2424 return gen_rtx_VEC_DUPLICATE (V4SImode
, gen_lowpart (SImode
, last
));
2426 /* Then try with a vspltish. */
2432 if (vspltis_constant (op
, step
, copies
))
2433 return gen_rtx_VEC_DUPLICATE (V8HImode
, gen_lowpart (HImode
, last
));
2435 /* And finally a vspltisb. */
2441 if (vspltis_constant (op
, step
, copies
))
2442 return gen_rtx_VEC_DUPLICATE (V16QImode
, gen_lowpart (QImode
, last
));
2448 output_vec_const_move (rtx
*operands
)
2451 enum machine_mode mode
;
2456 mode
= GET_MODE (dest
);
2461 if (zero_constant (vec
, mode
))
2462 return "vxor %0,%0,%0";
2464 splat_vec
= gen_easy_altivec_constant (vec
);
2465 gcc_assert (GET_CODE (splat_vec
) == VEC_DUPLICATE
);
2466 operands
[1] = XEXP (splat_vec
, 0);
2467 if (!EASY_VECTOR_15 (INTVAL (operands
[1])))
2470 switch (GET_MODE (splat_vec
))
2473 return "vspltisw %0,%1";
2476 return "vspltish %0,%1";
2479 return "vspltisb %0,%1";
2486 gcc_assert (TARGET_SPE
);
2488 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2489 pattern of V1DI, V4HI, and V2SF.
2491 FIXME: We should probably return # and add post reload
2492 splitters for these, but this way is so easy ;-). */
2493 cst
= INTVAL (CONST_VECTOR_ELT (vec
, 0));
2494 cst2
= INTVAL (CONST_VECTOR_ELT (vec
, 1));
2495 operands
[1] = CONST_VECTOR_ELT (vec
, 0);
2496 operands
[2] = CONST_VECTOR_ELT (vec
, 1);
2498 return "li %0,%1\n\tevmergelo %0,%0,%0";
2500 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
2503 /* Initialize vector TARGET to VALS. */
2506 rs6000_expand_vector_init (rtx target
, rtx vals
)
2508 enum machine_mode mode
= GET_MODE (target
);
2509 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2510 int n_elts
= GET_MODE_NUNITS (mode
);
2511 int n_var
= 0, one_var
= -1;
2512 bool all_same
= true, all_const_zero
= true;
2516 for (i
= 0; i
< n_elts
; ++i
)
2518 x
= XVECEXP (vals
, 0, i
);
2519 if (!CONSTANT_P (x
))
2520 ++n_var
, one_var
= i
;
2521 else if (x
!= CONST0_RTX (inner_mode
))
2522 all_const_zero
= false;
2524 if (i
> 0 && !rtx_equal_p (x
, XVECEXP (vals
, 0, 0)))
2530 if (mode
!= V4SFmode
&& all_const_zero
)
2532 /* Zero register. */
2533 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2534 gen_rtx_XOR (mode
, target
, target
)));
2537 else if (mode
!= V4SFmode
&& easy_vector_constant (vals
, mode
))
2539 /* Splat immediate. */
2540 emit_insn (gen_rtx_SET (VOIDmode
, target
, vals
));
2544 ; /* Splat vector element. */
2547 /* Load from constant pool. */
2548 emit_move_insn (target
, gen_rtx_CONST_VECTOR (mode
, XVEC (vals
, 0)));
2553 /* Store value to stack temp. Load vector element. Splat. */
2556 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2557 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0),
2558 XVECEXP (vals
, 0, 0));
2559 x
= gen_rtx_UNSPEC (VOIDmode
,
2560 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2561 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2563 gen_rtx_SET (VOIDmode
,
2566 x
= gen_rtx_VEC_SELECT (inner_mode
, target
,
2567 gen_rtx_PARALLEL (VOIDmode
,
2568 gen_rtvec (1, const0_rtx
)));
2569 emit_insn (gen_rtx_SET (VOIDmode
, target
,
2570 gen_rtx_VEC_DUPLICATE (mode
, x
)));
2574 /* One field is non-constant. Load constant then overwrite
2578 rtx copy
= copy_rtx (vals
);
2580 /* Load constant part of vector, substitute neighboring value for
2582 XVECEXP (copy
, 0, one_var
) = XVECEXP (vals
, 0, (one_var
+ 1) % n_elts
);
2583 rs6000_expand_vector_init (target
, copy
);
2585 /* Insert variable. */
2586 rs6000_expand_vector_set (target
, XVECEXP (vals
, 0, one_var
), one_var
);
2590 /* Construct the vector in memory one field at a time
2591 and load the whole vector. */
2592 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2593 for (i
= 0; i
< n_elts
; i
++)
2594 emit_move_insn (adjust_address_nv (mem
, inner_mode
,
2595 i
* GET_MODE_SIZE (inner_mode
)),
2596 XVECEXP (vals
, 0, i
));
2597 emit_move_insn (target
, mem
);
2600 /* Set field ELT of TARGET to VAL. */
2603 rs6000_expand_vector_set (rtx target
, rtx val
, int elt
)
2605 enum machine_mode mode
= GET_MODE (target
);
2606 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2607 rtx reg
= gen_reg_rtx (mode
);
2609 int width
= GET_MODE_SIZE (inner_mode
);
2612 /* Load single variable value. */
2613 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (inner_mode
), 0);
2614 emit_move_insn (adjust_address_nv (mem
, inner_mode
, 0), val
);
2615 x
= gen_rtx_UNSPEC (VOIDmode
,
2616 gen_rtvec (1, const0_rtx
), UNSPEC_LVE
);
2617 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2619 gen_rtx_SET (VOIDmode
,
2623 /* Linear sequence. */
2624 mask
= gen_rtx_PARALLEL (V16QImode
, rtvec_alloc (16));
2625 for (i
= 0; i
< 16; ++i
)
2626 XVECEXP (mask
, 0, i
) = GEN_INT (i
);
2628 /* Set permute mask to insert element into target. */
2629 for (i
= 0; i
< width
; ++i
)
2630 XVECEXP (mask
, 0, elt
*width
+ i
)
2631 = GEN_INT (i
+ 0x10);
2632 x
= gen_rtx_CONST_VECTOR (V16QImode
, XVEC (mask
, 0));
2633 x
= gen_rtx_UNSPEC (mode
,
2634 gen_rtvec (3, target
, reg
,
2635 force_reg (V16QImode
, x
)),
2637 emit_insn (gen_rtx_SET (VOIDmode
, target
, x
));
2640 /* Extract field ELT from VEC into TARGET. */
2643 rs6000_expand_vector_extract (rtx target
, rtx vec
, int elt
)
2645 enum machine_mode mode
= GET_MODE (vec
);
2646 enum machine_mode inner_mode
= GET_MODE_INNER (mode
);
2649 /* Allocate mode-sized buffer. */
2650 mem
= assign_stack_temp (mode
, GET_MODE_SIZE (mode
), 0);
2652 /* Add offset to field within buffer matching vector element. */
2653 mem
= adjust_address_nv (mem
, mode
, elt
* GET_MODE_SIZE (inner_mode
));
2655 /* Store single field into mode-sized buffer. */
2656 x
= gen_rtx_UNSPEC (VOIDmode
,
2657 gen_rtvec (1, const0_rtx
), UNSPEC_STVE
);
2658 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
2660 gen_rtx_SET (VOIDmode
,
2663 emit_move_insn (target
, adjust_address_nv (mem
, inner_mode
, 0));
2666 /* Generates shifts and masks for a pair of rldicl or rldicr insns to
2667 implement ANDing by the mask IN. */
2669 build_mask64_2_operands (rtx in
, rtx
*out
)
2671 #if HOST_BITS_PER_WIDE_INT >= 64
2672 unsigned HOST_WIDE_INT c
, lsb
, m1
, m2
;
2675 gcc_assert (GET_CODE (in
) == CONST_INT
);
2680 /* Assume c initially something like 0x00fff000000fffff. The idea
2681 is to rotate the word so that the middle ^^^^^^ group of zeros
2682 is at the MS end and can be cleared with an rldicl mask. We then
2683 rotate back and clear off the MS ^^ group of zeros with a
2685 c
= ~c
; /* c == 0xff000ffffff00000 */
2686 lsb
= c
& -c
; /* lsb == 0x0000000000100000 */
2687 m1
= -lsb
; /* m1 == 0xfffffffffff00000 */
2688 c
= ~c
; /* c == 0x00fff000000fffff */
2689 c
&= -lsb
; /* c == 0x00fff00000000000 */
2690 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2691 c
= ~c
; /* c == 0xff000fffffffffff */
2692 c
&= -lsb
; /* c == 0xff00000000000000 */
2694 while ((lsb
>>= 1) != 0)
2695 shift
++; /* shift == 44 on exit from loop */
2696 m1
<<= 64 - shift
; /* m1 == 0xffffff0000000000 */
2697 m1
= ~m1
; /* m1 == 0x000000ffffffffff */
2698 m2
= ~c
; /* m2 == 0x00ffffffffffffff */
2702 /* Assume c initially something like 0xff000f0000000000. The idea
2703 is to rotate the word so that the ^^^ middle group of zeros
2704 is at the LS end and can be cleared with an rldicr mask. We then
2705 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2707 lsb
= c
& -c
; /* lsb == 0x0000010000000000 */
2708 m2
= -lsb
; /* m2 == 0xffffff0000000000 */
2709 c
= ~c
; /* c == 0x00fff0ffffffffff */
2710 c
&= -lsb
; /* c == 0x00fff00000000000 */
2711 lsb
= c
& -c
; /* lsb == 0x0000100000000000 */
2712 c
= ~c
; /* c == 0xff000fffffffffff */
2713 c
&= -lsb
; /* c == 0xff00000000000000 */
2715 while ((lsb
>>= 1) != 0)
2716 shift
++; /* shift == 44 on exit from loop */
2717 m1
= ~c
; /* m1 == 0x00ffffffffffffff */
2718 m1
>>= shift
; /* m1 == 0x0000000000000fff */
2719 m1
= ~m1
; /* m1 == 0xfffffffffffff000 */
2722 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2723 masks will be all 1's. We are guaranteed more than one transition. */
2724 out
[0] = GEN_INT (64 - shift
);
2725 out
[1] = GEN_INT (m1
);
2726 out
[2] = GEN_INT (shift
);
2727 out
[3] = GEN_INT (m2
);
2735 /* Return TRUE if OP is an invalid SUBREG operation on the e500. */
2738 invalid_e500_subreg (rtx op
, enum machine_mode mode
)
2740 if (TARGET_E500_DOUBLE
)
2742 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
2743 subreg:TI and reg:TF. */
2744 if (GET_CODE (op
) == SUBREG
2745 && (mode
== SImode
|| mode
== DImode
|| mode
== TImode
)
2746 && REG_P (SUBREG_REG (op
))
2747 && (GET_MODE (SUBREG_REG (op
)) == DFmode
2748 || GET_MODE (SUBREG_REG (op
)) == TFmode
))
2751 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
2753 if (GET_CODE (op
) == SUBREG
2754 && (mode
== DFmode
|| mode
== TFmode
)
2755 && REG_P (SUBREG_REG (op
))
2756 && (GET_MODE (SUBREG_REG (op
)) == DImode
2757 || GET_MODE (SUBREG_REG (op
)) == TImode
))
2762 && GET_CODE (op
) == SUBREG
2764 && REG_P (SUBREG_REG (op
))
2765 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op
))))
2771 /* AIX increases natural record alignment to doubleword if the first
2772 field is an FP double while the FP fields remain word aligned. */
2775 rs6000_special_round_type_align (tree type
, unsigned int computed
,
2776 unsigned int specified
)
2778 unsigned int align
= MAX (computed
, specified
);
2779 tree field
= TYPE_FIELDS (type
);
2781 /* Skip all non field decls */
2782 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
2783 field
= TREE_CHAIN (field
);
2785 if (field
!= NULL
&& field
!= type
)
2787 type
= TREE_TYPE (field
);
2788 while (TREE_CODE (type
) == ARRAY_TYPE
)
2789 type
= TREE_TYPE (type
);
2791 if (type
!= error_mark_node
&& TYPE_MODE (type
) == DFmode
)
2792 align
= MAX (align
, 64);
2798 /* Darwin increases record alignment to the natural alignment of
2802 darwin_rs6000_special_round_type_align (tree type
, unsigned int computed
,
2803 unsigned int specified
)
2805 unsigned int align
= MAX (computed
, specified
);
2807 if (TYPE_PACKED (type
))
2810 /* Find the first field, looking down into aggregates. */
2812 tree field
= TYPE_FIELDS (type
);
2813 /* Skip all non field decls */
2814 while (field
!= NULL
&& TREE_CODE (field
) != FIELD_DECL
)
2815 field
= TREE_CHAIN (field
);
2818 type
= TREE_TYPE (field
);
2819 while (TREE_CODE (type
) == ARRAY_TYPE
)
2820 type
= TREE_TYPE (type
);
2821 } while (AGGREGATE_TYPE_P (type
));
2823 if (! AGGREGATE_TYPE_P (type
) && type
!= error_mark_node
)
2824 align
= MAX (align
, TYPE_ALIGN (type
));
2829 /* Return 1 for an operand in small memory on V.4/eabi. */
2832 small_data_operand (rtx op ATTRIBUTE_UNUSED
,
2833 enum machine_mode mode ATTRIBUTE_UNUSED
)
2838 if (rs6000_sdata
== SDATA_NONE
|| rs6000_sdata
== SDATA_DATA
)
2841 if (DEFAULT_ABI
!= ABI_V4
)
2844 if (GET_CODE (op
) == SYMBOL_REF
)
2847 else if (GET_CODE (op
) != CONST
2848 || GET_CODE (XEXP (op
, 0)) != PLUS
2849 || GET_CODE (XEXP (XEXP (op
, 0), 0)) != SYMBOL_REF
2850 || GET_CODE (XEXP (XEXP (op
, 0), 1)) != CONST_INT
)
2855 rtx sum
= XEXP (op
, 0);
2856 HOST_WIDE_INT summand
;
2858 /* We have to be careful here, because it is the referenced address
2859 that must be 32k from _SDA_BASE_, not just the symbol. */
2860 summand
= INTVAL (XEXP (sum
, 1));
2861 if (summand
< 0 || (unsigned HOST_WIDE_INT
) summand
> g_switch_value
)
2864 sym_ref
= XEXP (sum
, 0);
2867 return SYMBOL_REF_SMALL_P (sym_ref
);
2873 /* Return true if either operand is a general purpose register. */
2876 gpr_or_gpr_p (rtx op0
, rtx op1
)
2878 return ((REG_P (op0
) && INT_REGNO_P (REGNO (op0
)))
2879 || (REG_P (op1
) && INT_REGNO_P (REGNO (op1
))));
2883 /* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2886 constant_pool_expr_1 (rtx op
, int *have_sym
, int *have_toc
)
2888 switch (GET_CODE (op
))
2891 if (RS6000_SYMBOL_REF_TLS_P (op
))
2893 else if (CONSTANT_POOL_ADDRESS_P (op
))
2895 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op
), Pmode
))
2903 else if (! strcmp (XSTR (op
, 0), toc_label_name
))
2912 return (constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
)
2913 && constant_pool_expr_1 (XEXP (op
, 1), have_sym
, have_toc
));
2915 return constant_pool_expr_1 (XEXP (op
, 0), have_sym
, have_toc
);
2924 constant_pool_expr_p (rtx op
)
2928 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_sym
;
2932 toc_relative_expr_p (rtx op
)
2936 return constant_pool_expr_1 (op
, &have_sym
, &have_toc
) && have_toc
;
2940 legitimate_constant_pool_address_p (rtx x
)
2943 && GET_CODE (x
) == PLUS
2944 && GET_CODE (XEXP (x
, 0)) == REG
2945 && (TARGET_MINIMAL_TOC
|| REGNO (XEXP (x
, 0)) == TOC_REGISTER
)
2946 && constant_pool_expr_p (XEXP (x
, 1)));
2950 legitimate_small_data_p (enum machine_mode mode
, rtx x
)
2952 return (DEFAULT_ABI
== ABI_V4
2953 && !flag_pic
&& !TARGET_TOC
2954 && (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
)
2955 && small_data_operand (x
, mode
));
2958 /* SPE offset addressing is limited to 5-bits worth of double words. */
2959 #define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2962 rs6000_legitimate_offset_address_p (enum machine_mode mode
, rtx x
, int strict
)
2964 unsigned HOST_WIDE_INT offset
, extra
;
2966 if (GET_CODE (x
) != PLUS
)
2968 if (GET_CODE (XEXP (x
, 0)) != REG
)
2970 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
2972 if (legitimate_constant_pool_address_p (x
))
2974 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
2977 offset
= INTVAL (XEXP (x
, 1));
2985 /* AltiVec vector modes. Only reg+reg addressing is valid and
2986 constant offset zero should not occur due to canonicalization.
2987 Allow any offset when not strict before reload. */
2994 /* SPE vector modes. */
2995 return SPE_CONST_OFFSET_OK (offset
);
2998 if (TARGET_E500_DOUBLE
)
2999 return SPE_CONST_OFFSET_OK (offset
);
3002 /* On e500v2, we may have:
3004 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3006 Which gets addressed with evldd instructions. */
3007 if (TARGET_E500_DOUBLE
)
3008 return SPE_CONST_OFFSET_OK (offset
);
3010 if (mode
== DFmode
|| !TARGET_POWERPC64
)
3012 else if (offset
& 3)
3017 if (TARGET_E500_DOUBLE
)
3018 return (SPE_CONST_OFFSET_OK (offset
)
3019 && SPE_CONST_OFFSET_OK (offset
+ 8));
3022 if (mode
== TFmode
|| !TARGET_POWERPC64
)
3024 else if (offset
& 3)
3035 return (offset
< 0x10000) && (offset
+ extra
< 0x10000);
3039 legitimate_indexed_address_p (rtx x
, int strict
)
3043 if (GET_CODE (x
) != PLUS
)
3049 /* Recognize the rtl generated by reload which we know will later be
3050 replaced with proper base and index regs. */
3052 && reload_in_progress
3053 && (REG_P (op0
) || GET_CODE (op0
) == PLUS
)
3057 return (REG_P (op0
) && REG_P (op1
)
3058 && ((INT_REG_OK_FOR_BASE_P (op0
, strict
)
3059 && INT_REG_OK_FOR_INDEX_P (op1
, strict
))
3060 || (INT_REG_OK_FOR_BASE_P (op1
, strict
)
3061 && INT_REG_OK_FOR_INDEX_P (op0
, strict
))));
3065 legitimate_indirect_address_p (rtx x
, int strict
)
3067 return GET_CODE (x
) == REG
&& INT_REG_OK_FOR_BASE_P (x
, strict
);
3071 macho_lo_sum_memory_operand (rtx x
, enum machine_mode mode
)
3073 if (!TARGET_MACHO
|| !flag_pic
3074 || mode
!= SImode
|| GET_CODE (x
) != MEM
)
3078 if (GET_CODE (x
) != LO_SUM
)
3080 if (GET_CODE (XEXP (x
, 0)) != REG
)
3082 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), 0))
3086 return CONSTANT_P (x
);
3090 legitimate_lo_sum_address_p (enum machine_mode mode
, rtx x
, int strict
)
3092 if (GET_CODE (x
) != LO_SUM
)
3094 if (GET_CODE (XEXP (x
, 0)) != REG
)
3096 if (!INT_REG_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
3098 /* Restrict addressing for DI because of our SUBREG hackery. */
3099 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3104 if (TARGET_ELF
|| TARGET_MACHO
)
3106 if (DEFAULT_ABI
!= ABI_AIX
&& DEFAULT_ABI
!= ABI_DARWIN
&& flag_pic
)
3110 if (GET_MODE_NUNITS (mode
) != 1)
3112 if (GET_MODE_BITSIZE (mode
) > 64
3113 || (GET_MODE_BITSIZE (mode
) > 32 && !TARGET_POWERPC64
3114 && !(TARGET_HARD_FLOAT
&& TARGET_FPRS
&& mode
== DFmode
)))
3117 return CONSTANT_P (x
);
3124 /* Try machine-dependent ways of modifying an illegitimate address
3125 to be legitimate. If we find one, return the new, valid address.
3126 This is used from only one place: `memory_address' in explow.c.
3128 OLDX is the address as it was before break_out_memory_refs was
3129 called. In some cases it is useful to look at this to decide what
3132 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
3134 It is always safe for this function to do nothing. It exists to
3135 recognize opportunities to optimize the output.
3137 On RS/6000, first check for the sum of a register with a constant
3138 integer that is out of range. If so, generate code to add the
3139 constant with the low-order 16 bits masked to the register and force
3140 this result into another register (this can be done with `cau').
3141 Then generate an address of REG+(CONST&0xffff), allowing for the
3142 possibility of bit 16 being a one.
3144 Then check for the sum of a register and something not constant, try to
3145 load the other things into a register and return the sum. */
3148 rs6000_legitimize_address (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
3149 enum machine_mode mode
)
3151 if (GET_CODE (x
) == SYMBOL_REF
)
3153 enum tls_model model
= SYMBOL_REF_TLS_MODEL (x
);
3155 return rs6000_legitimize_tls_address (x
, model
);
3158 if (GET_CODE (x
) == PLUS
3159 && GET_CODE (XEXP (x
, 0)) == REG
3160 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3161 && (unsigned HOST_WIDE_INT
) (INTVAL (XEXP (x
, 1)) + 0x8000) >= 0x10000)
3163 HOST_WIDE_INT high_int
, low_int
;
3165 low_int
= ((INTVAL (XEXP (x
, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3166 high_int
= INTVAL (XEXP (x
, 1)) - low_int
;
3167 sum
= force_operand (gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3168 GEN_INT (high_int
)), 0);
3169 return gen_rtx_PLUS (Pmode
, sum
, GEN_INT (low_int
));
3171 else if (GET_CODE (x
) == PLUS
3172 && GET_CODE (XEXP (x
, 0)) == REG
3173 && GET_CODE (XEXP (x
, 1)) != CONST_INT
3174 && GET_MODE_NUNITS (mode
) == 1
3175 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3177 || (((mode
!= DImode
&& mode
!= DFmode
) || TARGET_E500_DOUBLE
)
3179 && (TARGET_POWERPC64
|| mode
!= DImode
)
3182 return gen_rtx_PLUS (Pmode
, XEXP (x
, 0),
3183 force_reg (Pmode
, force_operand (XEXP (x
, 1), 0)));
3185 else if (ALTIVEC_VECTOR_MODE (mode
))
3189 /* Make sure both operands are registers. */
3190 if (GET_CODE (x
) == PLUS
)
3191 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, XEXP (x
, 0)),
3192 force_reg (Pmode
, XEXP (x
, 1)));
3194 reg
= force_reg (Pmode
, x
);
3197 else if (SPE_VECTOR_MODE (mode
)
3198 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3199 || mode
== DImode
)))
3203 /* We accept [reg + reg] and [reg + OFFSET]. */
3205 if (GET_CODE (x
) == PLUS
)
3207 rtx op1
= XEXP (x
, 0);
3208 rtx op2
= XEXP (x
, 1);
3210 op1
= force_reg (Pmode
, op1
);
3212 if (GET_CODE (op2
) != REG
3213 && (GET_CODE (op2
) != CONST_INT
3214 || !SPE_CONST_OFFSET_OK (INTVAL (op2
))))
3215 op2
= force_reg (Pmode
, op2
);
3217 return gen_rtx_PLUS (Pmode
, op1
, op2
);
3220 return force_reg (Pmode
, x
);
3226 && GET_CODE (x
) != CONST_INT
3227 && GET_CODE (x
) != CONST_DOUBLE
3229 && GET_MODE_NUNITS (mode
) == 1
3230 && (GET_MODE_BITSIZE (mode
) <= 32
3231 || ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) && mode
== DFmode
)))
3233 rtx reg
= gen_reg_rtx (Pmode
);
3234 emit_insn (gen_elf_high (reg
, x
));
3235 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3237 else if (TARGET_MACHO
&& TARGET_32BIT
&& TARGET_NO_TOC
3240 && ! MACHO_DYNAMIC_NO_PIC_P
3242 && GET_CODE (x
) != CONST_INT
3243 && GET_CODE (x
) != CONST_DOUBLE
3245 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
) || mode
!= DFmode
)
3249 rtx reg
= gen_reg_rtx (Pmode
);
3250 emit_insn (gen_macho_high (reg
, x
));
3251 return gen_rtx_LO_SUM (Pmode
, reg
, x
);
3254 && constant_pool_expr_p (x
)
3255 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), Pmode
))
3257 return create_TOC_reference (x
);
3263 /* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
3264 We need to emit DTP-relative relocations. */
3267 rs6000_output_dwarf_dtprel (FILE *file
, int size
, rtx x
)
3272 fputs ("\t.long\t", file
);
3275 fputs (DOUBLE_INT_ASM_OP
, file
);
3280 output_addr_const (file
, x
);
3281 fputs ("@dtprel+0x8000", file
);
3284 /* Construct the SYMBOL_REF for the tls_get_addr function. */
3286 static GTY(()) rtx rs6000_tls_symbol
;
3288 rs6000_tls_get_addr (void)
3290 if (!rs6000_tls_symbol
)
3291 rs6000_tls_symbol
= init_one_libfunc ("__tls_get_addr");
3293 return rs6000_tls_symbol
;
3296 /* Construct the SYMBOL_REF for TLS GOT references. */
3298 static GTY(()) rtx rs6000_got_symbol
;
3300 rs6000_got_sym (void)
3302 if (!rs6000_got_symbol
)
3304 rs6000_got_symbol
= gen_rtx_SYMBOL_REF (Pmode
, "_GLOBAL_OFFSET_TABLE_");
3305 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_LOCAL
;
3306 SYMBOL_REF_FLAGS (rs6000_got_symbol
) |= SYMBOL_FLAG_EXTERNAL
;
3309 return rs6000_got_symbol
;
3312 /* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3313 this (thread-local) address. */
3316 rs6000_legitimize_tls_address (rtx addr
, enum tls_model model
)
3320 dest
= gen_reg_rtx (Pmode
);
3321 if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 16)
3327 tlsreg
= gen_rtx_REG (Pmode
, 13);
3328 insn
= gen_tls_tprel_64 (dest
, tlsreg
, addr
);
3332 tlsreg
= gen_rtx_REG (Pmode
, 2);
3333 insn
= gen_tls_tprel_32 (dest
, tlsreg
, addr
);
3337 else if (model
== TLS_MODEL_LOCAL_EXEC
&& rs6000_tls_size
== 32)
3341 tmp
= gen_reg_rtx (Pmode
);
3344 tlsreg
= gen_rtx_REG (Pmode
, 13);
3345 insn
= gen_tls_tprel_ha_64 (tmp
, tlsreg
, addr
);
3349 tlsreg
= gen_rtx_REG (Pmode
, 2);
3350 insn
= gen_tls_tprel_ha_32 (tmp
, tlsreg
, addr
);
3354 insn
= gen_tls_tprel_lo_64 (dest
, tmp
, addr
);
3356 insn
= gen_tls_tprel_lo_32 (dest
, tmp
, addr
);
3361 rtx r3
, got
, tga
, tmp1
, tmp2
, eqv
;
3363 /* We currently use relocations like @got@tlsgd for tls, which
3364 means the linker will handle allocation of tls entries, placing
3365 them in the .got section. So use a pointer to the .got section,
3366 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3367 or to secondary GOT sections used by 32-bit -fPIC. */
3369 got
= gen_rtx_REG (Pmode
, 2);
3373 got
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
3376 rtx gsym
= rs6000_got_sym ();
3377 got
= gen_reg_rtx (Pmode
);
3379 rs6000_emit_move (got
, gsym
, Pmode
);
3382 rtx tempLR
, tmp3
, mem
;
3385 tempLR
= gen_reg_rtx (Pmode
);
3386 tmp1
= gen_reg_rtx (Pmode
);
3387 tmp2
= gen_reg_rtx (Pmode
);
3388 tmp3
= gen_reg_rtx (Pmode
);
3389 mem
= gen_const_mem (Pmode
, tmp1
);
3391 first
= emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, gsym
));
3392 emit_move_insn (tmp1
, tempLR
);
3393 emit_move_insn (tmp2
, mem
);
3394 emit_insn (gen_addsi3 (tmp3
, tmp1
, tmp2
));
3395 last
= emit_move_insn (got
, tmp3
);
3396 set_unique_reg_note (last
, REG_EQUAL
, gsym
);
3397 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
3399 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
,
3405 if (model
== TLS_MODEL_GLOBAL_DYNAMIC
)
3407 r3
= gen_rtx_REG (Pmode
, 3);
3409 insn
= gen_tls_gd_64 (r3
, got
, addr
);
3411 insn
= gen_tls_gd_32 (r3
, got
, addr
);
3414 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3415 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3416 insn
= emit_call_insn (insn
);
3417 CONST_OR_PURE_CALL_P (insn
) = 1;
3418 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3419 insn
= get_insns ();
3421 emit_libcall_block (insn
, dest
, r3
, addr
);
3423 else if (model
== TLS_MODEL_LOCAL_DYNAMIC
)
3425 r3
= gen_rtx_REG (Pmode
, 3);
3427 insn
= gen_tls_ld_64 (r3
, got
);
3429 insn
= gen_tls_ld_32 (r3
, got
);
3432 tga
= gen_rtx_MEM (Pmode
, rs6000_tls_get_addr ());
3433 insn
= gen_call_value (r3
, tga
, const0_rtx
, const0_rtx
);
3434 insn
= emit_call_insn (insn
);
3435 CONST_OR_PURE_CALL_P (insn
) = 1;
3436 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), r3
);
3437 insn
= get_insns ();
3439 tmp1
= gen_reg_rtx (Pmode
);
3440 eqv
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, const0_rtx
),
3442 emit_libcall_block (insn
, tmp1
, r3
, eqv
);
3443 if (rs6000_tls_size
== 16)
3446 insn
= gen_tls_dtprel_64 (dest
, tmp1
, addr
);
3448 insn
= gen_tls_dtprel_32 (dest
, tmp1
, addr
);
3450 else if (rs6000_tls_size
== 32)
3452 tmp2
= gen_reg_rtx (Pmode
);
3454 insn
= gen_tls_dtprel_ha_64 (tmp2
, tmp1
, addr
);
3456 insn
= gen_tls_dtprel_ha_32 (tmp2
, tmp1
, addr
);
3459 insn
= gen_tls_dtprel_lo_64 (dest
, tmp2
, addr
);
3461 insn
= gen_tls_dtprel_lo_32 (dest
, tmp2
, addr
);
3465 tmp2
= gen_reg_rtx (Pmode
);
3467 insn
= gen_tls_got_dtprel_64 (tmp2
, got
, addr
);
3469 insn
= gen_tls_got_dtprel_32 (tmp2
, got
, addr
);
3471 insn
= gen_rtx_SET (Pmode
, dest
,
3472 gen_rtx_PLUS (Pmode
, tmp2
, tmp1
));
3478 /* IE, or 64 bit offset LE. */
3479 tmp2
= gen_reg_rtx (Pmode
);
3481 insn
= gen_tls_got_tprel_64 (tmp2
, got
, addr
);
3483 insn
= gen_tls_got_tprel_32 (tmp2
, got
, addr
);
3486 insn
= gen_tls_tls_64 (dest
, tmp2
, addr
);
3488 insn
= gen_tls_tls_32 (dest
, tmp2
, addr
);
3496 /* Return 1 if X contains a thread-local symbol. */
3499 rs6000_tls_referenced_p (rtx x
)
3501 if (! TARGET_HAVE_TLS
)
3504 return for_each_rtx (&x
, &rs6000_tls_symbol_ref_1
, 0);
3507 /* Return 1 if *X is a thread-local symbol. This is the same as
3508 rs6000_tls_symbol_ref except for the type of the unused argument. */
3511 rs6000_tls_symbol_ref_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
3513 return RS6000_SYMBOL_REF_TLS_P (*x
);
3516 /* The convention appears to be to define this wherever it is used.
3517 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3518 is now used here. */
3519 #ifndef REG_MODE_OK_FOR_BASE_P
3520 #define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3523 /* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3524 replace the input X, or the original X if no replacement is called for.
3525 The output parameter *WIN is 1 if the calling macro should goto WIN,
3528 For RS/6000, we wish to handle large displacements off a base
3529 register by splitting the addend across an addiu/addis and the mem insn.
3530 This cuts number of extra insns needed from 3 to 1.
3532 On Darwin, we use this to generate code for floating point constants.
3533 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3534 The Darwin code is inside #if TARGET_MACHO because only then is
3535 machopic_function_base_name() defined. */
3537 rs6000_legitimize_reload_address (rtx x
, enum machine_mode mode
,
3538 int opnum
, int type
,
3539 int ind_levels ATTRIBUTE_UNUSED
, int *win
)
3541 /* We must recognize output that we have already generated ourselves. */
3542 if (GET_CODE (x
) == PLUS
3543 && GET_CODE (XEXP (x
, 0)) == PLUS
3544 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3545 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3546 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3548 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3549 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3550 opnum
, (enum reload_type
)type
);
3556 if (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
3557 && GET_CODE (x
) == LO_SUM
3558 && GET_CODE (XEXP (x
, 0)) == PLUS
3559 && XEXP (XEXP (x
, 0), 0) == pic_offset_table_rtx
3560 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == HIGH
3561 && GET_CODE (XEXP (XEXP (XEXP (x
, 0), 1), 0)) == CONST
3562 && XEXP (XEXP (XEXP (x
, 0), 1), 0) == XEXP (x
, 1)
3563 && GET_CODE (XEXP (XEXP (x
, 1), 0)) == MINUS
3564 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 0)) == SYMBOL_REF
3565 && GET_CODE (XEXP (XEXP (XEXP (x
, 1), 0), 1)) == SYMBOL_REF
)
3567 /* Result of previous invocation of this function on Darwin
3568 floating point constant. */
3569 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3570 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3571 opnum
, (enum reload_type
)type
);
3577 /* Force ld/std non-word aligned offset into base register by wrapping
3579 if (GET_CODE (x
) == PLUS
3580 && GET_CODE (XEXP (x
, 0)) == REG
3581 && REGNO (XEXP (x
, 0)) < 32
3582 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3583 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3584 && (INTVAL (XEXP (x
, 1)) & 3) != 0
3585 && !ALTIVEC_VECTOR_MODE (mode
)
3586 && GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
3587 && TARGET_POWERPC64
)
3589 x
= gen_rtx_PLUS (GET_MODE (x
), x
, GEN_INT (0));
3590 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3591 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3592 opnum
, (enum reload_type
) type
);
3597 if (GET_CODE (x
) == PLUS
3598 && GET_CODE (XEXP (x
, 0)) == REG
3599 && REGNO (XEXP (x
, 0)) < FIRST_PSEUDO_REGISTER
3600 && REG_MODE_OK_FOR_BASE_P (XEXP (x
, 0), mode
)
3601 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3602 && !SPE_VECTOR_MODE (mode
)
3603 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3605 && !ALTIVEC_VECTOR_MODE (mode
))
3607 HOST_WIDE_INT val
= INTVAL (XEXP (x
, 1));
3608 HOST_WIDE_INT low
= ((val
& 0xffff) ^ 0x8000) - 0x8000;
3610 = (((val
- low
) & 0xffffffff) ^ 0x80000000) - 0x80000000;
3612 /* Check for 32-bit overflow. */
3613 if (high
+ low
!= val
)
3619 /* Reload the high part into a base reg; leave the low part
3620 in the mem directly. */
3622 x
= gen_rtx_PLUS (GET_MODE (x
),
3623 gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0),
3627 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3628 BASE_REG_CLASS
, GET_MODE (x
), VOIDmode
, 0, 0,
3629 opnum
, (enum reload_type
)type
);
3634 if (GET_CODE (x
) == SYMBOL_REF
3635 && !ALTIVEC_VECTOR_MODE (mode
)
3636 && !SPE_VECTOR_MODE (mode
)
3638 && DEFAULT_ABI
== ABI_DARWIN
3639 && (flag_pic
|| MACHO_DYNAMIC_NO_PIC_P
)
3641 && DEFAULT_ABI
== ABI_V4
3644 /* Don't do this for TFmode, since the result isn't offsettable.
3645 The same goes for DImode without 64-bit gprs and DFmode
3648 && (mode
!= DImode
|| TARGET_POWERPC64
)
3649 && (mode
!= DFmode
|| TARGET_POWERPC64
3650 || (TARGET_FPRS
&& TARGET_HARD_FLOAT
)))
3655 rtx offset
= gen_rtx_CONST (Pmode
,
3656 gen_rtx_MINUS (Pmode
, x
,
3657 machopic_function_base_sym ()));
3658 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3659 gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
,
3660 gen_rtx_HIGH (Pmode
, offset
)), offset
);
3664 x
= gen_rtx_LO_SUM (GET_MODE (x
),
3665 gen_rtx_HIGH (Pmode
, x
), x
);
3667 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
3668 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0,
3669 opnum
, (enum reload_type
)type
);
3674 /* Reload an offset address wrapped by an AND that represents the
3675 masking of the lower bits. Strip the outer AND and let reload
3676 convert the offset address into an indirect address. */
3678 && ALTIVEC_VECTOR_MODE (mode
)
3679 && GET_CODE (x
) == AND
3680 && GET_CODE (XEXP (x
, 0)) == PLUS
3681 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == REG
3682 && GET_CODE (XEXP (XEXP (x
, 0), 1)) == CONST_INT
3683 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3684 && INTVAL (XEXP (x
, 1)) == -16)
3692 && constant_pool_expr_p (x
)
3693 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x
), mode
))
3695 x
= create_TOC_reference (x
);
3703 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3704 that is a valid memory address for an instruction.
3705 The MODE argument is the machine mode for the MEM expression
3706 that wants to use this address.
3708 On the RS/6000, there are four valid address: a SYMBOL_REF that
3709 refers to a constant pool entry of an address (or the sum of it
3710 plus a constant), a short (16-bit signed) constant plus a register,
3711 the sum of two registers, or a register indirect, possibly with an
3712 auto-increment. For DFmode and DImode with a constant plus register,
3713 we must ensure that both words are addressable or PowerPC64 with offset
3716 For modes spanning multiple registers (DFmode in 32-bit GPRs,
3717 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
3718 adjacent memory cells are accessed by adding word-sized offsets
3719 during assembly output. */
3721 rs6000_legitimate_address (enum machine_mode mode
, rtx x
, int reg_ok_strict
)
3723 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3725 && ALTIVEC_VECTOR_MODE (mode
)
3726 && GET_CODE (x
) == AND
3727 && GET_CODE (XEXP (x
, 1)) == CONST_INT
3728 && INTVAL (XEXP (x
, 1)) == -16)
3731 if (RS6000_SYMBOL_REF_TLS_P (x
))
3733 if (legitimate_indirect_address_p (x
, reg_ok_strict
))
3735 if ((GET_CODE (x
) == PRE_INC
|| GET_CODE (x
) == PRE_DEC
)
3736 && !ALTIVEC_VECTOR_MODE (mode
)
3737 && !SPE_VECTOR_MODE (mode
)
3739 /* Restrict addressing for DI because of our SUBREG hackery. */
3740 && !(TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
3743 && legitimate_indirect_address_p (XEXP (x
, 0), reg_ok_strict
))
3745 if (legitimate_small_data_p (mode
, x
))
3747 if (legitimate_constant_pool_address_p (x
))
3749 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3751 && GET_CODE (x
) == PLUS
3752 && GET_CODE (XEXP (x
, 0)) == REG
3753 && (XEXP (x
, 0) == virtual_stack_vars_rtx
3754 || XEXP (x
, 0) == arg_pointer_rtx
)
3755 && GET_CODE (XEXP (x
, 1)) == CONST_INT
)
3757 if (rs6000_legitimate_offset_address_p (mode
, x
, reg_ok_strict
))
3761 && ((TARGET_HARD_FLOAT
&& TARGET_FPRS
)
3763 || ((mode
!= DFmode
|| TARGET_E500_DOUBLE
) && mode
!= TFmode
))
3764 && (TARGET_POWERPC64
|| mode
!= DImode
)
3765 && legitimate_indexed_address_p (x
, reg_ok_strict
))
3767 if (legitimate_lo_sum_address_p (mode
, x
, reg_ok_strict
))
3772 /* Go to LABEL if ADDR (a legitimate address expression)
3773 has an effect that depends on the machine mode it is used for.
3775 On the RS/6000 this is true of all integral offsets (since AltiVec
3776 modes don't allow them) or is a pre-increment or decrement.
3778 ??? Except that due to conceptual problems in offsettable_address_p
3779 we can't really report the problems of integral offsets. So leave
3780 this assuming that the adjustable offset must be valid for the
3781 sub-words of a TFmode operand, which is what we had before. */
3784 rs6000_mode_dependent_address (rtx addr
)
3786 switch (GET_CODE (addr
))
3789 if (GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
3791 unsigned HOST_WIDE_INT val
= INTVAL (XEXP (addr
, 1));
3792 return val
+ 12 + 0x8000 >= 0x10000;
3799 /* Auto-increment cases are now treated generically in recog.c. */
3808 /* More elaborate version of recog's offsettable_memref_p predicate
3809 that works around the ??? note of rs6000_mode_dependent_address.
3810 In particular it accepts
3812 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
3814 in 32-bit mode, that the recog predicate rejects. */
3817 rs6000_offsettable_memref_p (rtx op
)
3822 /* First mimic offsettable_memref_p. */
3823 if (offsettable_address_p (1, GET_MODE (op
), XEXP (op
, 0)))
3826 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
3827 the latter predicate knows nothing about the mode of the memory
3828 reference and, therefore, assumes that it is the largest supported
3829 mode (TFmode). As a consequence, legitimate offsettable memory
3830 references are rejected. rs6000_legitimate_offset_address_p contains
3831 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
3832 return rs6000_legitimate_offset_address_p (GET_MODE (op
), XEXP (op
, 0), 1);
3835 /* Return number of consecutive hard regs needed starting at reg REGNO
3836 to hold something of mode MODE.
3837 This is ordinarily the length in words of a value of mode MODE
3838 but can be less for certain modes in special long registers.
3840 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3841 scalar instructions. The upper 32 bits are only available to the
3844 POWER and PowerPC GPRs hold 32 bits worth;
3845 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3848 rs6000_hard_regno_nregs (int regno
, enum machine_mode mode
)
3850 if (FP_REGNO_P (regno
))
3851 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
3853 if (SPE_SIMD_REGNO_P (regno
) && TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
3854 return (GET_MODE_SIZE (mode
) + UNITS_PER_SPE_WORD
- 1) / UNITS_PER_SPE_WORD
;
3856 if (ALTIVEC_REGNO_P (regno
))
3858 (GET_MODE_SIZE (mode
) + UNITS_PER_ALTIVEC_WORD
- 1) / UNITS_PER_ALTIVEC_WORD
;
3860 /* The value returned for SCmode in the E500 double case is 2 for
3861 ABI compatibility; storing an SCmode value in a single register
3862 would require function_arg and rs6000_spe_function_arg to handle
3863 SCmode so as to pass the value correctly in a pair of
3865 if (TARGET_E500_DOUBLE
&& FLOAT_MODE_P (mode
) && mode
!= SCmode
)
3866 return (GET_MODE_SIZE (mode
) + UNITS_PER_FP_WORD
- 1) / UNITS_PER_FP_WORD
;
3868 return (GET_MODE_SIZE (mode
) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
3871 /* Change register usage conditional on target flags. */
3873 rs6000_conditional_register_usage (void)
3877 /* Set MQ register fixed (already call_used) if not POWER
3878 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3883 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
3885 fixed_regs
[13] = call_used_regs
[13]
3886 = call_really_used_regs
[13] = 1;
3888 /* Conditionally disable FPRs. */
3889 if (TARGET_SOFT_FLOAT
|| !TARGET_FPRS
)
3890 for (i
= 32; i
< 64; i
++)
3891 fixed_regs
[i
] = call_used_regs
[i
]
3892 = call_really_used_regs
[i
] = 1;
3894 /* The TOC register is not killed across calls in a way that is
3895 visible to the compiler. */
3896 if (DEFAULT_ABI
== ABI_AIX
)
3897 call_really_used_regs
[2] = 0;
3899 if (DEFAULT_ABI
== ABI_V4
3900 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3902 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3904 if (DEFAULT_ABI
== ABI_V4
3905 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
3907 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3908 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3909 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3911 if (DEFAULT_ABI
== ABI_DARWIN
3912 && PIC_OFFSET_TABLE_REGNUM
!= INVALID_REGNUM
)
3913 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3914 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3915 = call_really_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3917 if (TARGET_TOC
&& TARGET_MINIMAL_TOC
)
3918 fixed_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
]
3919 = call_used_regs
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
3922 global_regs
[VSCR_REGNO
] = 1;
3926 global_regs
[SPEFSCR_REGNO
] = 1;
3927 fixed_regs
[FIXED_SCRATCH
]
3928 = call_used_regs
[FIXED_SCRATCH
]
3929 = call_really_used_regs
[FIXED_SCRATCH
] = 1;
3932 if (! TARGET_ALTIVEC
)
3934 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
3935 fixed_regs
[i
] = call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3936 call_really_used_regs
[VRSAVE_REGNO
] = 1;
3939 if (TARGET_ALTIVEC_ABI
)
3940 for (i
= FIRST_ALTIVEC_REGNO
; i
< FIRST_ALTIVEC_REGNO
+ 20; ++i
)
3941 call_used_regs
[i
] = call_really_used_regs
[i
] = 1;
3944 /* Try to output insns to set TARGET equal to the constant C if it can
3945 be done in less than N insns. Do all computations in MODE.
3946 Returns the place where the output has been placed if it can be
3947 done and the insns have been emitted. If it would take more than N
3948 insns, zero is returned and no insns and emitted. */
3951 rs6000_emit_set_const (rtx dest
, enum machine_mode mode
,
3952 rtx source
, int n ATTRIBUTE_UNUSED
)
3954 rtx result
, insn
, set
;
3955 HOST_WIDE_INT c0
, c1
;
3962 dest
= gen_reg_rtx (mode
);
3963 emit_insn (gen_rtx_SET (VOIDmode
, dest
, source
));
3967 result
= no_new_pseudos
? dest
: gen_reg_rtx (SImode
);
3969 emit_insn (gen_rtx_SET (VOIDmode
, copy_rtx (result
),
3970 GEN_INT (INTVAL (source
)
3971 & (~ (HOST_WIDE_INT
) 0xffff))));
3972 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
3973 gen_rtx_IOR (SImode
, copy_rtx (result
),
3974 GEN_INT (INTVAL (source
) & 0xffff))));
3979 switch (GET_CODE (source
))
3982 c0
= INTVAL (source
);
3987 #if HOST_BITS_PER_WIDE_INT >= 64
3988 c0
= CONST_DOUBLE_LOW (source
);
3991 c0
= CONST_DOUBLE_LOW (source
);
3992 c1
= CONST_DOUBLE_HIGH (source
);
4000 result
= rs6000_emit_set_long_const (dest
, c0
, c1
);
4007 insn
= get_last_insn ();
4008 set
= single_set (insn
);
4009 if (! CONSTANT_P (SET_SRC (set
)))
4010 set_unique_reg_note (insn
, REG_EQUAL
, source
);
4015 /* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4016 fall back to a straight forward decomposition. We do this to avoid
4017 exponential run times encountered when looking for longer sequences
4018 with rs6000_emit_set_const. */
4020 rs6000_emit_set_long_const (rtx dest
, HOST_WIDE_INT c1
, HOST_WIDE_INT c2
)
4022 if (!TARGET_POWERPC64
)
4024 rtx operand1
, operand2
;
4026 operand1
= operand_subword_force (dest
, WORDS_BIG_ENDIAN
== 0,
4028 operand2
= operand_subword_force (copy_rtx (dest
), WORDS_BIG_ENDIAN
!= 0,
4030 emit_move_insn (operand1
, GEN_INT (c1
));
4031 emit_move_insn (operand2
, GEN_INT (c2
));
4035 HOST_WIDE_INT ud1
, ud2
, ud3
, ud4
;
4038 ud2
= (c1
& 0xffff0000) >> 16;
4039 #if HOST_BITS_PER_WIDE_INT >= 64
4043 ud4
= (c2
& 0xffff0000) >> 16;
4045 if ((ud4
== 0xffff && ud3
== 0xffff && ud2
== 0xffff && (ud1
& 0x8000))
4046 || (ud4
== 0 && ud3
== 0 && ud2
== 0 && ! (ud1
& 0x8000)))
4049 emit_move_insn (dest
, GEN_INT (((ud1
^ 0x8000) - 0x8000)));
4051 emit_move_insn (dest
, GEN_INT (ud1
));
4054 else if ((ud4
== 0xffff && ud3
== 0xffff && (ud2
& 0x8000))
4055 || (ud4
== 0 && ud3
== 0 && ! (ud2
& 0x8000)))
4058 emit_move_insn (dest
, GEN_INT (((ud2
<< 16) ^ 0x80000000)
4061 emit_move_insn (dest
, GEN_INT (ud2
<< 16));
4063 emit_move_insn (copy_rtx (dest
),
4064 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4067 else if ((ud4
== 0xffff && (ud3
& 0x8000))
4068 || (ud4
== 0 && ! (ud3
& 0x8000)))
4071 emit_move_insn (dest
, GEN_INT (((ud3
<< 16) ^ 0x80000000)
4074 emit_move_insn (dest
, GEN_INT (ud3
<< 16));
4077 emit_move_insn (copy_rtx (dest
),
4078 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4080 emit_move_insn (copy_rtx (dest
),
4081 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4084 emit_move_insn (copy_rtx (dest
),
4085 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4091 emit_move_insn (dest
, GEN_INT (((ud4
<< 16) ^ 0x80000000)
4094 emit_move_insn (dest
, GEN_INT (ud4
<< 16));
4097 emit_move_insn (copy_rtx (dest
),
4098 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4101 emit_move_insn (copy_rtx (dest
),
4102 gen_rtx_ASHIFT (DImode
, copy_rtx (dest
),
4105 emit_move_insn (copy_rtx (dest
),
4106 gen_rtx_IOR (DImode
, copy_rtx (dest
),
4107 GEN_INT (ud2
<< 16)));
4109 emit_move_insn (copy_rtx (dest
),
4110 gen_rtx_IOR (DImode
, copy_rtx (dest
), GEN_INT (ud1
)));
4116 /* Helper for the following. Get rid of [r+r] memory refs
4117 in cases where it won't work (TImode, TFmode). */
4120 rs6000_eliminate_indexed_memrefs (rtx operands
[2])
4122 if (GET_CODE (operands
[0]) == MEM
4123 && GET_CODE (XEXP (operands
[0], 0)) != REG
4124 && ! legitimate_constant_pool_address_p (XEXP (operands
[0], 0))
4125 && ! reload_in_progress
)
4127 = replace_equiv_address (operands
[0],
4128 copy_addr_to_reg (XEXP (operands
[0], 0)));
4130 if (GET_CODE (operands
[1]) == MEM
4131 && GET_CODE (XEXP (operands
[1], 0)) != REG
4132 && ! legitimate_constant_pool_address_p (XEXP (operands
[1], 0))
4133 && ! reload_in_progress
)
4135 = replace_equiv_address (operands
[1],
4136 copy_addr_to_reg (XEXP (operands
[1], 0)));
4139 /* Emit a move from SOURCE to DEST in mode MODE. */
4141 rs6000_emit_move (rtx dest
, rtx source
, enum machine_mode mode
)
4145 operands
[1] = source
;
4147 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4148 if (GET_CODE (operands
[1]) == CONST_DOUBLE
4149 && ! FLOAT_MODE_P (mode
)
4150 && GET_MODE_BITSIZE (mode
) <= HOST_BITS_PER_WIDE_INT
)
4152 /* FIXME. This should never happen. */
4153 /* Since it seems that it does, do the safe thing and convert
4155 operands
[1] = gen_int_mode (CONST_DOUBLE_LOW (operands
[1]), mode
);
4157 gcc_assert (GET_CODE (operands
[1]) != CONST_DOUBLE
4158 || FLOAT_MODE_P (mode
)
4159 || ((CONST_DOUBLE_HIGH (operands
[1]) != 0
4160 || CONST_DOUBLE_LOW (operands
[1]) < 0)
4161 && (CONST_DOUBLE_HIGH (operands
[1]) != -1
4162 || CONST_DOUBLE_LOW (operands
[1]) >= 0)));
4164 /* Check if GCC is setting up a block move that will end up using FP
4165 registers as temporaries. We must make sure this is acceptable. */
4166 if (GET_CODE (operands
[0]) == MEM
4167 && GET_CODE (operands
[1]) == MEM
4169 && (SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[0]))
4170 || SLOW_UNALIGNED_ACCESS (DImode
, MEM_ALIGN (operands
[1])))
4171 && ! (SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[0]) > 32
4172 ? 32 : MEM_ALIGN (operands
[0])))
4173 || SLOW_UNALIGNED_ACCESS (SImode
, (MEM_ALIGN (operands
[1]) > 32
4175 : MEM_ALIGN (operands
[1]))))
4176 && ! MEM_VOLATILE_P (operands
[0])
4177 && ! MEM_VOLATILE_P (operands
[1]))
4179 emit_move_insn (adjust_address (operands
[0], SImode
, 0),
4180 adjust_address (operands
[1], SImode
, 0));
4181 emit_move_insn (adjust_address (copy_rtx (operands
[0]), SImode
, 4),
4182 adjust_address (copy_rtx (operands
[1]), SImode
, 4));
4186 if (!no_new_pseudos
&& GET_CODE (operands
[0]) == MEM
4187 && !gpc_reg_operand (operands
[1], mode
))
4188 operands
[1] = force_reg (mode
, operands
[1]);
4190 if (mode
== SFmode
&& ! TARGET_POWERPC
4191 && TARGET_HARD_FLOAT
&& TARGET_FPRS
4192 && GET_CODE (operands
[0]) == MEM
)
4196 if (reload_in_progress
|| reload_completed
)
4197 regnum
= true_regnum (operands
[1]);
4198 else if (GET_CODE (operands
[1]) == REG
)
4199 regnum
= REGNO (operands
[1]);
4203 /* If operands[1] is a register, on POWER it may have
4204 double-precision data in it, so truncate it to single
4206 if (FP_REGNO_P (regnum
) || regnum
>= FIRST_PSEUDO_REGISTER
)
4209 newreg
= (no_new_pseudos
? copy_rtx (operands
[1])
4210 : gen_reg_rtx (mode
));
4211 emit_insn (gen_aux_truncdfsf2 (newreg
, operands
[1]));
4212 operands
[1] = newreg
;
4216 /* Recognize the case where operand[1] is a reference to thread-local
4217 data and load its address to a register. */
4218 if (rs6000_tls_referenced_p (operands
[1]))
4220 enum tls_model model
;
4221 rtx tmp
= operands
[1];
4224 if (GET_CODE (tmp
) == CONST
&& GET_CODE (XEXP (tmp
, 0)) == PLUS
)
4226 addend
= XEXP (XEXP (tmp
, 0), 1);
4227 tmp
= XEXP (XEXP (tmp
, 0), 0);
4230 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
4231 model
= SYMBOL_REF_TLS_MODEL (tmp
);
4232 gcc_assert (model
!= 0);
4234 tmp
= rs6000_legitimize_tls_address (tmp
, model
);
4237 tmp
= gen_rtx_PLUS (mode
, tmp
, addend
);
4238 tmp
= force_operand (tmp
, operands
[0]);
4243 /* Handle the case where reload calls us with an invalid address. */
4244 if (reload_in_progress
&& mode
== Pmode
4245 && (! general_operand (operands
[1], mode
)
4246 || ! nonimmediate_operand (operands
[0], mode
)))
4249 /* 128-bit constant floating-point values on Darwin should really be
4250 loaded as two parts. */
4251 if (!TARGET_IEEEQUAD
&& TARGET_LONG_DOUBLE_128
4252 && mode
== TFmode
&& GET_CODE (operands
[1]) == CONST_DOUBLE
)
4254 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4255 know how to get a DFmode SUBREG of a TFmode. */
4256 enum machine_mode imode
= (TARGET_E500_DOUBLE
? DFmode
: DImode
);
4257 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
, 0),
4258 simplify_gen_subreg (imode
, operands
[1], mode
, 0),
4260 rs6000_emit_move (simplify_gen_subreg (imode
, operands
[0], mode
,
4261 GET_MODE_SIZE (imode
)),
4262 simplify_gen_subreg (imode
, operands
[1], mode
,
4263 GET_MODE_SIZE (imode
)),
4268 /* FIXME: In the long term, this switch statement should go away
4269 and be replaced by a sequence of tests based on things like
4275 if (CONSTANT_P (operands
[1])
4276 && GET_CODE (operands
[1]) != CONST_INT
)
4277 operands
[1] = force_const_mem (mode
, operands
[1]);
4281 rs6000_eliminate_indexed_memrefs (operands
);
4286 if (CONSTANT_P (operands
[1])
4287 && ! easy_fp_constant (operands
[1], mode
))
4288 operands
[1] = force_const_mem (mode
, operands
[1]);
4299 if (CONSTANT_P (operands
[1])
4300 && !easy_vector_constant (operands
[1], mode
))
4301 operands
[1] = force_const_mem (mode
, operands
[1]);
4306 /* Use default pattern for address of ELF small data */
4309 && DEFAULT_ABI
== ABI_V4
4310 && (GET_CODE (operands
[1]) == SYMBOL_REF
4311 || GET_CODE (operands
[1]) == CONST
)
4312 && small_data_operand (operands
[1], mode
))
4314 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4318 if (DEFAULT_ABI
== ABI_V4
4319 && mode
== Pmode
&& mode
== SImode
4320 && flag_pic
== 1 && got_operand (operands
[1], mode
))
4322 emit_insn (gen_movsi_got (operands
[0], operands
[1]));
4326 if ((TARGET_ELF
|| DEFAULT_ABI
== ABI_DARWIN
)
4330 && CONSTANT_P (operands
[1])
4331 && GET_CODE (operands
[1]) != HIGH
4332 && GET_CODE (operands
[1]) != CONST_INT
)
4334 rtx target
= (no_new_pseudos
? operands
[0] : gen_reg_rtx (mode
));
4336 /* If this is a function address on -mcall-aixdesc,
4337 convert it to the address of the descriptor. */
4338 if (DEFAULT_ABI
== ABI_AIX
4339 && GET_CODE (operands
[1]) == SYMBOL_REF
4340 && XSTR (operands
[1], 0)[0] == '.')
4342 const char *name
= XSTR (operands
[1], 0);
4344 while (*name
== '.')
4346 new_ref
= gen_rtx_SYMBOL_REF (Pmode
, name
);
4347 CONSTANT_POOL_ADDRESS_P (new_ref
)
4348 = CONSTANT_POOL_ADDRESS_P (operands
[1]);
4349 SYMBOL_REF_FLAGS (new_ref
) = SYMBOL_REF_FLAGS (operands
[1]);
4350 SYMBOL_REF_USED (new_ref
) = SYMBOL_REF_USED (operands
[1]);
4351 SYMBOL_REF_DATA (new_ref
) = SYMBOL_REF_DATA (operands
[1]);
4352 operands
[1] = new_ref
;
4355 if (DEFAULT_ABI
== ABI_DARWIN
)
4358 if (MACHO_DYNAMIC_NO_PIC_P
)
4360 /* Take care of any required data indirection. */
4361 operands
[1] = rs6000_machopic_legitimize_pic_address (
4362 operands
[1], mode
, operands
[0]);
4363 if (operands
[0] != operands
[1])
4364 emit_insn (gen_rtx_SET (VOIDmode
,
4365 operands
[0], operands
[1]));
4369 emit_insn (gen_macho_high (target
, operands
[1]));
4370 emit_insn (gen_macho_low (operands
[0], target
, operands
[1]));
4374 emit_insn (gen_elf_high (target
, operands
[1]));
4375 emit_insn (gen_elf_low (operands
[0], target
, operands
[1]));
4379 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4380 and we have put it in the TOC, we just need to make a TOC-relative
4383 && GET_CODE (operands
[1]) == SYMBOL_REF
4384 && constant_pool_expr_p (operands
[1])
4385 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands
[1]),
4386 get_pool_mode (operands
[1])))
4388 operands
[1] = create_TOC_reference (operands
[1]);
4390 else if (mode
== Pmode
4391 && CONSTANT_P (operands
[1])
4392 && ((GET_CODE (operands
[1]) != CONST_INT
4393 && ! easy_fp_constant (operands
[1], mode
))
4394 || (GET_CODE (operands
[1]) == CONST_INT
4395 && num_insns_constant (operands
[1], mode
) > 2)
4396 || (GET_CODE (operands
[0]) == REG
4397 && FP_REGNO_P (REGNO (operands
[0]))))
4398 && GET_CODE (operands
[1]) != HIGH
4399 && ! legitimate_constant_pool_address_p (operands
[1])
4400 && ! toc_relative_expr_p (operands
[1]))
4402 /* Emit a USE operation so that the constant isn't deleted if
4403 expensive optimizations are turned on because nobody
4404 references it. This should only be done for operands that
4405 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4406 This should not be done for operands that contain LABEL_REFs.
4407 For now, we just handle the obvious case. */
4408 if (GET_CODE (operands
[1]) != LABEL_REF
)
4409 emit_insn (gen_rtx_USE (VOIDmode
, operands
[1]));
4412 /* Darwin uses a special PIC legitimizer. */
4413 if (DEFAULT_ABI
== ABI_DARWIN
&& MACHOPIC_INDIRECT
)
4416 rs6000_machopic_legitimize_pic_address (operands
[1], mode
,
4418 if (operands
[0] != operands
[1])
4419 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4424 /* If we are to limit the number of things we put in the TOC and
4425 this is a symbol plus a constant we can add in one insn,
4426 just put the symbol in the TOC and add the constant. Don't do
4427 this if reload is in progress. */
4428 if (GET_CODE (operands
[1]) == CONST
4429 && TARGET_NO_SUM_IN_TOC
&& ! reload_in_progress
4430 && GET_CODE (XEXP (operands
[1], 0)) == PLUS
4431 && add_operand (XEXP (XEXP (operands
[1], 0), 1), mode
)
4432 && (GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == LABEL_REF
4433 || GET_CODE (XEXP (XEXP (operands
[1], 0), 0)) == SYMBOL_REF
)
4434 && ! side_effects_p (operands
[0]))
4437 force_const_mem (mode
, XEXP (XEXP (operands
[1], 0), 0));
4438 rtx other
= XEXP (XEXP (operands
[1], 0), 1);
4440 sym
= force_reg (mode
, sym
);
4442 emit_insn (gen_addsi3 (operands
[0], sym
, other
));
4444 emit_insn (gen_adddi3 (operands
[0], sym
, other
));
4448 operands
[1] = force_const_mem (mode
, operands
[1]);
4451 && constant_pool_expr_p (XEXP (operands
[1], 0))
4452 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4453 get_pool_constant (XEXP (operands
[1], 0)),
4454 get_pool_mode (XEXP (operands
[1], 0))))
4457 = gen_const_mem (mode
,
4458 create_TOC_reference (XEXP (operands
[1], 0)));
4459 set_mem_alias_set (operands
[1], get_TOC_alias_set ());
4465 rs6000_eliminate_indexed_memrefs (operands
);
4469 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
4471 gen_rtx_SET (VOIDmode
,
4472 operands
[0], operands
[1]),
4473 gen_rtx_CLOBBER (VOIDmode
,
4474 gen_rtx_SCRATCH (SImode
)))));
4483 /* Above, we may have called force_const_mem which may have returned
4484 an invalid address. If we can, fix this up; otherwise, reload will
4485 have to deal with it. */
4486 if (GET_CODE (operands
[1]) == MEM
&& ! reload_in_progress
)
4487 operands
[1] = validize_mem (operands
[1]);
4490 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0], operands
[1]));
4493 /* Nonzero if we can use a floating-point register to pass this arg. */
4494 #define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
4495 (SCALAR_FLOAT_MODE_P (MODE) \
4496 && !DECIMAL_FLOAT_MODE_P (MODE) \
4497 && (CUM)->fregno <= FP_ARG_MAX_REG \
4498 && TARGET_HARD_FLOAT && TARGET_FPRS)
4500 /* Nonzero if we can use an AltiVec register to pass this arg. */
4501 #define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4502 (ALTIVEC_VECTOR_MODE (MODE) \
4503 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4504 && TARGET_ALTIVEC_ABI \
4507 /* Return a nonzero value to say to return the function value in
4508 memory, just as large structures are always returned. TYPE will be
4509 the data type of the value, and FNTYPE will be the type of the
4510 function doing the returning, or @code{NULL} for libcalls.
4512 The AIX ABI for the RS/6000 specifies that all structures are
4513 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4514 specifies that structures <= 8 bytes are returned in r3/r4, but a
4515 draft put them in memory, and GCC used to implement the draft
4516 instead of the final standard. Therefore, aix_struct_return
4517 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4518 compatibility can change DRAFT_V4_STRUCT_RET to override the
4519 default, and -m switches get the final word. See
4520 rs6000_override_options for more details.
4522 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4523 long double support is enabled. These values are returned in memory.
4525 int_size_in_bytes returns -1 for variable size objects, which go in
4526 memory always. The cast to unsigned makes -1 > 8. */
4529 rs6000_return_in_memory (tree type
, tree fntype ATTRIBUTE_UNUSED
)
4531 /* In the darwin64 abi, try to use registers for larger structs
4533 if (rs6000_darwin64_abi
4534 && TREE_CODE (type
) == RECORD_TYPE
4535 && int_size_in_bytes (type
) > 0)
4537 CUMULATIVE_ARGS valcum
;
4541 valcum
.fregno
= FP_ARG_MIN_REG
;
4542 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
4543 /* Do a trial code generation as if this were going to be passed
4544 as an argument; if any part goes in memory, we return NULL. */
4545 valret
= rs6000_darwin64_record_arg (&valcum
, type
, 1, true);
4548 /* Otherwise fall through to more conventional ABI rules. */
4551 if (AGGREGATE_TYPE_P (type
)
4552 && (aix_struct_return
4553 || (unsigned HOST_WIDE_INT
) int_size_in_bytes (type
) > 8))
4556 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4557 modes only exist for GCC vector types if -maltivec. */
4558 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
4559 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
4562 /* Return synthetic vectors in memory. */
4563 if (TREE_CODE (type
) == VECTOR_TYPE
4564 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
4566 static bool warned_for_return_big_vectors
= false;
4567 if (!warned_for_return_big_vectors
)
4569 warning (0, "GCC vector returned by reference: "
4570 "non-standard ABI extension with no compatibility guarantee");
4571 warned_for_return_big_vectors
= true;
4576 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& TYPE_MODE (type
) == TFmode
)
4582 /* Initialize a variable CUM of type CUMULATIVE_ARGS
4583 for a call to a function whose data type is FNTYPE.
4584 For a library call, FNTYPE is 0.
4586 For incoming args we set the number of arguments in the prototype large
4587 so we never return a PARALLEL. */
4590 init_cumulative_args (CUMULATIVE_ARGS
*cum
, tree fntype
,
4591 rtx libname ATTRIBUTE_UNUSED
, int incoming
,
4592 int libcall
, int n_named_args
)
4594 static CUMULATIVE_ARGS zero_cumulative
;
4596 *cum
= zero_cumulative
;
4598 cum
->fregno
= FP_ARG_MIN_REG
;
4599 cum
->vregno
= ALTIVEC_ARG_MIN_REG
;
4600 cum
->prototype
= (fntype
&& TYPE_ARG_TYPES (fntype
));
4601 cum
->call_cookie
= ((DEFAULT_ABI
== ABI_V4
&& libcall
)
4602 ? CALL_LIBCALL
: CALL_NORMAL
);
4603 cum
->sysv_gregno
= GP_ARG_MIN_REG
;
4604 cum
->stdarg
= fntype
4605 && (TYPE_ARG_TYPES (fntype
) != 0
4606 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype
)))
4607 != void_type_node
));
4609 cum
->nargs_prototype
= 0;
4610 if (incoming
|| cum
->prototype
)
4611 cum
->nargs_prototype
= n_named_args
;
4613 /* Check for a longcall attribute. */
4614 if ((!fntype
&& rs6000_default_long_calls
)
4616 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype
))
4617 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype
))))
4618 cum
->call_cookie
|= CALL_LONG
;
4620 if (TARGET_DEBUG_ARG
)
4622 fprintf (stderr
, "\ninit_cumulative_args:");
4625 tree ret_type
= TREE_TYPE (fntype
);
4626 fprintf (stderr
, " ret code = %s,",
4627 tree_code_name
[ (int)TREE_CODE (ret_type
) ]);
4630 if (cum
->call_cookie
& CALL_LONG
)
4631 fprintf (stderr
, " longcall,");
4633 fprintf (stderr
, " proto = %d, nargs = %d\n",
4634 cum
->prototype
, cum
->nargs_prototype
);
4639 && TARGET_ALTIVEC_ABI
4640 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype
))))
4642 error ("cannot return value in vector register because"
4643 " altivec instructions are disabled, use -maltivec"
4648 /* Return true if TYPE must be passed on the stack and not in registers. */
4651 rs6000_must_pass_in_stack (enum machine_mode mode
, tree type
)
4653 if (DEFAULT_ABI
== ABI_AIX
|| TARGET_64BIT
)
4654 return must_pass_in_stack_var_size (mode
, type
);
4656 return must_pass_in_stack_var_size_or_pad (mode
, type
);
4659 /* If defined, a C expression which determines whether, and in which
4660 direction, to pad out an argument with extra space. The value
4661 should be of type `enum direction': either `upward' to pad above
4662 the argument, `downward' to pad below, or `none' to inhibit
4665 For the AIX ABI structs are always stored left shifted in their
4669 function_arg_padding (enum machine_mode mode
, tree type
)
4671 #ifndef AGGREGATE_PADDING_FIXED
4672 #define AGGREGATE_PADDING_FIXED 0
4674 #ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4675 #define AGGREGATES_PAD_UPWARD_ALWAYS 0
4678 if (!AGGREGATE_PADDING_FIXED
)
4680 /* GCC used to pass structures of the same size as integer types as
4681 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
4682 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
4683 passed padded downward, except that -mstrict-align further
4684 muddied the water in that multi-component structures of 2 and 4
4685 bytes in size were passed padded upward.
4687 The following arranges for best compatibility with previous
4688 versions of gcc, but removes the -mstrict-align dependency. */
4689 if (BYTES_BIG_ENDIAN
)
4691 HOST_WIDE_INT size
= 0;
4693 if (mode
== BLKmode
)
4695 if (type
&& TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
)
4696 size
= int_size_in_bytes (type
);
4699 size
= GET_MODE_SIZE (mode
);
4701 if (size
== 1 || size
== 2 || size
== 4)
4707 if (AGGREGATES_PAD_UPWARD_ALWAYS
)
4709 if (type
!= 0 && AGGREGATE_TYPE_P (type
))
4713 /* Fall back to the default. */
4714 return DEFAULT_FUNCTION_ARG_PADDING (mode
, type
);
4717 /* If defined, a C expression that gives the alignment boundary, in bits,
4718 of an argument with the specified mode and type. If it is not defined,
4719 PARM_BOUNDARY is used for all arguments.
4721 V.4 wants long longs and doubles to be double word aligned. Just
4722 testing the mode size is a boneheaded way to do this as it means
4723 that other types such as complex int are also double word aligned.
4724 However, we're stuck with this because changing the ABI might break
4725 existing library interfaces.
4727 Doubleword align SPE vectors.
4728 Quadword align Altivec vectors.
4729 Quadword align large synthetic vector types. */
4732 function_arg_boundary (enum machine_mode mode
, tree type
)
4734 if (DEFAULT_ABI
== ABI_V4
4735 && (GET_MODE_SIZE (mode
) == 8
4736 || (TARGET_HARD_FLOAT
4738 && mode
== TFmode
)))
4740 else if (SPE_VECTOR_MODE (mode
)
4741 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4742 && int_size_in_bytes (type
) >= 8
4743 && int_size_in_bytes (type
) < 16))
4745 else if (ALTIVEC_VECTOR_MODE (mode
)
4746 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4747 && int_size_in_bytes (type
) >= 16))
4749 else if (rs6000_darwin64_abi
&& mode
== BLKmode
4750 && type
&& TYPE_ALIGN (type
) > 64)
4753 return PARM_BOUNDARY
;
4756 /* For a function parm of MODE and TYPE, return the starting word in
4757 the parameter area. NWORDS of the parameter area are already used. */
4760 rs6000_parm_start (enum machine_mode mode
, tree type
, unsigned int nwords
)
4763 unsigned int parm_offset
;
4765 align
= function_arg_boundary (mode
, type
) / PARM_BOUNDARY
- 1;
4766 parm_offset
= DEFAULT_ABI
== ABI_V4
? 2 : 6;
4767 return nwords
+ (-(parm_offset
+ nwords
) & align
);
4770 /* Compute the size (in words) of a function argument. */
4772 static unsigned long
4773 rs6000_arg_size (enum machine_mode mode
, tree type
)
4777 if (mode
!= BLKmode
)
4778 size
= GET_MODE_SIZE (mode
);
4780 size
= int_size_in_bytes (type
);
4783 return (size
+ 3) >> 2;
4785 return (size
+ 7) >> 3;
4788 /* Use this to flush pending int fields. */
4791 rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS
*cum
,
4792 HOST_WIDE_INT bitpos
)
4794 unsigned int startbit
, endbit
;
4795 int intregs
, intoffset
;
4796 enum machine_mode mode
;
4798 if (cum
->intoffset
== -1)
4801 intoffset
= cum
->intoffset
;
4802 cum
->intoffset
= -1;
4804 if (intoffset
% BITS_PER_WORD
!= 0)
4806 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
4808 if (mode
== BLKmode
)
4810 /* We couldn't find an appropriate mode, which happens,
4811 e.g., in packed structs when there are 3 bytes to load.
4812 Back intoffset back to the beginning of the word in this
4814 intoffset
= intoffset
& -BITS_PER_WORD
;
4818 startbit
= intoffset
& -BITS_PER_WORD
;
4819 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
4820 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
4821 cum
->words
+= intregs
;
4824 /* The darwin64 ABI calls for us to recurse down through structs,
4825 looking for elements passed in registers. Unfortunately, we have
4826 to track int register count here also because of misalignments
4827 in powerpc alignment mode. */
4830 rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS
*cum
,
4832 HOST_WIDE_INT startbitpos
)
4836 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
4837 if (TREE_CODE (f
) == FIELD_DECL
)
4839 HOST_WIDE_INT bitpos
= startbitpos
;
4840 tree ftype
= TREE_TYPE (f
);
4841 enum machine_mode mode
;
4842 if (ftype
== error_mark_node
)
4844 mode
= TYPE_MODE (ftype
);
4846 if (DECL_SIZE (f
) != 0
4847 && host_integerp (bit_position (f
), 1))
4848 bitpos
+= int_bit_position (f
);
4850 /* ??? FIXME: else assume zero offset. */
4852 if (TREE_CODE (ftype
) == RECORD_TYPE
)
4853 rs6000_darwin64_record_arg_advance_recurse (cum
, ftype
, bitpos
);
4854 else if (USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
4856 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4857 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4858 cum
->words
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4860 else if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, 1))
4862 rs6000_darwin64_record_arg_advance_flush (cum
, bitpos
);
4866 else if (cum
->intoffset
== -1)
4867 cum
->intoffset
= bitpos
;
4871 /* Update the data in CUM to advance over an argument
4872 of mode MODE and data type TYPE.
4873 (TYPE is null for libcalls where that information may not be available.)
4875 Note that for args passed by reference, function_arg will be called
4876 with MODE and TYPE set to that of the pointer to the arg, not the arg
4880 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
4881 tree type
, int named
, int depth
)
4885 /* Only tick off an argument if we're not recursing. */
4887 cum
->nargs_prototype
--;
4889 if (TARGET_ALTIVEC_ABI
4890 && (ALTIVEC_VECTOR_MODE (mode
)
4891 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
4892 && int_size_in_bytes (type
) == 16)))
4896 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
4899 if (!TARGET_ALTIVEC
)
4900 error ("cannot pass argument in vector register because"
4901 " altivec instructions are disabled, use -maltivec"
4904 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
4905 even if it is going to be passed in a vector register.
4906 Darwin does the same for variable-argument functions. */
4907 if ((DEFAULT_ABI
== ABI_AIX
&& TARGET_64BIT
)
4908 || (cum
->stdarg
&& DEFAULT_ABI
!= ABI_V4
))
4918 /* Vector parameters must be 16-byte aligned. This places
4919 them at 2 mod 4 in terms of words in 32-bit mode, since
4920 the parameter save area starts at offset 24 from the
4921 stack. In 64-bit mode, they just have to start on an
4922 even word, since the parameter save area is 16-byte
4923 aligned. Space for GPRs is reserved even if the argument
4924 will be passed in memory. */
4926 align
= (2 - cum
->words
) & 3;
4928 align
= cum
->words
& 1;
4929 cum
->words
+= align
+ rs6000_arg_size (mode
, type
);
4931 if (TARGET_DEBUG_ARG
)
4933 fprintf (stderr
, "function_adv: words = %2d, align=%d, ",
4935 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s\n",
4936 cum
->nargs_prototype
, cum
->prototype
,
4937 GET_MODE_NAME (mode
));
4941 else if (TARGET_SPE_ABI
&& TARGET_SPE
&& SPE_VECTOR_MODE (mode
)
4943 && cum
->sysv_gregno
<= GP_ARG_MAX_REG
)
4946 else if (rs6000_darwin64_abi
4948 && TREE_CODE (type
) == RECORD_TYPE
4949 && (size
= int_size_in_bytes (type
)) > 0)
4951 /* Variable sized types have size == -1 and are
4952 treated as if consisting entirely of ints.
4953 Pad to 16 byte boundary if needed. */
4954 if (TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
4955 && (cum
->words
% 2) != 0)
4957 /* For varargs, we can just go up by the size of the struct. */
4959 cum
->words
+= (size
+ 7) / 8;
4962 /* It is tempting to say int register count just goes up by
4963 sizeof(type)/8, but this is wrong in a case such as
4964 { int; double; int; } [powerpc alignment]. We have to
4965 grovel through the fields for these too. */
4967 rs6000_darwin64_record_arg_advance_recurse (cum
, type
, 0);
4968 rs6000_darwin64_record_arg_advance_flush (cum
,
4969 size
* BITS_PER_UNIT
);
4972 else if (DEFAULT_ABI
== ABI_V4
)
4974 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
4975 && (mode
== SFmode
|| mode
== DFmode
4976 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
4978 if (cum
->fregno
+ (mode
== TFmode
? 1 : 0) <= FP_ARG_V4_MAX_REG
)
4979 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
4982 cum
->fregno
= FP_ARG_V4_MAX_REG
+ 1;
4983 if (mode
== DFmode
|| mode
== TFmode
)
4984 cum
->words
+= cum
->words
& 1;
4985 cum
->words
+= rs6000_arg_size (mode
, type
);
4990 int n_words
= rs6000_arg_size (mode
, type
);
4991 int gregno
= cum
->sysv_gregno
;
4993 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4994 (r7,r8) or (r9,r10). As does any other 2 word item such
4995 as complex int due to a historical mistake. */
4997 gregno
+= (1 - gregno
) & 1;
4999 /* Multi-reg args are not split between registers and stack. */
5000 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5002 /* Long long and SPE vectors are aligned on the stack.
5003 So are other 2 word items such as complex int due to
5004 a historical mistake. */
5006 cum
->words
+= cum
->words
& 1;
5007 cum
->words
+= n_words
;
5010 /* Note: continuing to accumulate gregno past when we've started
5011 spilling to the stack indicates the fact that we've started
5012 spilling to the stack to expand_builtin_saveregs. */
5013 cum
->sysv_gregno
= gregno
+ n_words
;
5016 if (TARGET_DEBUG_ARG
)
5018 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5019 cum
->words
, cum
->fregno
);
5020 fprintf (stderr
, "gregno = %2d, nargs = %4d, proto = %d, ",
5021 cum
->sysv_gregno
, cum
->nargs_prototype
, cum
->prototype
);
5022 fprintf (stderr
, "mode = %4s, named = %d\n",
5023 GET_MODE_NAME (mode
), named
);
5028 int n_words
= rs6000_arg_size (mode
, type
);
5029 int start_words
= cum
->words
;
5030 int align_words
= rs6000_parm_start (mode
, type
, start_words
);
5032 cum
->words
= align_words
+ n_words
;
5034 if (SCALAR_FLOAT_MODE_P (mode
)
5035 && !DECIMAL_FLOAT_MODE_P (mode
)
5036 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5037 cum
->fregno
+= (GET_MODE_SIZE (mode
) + 7) >> 3;
5039 if (TARGET_DEBUG_ARG
)
5041 fprintf (stderr
, "function_adv: words = %2d, fregno = %2d, ",
5042 cum
->words
, cum
->fregno
);
5043 fprintf (stderr
, "nargs = %4d, proto = %d, mode = %4s, ",
5044 cum
->nargs_prototype
, cum
->prototype
, GET_MODE_NAME (mode
));
5045 fprintf (stderr
, "named = %d, align = %d, depth = %d\n",
5046 named
, align_words
- start_words
, depth
);
5052 spe_build_register_parallel (enum machine_mode mode
, int gregno
)
5059 r1
= gen_rtx_REG (DImode
, gregno
);
5060 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5061 return gen_rtx_PARALLEL (mode
, gen_rtvec (1, r1
));
5065 r1
= gen_rtx_REG (DImode
, gregno
);
5066 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5067 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5068 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5069 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r3
));
5072 r1
= gen_rtx_REG (DImode
, gregno
);
5073 r1
= gen_rtx_EXPR_LIST (VOIDmode
, r1
, const0_rtx
);
5074 r3
= gen_rtx_REG (DImode
, gregno
+ 2);
5075 r3
= gen_rtx_EXPR_LIST (VOIDmode
, r3
, GEN_INT (8));
5076 r5
= gen_rtx_REG (DImode
, gregno
+ 4);
5077 r5
= gen_rtx_EXPR_LIST (VOIDmode
, r5
, GEN_INT (16));
5078 r7
= gen_rtx_REG (DImode
, gregno
+ 6);
5079 r7
= gen_rtx_EXPR_LIST (VOIDmode
, r7
, GEN_INT (24));
5080 return gen_rtx_PARALLEL (mode
, gen_rtvec (4, r1
, r3
, r5
, r7
));
5087 /* Determine where to put a SIMD argument on the SPE. */
5089 rs6000_spe_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5092 int gregno
= cum
->sysv_gregno
;
5094 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
5095 are passed and returned in a pair of GPRs for ABI compatibility. */
5096 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== DCmode
5097 || mode
== TFmode
|| mode
== TCmode
))
5099 int n_words
= rs6000_arg_size (mode
, type
);
5101 /* Doubles go in an odd/even register pair (r5/r6, etc). */
5103 gregno
+= (1 - gregno
) & 1;
5105 /* Multi-reg args are not split between registers and stack. */
5106 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5109 return spe_build_register_parallel (mode
, gregno
);
5113 int n_words
= rs6000_arg_size (mode
, type
);
5115 /* SPE vectors are put in odd registers. */
5116 if (n_words
== 2 && (gregno
& 1) == 0)
5119 if (gregno
+ n_words
- 1 <= GP_ARG_MAX_REG
)
5122 enum machine_mode m
= SImode
;
5124 r1
= gen_rtx_REG (m
, gregno
);
5125 r1
= gen_rtx_EXPR_LIST (m
, r1
, const0_rtx
);
5126 r2
= gen_rtx_REG (m
, gregno
+ 1);
5127 r2
= gen_rtx_EXPR_LIST (m
, r2
, GEN_INT (4));
5128 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
5135 if (gregno
<= GP_ARG_MAX_REG
)
5136 return gen_rtx_REG (mode
, gregno
);
5142 /* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5143 structure between cum->intoffset and bitpos to integer registers. */
5146 rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS
*cum
,
5147 HOST_WIDE_INT bitpos
, rtx rvec
[], int *k
)
5149 enum machine_mode mode
;
5151 unsigned int startbit
, endbit
;
5152 int this_regno
, intregs
, intoffset
;
5155 if (cum
->intoffset
== -1)
5158 intoffset
= cum
->intoffset
;
5159 cum
->intoffset
= -1;
5161 /* If this is the trailing part of a word, try to only load that
5162 much into the register. Otherwise load the whole register. Note
5163 that in the latter case we may pick up unwanted bits. It's not a
5164 problem at the moment but may wish to revisit. */
5166 if (intoffset
% BITS_PER_WORD
!= 0)
5168 mode
= mode_for_size (BITS_PER_WORD
- intoffset
% BITS_PER_WORD
,
5170 if (mode
== BLKmode
)
5172 /* We couldn't find an appropriate mode, which happens,
5173 e.g., in packed structs when there are 3 bytes to load.
5174 Back intoffset back to the beginning of the word in this
5176 intoffset
= intoffset
& -BITS_PER_WORD
;
5183 startbit
= intoffset
& -BITS_PER_WORD
;
5184 endbit
= (bitpos
+ BITS_PER_WORD
- 1) & -BITS_PER_WORD
;
5185 intregs
= (endbit
- startbit
) / BITS_PER_WORD
;
5186 this_regno
= cum
->words
+ intoffset
/ BITS_PER_WORD
;
5188 if (intregs
> 0 && intregs
> GP_ARG_NUM_REG
- this_regno
)
5191 intregs
= MIN (intregs
, GP_ARG_NUM_REG
- this_regno
);
5195 intoffset
/= BITS_PER_UNIT
;
5198 regno
= GP_ARG_MIN_REG
+ this_regno
;
5199 reg
= gen_rtx_REG (mode
, regno
);
5201 gen_rtx_EXPR_LIST (VOIDmode
, reg
, GEN_INT (intoffset
));
5204 intoffset
= (intoffset
| (UNITS_PER_WORD
-1)) + 1;
5208 while (intregs
> 0);
5211 /* Recursive workhorse for the following. */
5214 rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS
*cum
, tree type
,
5215 HOST_WIDE_INT startbitpos
, rtx rvec
[],
5220 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
5221 if (TREE_CODE (f
) == FIELD_DECL
)
5223 HOST_WIDE_INT bitpos
= startbitpos
;
5224 tree ftype
= TREE_TYPE (f
);
5225 enum machine_mode mode
;
5226 if (ftype
== error_mark_node
)
5228 mode
= TYPE_MODE (ftype
);
5230 if (DECL_SIZE (f
) != 0
5231 && host_integerp (bit_position (f
), 1))
5232 bitpos
+= int_bit_position (f
);
5234 /* ??? FIXME: else assume zero offset. */
5236 if (TREE_CODE (ftype
) == RECORD_TYPE
)
5237 rs6000_darwin64_record_arg_recurse (cum
, ftype
, bitpos
, rvec
, k
);
5238 else if (cum
->named
&& USE_FP_FOR_ARG_P (cum
, mode
, ftype
))
5243 case SCmode
: mode
= SFmode
; break;
5244 case DCmode
: mode
= DFmode
; break;
5245 case TCmode
: mode
= TFmode
; break;
5249 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5251 = gen_rtx_EXPR_LIST (VOIDmode
,
5252 gen_rtx_REG (mode
, cum
->fregno
++),
5253 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5257 else if (cum
->named
&& USE_ALTIVEC_FOR_ARG_P (cum
, mode
, ftype
, 1))
5259 rs6000_darwin64_record_arg_flush (cum
, bitpos
, rvec
, k
);
5261 = gen_rtx_EXPR_LIST (VOIDmode
,
5262 gen_rtx_REG (mode
, cum
->vregno
++),
5263 GEN_INT (bitpos
/ BITS_PER_UNIT
));
5265 else if (cum
->intoffset
== -1)
5266 cum
->intoffset
= bitpos
;
5270 /* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5271 the register(s) to be used for each field and subfield of a struct
5272 being passed by value, along with the offset of where the
5273 register's value may be found in the block. FP fields go in FP
5274 register, vector fields go in vector registers, and everything
5275 else goes in int registers, packed as in memory.
5277 This code is also used for function return values. RETVAL indicates
5278 whether this is the case.
5280 Much of this is taken from the SPARC V9 port, which has a similar
5281 calling convention. */
5284 rs6000_darwin64_record_arg (CUMULATIVE_ARGS
*orig_cum
, tree type
,
5285 int named
, bool retval
)
5287 rtx rvec
[FIRST_PSEUDO_REGISTER
];
5288 int k
= 1, kbase
= 1;
5289 HOST_WIDE_INT typesize
= int_size_in_bytes (type
);
5290 /* This is a copy; modifications are not visible to our caller. */
5291 CUMULATIVE_ARGS copy_cum
= *orig_cum
;
5292 CUMULATIVE_ARGS
*cum
= ©_cum
;
5294 /* Pad to 16 byte boundary if needed. */
5295 if (!retval
&& TYPE_ALIGN (type
) >= 2 * BITS_PER_WORD
5296 && (cum
->words
% 2) != 0)
5303 /* Put entries into rvec[] for individual FP and vector fields, and
5304 for the chunks of memory that go in int regs. Note we start at
5305 element 1; 0 is reserved for an indication of using memory, and
5306 may or may not be filled in below. */
5307 rs6000_darwin64_record_arg_recurse (cum
, type
, 0, rvec
, &k
);
5308 rs6000_darwin64_record_arg_flush (cum
, typesize
* BITS_PER_UNIT
, rvec
, &k
);
5310 /* If any part of the struct went on the stack put all of it there.
5311 This hack is because the generic code for
5312 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5313 parts of the struct are not at the beginning. */
5317 return NULL_RTX
; /* doesn't go in registers at all */
5319 rvec
[0] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5321 if (k
> 1 || cum
->use_stack
)
5322 return gen_rtx_PARALLEL (BLKmode
, gen_rtvec_v (k
- kbase
, &rvec
[kbase
]));
5327 /* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5330 rs6000_mixed_function_arg (enum machine_mode mode
, tree type
, int align_words
)
5334 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5336 if (align_words
>= GP_ARG_NUM_REG
)
5339 n_units
= rs6000_arg_size (mode
, type
);
5341 /* Optimize the simple case where the arg fits in one gpr, except in
5342 the case of BLKmode due to assign_parms assuming that registers are
5343 BITS_PER_WORD wide. */
5345 || (n_units
== 1 && mode
!= BLKmode
))
5346 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5349 if (align_words
+ n_units
> GP_ARG_NUM_REG
)
5350 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5351 using a magic NULL_RTX component.
5352 This is not strictly correct. Only some of the arg belongs in
5353 memory, not all of it. However, the normal scheme using
5354 function_arg_partial_nregs can result in unusual subregs, eg.
5355 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5356 store the whole arg to memory is often more efficient than code
5357 to store pieces, and we know that space is available in the right
5358 place for the whole arg. */
5359 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5364 rtx r
= gen_rtx_REG (SImode
, GP_ARG_MIN_REG
+ align_words
);
5365 rtx off
= GEN_INT (i
++ * 4);
5366 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5368 while (++align_words
< GP_ARG_NUM_REG
&& --n_units
!= 0);
5370 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5373 /* Determine where to put an argument to a function.
5374 Value is zero to push the argument on the stack,
5375 or a hard register in which to store the argument.
5377 MODE is the argument's machine mode.
5378 TYPE is the data type of the argument (as a tree).
5379 This is null for libcalls where that information may
5381 CUM is a variable of type CUMULATIVE_ARGS which gives info about
5382 the preceding args and about the function being called. It is
5383 not modified in this routine.
5384 NAMED is nonzero if this argument is a named parameter
5385 (otherwise it is an extra parameter matching an ellipsis).
5387 On RS/6000 the first eight words of non-FP are normally in registers
5388 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5389 Under V.4, the first 8 FP args are in registers.
5391 If this is floating-point and no prototype is specified, we use
5392 both an FP and integer register (or possibly FP reg and stack). Library
5393 functions (when CALL_LIBCALL is set) always have the proper types for args,
5394 so we can pass the FP value just in one register. emit_library_function
5395 doesn't support PARALLEL anyway.
5397 Note that for args passed by reference, function_arg will be called
5398 with MODE and TYPE set to that of the pointer to the arg, not the arg
5402 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5403 tree type
, int named
)
5405 enum rs6000_abi abi
= DEFAULT_ABI
;
5407 /* Return a marker to indicate whether CR1 needs to set or clear the
5408 bit that V.4 uses to say fp args were passed in registers.
5409 Assume that we don't need the marker for software floating point,
5410 or compiler generated library calls. */
5411 if (mode
== VOIDmode
)
5414 && (cum
->call_cookie
& CALL_LIBCALL
) == 0
5416 || (cum
->nargs_prototype
< 0
5417 && (cum
->prototype
|| TARGET_NO_PROTOTYPE
))))
5419 /* For the SPE, we need to crxor CR6 always. */
5421 return GEN_INT (cum
->call_cookie
| CALL_V4_SET_FP_ARGS
);
5422 else if (TARGET_HARD_FLOAT
&& TARGET_FPRS
)
5423 return GEN_INT (cum
->call_cookie
5424 | ((cum
->fregno
== FP_ARG_MIN_REG
)
5425 ? CALL_V4_SET_FP_ARGS
5426 : CALL_V4_CLEAR_FP_ARGS
));
5429 return GEN_INT (cum
->call_cookie
);
5432 if (rs6000_darwin64_abi
&& mode
== BLKmode
5433 && TREE_CODE (type
) == RECORD_TYPE
)
5435 rtx rslt
= rs6000_darwin64_record_arg (cum
, type
, named
, false);
5436 if (rslt
!= NULL_RTX
)
5438 /* Else fall through to usual handling. */
5441 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
))
5442 if (TARGET_64BIT
&& ! cum
->prototype
)
5444 /* Vector parameters get passed in vector register
5445 and also in GPRs or memory, in absence of prototype. */
5448 align_words
= (cum
->words
+ 1) & ~1;
5450 if (align_words
>= GP_ARG_NUM_REG
)
5456 slot
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5458 return gen_rtx_PARALLEL (mode
,
5460 gen_rtx_EXPR_LIST (VOIDmode
,
5462 gen_rtx_EXPR_LIST (VOIDmode
,
5463 gen_rtx_REG (mode
, cum
->vregno
),
5467 return gen_rtx_REG (mode
, cum
->vregno
);
5468 else if (TARGET_ALTIVEC_ABI
5469 && (ALTIVEC_VECTOR_MODE (mode
)
5470 || (type
&& TREE_CODE (type
) == VECTOR_TYPE
5471 && int_size_in_bytes (type
) == 16)))
5473 if (named
|| abi
== ABI_V4
)
5477 /* Vector parameters to varargs functions under AIX or Darwin
5478 get passed in memory and possibly also in GPRs. */
5479 int align
, align_words
, n_words
;
5480 enum machine_mode part_mode
;
5482 /* Vector parameters must be 16-byte aligned. This places them at
5483 2 mod 4 in terms of words in 32-bit mode, since the parameter
5484 save area starts at offset 24 from the stack. In 64-bit mode,
5485 they just have to start on an even word, since the parameter
5486 save area is 16-byte aligned. */
5488 align
= (2 - cum
->words
) & 3;
5490 align
= cum
->words
& 1;
5491 align_words
= cum
->words
+ align
;
5493 /* Out of registers? Memory, then. */
5494 if (align_words
>= GP_ARG_NUM_REG
)
5497 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5498 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5500 /* The vector value goes in GPRs. Only the part of the
5501 value in GPRs is reported here. */
5503 n_words
= rs6000_arg_size (mode
, type
);
5504 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
5505 /* Fortunately, there are only two possibilities, the value
5506 is either wholly in GPRs or half in GPRs and half not. */
5509 return gen_rtx_REG (part_mode
, GP_ARG_MIN_REG
+ align_words
);
5512 else if (TARGET_SPE_ABI
&& TARGET_SPE
5513 && (SPE_VECTOR_MODE (mode
)
5514 || (TARGET_E500_DOUBLE
&& (mode
== DFmode
5517 || mode
== TCmode
))))
5518 return rs6000_spe_function_arg (cum
, mode
, type
);
5520 else if (abi
== ABI_V4
)
5522 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5523 && (mode
== SFmode
|| mode
== DFmode
5524 || (mode
== TFmode
&& !TARGET_IEEEQUAD
)))
5526 if (cum
->fregno
+ (mode
== TFmode
? 1 : 0) <= FP_ARG_V4_MAX_REG
)
5527 return gen_rtx_REG (mode
, cum
->fregno
);
5533 int n_words
= rs6000_arg_size (mode
, type
);
5534 int gregno
= cum
->sysv_gregno
;
5536 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5537 (r7,r8) or (r9,r10). As does any other 2 word item such
5538 as complex int due to a historical mistake. */
5540 gregno
+= (1 - gregno
) & 1;
5542 /* Multi-reg args are not split between registers and stack. */
5543 if (gregno
+ n_words
- 1 > GP_ARG_MAX_REG
)
5546 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5547 return rs6000_mixed_function_arg (mode
, type
,
5548 gregno
- GP_ARG_MIN_REG
);
5549 return gen_rtx_REG (mode
, gregno
);
5554 int align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5556 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
5558 rtx rvec
[GP_ARG_NUM_REG
+ 1];
5562 enum machine_mode fmode
= mode
;
5563 unsigned long n_fpreg
= (GET_MODE_SIZE (mode
) + 7) >> 3;
5565 if (cum
->fregno
+ n_fpreg
> FP_ARG_MAX_REG
+ 1)
5567 /* Currently, we only ever need one reg here because complex
5568 doubles are split. */
5569 gcc_assert (cum
->fregno
== FP_ARG_MAX_REG
&& fmode
== TFmode
);
5571 /* Long double split over regs and memory. */
5575 /* Do we also need to pass this arg in the parameter save
5578 && (cum
->nargs_prototype
<= 0
5579 || (DEFAULT_ABI
== ABI_AIX
5581 && align_words
>= GP_ARG_NUM_REG
)));
5583 if (!needs_psave
&& mode
== fmode
)
5584 return gen_rtx_REG (fmode
, cum
->fregno
);
5589 /* Describe the part that goes in gprs or the stack.
5590 This piece must come first, before the fprs. */
5591 if (align_words
< GP_ARG_NUM_REG
)
5593 unsigned long n_words
= rs6000_arg_size (mode
, type
);
5595 if (align_words
+ n_words
> GP_ARG_NUM_REG
5596 || (TARGET_32BIT
&& TARGET_POWERPC64
))
5598 /* If this is partially on the stack, then we only
5599 include the portion actually in registers here. */
5600 enum machine_mode rmode
= TARGET_32BIT
? SImode
: DImode
;
5603 if (align_words
+ n_words
> GP_ARG_NUM_REG
)
5604 /* Not all of the arg fits in gprs. Say that it
5605 goes in memory too, using a magic NULL_RTX
5606 component. Also see comment in
5607 rs6000_mixed_function_arg for why the normal
5608 function_arg_partial_nregs scheme doesn't work
5610 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
,
5614 r
= gen_rtx_REG (rmode
,
5615 GP_ARG_MIN_REG
+ align_words
);
5616 off
= GEN_INT (i
++ * GET_MODE_SIZE (rmode
));
5617 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, off
);
5619 while (++align_words
< GP_ARG_NUM_REG
&& --n_words
!= 0);
5623 /* The whole arg fits in gprs. */
5624 r
= gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5625 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5629 /* It's entirely in memory. */
5630 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, NULL_RTX
, const0_rtx
);
5633 /* Describe where this piece goes in the fprs. */
5634 r
= gen_rtx_REG (fmode
, cum
->fregno
);
5635 rvec
[k
++] = gen_rtx_EXPR_LIST (VOIDmode
, r
, const0_rtx
);
5637 return gen_rtx_PARALLEL (mode
, gen_rtvec_v (k
, rvec
));
5639 else if (align_words
< GP_ARG_NUM_REG
)
5641 if (TARGET_32BIT
&& TARGET_POWERPC64
)
5642 return rs6000_mixed_function_arg (mode
, type
, align_words
);
5644 if (mode
== BLKmode
)
5647 return gen_rtx_REG (mode
, GP_ARG_MIN_REG
+ align_words
);
5654 /* For an arg passed partly in registers and partly in memory, this is
5655 the number of bytes passed in registers. For args passed entirely in
5656 registers or entirely in memory, zero. When an arg is described by a
5657 PARALLEL, perhaps using more than one register type, this function
5658 returns the number of bytes used by the first element of the PARALLEL. */
5661 rs6000_arg_partial_bytes (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5662 tree type
, bool named
)
5667 if (DEFAULT_ABI
== ABI_V4
)
5670 if (USE_ALTIVEC_FOR_ARG_P (cum
, mode
, type
, named
)
5671 && cum
->nargs_prototype
>= 0)
5674 /* In this complicated case we just disable the partial_nregs code. */
5675 if (rs6000_darwin64_abi
&& mode
== BLKmode
5676 && TREE_CODE (type
) == RECORD_TYPE
5677 && int_size_in_bytes (type
) > 0)
5680 align_words
= rs6000_parm_start (mode
, type
, cum
->words
);
5682 if (USE_FP_FOR_ARG_P (cum
, mode
, type
))
5684 /* If we are passing this arg in the fixed parameter save area
5685 (gprs or memory) as well as fprs, then this function should
5686 return the number of partial bytes passed in the parameter
5687 save area rather than partial bytes passed in fprs. */
5689 && (cum
->nargs_prototype
<= 0
5690 || (DEFAULT_ABI
== ABI_AIX
5692 && align_words
>= GP_ARG_NUM_REG
)))
5694 else if (cum
->fregno
+ ((GET_MODE_SIZE (mode
) + 7) >> 3)
5695 > FP_ARG_MAX_REG
+ 1)
5696 ret
= (FP_ARG_MAX_REG
+ 1 - cum
->fregno
) * 8;
5697 else if (cum
->nargs_prototype
>= 0)
5701 if (align_words
< GP_ARG_NUM_REG
5702 && GP_ARG_NUM_REG
< align_words
+ rs6000_arg_size (mode
, type
))
5703 ret
= (GP_ARG_NUM_REG
- align_words
) * (TARGET_32BIT
? 4 : 8);
5705 if (ret
!= 0 && TARGET_DEBUG_ARG
)
5706 fprintf (stderr
, "rs6000_arg_partial_bytes: %d\n", ret
);
5711 /* A C expression that indicates when an argument must be passed by
5712 reference. If nonzero for an argument, a copy of that argument is
5713 made in memory and a pointer to the argument is passed instead of
5714 the argument itself. The pointer is passed in whatever way is
5715 appropriate for passing a pointer to that type.
5717 Under V.4, aggregates and long double are passed by reference.
5719 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5720 reference unless the AltiVec vector extension ABI is in force.
5722 As an extension to all ABIs, variable sized types are passed by
5726 rs6000_pass_by_reference (CUMULATIVE_ARGS
*cum ATTRIBUTE_UNUSED
,
5727 enum machine_mode mode
, tree type
,
5728 bool named ATTRIBUTE_UNUSED
)
5730 if (DEFAULT_ABI
== ABI_V4
&& TARGET_IEEEQUAD
&& mode
== TFmode
)
5732 if (TARGET_DEBUG_ARG
)
5733 fprintf (stderr
, "function_arg_pass_by_reference: V4 long double\n");
5740 if (DEFAULT_ABI
== ABI_V4
&& AGGREGATE_TYPE_P (type
))
5742 if (TARGET_DEBUG_ARG
)
5743 fprintf (stderr
, "function_arg_pass_by_reference: V4 aggregate\n");
5747 if (int_size_in_bytes (type
) < 0)
5749 if (TARGET_DEBUG_ARG
)
5750 fprintf (stderr
, "function_arg_pass_by_reference: variable size\n");
5754 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5755 modes only exist for GCC vector types if -maltivec. */
5756 if (TARGET_32BIT
&& !TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
5758 if (TARGET_DEBUG_ARG
)
5759 fprintf (stderr
, "function_arg_pass_by_reference: AltiVec\n");
5763 /* Pass synthetic vectors in memory. */
5764 if (TREE_CODE (type
) == VECTOR_TYPE
5765 && int_size_in_bytes (type
) > (TARGET_ALTIVEC_ABI
? 16 : 8))
5767 static bool warned_for_pass_big_vectors
= false;
5768 if (TARGET_DEBUG_ARG
)
5769 fprintf (stderr
, "function_arg_pass_by_reference: synthetic vector\n");
5770 if (!warned_for_pass_big_vectors
)
5772 warning (0, "GCC vector passed by reference: "
5773 "non-standard ABI extension with no compatibility guarantee");
5774 warned_for_pass_big_vectors
= true;
5783 rs6000_move_block_from_reg (int regno
, rtx x
, int nregs
)
5786 enum machine_mode reg_mode
= TARGET_32BIT
? SImode
: DImode
;
5791 for (i
= 0; i
< nregs
; i
++)
5793 rtx tem
= adjust_address_nv (x
, reg_mode
, i
* GET_MODE_SIZE (reg_mode
));
5794 if (reload_completed
)
5796 if (! strict_memory_address_p (reg_mode
, XEXP (tem
, 0)))
5799 tem
= simplify_gen_subreg (reg_mode
, x
, BLKmode
,
5800 i
* GET_MODE_SIZE (reg_mode
));
5803 tem
= replace_equiv_address (tem
, XEXP (tem
, 0));
5807 emit_move_insn (tem
, gen_rtx_REG (reg_mode
, regno
+ i
));
5811 /* Perform any needed actions needed for a function that is receiving a
5812 variable number of arguments.
5816 MODE and TYPE are the mode and type of the current parameter.
5818 PRETEND_SIZE is a variable that should be set to the amount of stack
5819 that must be pushed by the prolog to pretend that our caller pushed
5822 Normally, this macro will push all remaining incoming registers on the
5823 stack and set PRETEND_SIZE to the length of the registers pushed. */
5826 setup_incoming_varargs (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
5827 tree type
, int *pretend_size ATTRIBUTE_UNUSED
,
5830 CUMULATIVE_ARGS next_cum
;
5831 int reg_size
= TARGET_32BIT
? 4 : 8;
5832 rtx save_area
= NULL_RTX
, mem
;
5833 int first_reg_offset
, set
;
5835 /* Skip the last named argument. */
5837 function_arg_advance (&next_cum
, mode
, type
, 1, 0);
5839 if (DEFAULT_ABI
== ABI_V4
)
5841 first_reg_offset
= next_cum
.sysv_gregno
- GP_ARG_MIN_REG
;
5845 int gpr_reg_num
= 0, gpr_size
= 0, fpr_size
= 0;
5846 HOST_WIDE_INT offset
= 0;
5848 /* Try to optimize the size of the varargs save area.
5849 The ABI requires that ap.reg_save_area is doubleword
5850 aligned, but we don't need to allocate space for all
5851 the bytes, only those to which we actually will save
5853 if (cfun
->va_list_gpr_size
&& first_reg_offset
< GP_ARG_NUM_REG
)
5854 gpr_reg_num
= GP_ARG_NUM_REG
- first_reg_offset
;
5855 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
5856 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5857 && cfun
->va_list_fpr_size
)
5860 fpr_size
= (next_cum
.fregno
- FP_ARG_MIN_REG
)
5861 * UNITS_PER_FP_WORD
;
5862 if (cfun
->va_list_fpr_size
5863 < FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5864 fpr_size
+= cfun
->va_list_fpr_size
* UNITS_PER_FP_WORD
;
5866 fpr_size
+= (FP_ARG_V4_MAX_REG
+ 1 - next_cum
.fregno
)
5867 * UNITS_PER_FP_WORD
;
5871 offset
= -((first_reg_offset
* reg_size
) & ~7);
5872 if (!fpr_size
&& gpr_reg_num
> cfun
->va_list_gpr_size
)
5874 gpr_reg_num
= cfun
->va_list_gpr_size
;
5875 if (reg_size
== 4 && (first_reg_offset
& 1))
5878 gpr_size
= (gpr_reg_num
* reg_size
+ 7) & ~7;
5881 offset
= - (int) (next_cum
.fregno
- FP_ARG_MIN_REG
)
5883 - (int) (GP_ARG_NUM_REG
* reg_size
);
5885 if (gpr_size
+ fpr_size
)
5888 = assign_stack_local (BLKmode
, gpr_size
+ fpr_size
, 64);
5889 gcc_assert (GET_CODE (reg_save_area
) == MEM
);
5890 reg_save_area
= XEXP (reg_save_area
, 0);
5891 if (GET_CODE (reg_save_area
) == PLUS
)
5893 gcc_assert (XEXP (reg_save_area
, 0)
5894 == virtual_stack_vars_rtx
);
5895 gcc_assert (GET_CODE (XEXP (reg_save_area
, 1)) == CONST_INT
);
5896 offset
+= INTVAL (XEXP (reg_save_area
, 1));
5899 gcc_assert (reg_save_area
== virtual_stack_vars_rtx
);
5902 cfun
->machine
->varargs_save_offset
= offset
;
5903 save_area
= plus_constant (virtual_stack_vars_rtx
, offset
);
5908 first_reg_offset
= next_cum
.words
;
5909 save_area
= virtual_incoming_args_rtx
;
5911 if (targetm
.calls
.must_pass_in_stack (mode
, type
))
5912 first_reg_offset
+= rs6000_arg_size (TYPE_MODE (type
), type
);
5915 set
= get_varargs_alias_set ();
5916 if (! no_rtl
&& first_reg_offset
< GP_ARG_NUM_REG
5917 && cfun
->va_list_gpr_size
)
5919 int nregs
= GP_ARG_NUM_REG
- first_reg_offset
;
5921 if (va_list_gpr_counter_field
)
5923 /* V4 va_list_gpr_size counts number of registers needed. */
5924 if (nregs
> cfun
->va_list_gpr_size
)
5925 nregs
= cfun
->va_list_gpr_size
;
5929 /* char * va_list instead counts number of bytes needed. */
5930 if (nregs
> cfun
->va_list_gpr_size
/ reg_size
)
5931 nregs
= cfun
->va_list_gpr_size
/ reg_size
;
5934 mem
= gen_rtx_MEM (BLKmode
,
5935 plus_constant (save_area
,
5936 first_reg_offset
* reg_size
));
5937 MEM_NOTRAP_P (mem
) = 1;
5938 set_mem_alias_set (mem
, set
);
5939 set_mem_align (mem
, BITS_PER_WORD
);
5941 rs6000_move_block_from_reg (GP_ARG_MIN_REG
+ first_reg_offset
, mem
,
5945 /* Save FP registers if needed. */
5946 if (DEFAULT_ABI
== ABI_V4
5947 && TARGET_HARD_FLOAT
&& TARGET_FPRS
5949 && next_cum
.fregno
<= FP_ARG_V4_MAX_REG
5950 && cfun
->va_list_fpr_size
)
5952 int fregno
= next_cum
.fregno
, nregs
;
5953 rtx cr1
= gen_rtx_REG (CCmode
, CR1_REGNO
);
5954 rtx lab
= gen_label_rtx ();
5955 int off
= (GP_ARG_NUM_REG
* reg_size
) + ((fregno
- FP_ARG_MIN_REG
)
5956 * UNITS_PER_FP_WORD
);
5959 (gen_rtx_SET (VOIDmode
,
5961 gen_rtx_IF_THEN_ELSE (VOIDmode
,
5962 gen_rtx_NE (VOIDmode
, cr1
,
5964 gen_rtx_LABEL_REF (VOIDmode
, lab
),
5968 fregno
<= FP_ARG_V4_MAX_REG
&& nregs
< cfun
->va_list_fpr_size
;
5969 fregno
++, off
+= UNITS_PER_FP_WORD
, nregs
++)
5971 mem
= gen_rtx_MEM (DFmode
, plus_constant (save_area
, off
));
5972 MEM_NOTRAP_P (mem
) = 1;
5973 set_mem_alias_set (mem
, set
);
5974 set_mem_align (mem
, GET_MODE_ALIGNMENT (DFmode
));
5975 emit_move_insn (mem
, gen_rtx_REG (DFmode
, fregno
));
5982 /* Create the va_list data type. */
5985 rs6000_build_builtin_va_list (void)
5987 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
, record
, type_decl
;
5989 /* For AIX, prefer 'char *' because that's what the system
5990 header files like. */
5991 if (DEFAULT_ABI
!= ABI_V4
)
5992 return build_pointer_type (char_type_node
);
5994 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
5995 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
5997 f_gpr
= build_decl (FIELD_DECL
, get_identifier ("gpr"),
5998 unsigned_char_type_node
);
5999 f_fpr
= build_decl (FIELD_DECL
, get_identifier ("fpr"),
6000 unsigned_char_type_node
);
6001 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6003 f_res
= build_decl (FIELD_DECL
, get_identifier ("reserved"),
6004 short_unsigned_type_node
);
6005 f_ovf
= build_decl (FIELD_DECL
, get_identifier ("overflow_arg_area"),
6007 f_sav
= build_decl (FIELD_DECL
, get_identifier ("reg_save_area"),
6010 va_list_gpr_counter_field
= f_gpr
;
6011 va_list_fpr_counter_field
= f_fpr
;
6013 DECL_FIELD_CONTEXT (f_gpr
) = record
;
6014 DECL_FIELD_CONTEXT (f_fpr
) = record
;
6015 DECL_FIELD_CONTEXT (f_res
) = record
;
6016 DECL_FIELD_CONTEXT (f_ovf
) = record
;
6017 DECL_FIELD_CONTEXT (f_sav
) = record
;
6019 TREE_CHAIN (record
) = type_decl
;
6020 TYPE_NAME (record
) = type_decl
;
6021 TYPE_FIELDS (record
) = f_gpr
;
6022 TREE_CHAIN (f_gpr
) = f_fpr
;
6023 TREE_CHAIN (f_fpr
) = f_res
;
6024 TREE_CHAIN (f_res
) = f_ovf
;
6025 TREE_CHAIN (f_ovf
) = f_sav
;
6027 layout_type (record
);
6029 /* The correct type is an array type of one element. */
6030 return build_array_type (record
, build_index_type (size_zero_node
));
6033 /* Implement va_start. */
6036 rs6000_va_start (tree valist
, rtx nextarg
)
6038 HOST_WIDE_INT words
, n_gpr
, n_fpr
;
6039 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6040 tree gpr
, fpr
, ovf
, sav
, t
;
6042 /* Only SVR4 needs something special. */
6043 if (DEFAULT_ABI
!= ABI_V4
)
6045 std_expand_builtin_va_start (valist
, nextarg
);
6049 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6050 f_fpr
= TREE_CHAIN (f_gpr
);
6051 f_res
= TREE_CHAIN (f_fpr
);
6052 f_ovf
= TREE_CHAIN (f_res
);
6053 f_sav
= TREE_CHAIN (f_ovf
);
6055 valist
= build_va_arg_indirect_ref (valist
);
6056 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6057 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6058 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6059 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6061 /* Count number of gp and fp argument registers used. */
6062 words
= current_function_args_info
.words
;
6063 n_gpr
= MIN (current_function_args_info
.sysv_gregno
- GP_ARG_MIN_REG
,
6065 n_fpr
= MIN (current_function_args_info
.fregno
- FP_ARG_MIN_REG
,
6068 if (TARGET_DEBUG_ARG
)
6069 fprintf (stderr
, "va_start: words = "HOST_WIDE_INT_PRINT_DEC
", n_gpr = "
6070 HOST_WIDE_INT_PRINT_DEC
", n_fpr = "HOST_WIDE_INT_PRINT_DEC
"\n",
6071 words
, n_gpr
, n_fpr
);
6073 if (cfun
->va_list_gpr_size
)
6075 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (gpr
), gpr
,
6076 build_int_cst (NULL_TREE
, n_gpr
));
6077 TREE_SIDE_EFFECTS (t
) = 1;
6078 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6081 if (cfun
->va_list_fpr_size
)
6083 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (fpr
), fpr
,
6084 build_int_cst (NULL_TREE
, n_fpr
));
6085 TREE_SIDE_EFFECTS (t
) = 1;
6086 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6089 /* Find the overflow area. */
6090 t
= make_tree (TREE_TYPE (ovf
), virtual_incoming_args_rtx
);
6092 t
= build2 (PLUS_EXPR
, TREE_TYPE (ovf
), t
,
6093 build_int_cst (NULL_TREE
, words
* UNITS_PER_WORD
));
6094 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6095 TREE_SIDE_EFFECTS (t
) = 1;
6096 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6098 /* If there were no va_arg invocations, don't set up the register
6100 if (!cfun
->va_list_gpr_size
6101 && !cfun
->va_list_fpr_size
6102 && n_gpr
< GP_ARG_NUM_REG
6103 && n_fpr
< FP_ARG_V4_MAX_REG
)
6106 /* Find the register save area. */
6107 t
= make_tree (TREE_TYPE (sav
), virtual_stack_vars_rtx
);
6108 if (cfun
->machine
->varargs_save_offset
)
6109 t
= build2 (PLUS_EXPR
, TREE_TYPE (sav
), t
,
6110 build_int_cst (NULL_TREE
, cfun
->machine
->varargs_save_offset
));
6111 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (sav
), sav
, t
);
6112 TREE_SIDE_EFFECTS (t
) = 1;
6113 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
6116 /* Implement va_arg. */
6119 rs6000_gimplify_va_arg (tree valist
, tree type
, tree
*pre_p
, tree
*post_p
)
6121 tree f_gpr
, f_fpr
, f_res
, f_ovf
, f_sav
;
6122 tree gpr
, fpr
, ovf
, sav
, reg
, t
, u
;
6123 int size
, rsize
, n_reg
, sav_ofs
, sav_scale
;
6124 tree lab_false
, lab_over
, addr
;
6126 tree ptrtype
= build_pointer_type (type
);
6128 if (pass_by_reference (NULL
, TYPE_MODE (type
), type
, false))
6130 t
= rs6000_gimplify_va_arg (valist
, ptrtype
, pre_p
, post_p
);
6131 return build_va_arg_indirect_ref (t
);
6134 if (DEFAULT_ABI
!= ABI_V4
)
6136 if (targetm
.calls
.split_complex_arg
&& TREE_CODE (type
) == COMPLEX_TYPE
)
6138 tree elem_type
= TREE_TYPE (type
);
6139 enum machine_mode elem_mode
= TYPE_MODE (elem_type
);
6140 int elem_size
= GET_MODE_SIZE (elem_mode
);
6142 if (elem_size
< UNITS_PER_WORD
)
6144 tree real_part
, imag_part
;
6145 tree post
= NULL_TREE
;
6147 real_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6149 /* Copy the value into a temporary, lest the formal temporary
6150 be reused out from under us. */
6151 real_part
= get_initialized_tmp_var (real_part
, pre_p
, &post
);
6152 append_to_statement_list (post
, pre_p
);
6154 imag_part
= rs6000_gimplify_va_arg (valist
, elem_type
, pre_p
,
6157 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
6161 return std_gimplify_va_arg_expr (valist
, type
, pre_p
, post_p
);
6164 f_gpr
= TYPE_FIELDS (TREE_TYPE (va_list_type_node
));
6165 f_fpr
= TREE_CHAIN (f_gpr
);
6166 f_res
= TREE_CHAIN (f_fpr
);
6167 f_ovf
= TREE_CHAIN (f_res
);
6168 f_sav
= TREE_CHAIN (f_ovf
);
6170 valist
= build_va_arg_indirect_ref (valist
);
6171 gpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_gpr
), valist
, f_gpr
, NULL_TREE
);
6172 fpr
= build3 (COMPONENT_REF
, TREE_TYPE (f_fpr
), valist
, f_fpr
, NULL_TREE
);
6173 ovf
= build3 (COMPONENT_REF
, TREE_TYPE (f_ovf
), valist
, f_ovf
, NULL_TREE
);
6174 sav
= build3 (COMPONENT_REF
, TREE_TYPE (f_sav
), valist
, f_sav
, NULL_TREE
);
6176 size
= int_size_in_bytes (type
);
6177 rsize
= (size
+ 3) / 4;
6180 if (TARGET_HARD_FLOAT
&& TARGET_FPRS
6181 && (TYPE_MODE (type
) == SFmode
6182 || TYPE_MODE (type
) == DFmode
6183 || TYPE_MODE (type
) == TFmode
))
6185 /* FP args go in FP registers, if present. */
6187 n_reg
= (size
+ 7) / 8;
6190 if (TYPE_MODE (type
) != SFmode
)
6195 /* Otherwise into GP registers. */
6204 /* Pull the value out of the saved registers.... */
6207 addr
= create_tmp_var (ptr_type_node
, "addr");
6208 DECL_POINTER_ALIAS_SET (addr
) = get_varargs_alias_set ();
6210 /* AltiVec vectors never go in registers when -mabi=altivec. */
6211 if (TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (TYPE_MODE (type
)))
6215 lab_false
= create_artificial_label ();
6216 lab_over
= create_artificial_label ();
6218 /* Long long and SPE vectors are aligned in the registers.
6219 As are any other 2 gpr item such as complex int due to a
6220 historical mistake. */
6222 if (n_reg
== 2 && reg
== gpr
)
6224 u
= build2 (BIT_AND_EXPR
, TREE_TYPE (reg
), reg
,
6225 size_int (n_reg
- 1));
6226 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, u
);
6229 t
= fold_convert (TREE_TYPE (reg
), size_int (8 - n_reg
+ 1));
6230 t
= build2 (GE_EXPR
, boolean_type_node
, u
, t
);
6231 u
= build1 (GOTO_EXPR
, void_type_node
, lab_false
);
6232 t
= build3 (COND_EXPR
, void_type_node
, t
, u
, NULL_TREE
);
6233 gimplify_and_add (t
, pre_p
);
6237 t
= build2 (PLUS_EXPR
, ptr_type_node
, sav
, size_int (sav_ofs
));
6239 u
= build2 (POSTINCREMENT_EXPR
, TREE_TYPE (reg
), reg
, size_int (n_reg
));
6240 u
= build1 (CONVERT_EXPR
, integer_type_node
, u
);
6241 u
= build2 (MULT_EXPR
, integer_type_node
, u
, size_int (sav_scale
));
6242 t
= build2 (PLUS_EXPR
, ptr_type_node
, t
, u
);
6244 t
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6245 gimplify_and_add (t
, pre_p
);
6247 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
6248 gimplify_and_add (t
, pre_p
);
6250 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
6251 append_to_statement_list (t
, pre_p
);
6253 if ((n_reg
== 2 && reg
!= gpr
) || n_reg
> 2)
6255 /* Ensure that we don't find any more args in regs.
6256 Alignment has taken care of the n_reg == 2 gpr case. */
6257 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (reg
), reg
, size_int (8));
6258 gimplify_and_add (t
, pre_p
);
6262 /* ... otherwise out of the overflow area. */
6264 /* Care for on-stack alignment if needed. */
6268 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (align
- 1));
6269 t
= build2 (BIT_AND_EXPR
, TREE_TYPE (t
), t
,
6270 build_int_cst (NULL_TREE
, -align
));
6272 gimplify_expr (&t
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
6274 u
= build2 (GIMPLE_MODIFY_STMT
, void_type_node
, addr
, t
);
6275 gimplify_and_add (u
, pre_p
);
6277 t
= build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, size_int (size
));
6278 t
= build2 (GIMPLE_MODIFY_STMT
, TREE_TYPE (ovf
), ovf
, t
);
6279 gimplify_and_add (t
, pre_p
);
6283 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
6284 append_to_statement_list (t
, pre_p
);
6287 if (STRICT_ALIGNMENT
6288 && (TYPE_ALIGN (type
)
6289 > (unsigned) BITS_PER_UNIT
* (align
< 4 ? 4 : align
)))
6291 /* The value (of type complex double, for example) may not be
6292 aligned in memory in the saved registers, so copy via a
6293 temporary. (This is the same code as used for SPARC.) */
6294 tree tmp
= create_tmp_var (type
, "va_arg_tmp");
6295 tree dest_addr
= build_fold_addr_expr (tmp
);
6297 tree copy
= build_call_expr (implicit_built_in_decls
[BUILT_IN_MEMCPY
],
6298 3, dest_addr
, addr
, size_int (rsize
* 4));
6300 gimplify_and_add (copy
, pre_p
);
6304 addr
= fold_convert (ptrtype
, addr
);
6305 return build_va_arg_indirect_ref (addr
);
6311 def_builtin (int mask
, const char *name
, tree type
, int code
)
6313 if (mask
& target_flags
)
6315 if (rs6000_builtin_decls
[code
])
6318 rs6000_builtin_decls
[code
] =
6319 add_builtin_function (name
, type
, code
, BUILT_IN_MD
,
6324 /* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6326 static const struct builtin_description bdesc_3arg
[] =
6328 { MASK_ALTIVEC
, CODE_FOR_altivec_vmaddfp
, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP
},
6329 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhaddshs
, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS
},
6330 { MASK_ALTIVEC
, CODE_FOR_altivec_vmhraddshs
, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS
},
6331 { MASK_ALTIVEC
, CODE_FOR_altivec_vmladduhm
, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM
},
6332 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumubm
, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM
},
6333 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsummbm
, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM
},
6334 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhm
, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM
},
6335 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshm
, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM
},
6336 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumuhs
, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS
},
6337 { MASK_ALTIVEC
, CODE_FOR_altivec_vmsumshs
, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS
},
6338 { MASK_ALTIVEC
, CODE_FOR_altivec_vnmsubfp
, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP
},
6339 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4sf
, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF
},
6340 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v4si
, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI
},
6341 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v8hi
, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI
},
6342 { MASK_ALTIVEC
, CODE_FOR_altivec_vperm_v16qi
, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI
},
6343 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4sf
, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF
},
6344 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v4si
, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI
},
6345 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v8hi
, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI
},
6346 { MASK_ALTIVEC
, CODE_FOR_altivec_vsel_v16qi
, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI
},
6347 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v16qi
, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI
},
6348 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v8hi
, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI
},
6349 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4si
, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI
},
6350 { MASK_ALTIVEC
, CODE_FOR_altivec_vsldoi_v4sf
, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF
},
6352 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD
},
6353 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS
},
6354 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD
},
6355 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS
},
6356 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM
},
6357 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM
},
6358 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM
},
6359 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM
},
6360 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM
},
6361 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS
},
6362 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS
},
6363 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS
},
6364 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB
},
6365 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM
},
6366 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL
},
6369 /* DST operations: void foo (void *, const int, const char). */
6371 static const struct builtin_description bdesc_dst
[] =
6373 { MASK_ALTIVEC
, CODE_FOR_altivec_dst
, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST
},
6374 { MASK_ALTIVEC
, CODE_FOR_altivec_dstt
, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT
},
6375 { MASK_ALTIVEC
, CODE_FOR_altivec_dstst
, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST
},
6376 { MASK_ALTIVEC
, CODE_FOR_altivec_dststt
, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT
},
6378 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST
},
6379 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT
},
6380 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST
},
6381 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT
}
6384 /* Simple binary operations: VECc = foo (VECa, VECb). */
6386 static struct builtin_description bdesc_2arg
[] =
6388 { MASK_ALTIVEC
, CODE_FOR_addv16qi3
, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM
},
6389 { MASK_ALTIVEC
, CODE_FOR_addv8hi3
, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM
},
6390 { MASK_ALTIVEC
, CODE_FOR_addv4si3
, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM
},
6391 { MASK_ALTIVEC
, CODE_FOR_addv4sf3
, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP
},
6392 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddcuw
, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW
},
6393 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddubs
, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS
},
6394 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsbs
, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS
},
6395 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduhs
, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS
},
6396 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddshs
, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS
},
6397 { MASK_ALTIVEC
, CODE_FOR_altivec_vadduws
, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS
},
6398 { MASK_ALTIVEC
, CODE_FOR_altivec_vaddsws
, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS
},
6399 { MASK_ALTIVEC
, CODE_FOR_andv4si3
, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND
},
6400 { MASK_ALTIVEC
, CODE_FOR_andcv4si3
, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC
},
6401 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgub
, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB
},
6402 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsb
, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB
},
6403 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguh
, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH
},
6404 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsh
, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH
},
6405 { MASK_ALTIVEC
, CODE_FOR_altivec_vavguw
, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW
},
6406 { MASK_ALTIVEC
, CODE_FOR_altivec_vavgsw
, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW
},
6407 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfux
, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX
},
6408 { MASK_ALTIVEC
, CODE_FOR_altivec_vcfsx
, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX
},
6409 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpbfp
, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP
},
6410 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequb
, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB
},
6411 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequh
, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH
},
6412 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpequw
, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW
},
6413 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpeqfp
, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP
},
6414 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgefp
, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP
},
6415 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtub
, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB
},
6416 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsb
, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB
},
6417 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuh
, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH
},
6418 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsh
, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH
},
6419 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtuw
, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW
},
6420 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtsw
, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW
},
6421 { MASK_ALTIVEC
, CODE_FOR_altivec_vcmpgtfp
, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP
},
6422 { MASK_ALTIVEC
, CODE_FOR_altivec_vctsxs
, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS
},
6423 { MASK_ALTIVEC
, CODE_FOR_altivec_vctuxs
, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS
},
6424 { MASK_ALTIVEC
, CODE_FOR_umaxv16qi3
, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB
},
6425 { MASK_ALTIVEC
, CODE_FOR_smaxv16qi3
, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB
},
6426 { MASK_ALTIVEC
, CODE_FOR_umaxv8hi3
, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH
},
6427 { MASK_ALTIVEC
, CODE_FOR_smaxv8hi3
, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH
},
6428 { MASK_ALTIVEC
, CODE_FOR_umaxv4si3
, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW
},
6429 { MASK_ALTIVEC
, CODE_FOR_smaxv4si3
, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW
},
6430 { MASK_ALTIVEC
, CODE_FOR_smaxv4sf3
, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP
},
6431 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghb
, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB
},
6432 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghh
, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH
},
6433 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrghw
, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW
},
6434 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglb
, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB
},
6435 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglh
, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH
},
6436 { MASK_ALTIVEC
, CODE_FOR_altivec_vmrglw
, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW
},
6437 { MASK_ALTIVEC
, CODE_FOR_uminv16qi3
, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB
},
6438 { MASK_ALTIVEC
, CODE_FOR_sminv16qi3
, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB
},
6439 { MASK_ALTIVEC
, CODE_FOR_uminv8hi3
, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH
},
6440 { MASK_ALTIVEC
, CODE_FOR_sminv8hi3
, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH
},
6441 { MASK_ALTIVEC
, CODE_FOR_uminv4si3
, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW
},
6442 { MASK_ALTIVEC
, CODE_FOR_sminv4si3
, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW
},
6443 { MASK_ALTIVEC
, CODE_FOR_sminv4sf3
, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP
},
6444 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleub
, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB
},
6445 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesb
, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB
},
6446 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuleuh
, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH
},
6447 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulesh
, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH
},
6448 { MASK_ALTIVEC
, CODE_FOR_altivec_vmuloub
, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB
},
6449 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosb
, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB
},
6450 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulouh
, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH
},
6451 { MASK_ALTIVEC
, CODE_FOR_altivec_vmulosh
, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH
},
6452 { MASK_ALTIVEC
, CODE_FOR_altivec_norv4si3
, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR
},
6453 { MASK_ALTIVEC
, CODE_FOR_iorv4si3
, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR
},
6454 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhum
, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM
},
6455 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwum
, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM
},
6456 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkpx
, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX
},
6457 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshss
, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS
},
6458 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswss
, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS
},
6459 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuhus
, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS
},
6460 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkshus
, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS
},
6461 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkuwus
, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS
},
6462 { MASK_ALTIVEC
, CODE_FOR_altivec_vpkswus
, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS
},
6463 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlb
, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB
},
6464 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlh
, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH
},
6465 { MASK_ALTIVEC
, CODE_FOR_altivec_vrlw
, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW
},
6466 { MASK_ALTIVEC
, CODE_FOR_altivec_vslb
, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB
},
6467 { MASK_ALTIVEC
, CODE_FOR_altivec_vslh
, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH
},
6468 { MASK_ALTIVEC
, CODE_FOR_altivec_vslw
, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW
},
6469 { MASK_ALTIVEC
, CODE_FOR_altivec_vsl
, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL
},
6470 { MASK_ALTIVEC
, CODE_FOR_altivec_vslo
, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO
},
6471 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltb
, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB
},
6472 { MASK_ALTIVEC
, CODE_FOR_altivec_vsplth
, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH
},
6473 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltw
, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW
},
6474 { MASK_ALTIVEC
, CODE_FOR_lshrv16qi3
, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB
},
6475 { MASK_ALTIVEC
, CODE_FOR_lshrv8hi3
, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH
},
6476 { MASK_ALTIVEC
, CODE_FOR_lshrv4si3
, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW
},
6477 { MASK_ALTIVEC
, CODE_FOR_ashrv16qi3
, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB
},
6478 { MASK_ALTIVEC
, CODE_FOR_ashrv8hi3
, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH
},
6479 { MASK_ALTIVEC
, CODE_FOR_ashrv4si3
, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW
},
6480 { MASK_ALTIVEC
, CODE_FOR_altivec_vsr
, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR
},
6481 { MASK_ALTIVEC
, CODE_FOR_altivec_vsro
, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO
},
6482 { MASK_ALTIVEC
, CODE_FOR_subv16qi3
, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM
},
6483 { MASK_ALTIVEC
, CODE_FOR_subv8hi3
, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM
},
6484 { MASK_ALTIVEC
, CODE_FOR_subv4si3
, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM
},
6485 { MASK_ALTIVEC
, CODE_FOR_subv4sf3
, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP
},
6486 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubcuw
, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW
},
6487 { MASK_ALTIVEC
, CODE_FOR_altivec_vsububs
, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS
},
6488 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsbs
, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS
},
6489 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuhs
, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS
},
6490 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubshs
, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS
},
6491 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubuws
, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS
},
6492 { MASK_ALTIVEC
, CODE_FOR_altivec_vsubsws
, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS
},
6493 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4ubs
, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS
},
6494 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4sbs
, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS
},
6495 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum4shs
, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS
},
6496 { MASK_ALTIVEC
, CODE_FOR_altivec_vsum2sws
, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS
},
6497 { MASK_ALTIVEC
, CODE_FOR_altivec_vsumsws
, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS
},
6498 { MASK_ALTIVEC
, CODE_FOR_xorv4si3
, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR
},
6500 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD
},
6501 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP
},
6502 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM
},
6503 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM
},
6504 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM
},
6505 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC
},
6506 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS
},
6507 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS
},
6508 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS
},
6509 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS
},
6510 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS
},
6511 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS
},
6512 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS
},
6513 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND
},
6514 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC
},
6515 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG
},
6516 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW
},
6517 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW
},
6518 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH
},
6519 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH
},
6520 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB
},
6521 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB
},
6522 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB
},
6523 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ
},
6524 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP
},
6525 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW
},
6526 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH
},
6527 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB
},
6528 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE
},
6529 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT
},
6530 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP
},
6531 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW
},
6532 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW
},
6533 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH
},
6534 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH
},
6535 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB
},
6536 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB
},
6537 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE
},
6538 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT
},
6539 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX
},
6540 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP
},
6541 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW
},
6542 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW
},
6543 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH
},
6544 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH
},
6545 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB
},
6546 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB
},
6547 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH
},
6548 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW
},
6549 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH
},
6550 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB
},
6551 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL
},
6552 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW
},
6553 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH
},
6554 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB
},
6555 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN
},
6556 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP
},
6557 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW
},
6558 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW
},
6559 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH
},
6560 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH
},
6561 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB
},
6562 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB
},
6563 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE
},
6564 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB
},
6565 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB
},
6566 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH
},
6567 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH
},
6568 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO
},
6569 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH
},
6570 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH
},
6571 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB
},
6572 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB
},
6573 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR
},
6574 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR
},
6575 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK
},
6576 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM
},
6577 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM
},
6578 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX
},
6579 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS
},
6580 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS
},
6581 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS
},
6582 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS
},
6583 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS
},
6584 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU
},
6585 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS
},
6586 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS
},
6587 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL
},
6588 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW
},
6589 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH
},
6590 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB
},
6591 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL
},
6592 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW
},
6593 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH
},
6594 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB
},
6595 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL
},
6596 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO
},
6597 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR
},
6598 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW
},
6599 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH
},
6600 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB
},
6601 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA
},
6602 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW
},
6603 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH
},
6604 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB
},
6605 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL
},
6606 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO
},
6607 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB
},
6608 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP
},
6609 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM
},
6610 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM
},
6611 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM
},
6612 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC
},
6613 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS
},
6614 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS
},
6615 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS
},
6616 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS
},
6617 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS
},
6618 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS
},
6619 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS
},
6620 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S
},
6621 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS
},
6622 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS
},
6623 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS
},
6624 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S
},
6625 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS
},
6626 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR
},
6628 /* Place holder, leave as first spe builtin. */
6629 { 0, CODE_FOR_spe_evaddw
, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW
},
6630 { 0, CODE_FOR_spe_evand
, "__builtin_spe_evand", SPE_BUILTIN_EVAND
},
6631 { 0, CODE_FOR_spe_evandc
, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC
},
6632 { 0, CODE_FOR_spe_evdivws
, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS
},
6633 { 0, CODE_FOR_spe_evdivwu
, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU
},
6634 { 0, CODE_FOR_spe_eveqv
, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV
},
6635 { 0, CODE_FOR_spe_evfsadd
, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD
},
6636 { 0, CODE_FOR_spe_evfsdiv
, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV
},
6637 { 0, CODE_FOR_spe_evfsmul
, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL
},
6638 { 0, CODE_FOR_spe_evfssub
, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB
},
6639 { 0, CODE_FOR_spe_evmergehi
, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI
},
6640 { 0, CODE_FOR_spe_evmergehilo
, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO
},
6641 { 0, CODE_FOR_spe_evmergelo
, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO
},
6642 { 0, CODE_FOR_spe_evmergelohi
, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI
},
6643 { 0, CODE_FOR_spe_evmhegsmfaa
, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA
},
6644 { 0, CODE_FOR_spe_evmhegsmfan
, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN
},
6645 { 0, CODE_FOR_spe_evmhegsmiaa
, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA
},
6646 { 0, CODE_FOR_spe_evmhegsmian
, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN
},
6647 { 0, CODE_FOR_spe_evmhegumiaa
, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA
},
6648 { 0, CODE_FOR_spe_evmhegumian
, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN
},
6649 { 0, CODE_FOR_spe_evmhesmf
, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF
},
6650 { 0, CODE_FOR_spe_evmhesmfa
, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA
},
6651 { 0, CODE_FOR_spe_evmhesmfaaw
, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW
},
6652 { 0, CODE_FOR_spe_evmhesmfanw
, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW
},
6653 { 0, CODE_FOR_spe_evmhesmi
, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI
},
6654 { 0, CODE_FOR_spe_evmhesmia
, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA
},
6655 { 0, CODE_FOR_spe_evmhesmiaaw
, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW
},
6656 { 0, CODE_FOR_spe_evmhesmianw
, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW
},
6657 { 0, CODE_FOR_spe_evmhessf
, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF
},
6658 { 0, CODE_FOR_spe_evmhessfa
, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA
},
6659 { 0, CODE_FOR_spe_evmhessfaaw
, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW
},
6660 { 0, CODE_FOR_spe_evmhessfanw
, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW
},
6661 { 0, CODE_FOR_spe_evmhessiaaw
, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW
},
6662 { 0, CODE_FOR_spe_evmhessianw
, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW
},
6663 { 0, CODE_FOR_spe_evmheumi
, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI
},
6664 { 0, CODE_FOR_spe_evmheumia
, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA
},
6665 { 0, CODE_FOR_spe_evmheumiaaw
, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW
},
6666 { 0, CODE_FOR_spe_evmheumianw
, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW
},
6667 { 0, CODE_FOR_spe_evmheusiaaw
, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW
},
6668 { 0, CODE_FOR_spe_evmheusianw
, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW
},
6669 { 0, CODE_FOR_spe_evmhogsmfaa
, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA
},
6670 { 0, CODE_FOR_spe_evmhogsmfan
, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN
},
6671 { 0, CODE_FOR_spe_evmhogsmiaa
, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA
},
6672 { 0, CODE_FOR_spe_evmhogsmian
, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN
},
6673 { 0, CODE_FOR_spe_evmhogumiaa
, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA
},
6674 { 0, CODE_FOR_spe_evmhogumian
, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN
},
6675 { 0, CODE_FOR_spe_evmhosmf
, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF
},
6676 { 0, CODE_FOR_spe_evmhosmfa
, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA
},
6677 { 0, CODE_FOR_spe_evmhosmfaaw
, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW
},
6678 { 0, CODE_FOR_spe_evmhosmfanw
, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW
},
6679 { 0, CODE_FOR_spe_evmhosmi
, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI
},
6680 { 0, CODE_FOR_spe_evmhosmia
, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA
},
6681 { 0, CODE_FOR_spe_evmhosmiaaw
, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW
},
6682 { 0, CODE_FOR_spe_evmhosmianw
, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW
},
6683 { 0, CODE_FOR_spe_evmhossf
, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF
},
6684 { 0, CODE_FOR_spe_evmhossfa
, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA
},
6685 { 0, CODE_FOR_spe_evmhossfaaw
, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW
},
6686 { 0, CODE_FOR_spe_evmhossfanw
, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW
},
6687 { 0, CODE_FOR_spe_evmhossiaaw
, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW
},
6688 { 0, CODE_FOR_spe_evmhossianw
, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW
},
6689 { 0, CODE_FOR_spe_evmhoumi
, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI
},
6690 { 0, CODE_FOR_spe_evmhoumia
, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA
},
6691 { 0, CODE_FOR_spe_evmhoumiaaw
, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW
},
6692 { 0, CODE_FOR_spe_evmhoumianw
, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW
},
6693 { 0, CODE_FOR_spe_evmhousiaaw
, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW
},
6694 { 0, CODE_FOR_spe_evmhousianw
, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW
},
6695 { 0, CODE_FOR_spe_evmwhsmf
, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF
},
6696 { 0, CODE_FOR_spe_evmwhsmfa
, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA
},
6697 { 0, CODE_FOR_spe_evmwhsmi
, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI
},
6698 { 0, CODE_FOR_spe_evmwhsmia
, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA
},
6699 { 0, CODE_FOR_spe_evmwhssf
, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF
},
6700 { 0, CODE_FOR_spe_evmwhssfa
, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA
},
6701 { 0, CODE_FOR_spe_evmwhumi
, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI
},
6702 { 0, CODE_FOR_spe_evmwhumia
, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA
},
6703 { 0, CODE_FOR_spe_evmwlsmiaaw
, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW
},
6704 { 0, CODE_FOR_spe_evmwlsmianw
, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW
},
6705 { 0, CODE_FOR_spe_evmwlssiaaw
, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW
},
6706 { 0, CODE_FOR_spe_evmwlssianw
, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW
},
6707 { 0, CODE_FOR_spe_evmwlumi
, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI
},
6708 { 0, CODE_FOR_spe_evmwlumia
, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA
},
6709 { 0, CODE_FOR_spe_evmwlumiaaw
, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW
},
6710 { 0, CODE_FOR_spe_evmwlumianw
, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW
},
6711 { 0, CODE_FOR_spe_evmwlusiaaw
, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW
},
6712 { 0, CODE_FOR_spe_evmwlusianw
, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW
},
6713 { 0, CODE_FOR_spe_evmwsmf
, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF
},
6714 { 0, CODE_FOR_spe_evmwsmfa
, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA
},
6715 { 0, CODE_FOR_spe_evmwsmfaa
, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA
},
6716 { 0, CODE_FOR_spe_evmwsmfan
, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN
},
6717 { 0, CODE_FOR_spe_evmwsmi
, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI
},
6718 { 0, CODE_FOR_spe_evmwsmia
, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA
},
6719 { 0, CODE_FOR_spe_evmwsmiaa
, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA
},
6720 { 0, CODE_FOR_spe_evmwsmian
, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN
},
6721 { 0, CODE_FOR_spe_evmwssf
, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF
},
6722 { 0, CODE_FOR_spe_evmwssfa
, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA
},
6723 { 0, CODE_FOR_spe_evmwssfaa
, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA
},
6724 { 0, CODE_FOR_spe_evmwssfan
, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN
},
6725 { 0, CODE_FOR_spe_evmwumi
, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI
},
6726 { 0, CODE_FOR_spe_evmwumia
, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA
},
6727 { 0, CODE_FOR_spe_evmwumiaa
, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA
},
6728 { 0, CODE_FOR_spe_evmwumian
, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN
},
6729 { 0, CODE_FOR_spe_evnand
, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND
},
6730 { 0, CODE_FOR_spe_evnor
, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR
},
6731 { 0, CODE_FOR_spe_evor
, "__builtin_spe_evor", SPE_BUILTIN_EVOR
},
6732 { 0, CODE_FOR_spe_evorc
, "__builtin_spe_evorc", SPE_BUILTIN_EVORC
},
6733 { 0, CODE_FOR_spe_evrlw
, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW
},
6734 { 0, CODE_FOR_spe_evslw
, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW
},
6735 { 0, CODE_FOR_spe_evsrws
, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS
},
6736 { 0, CODE_FOR_spe_evsrwu
, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU
},
6737 { 0, CODE_FOR_spe_evsubfw
, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW
},
6739 /* SPE binary operations expecting a 5-bit unsigned literal. */
6740 { 0, CODE_FOR_spe_evaddiw
, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW
},
6742 { 0, CODE_FOR_spe_evrlwi
, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI
},
6743 { 0, CODE_FOR_spe_evslwi
, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI
},
6744 { 0, CODE_FOR_spe_evsrwis
, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS
},
6745 { 0, CODE_FOR_spe_evsrwiu
, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU
},
6746 { 0, CODE_FOR_spe_evsubifw
, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW
},
6747 { 0, CODE_FOR_spe_evmwhssfaa
, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA
},
6748 { 0, CODE_FOR_spe_evmwhssmaa
, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA
},
6749 { 0, CODE_FOR_spe_evmwhsmfaa
, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA
},
6750 { 0, CODE_FOR_spe_evmwhsmiaa
, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA
},
6751 { 0, CODE_FOR_spe_evmwhusiaa
, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA
},
6752 { 0, CODE_FOR_spe_evmwhumiaa
, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA
},
6753 { 0, CODE_FOR_spe_evmwhssfan
, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN
},
6754 { 0, CODE_FOR_spe_evmwhssian
, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN
},
6755 { 0, CODE_FOR_spe_evmwhsmfan
, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN
},
6756 { 0, CODE_FOR_spe_evmwhsmian
, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN
},
6757 { 0, CODE_FOR_spe_evmwhusian
, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN
},
6758 { 0, CODE_FOR_spe_evmwhumian
, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN
},
6759 { 0, CODE_FOR_spe_evmwhgssfaa
, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA
},
6760 { 0, CODE_FOR_spe_evmwhgsmfaa
, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA
},
6761 { 0, CODE_FOR_spe_evmwhgsmiaa
, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA
},
6762 { 0, CODE_FOR_spe_evmwhgumiaa
, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA
},
6763 { 0, CODE_FOR_spe_evmwhgssfan
, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN
},
6764 { 0, CODE_FOR_spe_evmwhgsmfan
, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN
},
6765 { 0, CODE_FOR_spe_evmwhgsmian
, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN
},
6766 { 0, CODE_FOR_spe_evmwhgumian
, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN
},
6767 { 0, CODE_FOR_spe_brinc
, "__builtin_spe_brinc", SPE_BUILTIN_BRINC
},
6769 /* Place-holder. Leave as last binary SPE builtin. */
6770 { 0, CODE_FOR_xorv2si3
, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR
}
6773 /* AltiVec predicates. */
6775 struct builtin_description_predicates
6777 const unsigned int mask
;
6778 const enum insn_code icode
;
6780 const char *const name
;
6781 const enum rs6000_builtins code
;
6784 static const struct builtin_description_predicates bdesc_altivec_preds
[] =
6786 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P
},
6787 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P
},
6788 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P
},
6789 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4sf
, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P
},
6790 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P
},
6791 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P
},
6792 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v4si
, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P
},
6793 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P
},
6794 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P
},
6795 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v8hi
, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P
},
6796 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P
},
6797 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P
},
6798 { MASK_ALTIVEC
, CODE_FOR_altivec_predicate_v16qi
, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P
},
6800 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P
},
6801 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P
},
6802 { MASK_ALTIVEC
, 0, NULL
, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P
}
6805 /* SPE predicates. */
6806 static struct builtin_description bdesc_spe_predicates
[] =
6808 /* Place-holder. Leave as first. */
6809 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ
},
6810 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS
},
6811 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU
},
6812 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS
},
6813 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU
},
6814 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ
},
6815 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT
},
6816 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT
},
6817 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ
},
6818 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT
},
6819 /* Place-holder. Leave as last. */
6820 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT
},
6823 /* SPE evsel predicates. */
6824 static struct builtin_description bdesc_spe_evsel
[] =
6826 /* Place-holder. Leave as first. */
6827 { 0, CODE_FOR_spe_evcmpgts
, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS
},
6828 { 0, CODE_FOR_spe_evcmpgtu
, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU
},
6829 { 0, CODE_FOR_spe_evcmplts
, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS
},
6830 { 0, CODE_FOR_spe_evcmpltu
, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU
},
6831 { 0, CODE_FOR_spe_evcmpeq
, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ
},
6832 { 0, CODE_FOR_spe_evfscmpgt
, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT
},
6833 { 0, CODE_FOR_spe_evfscmplt
, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT
},
6834 { 0, CODE_FOR_spe_evfscmpeq
, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ
},
6835 { 0, CODE_FOR_spe_evfststgt
, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT
},
6836 { 0, CODE_FOR_spe_evfststlt
, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT
},
6837 /* Place-holder. Leave as last. */
6838 { 0, CODE_FOR_spe_evfststeq
, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ
},
6841 /* ABS* operations. */
6843 static const struct builtin_description bdesc_abs
[] =
6845 { MASK_ALTIVEC
, CODE_FOR_absv4si2
, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI
},
6846 { MASK_ALTIVEC
, CODE_FOR_absv8hi2
, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI
},
6847 { MASK_ALTIVEC
, CODE_FOR_absv4sf2
, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF
},
6848 { MASK_ALTIVEC
, CODE_FOR_absv16qi2
, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI
},
6849 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v4si
, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI
},
6850 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v8hi
, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI
},
6851 { MASK_ALTIVEC
, CODE_FOR_altivec_abss_v16qi
, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI
}
6854 /* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6857 static struct builtin_description bdesc_1arg
[] =
6859 { MASK_ALTIVEC
, CODE_FOR_altivec_vexptefp
, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP
},
6860 { MASK_ALTIVEC
, CODE_FOR_altivec_vlogefp
, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP
},
6861 { MASK_ALTIVEC
, CODE_FOR_altivec_vrefp
, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP
},
6862 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfim
, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM
},
6863 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfin
, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN
},
6864 { MASK_ALTIVEC
, CODE_FOR_altivec_vrfip
, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP
},
6865 { MASK_ALTIVEC
, CODE_FOR_ftruncv4sf2
, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ
},
6866 { MASK_ALTIVEC
, CODE_FOR_altivec_vrsqrtefp
, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP
},
6867 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisb
, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB
},
6868 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltish
, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH
},
6869 { MASK_ALTIVEC
, CODE_FOR_altivec_vspltisw
, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW
},
6870 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsb
, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB
},
6871 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhpx
, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX
},
6872 { MASK_ALTIVEC
, CODE_FOR_altivec_vupkhsh
, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH
},
6873 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsb
, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB
},
6874 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklpx
, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX
},
6875 { MASK_ALTIVEC
, CODE_FOR_altivec_vupklsh
, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH
},
6877 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS
},
6878 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS
},
6879 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL
},
6880 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE
},
6881 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR
},
6882 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE
},
6883 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR
},
6884 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE
},
6885 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND
},
6886 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE
},
6887 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC
},
6888 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH
},
6889 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH
},
6890 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX
},
6891 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB
},
6892 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL
},
6893 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX
},
6894 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH
},
6895 { MASK_ALTIVEC
, CODE_FOR_nothing
, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB
},
6897 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6898 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6899 { 0, CODE_FOR_spe_evabs
, "__builtin_spe_evabs", SPE_BUILTIN_EVABS
},
6900 { 0, CODE_FOR_spe_evaddsmiaaw
, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW
},
6901 { 0, CODE_FOR_spe_evaddssiaaw
, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW
},
6902 { 0, CODE_FOR_spe_evaddumiaaw
, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW
},
6903 { 0, CODE_FOR_spe_evaddusiaaw
, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW
},
6904 { 0, CODE_FOR_spe_evcntlsw
, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW
},
6905 { 0, CODE_FOR_spe_evcntlzw
, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW
},
6906 { 0, CODE_FOR_spe_evextsb
, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB
},
6907 { 0, CODE_FOR_spe_evextsh
, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH
},
6908 { 0, CODE_FOR_spe_evfsabs
, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS
},
6909 { 0, CODE_FOR_spe_evfscfsf
, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF
},
6910 { 0, CODE_FOR_spe_evfscfsi
, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI
},
6911 { 0, CODE_FOR_spe_evfscfuf
, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF
},
6912 { 0, CODE_FOR_spe_evfscfui
, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI
},
6913 { 0, CODE_FOR_spe_evfsctsf
, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF
},
6914 { 0, CODE_FOR_spe_evfsctsi
, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI
},
6915 { 0, CODE_FOR_spe_evfsctsiz
, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ
},
6916 { 0, CODE_FOR_spe_evfsctuf
, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF
},
6917 { 0, CODE_FOR_spe_evfsctui
, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI
},
6918 { 0, CODE_FOR_spe_evfsctuiz
, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ
},
6919 { 0, CODE_FOR_spe_evfsnabs
, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS
},
6920 { 0, CODE_FOR_spe_evfsneg
, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG
},
6921 { 0, CODE_FOR_spe_evmra
, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA
},
6922 { 0, CODE_FOR_negv2si2
, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG
},
6923 { 0, CODE_FOR_spe_evrndw
, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW
},
6924 { 0, CODE_FOR_spe_evsubfsmiaaw
, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW
},
6925 { 0, CODE_FOR_spe_evsubfssiaaw
, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW
},
6926 { 0, CODE_FOR_spe_evsubfumiaaw
, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW
},
6928 /* Place-holder. Leave as last unary SPE builtin. */
6929 { 0, CODE_FOR_spe_evsubfusiaaw
, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW
}
6933 rs6000_expand_unop_builtin (enum insn_code icode
, tree exp
, rtx target
)
6936 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6937 rtx op0
= expand_normal (arg0
);
6938 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6939 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6941 if (icode
== CODE_FOR_nothing
)
6942 /* Builtin not supported on this processor. */
6945 /* If we got invalid arguments bail out before generating bad rtl. */
6946 if (arg0
== error_mark_node
)
6949 if (icode
== CODE_FOR_altivec_vspltisb
6950 || icode
== CODE_FOR_altivec_vspltish
6951 || icode
== CODE_FOR_altivec_vspltisw
6952 || icode
== CODE_FOR_spe_evsplatfi
6953 || icode
== CODE_FOR_spe_evsplati
)
6955 /* Only allow 5-bit *signed* literals. */
6956 if (GET_CODE (op0
) != CONST_INT
6957 || INTVAL (op0
) > 15
6958 || INTVAL (op0
) < -16)
6960 error ("argument 1 must be a 5-bit signed literal");
6966 || GET_MODE (target
) != tmode
6967 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6968 target
= gen_reg_rtx (tmode
);
6970 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
6971 op0
= copy_to_mode_reg (mode0
, op0
);
6973 pat
= GEN_FCN (icode
) (target
, op0
);
6982 altivec_expand_abs_builtin (enum insn_code icode
, tree exp
, rtx target
)
6984 rtx pat
, scratch1
, scratch2
;
6985 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6986 rtx op0
= expand_normal (arg0
);
6987 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6988 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
6990 /* If we have invalid arguments, bail out before generating bad rtl. */
6991 if (arg0
== error_mark_node
)
6995 || GET_MODE (target
) != tmode
6996 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
6997 target
= gen_reg_rtx (tmode
);
6999 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7000 op0
= copy_to_mode_reg (mode0
, op0
);
7002 scratch1
= gen_reg_rtx (mode0
);
7003 scratch2
= gen_reg_rtx (mode0
);
7005 pat
= GEN_FCN (icode
) (target
, op0
, scratch1
, scratch2
);
7014 rs6000_expand_binop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7017 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7018 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7019 rtx op0
= expand_normal (arg0
);
7020 rtx op1
= expand_normal (arg1
);
7021 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7022 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7023 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7025 if (icode
== CODE_FOR_nothing
)
7026 /* Builtin not supported on this processor. */
7029 /* If we got invalid arguments bail out before generating bad rtl. */
7030 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7033 if (icode
== CODE_FOR_altivec_vcfux
7034 || icode
== CODE_FOR_altivec_vcfsx
7035 || icode
== CODE_FOR_altivec_vctsxs
7036 || icode
== CODE_FOR_altivec_vctuxs
7037 || icode
== CODE_FOR_altivec_vspltb
7038 || icode
== CODE_FOR_altivec_vsplth
7039 || icode
== CODE_FOR_altivec_vspltw
7040 || icode
== CODE_FOR_spe_evaddiw
7041 || icode
== CODE_FOR_spe_evldd
7042 || icode
== CODE_FOR_spe_evldh
7043 || icode
== CODE_FOR_spe_evldw
7044 || icode
== CODE_FOR_spe_evlhhesplat
7045 || icode
== CODE_FOR_spe_evlhhossplat
7046 || icode
== CODE_FOR_spe_evlhhousplat
7047 || icode
== CODE_FOR_spe_evlwhe
7048 || icode
== CODE_FOR_spe_evlwhos
7049 || icode
== CODE_FOR_spe_evlwhou
7050 || icode
== CODE_FOR_spe_evlwhsplat
7051 || icode
== CODE_FOR_spe_evlwwsplat
7052 || icode
== CODE_FOR_spe_evrlwi
7053 || icode
== CODE_FOR_spe_evslwi
7054 || icode
== CODE_FOR_spe_evsrwis
7055 || icode
== CODE_FOR_spe_evsubifw
7056 || icode
== CODE_FOR_spe_evsrwiu
)
7058 /* Only allow 5-bit unsigned literals. */
7060 if (TREE_CODE (arg1
) != INTEGER_CST
7061 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7063 error ("argument 2 must be a 5-bit unsigned literal");
7069 || GET_MODE (target
) != tmode
7070 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7071 target
= gen_reg_rtx (tmode
);
7073 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7074 op0
= copy_to_mode_reg (mode0
, op0
);
7075 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7076 op1
= copy_to_mode_reg (mode1
, op1
);
7078 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
7087 altivec_expand_predicate_builtin (enum insn_code icode
, const char *opcode
,
7088 tree exp
, rtx target
)
7091 tree cr6_form
= CALL_EXPR_ARG (exp
, 0);
7092 tree arg0
= CALL_EXPR_ARG (exp
, 1);
7093 tree arg1
= CALL_EXPR_ARG (exp
, 2);
7094 rtx op0
= expand_normal (arg0
);
7095 rtx op1
= expand_normal (arg1
);
7096 enum machine_mode tmode
= SImode
;
7097 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7098 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7101 if (TREE_CODE (cr6_form
) != INTEGER_CST
)
7103 error ("argument 1 of __builtin_altivec_predicate must be a constant");
7107 cr6_form_int
= TREE_INT_CST_LOW (cr6_form
);
7109 gcc_assert (mode0
== mode1
);
7111 /* If we have invalid arguments, bail out before generating bad rtl. */
7112 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7116 || GET_MODE (target
) != tmode
7117 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7118 target
= gen_reg_rtx (tmode
);
7120 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7121 op0
= copy_to_mode_reg (mode0
, op0
);
7122 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7123 op1
= copy_to_mode_reg (mode1
, op1
);
7125 scratch
= gen_reg_rtx (mode0
);
7127 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
,
7128 gen_rtx_SYMBOL_REF (Pmode
, opcode
));
7133 /* The vec_any* and vec_all* predicates use the same opcodes for two
7134 different operations, but the bits in CR6 will be different
7135 depending on what information we want. So we have to play tricks
7136 with CR6 to get the right bits out.
7138 If you think this is disgusting, look at the specs for the
7139 AltiVec predicates. */
7141 switch (cr6_form_int
)
7144 emit_insn (gen_cr6_test_for_zero (target
));
7147 emit_insn (gen_cr6_test_for_zero_reverse (target
));
7150 emit_insn (gen_cr6_test_for_lt (target
));
7153 emit_insn (gen_cr6_test_for_lt_reverse (target
));
7156 error ("argument 1 of __builtin_altivec_predicate is out of range");
7164 altivec_expand_lv_builtin (enum insn_code icode
, tree exp
, rtx target
)
7167 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7168 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7169 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7170 enum machine_mode mode0
= Pmode
;
7171 enum machine_mode mode1
= Pmode
;
7172 rtx op0
= expand_normal (arg0
);
7173 rtx op1
= expand_normal (arg1
);
7175 if (icode
== CODE_FOR_nothing
)
7176 /* Builtin not supported on this processor. */
7179 /* If we got invalid arguments bail out before generating bad rtl. */
7180 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7184 || GET_MODE (target
) != tmode
7185 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7186 target
= gen_reg_rtx (tmode
);
7188 op1
= copy_to_mode_reg (mode1
, op1
);
7190 if (op0
== const0_rtx
)
7192 addr
= gen_rtx_MEM (tmode
, op1
);
7196 op0
= copy_to_mode_reg (mode0
, op0
);
7197 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op0
, op1
));
7200 pat
= GEN_FCN (icode
) (target
, addr
);
7210 spe_expand_stv_builtin (enum insn_code icode
, tree exp
)
7212 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7213 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7214 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7215 rtx op0
= expand_normal (arg0
);
7216 rtx op1
= expand_normal (arg1
);
7217 rtx op2
= expand_normal (arg2
);
7219 enum machine_mode mode0
= insn_data
[icode
].operand
[0].mode
;
7220 enum machine_mode mode1
= insn_data
[icode
].operand
[1].mode
;
7221 enum machine_mode mode2
= insn_data
[icode
].operand
[2].mode
;
7223 /* Invalid arguments. Bail before doing anything stoopid! */
7224 if (arg0
== error_mark_node
7225 || arg1
== error_mark_node
7226 || arg2
== error_mark_node
)
7229 if (! (*insn_data
[icode
].operand
[2].predicate
) (op0
, mode2
))
7230 op0
= copy_to_mode_reg (mode2
, op0
);
7231 if (! (*insn_data
[icode
].operand
[0].predicate
) (op1
, mode0
))
7232 op1
= copy_to_mode_reg (mode0
, op1
);
7233 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
7234 op2
= copy_to_mode_reg (mode1
, op2
);
7236 pat
= GEN_FCN (icode
) (op1
, op2
, op0
);
7243 altivec_expand_stv_builtin (enum insn_code icode
, tree exp
)
7245 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7246 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7247 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7248 rtx op0
= expand_normal (arg0
);
7249 rtx op1
= expand_normal (arg1
);
7250 rtx op2
= expand_normal (arg2
);
7252 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7253 enum machine_mode mode1
= Pmode
;
7254 enum machine_mode mode2
= Pmode
;
7256 /* Invalid arguments. Bail before doing anything stoopid! */
7257 if (arg0
== error_mark_node
7258 || arg1
== error_mark_node
7259 || arg2
== error_mark_node
)
7262 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, tmode
))
7263 op0
= copy_to_mode_reg (tmode
, op0
);
7265 op2
= copy_to_mode_reg (mode2
, op2
);
7267 if (op1
== const0_rtx
)
7269 addr
= gen_rtx_MEM (tmode
, op2
);
7273 op1
= copy_to_mode_reg (mode1
, op1
);
7274 addr
= gen_rtx_MEM (tmode
, gen_rtx_PLUS (Pmode
, op1
, op2
));
7277 pat
= GEN_FCN (icode
) (addr
, op0
);
7284 rs6000_expand_ternop_builtin (enum insn_code icode
, tree exp
, rtx target
)
7287 tree arg0
= CALL_EXPR_ARG (exp
, 0);
7288 tree arg1
= CALL_EXPR_ARG (exp
, 1);
7289 tree arg2
= CALL_EXPR_ARG (exp
, 2);
7290 rtx op0
= expand_normal (arg0
);
7291 rtx op1
= expand_normal (arg1
);
7292 rtx op2
= expand_normal (arg2
);
7293 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7294 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7295 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7296 enum machine_mode mode2
= insn_data
[icode
].operand
[3].mode
;
7298 if (icode
== CODE_FOR_nothing
)
7299 /* Builtin not supported on this processor. */
7302 /* If we got invalid arguments bail out before generating bad rtl. */
7303 if (arg0
== error_mark_node
7304 || arg1
== error_mark_node
7305 || arg2
== error_mark_node
)
7308 if (icode
== CODE_FOR_altivec_vsldoi_v4sf
7309 || icode
== CODE_FOR_altivec_vsldoi_v4si
7310 || icode
== CODE_FOR_altivec_vsldoi_v8hi
7311 || icode
== CODE_FOR_altivec_vsldoi_v16qi
)
7313 /* Only allow 4-bit unsigned literals. */
7315 if (TREE_CODE (arg2
) != INTEGER_CST
7316 || TREE_INT_CST_LOW (arg2
) & ~0xf)
7318 error ("argument 3 must be a 4-bit unsigned literal");
7324 || GET_MODE (target
) != tmode
7325 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7326 target
= gen_reg_rtx (tmode
);
7328 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7329 op0
= copy_to_mode_reg (mode0
, op0
);
7330 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7331 op1
= copy_to_mode_reg (mode1
, op1
);
7332 if (! (*insn_data
[icode
].operand
[3].predicate
) (op2
, mode2
))
7333 op2
= copy_to_mode_reg (mode2
, op2
);
7335 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
7343 /* Expand the lvx builtins. */
7345 altivec_expand_ld_builtin (tree exp
, rtx target
, bool *expandedp
)
7347 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7348 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7350 enum machine_mode tmode
, mode0
;
7352 enum insn_code icode
;
7356 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi
:
7357 icode
= CODE_FOR_altivec_lvx_v16qi
;
7359 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi
:
7360 icode
= CODE_FOR_altivec_lvx_v8hi
;
7362 case ALTIVEC_BUILTIN_LD_INTERNAL_4si
:
7363 icode
= CODE_FOR_altivec_lvx_v4si
;
7365 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf
:
7366 icode
= CODE_FOR_altivec_lvx_v4sf
;
7375 arg0
= CALL_EXPR_ARG (exp
, 0);
7376 op0
= expand_normal (arg0
);
7377 tmode
= insn_data
[icode
].operand
[0].mode
;
7378 mode0
= insn_data
[icode
].operand
[1].mode
;
7381 || GET_MODE (target
) != tmode
7382 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7383 target
= gen_reg_rtx (tmode
);
7385 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7386 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
7388 pat
= GEN_FCN (icode
) (target
, op0
);
7395 /* Expand the stvx builtins. */
7397 altivec_expand_st_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
7400 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7401 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7403 enum machine_mode mode0
, mode1
;
7405 enum insn_code icode
;
7409 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi
:
7410 icode
= CODE_FOR_altivec_stvx_v16qi
;
7412 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi
:
7413 icode
= CODE_FOR_altivec_stvx_v8hi
;
7415 case ALTIVEC_BUILTIN_ST_INTERNAL_4si
:
7416 icode
= CODE_FOR_altivec_stvx_v4si
;
7418 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf
:
7419 icode
= CODE_FOR_altivec_stvx_v4sf
;
7426 arg0
= CALL_EXPR_ARG (exp
, 0);
7427 arg1
= CALL_EXPR_ARG (exp
, 1);
7428 op0
= expand_normal (arg0
);
7429 op1
= expand_normal (arg1
);
7430 mode0
= insn_data
[icode
].operand
[0].mode
;
7431 mode1
= insn_data
[icode
].operand
[1].mode
;
7433 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7434 op0
= gen_rtx_MEM (mode0
, copy_to_mode_reg (Pmode
, op0
));
7435 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
7436 op1
= copy_to_mode_reg (mode1
, op1
);
7438 pat
= GEN_FCN (icode
) (op0
, op1
);
7446 /* Expand the dst builtins. */
7448 altivec_expand_dst_builtin (tree exp
, rtx target ATTRIBUTE_UNUSED
,
7451 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7452 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7453 tree arg0
, arg1
, arg2
;
7454 enum machine_mode mode0
, mode1
, mode2
;
7455 rtx pat
, op0
, op1
, op2
;
7456 struct builtin_description
*d
;
7461 /* Handle DST variants. */
7462 d
= (struct builtin_description
*) bdesc_dst
;
7463 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
7464 if (d
->code
== fcode
)
7466 arg0
= CALL_EXPR_ARG (exp
, 0);
7467 arg1
= CALL_EXPR_ARG (exp
, 1);
7468 arg2
= CALL_EXPR_ARG (exp
, 2);
7469 op0
= expand_normal (arg0
);
7470 op1
= expand_normal (arg1
);
7471 op2
= expand_normal (arg2
);
7472 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
7473 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
7474 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
7476 /* Invalid arguments, bail out before generating bad rtl. */
7477 if (arg0
== error_mark_node
7478 || arg1
== error_mark_node
7479 || arg2
== error_mark_node
)
7484 if (TREE_CODE (arg2
) != INTEGER_CST
7485 || TREE_INT_CST_LOW (arg2
) & ~0x3)
7487 error ("argument to %qs must be a 2-bit unsigned literal", d
->name
);
7491 if (! (*insn_data
[d
->icode
].operand
[0].predicate
) (op0
, mode0
))
7492 op0
= copy_to_mode_reg (Pmode
, op0
);
7493 if (! (*insn_data
[d
->icode
].operand
[1].predicate
) (op1
, mode1
))
7494 op1
= copy_to_mode_reg (mode1
, op1
);
7496 pat
= GEN_FCN (d
->icode
) (op0
, op1
, op2
);
7506 /* Expand vec_init builtin. */
7508 altivec_expand_vec_init_builtin (tree type
, tree exp
, rtx target
)
7510 enum machine_mode tmode
= TYPE_MODE (type
);
7511 enum machine_mode inner_mode
= GET_MODE_INNER (tmode
);
7512 int i
, n_elt
= GET_MODE_NUNITS (tmode
);
7513 rtvec v
= rtvec_alloc (n_elt
);
7515 gcc_assert (VECTOR_MODE_P (tmode
));
7516 gcc_assert (n_elt
== call_expr_nargs (exp
));
7518 for (i
= 0; i
< n_elt
; ++i
)
7520 rtx x
= expand_normal (CALL_EXPR_ARG (exp
, i
));
7521 RTVEC_ELT (v
, i
) = gen_lowpart (inner_mode
, x
);
7524 if (!target
|| !register_operand (target
, tmode
))
7525 target
= gen_reg_rtx (tmode
);
7527 rs6000_expand_vector_init (target
, gen_rtx_PARALLEL (tmode
, v
));
7531 /* Return the integer constant in ARG. Constrain it to be in the range
7532 of the subparts of VEC_TYPE; issue an error if not. */
7535 get_element_number (tree vec_type
, tree arg
)
7537 unsigned HOST_WIDE_INT elt
, max
= TYPE_VECTOR_SUBPARTS (vec_type
) - 1;
7539 if (!host_integerp (arg
, 1)
7540 || (elt
= tree_low_cst (arg
, 1), elt
> max
))
7542 error ("selector must be an integer constant in the range 0..%wi", max
);
7549 /* Expand vec_set builtin. */
7551 altivec_expand_vec_set_builtin (tree exp
)
7553 enum machine_mode tmode
, mode1
;
7554 tree arg0
, arg1
, arg2
;
7558 arg0
= CALL_EXPR_ARG (exp
, 0);
7559 arg1
= CALL_EXPR_ARG (exp
, 1);
7560 arg2
= CALL_EXPR_ARG (exp
, 2);
7562 tmode
= TYPE_MODE (TREE_TYPE (arg0
));
7563 mode1
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7564 gcc_assert (VECTOR_MODE_P (tmode
));
7566 op0
= expand_expr (arg0
, NULL_RTX
, tmode
, 0);
7567 op1
= expand_expr (arg1
, NULL_RTX
, mode1
, 0);
7568 elt
= get_element_number (TREE_TYPE (arg0
), arg2
);
7570 if (GET_MODE (op1
) != mode1
&& GET_MODE (op1
) != VOIDmode
)
7571 op1
= convert_modes (mode1
, GET_MODE (op1
), op1
, true);
7573 op0
= force_reg (tmode
, op0
);
7574 op1
= force_reg (mode1
, op1
);
7576 rs6000_expand_vector_set (op0
, op1
, elt
);
7581 /* Expand vec_ext builtin. */
7583 altivec_expand_vec_ext_builtin (tree exp
, rtx target
)
7585 enum machine_mode tmode
, mode0
;
7590 arg0
= CALL_EXPR_ARG (exp
, 0);
7591 arg1
= CALL_EXPR_ARG (exp
, 1);
7593 op0
= expand_normal (arg0
);
7594 elt
= get_element_number (TREE_TYPE (arg0
), arg1
);
7596 tmode
= TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0
)));
7597 mode0
= TYPE_MODE (TREE_TYPE (arg0
));
7598 gcc_assert (VECTOR_MODE_P (mode0
));
7600 op0
= force_reg (mode0
, op0
);
7602 if (optimize
|| !target
|| !register_operand (target
, tmode
))
7603 target
= gen_reg_rtx (tmode
);
7605 rs6000_expand_vector_extract (target
, op0
, elt
);
7610 /* Expand the builtin in EXP and store the result in TARGET. Store
7611 true in *EXPANDEDP if we found a builtin to expand. */
7613 altivec_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7615 struct builtin_description
*d
;
7616 struct builtin_description_predicates
*dp
;
7618 enum insn_code icode
;
7619 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7622 enum machine_mode tmode
, mode0
;
7623 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7625 if (fcode
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7626 && fcode
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
)
7629 error ("unresolved overload for Altivec builtin %qF", fndecl
);
7633 target
= altivec_expand_ld_builtin (exp
, target
, expandedp
);
7637 target
= altivec_expand_st_builtin (exp
, target
, expandedp
);
7641 target
= altivec_expand_dst_builtin (exp
, target
, expandedp
);
7649 case ALTIVEC_BUILTIN_STVX
:
7650 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx
, exp
);
7651 case ALTIVEC_BUILTIN_STVEBX
:
7652 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx
, exp
);
7653 case ALTIVEC_BUILTIN_STVEHX
:
7654 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx
, exp
);
7655 case ALTIVEC_BUILTIN_STVEWX
:
7656 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx
, exp
);
7657 case ALTIVEC_BUILTIN_STVXL
:
7658 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl
, exp
);
7660 case ALTIVEC_BUILTIN_MFVSCR
:
7661 icode
= CODE_FOR_altivec_mfvscr
;
7662 tmode
= insn_data
[icode
].operand
[0].mode
;
7665 || GET_MODE (target
) != tmode
7666 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7667 target
= gen_reg_rtx (tmode
);
7669 pat
= GEN_FCN (icode
) (target
);
7675 case ALTIVEC_BUILTIN_MTVSCR
:
7676 icode
= CODE_FOR_altivec_mtvscr
;
7677 arg0
= CALL_EXPR_ARG (exp
, 0);
7678 op0
= expand_normal (arg0
);
7679 mode0
= insn_data
[icode
].operand
[0].mode
;
7681 /* If we got invalid arguments bail out before generating bad rtl. */
7682 if (arg0
== error_mark_node
)
7685 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7686 op0
= copy_to_mode_reg (mode0
, op0
);
7688 pat
= GEN_FCN (icode
) (op0
);
7693 case ALTIVEC_BUILTIN_DSSALL
:
7694 emit_insn (gen_altivec_dssall ());
7697 case ALTIVEC_BUILTIN_DSS
:
7698 icode
= CODE_FOR_altivec_dss
;
7699 arg0
= CALL_EXPR_ARG (exp
, 0);
7701 op0
= expand_normal (arg0
);
7702 mode0
= insn_data
[icode
].operand
[0].mode
;
7704 /* If we got invalid arguments bail out before generating bad rtl. */
7705 if (arg0
== error_mark_node
)
7708 if (TREE_CODE (arg0
) != INTEGER_CST
7709 || TREE_INT_CST_LOW (arg0
) & ~0x3)
7711 error ("argument to dss must be a 2-bit unsigned literal");
7715 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7716 op0
= copy_to_mode_reg (mode0
, op0
);
7718 emit_insn (gen_altivec_dss (op0
));
7721 case ALTIVEC_BUILTIN_VEC_INIT_V4SI
:
7722 case ALTIVEC_BUILTIN_VEC_INIT_V8HI
:
7723 case ALTIVEC_BUILTIN_VEC_INIT_V16QI
:
7724 case ALTIVEC_BUILTIN_VEC_INIT_V4SF
:
7725 return altivec_expand_vec_init_builtin (TREE_TYPE (exp
), exp
, target
);
7727 case ALTIVEC_BUILTIN_VEC_SET_V4SI
:
7728 case ALTIVEC_BUILTIN_VEC_SET_V8HI
:
7729 case ALTIVEC_BUILTIN_VEC_SET_V16QI
:
7730 case ALTIVEC_BUILTIN_VEC_SET_V4SF
:
7731 return altivec_expand_vec_set_builtin (exp
);
7733 case ALTIVEC_BUILTIN_VEC_EXT_V4SI
:
7734 case ALTIVEC_BUILTIN_VEC_EXT_V8HI
:
7735 case ALTIVEC_BUILTIN_VEC_EXT_V16QI
:
7736 case ALTIVEC_BUILTIN_VEC_EXT_V4SF
:
7737 return altivec_expand_vec_ext_builtin (exp
, target
);
7744 /* Expand abs* operations. */
7745 d
= (struct builtin_description
*) bdesc_abs
;
7746 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
7747 if (d
->code
== fcode
)
7748 return altivec_expand_abs_builtin (d
->icode
, exp
, target
);
7750 /* Expand the AltiVec predicates. */
7751 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
7752 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
7753 if (dp
->code
== fcode
)
7754 return altivec_expand_predicate_builtin (dp
->icode
, dp
->opcode
,
7757 /* LV* are funky. We initialized them differently. */
7760 case ALTIVEC_BUILTIN_LVSL
:
7761 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl
,
7763 case ALTIVEC_BUILTIN_LVSR
:
7764 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr
,
7766 case ALTIVEC_BUILTIN_LVEBX
:
7767 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx
,
7769 case ALTIVEC_BUILTIN_LVEHX
:
7770 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx
,
7772 case ALTIVEC_BUILTIN_LVEWX
:
7773 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx
,
7775 case ALTIVEC_BUILTIN_LVXL
:
7776 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl
,
7778 case ALTIVEC_BUILTIN_LVX
:
7779 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx
,
7790 /* Binops that need to be initialized manually, but can be expanded
7791 automagically by rs6000_expand_binop_builtin. */
7792 static struct builtin_description bdesc_2arg_spe
[] =
7794 { 0, CODE_FOR_spe_evlddx
, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX
},
7795 { 0, CODE_FOR_spe_evldwx
, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX
},
7796 { 0, CODE_FOR_spe_evldhx
, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX
},
7797 { 0, CODE_FOR_spe_evlwhex
, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX
},
7798 { 0, CODE_FOR_spe_evlwhoux
, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX
},
7799 { 0, CODE_FOR_spe_evlwhosx
, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX
},
7800 { 0, CODE_FOR_spe_evlwwsplatx
, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX
},
7801 { 0, CODE_FOR_spe_evlwhsplatx
, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX
},
7802 { 0, CODE_FOR_spe_evlhhesplatx
, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX
},
7803 { 0, CODE_FOR_spe_evlhhousplatx
, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX
},
7804 { 0, CODE_FOR_spe_evlhhossplatx
, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX
},
7805 { 0, CODE_FOR_spe_evldd
, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD
},
7806 { 0, CODE_FOR_spe_evldw
, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW
},
7807 { 0, CODE_FOR_spe_evldh
, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH
},
7808 { 0, CODE_FOR_spe_evlwhe
, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE
},
7809 { 0, CODE_FOR_spe_evlwhou
, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU
},
7810 { 0, CODE_FOR_spe_evlwhos
, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS
},
7811 { 0, CODE_FOR_spe_evlwwsplat
, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT
},
7812 { 0, CODE_FOR_spe_evlwhsplat
, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT
},
7813 { 0, CODE_FOR_spe_evlhhesplat
, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT
},
7814 { 0, CODE_FOR_spe_evlhhousplat
, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT
},
7815 { 0, CODE_FOR_spe_evlhhossplat
, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT
}
7818 /* Expand the builtin in EXP and store the result in TARGET. Store
7819 true in *EXPANDEDP if we found a builtin to expand.
7821 This expands the SPE builtins that are not simple unary and binary
7824 spe_expand_builtin (tree exp
, rtx target
, bool *expandedp
)
7826 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7828 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
7829 enum insn_code icode
;
7830 enum machine_mode tmode
, mode0
;
7832 struct builtin_description
*d
;
7837 /* Syntax check for a 5-bit unsigned immediate. */
7840 case SPE_BUILTIN_EVSTDD
:
7841 case SPE_BUILTIN_EVSTDH
:
7842 case SPE_BUILTIN_EVSTDW
:
7843 case SPE_BUILTIN_EVSTWHE
:
7844 case SPE_BUILTIN_EVSTWHO
:
7845 case SPE_BUILTIN_EVSTWWE
:
7846 case SPE_BUILTIN_EVSTWWO
:
7847 arg1
= CALL_EXPR_ARG (exp
, 2);
7848 if (TREE_CODE (arg1
) != INTEGER_CST
7849 || TREE_INT_CST_LOW (arg1
) & ~0x1f)
7851 error ("argument 2 must be a 5-bit unsigned literal");
7859 /* The evsplat*i instructions are not quite generic. */
7862 case SPE_BUILTIN_EVSPLATFI
:
7863 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi
,
7865 case SPE_BUILTIN_EVSPLATI
:
7866 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati
,
7872 d
= (struct builtin_description
*) bdesc_2arg_spe
;
7873 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg_spe
); ++i
, ++d
)
7874 if (d
->code
== fcode
)
7875 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
7877 d
= (struct builtin_description
*) bdesc_spe_predicates
;
7878 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, ++d
)
7879 if (d
->code
== fcode
)
7880 return spe_expand_predicate_builtin (d
->icode
, exp
, target
);
7882 d
= (struct builtin_description
*) bdesc_spe_evsel
;
7883 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, ++d
)
7884 if (d
->code
== fcode
)
7885 return spe_expand_evsel_builtin (d
->icode
, exp
, target
);
7889 case SPE_BUILTIN_EVSTDDX
:
7890 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx
, exp
);
7891 case SPE_BUILTIN_EVSTDHX
:
7892 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx
, exp
);
7893 case SPE_BUILTIN_EVSTDWX
:
7894 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx
, exp
);
7895 case SPE_BUILTIN_EVSTWHEX
:
7896 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex
, exp
);
7897 case SPE_BUILTIN_EVSTWHOX
:
7898 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox
, exp
);
7899 case SPE_BUILTIN_EVSTWWEX
:
7900 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex
, exp
);
7901 case SPE_BUILTIN_EVSTWWOX
:
7902 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox
, exp
);
7903 case SPE_BUILTIN_EVSTDD
:
7904 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd
, exp
);
7905 case SPE_BUILTIN_EVSTDH
:
7906 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh
, exp
);
7907 case SPE_BUILTIN_EVSTDW
:
7908 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw
, exp
);
7909 case SPE_BUILTIN_EVSTWHE
:
7910 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe
, exp
);
7911 case SPE_BUILTIN_EVSTWHO
:
7912 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho
, exp
);
7913 case SPE_BUILTIN_EVSTWWE
:
7914 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe
, exp
);
7915 case SPE_BUILTIN_EVSTWWO
:
7916 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo
, exp
);
7917 case SPE_BUILTIN_MFSPEFSCR
:
7918 icode
= CODE_FOR_spe_mfspefscr
;
7919 tmode
= insn_data
[icode
].operand
[0].mode
;
7922 || GET_MODE (target
) != tmode
7923 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
7924 target
= gen_reg_rtx (tmode
);
7926 pat
= GEN_FCN (icode
) (target
);
7931 case SPE_BUILTIN_MTSPEFSCR
:
7932 icode
= CODE_FOR_spe_mtspefscr
;
7933 arg0
= CALL_EXPR_ARG (exp
, 0);
7934 op0
= expand_normal (arg0
);
7935 mode0
= insn_data
[icode
].operand
[0].mode
;
7937 if (arg0
== error_mark_node
)
7940 if (! (*insn_data
[icode
].operand
[0].predicate
) (op0
, mode0
))
7941 op0
= copy_to_mode_reg (mode0
, op0
);
7943 pat
= GEN_FCN (icode
) (op0
);
7956 spe_expand_predicate_builtin (enum insn_code icode
, tree exp
, rtx target
)
7958 rtx pat
, scratch
, tmp
;
7959 tree form
= CALL_EXPR_ARG (exp
, 0);
7960 tree arg0
= CALL_EXPR_ARG (exp
, 1);
7961 tree arg1
= CALL_EXPR_ARG (exp
, 2);
7962 rtx op0
= expand_normal (arg0
);
7963 rtx op1
= expand_normal (arg1
);
7964 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
7965 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
7969 if (TREE_CODE (form
) != INTEGER_CST
)
7971 error ("argument 1 of __builtin_spe_predicate must be a constant");
7975 form_int
= TREE_INT_CST_LOW (form
);
7977 gcc_assert (mode0
== mode1
);
7979 if (arg0
== error_mark_node
|| arg1
== error_mark_node
)
7983 || GET_MODE (target
) != SImode
7984 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, SImode
))
7985 target
= gen_reg_rtx (SImode
);
7987 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
7988 op0
= copy_to_mode_reg (mode0
, op0
);
7989 if (! (*insn_data
[icode
].operand
[2].predicate
) (op1
, mode1
))
7990 op1
= copy_to_mode_reg (mode1
, op1
);
7992 scratch
= gen_reg_rtx (CCmode
);
7994 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
7999 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8000 _lower_. We use one compare, but look in different bits of the
8001 CR for each variant.
8003 There are 2 elements in each SPE simd type (upper/lower). The CR
8004 bits are set as follows:
8006 BIT0 | BIT 1 | BIT 2 | BIT 3
8007 U | L | (U | L) | (U & L)
8009 So, for an "all" relationship, BIT 3 would be set.
8010 For an "any" relationship, BIT 2 would be set. Etc.
8012 Following traditional nomenclature, these bits map to:
8014 BIT0 | BIT 1 | BIT 2 | BIT 3
8017 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8022 /* All variant. OV bit. */
8024 /* We need to get to the OV bit, which is the ORDERED bit. We
8025 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
8026 that's ugly and will make validate_condition_mode die.
8027 So let's just use another pattern. */
8028 emit_insn (gen_move_from_CR_ov_bit (target
, scratch
));
8030 /* Any variant. EQ bit. */
8034 /* Upper variant. LT bit. */
8038 /* Lower variant. GT bit. */
8043 error ("argument 1 of __builtin_spe_predicate is out of range");
8047 tmp
= gen_rtx_fmt_ee (code
, SImode
, scratch
, const0_rtx
);
8048 emit_move_insn (target
, tmp
);
8053 /* The evsel builtins look like this:
8055 e = __builtin_spe_evsel_OP (a, b, c, d);
8059 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8060 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8064 spe_expand_evsel_builtin (enum insn_code icode
, tree exp
, rtx target
)
8067 tree arg0
= CALL_EXPR_ARG (exp
, 0);
8068 tree arg1
= CALL_EXPR_ARG (exp
, 1);
8069 tree arg2
= CALL_EXPR_ARG (exp
, 2);
8070 tree arg3
= CALL_EXPR_ARG (exp
, 3);
8071 rtx op0
= expand_normal (arg0
);
8072 rtx op1
= expand_normal (arg1
);
8073 rtx op2
= expand_normal (arg2
);
8074 rtx op3
= expand_normal (arg3
);
8075 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
8076 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
8078 gcc_assert (mode0
== mode1
);
8080 if (arg0
== error_mark_node
|| arg1
== error_mark_node
8081 || arg2
== error_mark_node
|| arg3
== error_mark_node
)
8085 || GET_MODE (target
) != mode0
8086 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, mode0
))
8087 target
= gen_reg_rtx (mode0
);
8089 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
8090 op0
= copy_to_mode_reg (mode0
, op0
);
8091 if (! (*insn_data
[icode
].operand
[1].predicate
) (op1
, mode1
))
8092 op1
= copy_to_mode_reg (mode0
, op1
);
8093 if (! (*insn_data
[icode
].operand
[1].predicate
) (op2
, mode1
))
8094 op2
= copy_to_mode_reg (mode0
, op2
);
8095 if (! (*insn_data
[icode
].operand
[1].predicate
) (op3
, mode1
))
8096 op3
= copy_to_mode_reg (mode0
, op3
);
8098 /* Generate the compare. */
8099 scratch
= gen_reg_rtx (CCmode
);
8100 pat
= GEN_FCN (icode
) (scratch
, op0
, op1
);
8105 if (mode0
== V2SImode
)
8106 emit_insn (gen_spe_evsel (target
, op2
, op3
, scratch
));
8108 emit_insn (gen_spe_evsel_fs (target
, op2
, op3
, scratch
));
8113 /* Expand an expression EXP that calls a built-in function,
8114 with result going to TARGET if that's convenient
8115 (and in mode MODE if that's convenient).
8116 SUBTARGET may be used as the target for computing one of EXP's operands.
8117 IGNORE is nonzero if the value is to be ignored. */
8120 rs6000_expand_builtin (tree exp
, rtx target
, rtx subtarget ATTRIBUTE_UNUSED
,
8121 enum machine_mode mode ATTRIBUTE_UNUSED
,
8122 int ignore ATTRIBUTE_UNUSED
)
8124 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
8125 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
8126 struct builtin_description
*d
;
8131 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_LOAD
8132 || fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
8134 int icode
= (int) CODE_FOR_altivec_lvsr
;
8135 enum machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
8136 enum machine_mode mode
= insn_data
[icode
].operand
[1].mode
;
8140 gcc_assert (TARGET_ALTIVEC
);
8142 arg
= CALL_EXPR_ARG (exp
, 0);
8143 gcc_assert (TREE_CODE (TREE_TYPE (arg
)) == POINTER_TYPE
);
8144 op
= expand_expr (arg
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
8145 addr
= memory_address (mode
, op
);
8146 if (fcode
== ALTIVEC_BUILTIN_MASK_FOR_STORE
)
8150 /* For the load case need to negate the address. */
8151 op
= gen_reg_rtx (GET_MODE (addr
));
8152 emit_insn (gen_rtx_SET (VOIDmode
, op
,
8153 gen_rtx_NEG (GET_MODE (addr
), addr
)));
8155 op
= gen_rtx_MEM (mode
, op
);
8158 || GET_MODE (target
) != tmode
8159 || ! (*insn_data
[icode
].operand
[0].predicate
) (target
, tmode
))
8160 target
= gen_reg_rtx (tmode
);
8162 /*pat = gen_altivec_lvsr (target, op);*/
8163 pat
= GEN_FCN (icode
) (target
, op
);
8171 /* FIXME: There's got to be a nicer way to handle this case than
8172 constructing a new CALL_EXPR. */
8173 if (fcode
== ALTIVEC_BUILTIN_VCFUX
8174 || fcode
== ALTIVEC_BUILTIN_VCFSX
)
8176 if (call_expr_nargs (exp
) == 1)
8177 exp
= build_call_nary (TREE_TYPE (exp
), CALL_EXPR_FN (exp
),
8178 2, CALL_EXPR_ARG (exp
, 0), integer_zero_node
);
8183 ret
= altivec_expand_builtin (exp
, target
, &success
);
8190 ret
= spe_expand_builtin (exp
, target
, &success
);
8196 gcc_assert (TARGET_ALTIVEC
|| TARGET_SPE
);
8198 /* Handle simple unary operations. */
8199 d
= (struct builtin_description
*) bdesc_1arg
;
8200 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
8201 if (d
->code
== fcode
)
8202 return rs6000_expand_unop_builtin (d
->icode
, exp
, target
);
8204 /* Handle simple binary operations. */
8205 d
= (struct builtin_description
*) bdesc_2arg
;
8206 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
8207 if (d
->code
== fcode
)
8208 return rs6000_expand_binop_builtin (d
->icode
, exp
, target
);
8210 /* Handle simple ternary operations. */
8211 d
= (struct builtin_description
*) bdesc_3arg
;
8212 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
8213 if (d
->code
== fcode
)
8214 return rs6000_expand_ternop_builtin (d
->icode
, exp
, target
);
8220 build_opaque_vector_type (tree node
, int nunits
)
8222 node
= copy_node (node
);
8223 TYPE_MAIN_VARIANT (node
) = node
;
8224 return build_vector_type (node
, nunits
);
8228 rs6000_init_builtins (void)
8230 V2SI_type_node
= build_vector_type (intSI_type_node
, 2);
8231 V2SF_type_node
= build_vector_type (float_type_node
, 2);
8232 V4HI_type_node
= build_vector_type (intHI_type_node
, 4);
8233 V4SI_type_node
= build_vector_type (intSI_type_node
, 4);
8234 V4SF_type_node
= build_vector_type (float_type_node
, 4);
8235 V8HI_type_node
= build_vector_type (intHI_type_node
, 8);
8236 V16QI_type_node
= build_vector_type (intQI_type_node
, 16);
8238 unsigned_V16QI_type_node
= build_vector_type (unsigned_intQI_type_node
, 16);
8239 unsigned_V8HI_type_node
= build_vector_type (unsigned_intHI_type_node
, 8);
8240 unsigned_V4SI_type_node
= build_vector_type (unsigned_intSI_type_node
, 4);
8242 opaque_V2SF_type_node
= build_opaque_vector_type (float_type_node
, 2);
8243 opaque_V2SI_type_node
= build_opaque_vector_type (intSI_type_node
, 2);
8244 opaque_p_V2SI_type_node
= build_pointer_type (opaque_V2SI_type_node
);
8245 opaque_V4SI_type_node
= copy_node (V4SI_type_node
);
8247 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
8248 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
8249 'vector unsigned short'. */
8251 bool_char_type_node
= build_distinct_type_copy (unsigned_intQI_type_node
);
8252 bool_short_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
8253 bool_int_type_node
= build_distinct_type_copy (unsigned_intSI_type_node
);
8254 pixel_type_node
= build_distinct_type_copy (unsigned_intHI_type_node
);
8256 long_integer_type_internal_node
= long_integer_type_node
;
8257 long_unsigned_type_internal_node
= long_unsigned_type_node
;
8258 intQI_type_internal_node
= intQI_type_node
;
8259 uintQI_type_internal_node
= unsigned_intQI_type_node
;
8260 intHI_type_internal_node
= intHI_type_node
;
8261 uintHI_type_internal_node
= unsigned_intHI_type_node
;
8262 intSI_type_internal_node
= intSI_type_node
;
8263 uintSI_type_internal_node
= unsigned_intSI_type_node
;
8264 float_type_internal_node
= float_type_node
;
8265 void_type_internal_node
= void_type_node
;
8267 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8268 get_identifier ("__bool char"),
8269 bool_char_type_node
));
8270 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8271 get_identifier ("__bool short"),
8272 bool_short_type_node
));
8273 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8274 get_identifier ("__bool int"),
8275 bool_int_type_node
));
8276 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8277 get_identifier ("__pixel"),
8280 bool_V16QI_type_node
= build_vector_type (bool_char_type_node
, 16);
8281 bool_V8HI_type_node
= build_vector_type (bool_short_type_node
, 8);
8282 bool_V4SI_type_node
= build_vector_type (bool_int_type_node
, 4);
8283 pixel_V8HI_type_node
= build_vector_type (pixel_type_node
, 8);
8285 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8286 get_identifier ("__vector unsigned char"),
8287 unsigned_V16QI_type_node
));
8288 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8289 get_identifier ("__vector signed char"),
8291 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8292 get_identifier ("__vector __bool char"),
8293 bool_V16QI_type_node
));
8295 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8296 get_identifier ("__vector unsigned short"),
8297 unsigned_V8HI_type_node
));
8298 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8299 get_identifier ("__vector signed short"),
8301 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8302 get_identifier ("__vector __bool short"),
8303 bool_V8HI_type_node
));
8305 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8306 get_identifier ("__vector unsigned int"),
8307 unsigned_V4SI_type_node
));
8308 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8309 get_identifier ("__vector signed int"),
8311 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8312 get_identifier ("__vector __bool int"),
8313 bool_V4SI_type_node
));
8315 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8316 get_identifier ("__vector float"),
8318 (*lang_hooks
.decls
.pushdecl
) (build_decl (TYPE_DECL
,
8319 get_identifier ("__vector __pixel"),
8320 pixel_V8HI_type_node
));
8323 spe_init_builtins ();
8325 altivec_init_builtins ();
8326 if (TARGET_ALTIVEC
|| TARGET_SPE
)
8327 rs6000_common_init_builtins ();
8330 /* AIX libm provides clog as __clog. */
8331 if (built_in_decls
[BUILT_IN_CLOG
])
8332 set_user_assembler_name (built_in_decls
[BUILT_IN_CLOG
], "__clog");
8336 /* Search through a set of builtins and enable the mask bits.
8337 DESC is an array of builtins.
8338 SIZE is the total number of builtins.
8339 START is the builtin enum at which to start.
8340 END is the builtin enum at which to end. */
8342 enable_mask_for_builtins (struct builtin_description
*desc
, int size
,
8343 enum rs6000_builtins start
,
8344 enum rs6000_builtins end
)
8348 for (i
= 0; i
< size
; ++i
)
8349 if (desc
[i
].code
== start
)
8355 for (; i
< size
; ++i
)
8357 /* Flip all the bits on. */
8358 desc
[i
].mask
= target_flags
;
8359 if (desc
[i
].code
== end
)
8365 spe_init_builtins (void)
8367 tree endlink
= void_list_node
;
8368 tree puint_type_node
= build_pointer_type (unsigned_type_node
);
8369 tree pushort_type_node
= build_pointer_type (short_unsigned_type_node
);
8370 struct builtin_description
*d
;
8373 tree v2si_ftype_4_v2si
8374 = build_function_type
8375 (opaque_V2SI_type_node
,
8376 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8377 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8378 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8379 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8382 tree v2sf_ftype_4_v2sf
8383 = build_function_type
8384 (opaque_V2SF_type_node
,
8385 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8386 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8387 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8388 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8391 tree int_ftype_int_v2si_v2si
8392 = build_function_type
8394 tree_cons (NULL_TREE
, integer_type_node
,
8395 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8396 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8399 tree int_ftype_int_v2sf_v2sf
8400 = build_function_type
8402 tree_cons (NULL_TREE
, integer_type_node
,
8403 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8404 tree_cons (NULL_TREE
, opaque_V2SF_type_node
,
8407 tree void_ftype_v2si_puint_int
8408 = build_function_type (void_type_node
,
8409 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8410 tree_cons (NULL_TREE
, puint_type_node
,
8411 tree_cons (NULL_TREE
,
8415 tree void_ftype_v2si_puint_char
8416 = build_function_type (void_type_node
,
8417 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8418 tree_cons (NULL_TREE
, puint_type_node
,
8419 tree_cons (NULL_TREE
,
8423 tree void_ftype_v2si_pv2si_int
8424 = build_function_type (void_type_node
,
8425 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8426 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8427 tree_cons (NULL_TREE
,
8431 tree void_ftype_v2si_pv2si_char
8432 = build_function_type (void_type_node
,
8433 tree_cons (NULL_TREE
, opaque_V2SI_type_node
,
8434 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8435 tree_cons (NULL_TREE
,
8440 = build_function_type (void_type_node
,
8441 tree_cons (NULL_TREE
, integer_type_node
, endlink
));
8444 = build_function_type (integer_type_node
, endlink
);
8446 tree v2si_ftype_pv2si_int
8447 = build_function_type (opaque_V2SI_type_node
,
8448 tree_cons (NULL_TREE
, opaque_p_V2SI_type_node
,
8449 tree_cons (NULL_TREE
, integer_type_node
,
8452 tree v2si_ftype_puint_int
8453 = build_function_type (opaque_V2SI_type_node
,
8454 tree_cons (NULL_TREE
, puint_type_node
,
8455 tree_cons (NULL_TREE
, integer_type_node
,
8458 tree v2si_ftype_pushort_int
8459 = build_function_type (opaque_V2SI_type_node
,
8460 tree_cons (NULL_TREE
, pushort_type_node
,
8461 tree_cons (NULL_TREE
, integer_type_node
,
8464 tree v2si_ftype_signed_char
8465 = build_function_type (opaque_V2SI_type_node
,
8466 tree_cons (NULL_TREE
, signed_char_type_node
,
8469 /* The initialization of the simple binary and unary builtins is
8470 done in rs6000_common_init_builtins, but we have to enable the
8471 mask bits here manually because we have run out of `target_flags'
8472 bits. We really need to redesign this mask business. */
8474 enable_mask_for_builtins ((struct builtin_description
*) bdesc_2arg
,
8475 ARRAY_SIZE (bdesc_2arg
),
8478 enable_mask_for_builtins ((struct builtin_description
*) bdesc_1arg
,
8479 ARRAY_SIZE (bdesc_1arg
),
8481 SPE_BUILTIN_EVSUBFUSIAAW
);
8482 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_predicates
,
8483 ARRAY_SIZE (bdesc_spe_predicates
),
8484 SPE_BUILTIN_EVCMPEQ
,
8485 SPE_BUILTIN_EVFSTSTLT
);
8486 enable_mask_for_builtins ((struct builtin_description
*) bdesc_spe_evsel
,
8487 ARRAY_SIZE (bdesc_spe_evsel
),
8488 SPE_BUILTIN_EVSEL_CMPGTS
,
8489 SPE_BUILTIN_EVSEL_FSTSTEQ
);
8491 (*lang_hooks
.decls
.pushdecl
)
8492 (build_decl (TYPE_DECL
, get_identifier ("__ev64_opaque__"),
8493 opaque_V2SI_type_node
));
8495 /* Initialize irregular SPE builtins. */
8497 def_builtin (target_flags
, "__builtin_spe_mtspefscr", void_ftype_int
, SPE_BUILTIN_MTSPEFSCR
);
8498 def_builtin (target_flags
, "__builtin_spe_mfspefscr", int_ftype_void
, SPE_BUILTIN_MFSPEFSCR
);
8499 def_builtin (target_flags
, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDDX
);
8500 def_builtin (target_flags
, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDHX
);
8501 def_builtin (target_flags
, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int
, SPE_BUILTIN_EVSTDWX
);
8502 def_builtin (target_flags
, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHEX
);
8503 def_builtin (target_flags
, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWHOX
);
8504 def_builtin (target_flags
, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWEX
);
8505 def_builtin (target_flags
, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int
, SPE_BUILTIN_EVSTWWOX
);
8506 def_builtin (target_flags
, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDD
);
8507 def_builtin (target_flags
, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDH
);
8508 def_builtin (target_flags
, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char
, SPE_BUILTIN_EVSTDW
);
8509 def_builtin (target_flags
, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHE
);
8510 def_builtin (target_flags
, "__builtin_spe_evstwho", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWHO
);
8511 def_builtin (target_flags
, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWE
);
8512 def_builtin (target_flags
, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char
, SPE_BUILTIN_EVSTWWO
);
8513 def_builtin (target_flags
, "__builtin_spe_evsplatfi", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATFI
);
8514 def_builtin (target_flags
, "__builtin_spe_evsplati", v2si_ftype_signed_char
, SPE_BUILTIN_EVSPLATI
);
8517 def_builtin (target_flags
, "__builtin_spe_evlddx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDDX
);
8518 def_builtin (target_flags
, "__builtin_spe_evldwx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDWX
);
8519 def_builtin (target_flags
, "__builtin_spe_evldhx", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDHX
);
8520 def_builtin (target_flags
, "__builtin_spe_evlwhex", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHEX
);
8521 def_builtin (target_flags
, "__builtin_spe_evlwhoux", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOUX
);
8522 def_builtin (target_flags
, "__builtin_spe_evlwhosx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOSX
);
8523 def_builtin (target_flags
, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLATX
);
8524 def_builtin (target_flags
, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLATX
);
8525 def_builtin (target_flags
, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLATX
);
8526 def_builtin (target_flags
, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLATX
);
8527 def_builtin (target_flags
, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLATX
);
8528 def_builtin (target_flags
, "__builtin_spe_evldd", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDD
);
8529 def_builtin (target_flags
, "__builtin_spe_evldw", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDW
);
8530 def_builtin (target_flags
, "__builtin_spe_evldh", v2si_ftype_pv2si_int
, SPE_BUILTIN_EVLDH
);
8531 def_builtin (target_flags
, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHESPLAT
);
8532 def_builtin (target_flags
, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOSSPLAT
);
8533 def_builtin (target_flags
, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int
, SPE_BUILTIN_EVLHHOUSPLAT
);
8534 def_builtin (target_flags
, "__builtin_spe_evlwhe", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHE
);
8535 def_builtin (target_flags
, "__builtin_spe_evlwhos", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOS
);
8536 def_builtin (target_flags
, "__builtin_spe_evlwhou", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHOU
);
8537 def_builtin (target_flags
, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWHSPLAT
);
8538 def_builtin (target_flags
, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int
, SPE_BUILTIN_EVLWWSPLAT
);
8541 d
= (struct builtin_description
*) bdesc_spe_predicates
;
8542 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_predicates
); ++i
, d
++)
8546 switch (insn_data
[d
->icode
].operand
[1].mode
)
8549 type
= int_ftype_int_v2si_v2si
;
8552 type
= int_ftype_int_v2sf_v2sf
;
8558 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8561 /* Evsel predicates. */
8562 d
= (struct builtin_description
*) bdesc_spe_evsel
;
8563 for (i
= 0; i
< ARRAY_SIZE (bdesc_spe_evsel
); ++i
, d
++)
8567 switch (insn_data
[d
->icode
].operand
[1].mode
)
8570 type
= v2si_ftype_4_v2si
;
8573 type
= v2sf_ftype_4_v2sf
;
8579 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8584 altivec_init_builtins (void)
8586 struct builtin_description
*d
;
8587 struct builtin_description_predicates
*dp
;
8591 tree pfloat_type_node
= build_pointer_type (float_type_node
);
8592 tree pint_type_node
= build_pointer_type (integer_type_node
);
8593 tree pshort_type_node
= build_pointer_type (short_integer_type_node
);
8594 tree pchar_type_node
= build_pointer_type (char_type_node
);
8596 tree pvoid_type_node
= build_pointer_type (void_type_node
);
8598 tree pcfloat_type_node
= build_pointer_type (build_qualified_type (float_type_node
, TYPE_QUAL_CONST
));
8599 tree pcint_type_node
= build_pointer_type (build_qualified_type (integer_type_node
, TYPE_QUAL_CONST
));
8600 tree pcshort_type_node
= build_pointer_type (build_qualified_type (short_integer_type_node
, TYPE_QUAL_CONST
));
8601 tree pcchar_type_node
= build_pointer_type (build_qualified_type (char_type_node
, TYPE_QUAL_CONST
));
8603 tree pcvoid_type_node
= build_pointer_type (build_qualified_type (void_type_node
, TYPE_QUAL_CONST
));
8605 tree int_ftype_opaque
8606 = build_function_type_list (integer_type_node
,
8607 opaque_V4SI_type_node
, NULL_TREE
);
8609 tree opaque_ftype_opaque_int
8610 = build_function_type_list (opaque_V4SI_type_node
,
8611 opaque_V4SI_type_node
, integer_type_node
, NULL_TREE
);
8612 tree opaque_ftype_opaque_opaque_int
8613 = build_function_type_list (opaque_V4SI_type_node
,
8614 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
8615 integer_type_node
, NULL_TREE
);
8616 tree int_ftype_int_opaque_opaque
8617 = build_function_type_list (integer_type_node
,
8618 integer_type_node
, opaque_V4SI_type_node
,
8619 opaque_V4SI_type_node
, NULL_TREE
);
8620 tree int_ftype_int_v4si_v4si
8621 = build_function_type_list (integer_type_node
,
8622 integer_type_node
, V4SI_type_node
,
8623 V4SI_type_node
, NULL_TREE
);
8624 tree v4sf_ftype_pcfloat
8625 = build_function_type_list (V4SF_type_node
, pcfloat_type_node
, NULL_TREE
);
8626 tree void_ftype_pfloat_v4sf
8627 = build_function_type_list (void_type_node
,
8628 pfloat_type_node
, V4SF_type_node
, NULL_TREE
);
8629 tree v4si_ftype_pcint
8630 = build_function_type_list (V4SI_type_node
, pcint_type_node
, NULL_TREE
);
8631 tree void_ftype_pint_v4si
8632 = build_function_type_list (void_type_node
,
8633 pint_type_node
, V4SI_type_node
, NULL_TREE
);
8634 tree v8hi_ftype_pcshort
8635 = build_function_type_list (V8HI_type_node
, pcshort_type_node
, NULL_TREE
);
8636 tree void_ftype_pshort_v8hi
8637 = build_function_type_list (void_type_node
,
8638 pshort_type_node
, V8HI_type_node
, NULL_TREE
);
8639 tree v16qi_ftype_pcchar
8640 = build_function_type_list (V16QI_type_node
, pcchar_type_node
, NULL_TREE
);
8641 tree void_ftype_pchar_v16qi
8642 = build_function_type_list (void_type_node
,
8643 pchar_type_node
, V16QI_type_node
, NULL_TREE
);
8644 tree void_ftype_v4si
8645 = build_function_type_list (void_type_node
, V4SI_type_node
, NULL_TREE
);
8646 tree v8hi_ftype_void
8647 = build_function_type (V8HI_type_node
, void_list_node
);
8648 tree void_ftype_void
8649 = build_function_type (void_type_node
, void_list_node
);
8651 = build_function_type_list (void_type_node
, integer_type_node
, NULL_TREE
);
8653 tree opaque_ftype_long_pcvoid
8654 = build_function_type_list (opaque_V4SI_type_node
,
8655 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8656 tree v16qi_ftype_long_pcvoid
8657 = build_function_type_list (V16QI_type_node
,
8658 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8659 tree v8hi_ftype_long_pcvoid
8660 = build_function_type_list (V8HI_type_node
,
8661 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8662 tree v4si_ftype_long_pcvoid
8663 = build_function_type_list (V4SI_type_node
,
8664 long_integer_type_node
, pcvoid_type_node
, NULL_TREE
);
8666 tree void_ftype_opaque_long_pvoid
8667 = build_function_type_list (void_type_node
,
8668 opaque_V4SI_type_node
, long_integer_type_node
,
8669 pvoid_type_node
, NULL_TREE
);
8670 tree void_ftype_v4si_long_pvoid
8671 = build_function_type_list (void_type_node
,
8672 V4SI_type_node
, long_integer_type_node
,
8673 pvoid_type_node
, NULL_TREE
);
8674 tree void_ftype_v16qi_long_pvoid
8675 = build_function_type_list (void_type_node
,
8676 V16QI_type_node
, long_integer_type_node
,
8677 pvoid_type_node
, NULL_TREE
);
8678 tree void_ftype_v8hi_long_pvoid
8679 = build_function_type_list (void_type_node
,
8680 V8HI_type_node
, long_integer_type_node
,
8681 pvoid_type_node
, NULL_TREE
);
8682 tree int_ftype_int_v8hi_v8hi
8683 = build_function_type_list (integer_type_node
,
8684 integer_type_node
, V8HI_type_node
,
8685 V8HI_type_node
, NULL_TREE
);
8686 tree int_ftype_int_v16qi_v16qi
8687 = build_function_type_list (integer_type_node
,
8688 integer_type_node
, V16QI_type_node
,
8689 V16QI_type_node
, NULL_TREE
);
8690 tree int_ftype_int_v4sf_v4sf
8691 = build_function_type_list (integer_type_node
,
8692 integer_type_node
, V4SF_type_node
,
8693 V4SF_type_node
, NULL_TREE
);
8694 tree v4si_ftype_v4si
8695 = build_function_type_list (V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
8696 tree v8hi_ftype_v8hi
8697 = build_function_type_list (V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
8698 tree v16qi_ftype_v16qi
8699 = build_function_type_list (V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
8700 tree v4sf_ftype_v4sf
8701 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8702 tree void_ftype_pcvoid_int_int
8703 = build_function_type_list (void_type_node
,
8704 pcvoid_type_node
, integer_type_node
,
8705 integer_type_node
, NULL_TREE
);
8707 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat
,
8708 ALTIVEC_BUILTIN_LD_INTERNAL_4sf
);
8709 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf
,
8710 ALTIVEC_BUILTIN_ST_INTERNAL_4sf
);
8711 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint
,
8712 ALTIVEC_BUILTIN_LD_INTERNAL_4si
);
8713 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si
,
8714 ALTIVEC_BUILTIN_ST_INTERNAL_4si
);
8715 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort
,
8716 ALTIVEC_BUILTIN_LD_INTERNAL_8hi
);
8717 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi
,
8718 ALTIVEC_BUILTIN_ST_INTERNAL_8hi
);
8719 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar
,
8720 ALTIVEC_BUILTIN_LD_INTERNAL_16qi
);
8721 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi
,
8722 ALTIVEC_BUILTIN_ST_INTERNAL_16qi
);
8723 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mtvscr", void_ftype_v4si
, ALTIVEC_BUILTIN_MTVSCR
);
8724 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_mfvscr", v8hi_ftype_void
, ALTIVEC_BUILTIN_MFVSCR
);
8725 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dssall", void_ftype_void
, ALTIVEC_BUILTIN_DSSALL
);
8726 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_dss", void_ftype_int
, ALTIVEC_BUILTIN_DSS
);
8727 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSL
);
8728 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVSR
);
8729 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEBX
);
8730 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEHX
);
8731 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVEWX
);
8732 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVXL
);
8733 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_LVX
);
8734 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVX
);
8735 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVEWX
);
8736 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid
, ALTIVEC_BUILTIN_STVXL
);
8737 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid
, ALTIVEC_BUILTIN_STVEBX
);
8738 def_builtin (MASK_ALTIVEC
, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid
, ALTIVEC_BUILTIN_STVEHX
);
8739 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ld", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LD
);
8740 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lde", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDE
);
8741 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ldl", opaque_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LDL
);
8742 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSL
);
8743 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVSR
);
8744 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEBX
);
8745 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEHX
);
8746 def_builtin (MASK_ALTIVEC
, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid
, ALTIVEC_BUILTIN_VEC_LVEWX
);
8747 def_builtin (MASK_ALTIVEC
, "__builtin_vec_st", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_ST
);
8748 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ste", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STE
);
8749 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stl", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STL
);
8750 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEWX
);
8751 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEBX
);
8752 def_builtin (MASK_ALTIVEC
, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid
, ALTIVEC_BUILTIN_VEC_STVEHX
);
8754 def_builtin (MASK_ALTIVEC
, "__builtin_vec_step", int_ftype_opaque
, ALTIVEC_BUILTIN_VEC_STEP
);
8756 def_builtin (MASK_ALTIVEC
, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int
, ALTIVEC_BUILTIN_VEC_SLD
);
8757 def_builtin (MASK_ALTIVEC
, "__builtin_vec_splat", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_SPLAT
);
8758 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltw", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTW
);
8759 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vsplth", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTH
);
8760 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vspltb", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VSPLTB
);
8761 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctf", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTF
);
8762 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfsx", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFSX
);
8763 def_builtin (MASK_ALTIVEC
, "__builtin_vec_vcfux", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_VCFUX
);
8764 def_builtin (MASK_ALTIVEC
, "__builtin_vec_cts", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTS
);
8765 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ctu", opaque_ftype_opaque_int
, ALTIVEC_BUILTIN_VEC_CTU
);
8767 /* Add the DST variants. */
8768 d
= (struct builtin_description
*) bdesc_dst
;
8769 for (i
= 0; i
< ARRAY_SIZE (bdesc_dst
); i
++, d
++)
8770 def_builtin (d
->mask
, d
->name
, void_ftype_pcvoid_int_int
, d
->code
);
8772 /* Initialize the predicates. */
8773 dp
= (struct builtin_description_predicates
*) bdesc_altivec_preds
;
8774 for (i
= 0; i
< ARRAY_SIZE (bdesc_altivec_preds
); i
++, dp
++)
8776 enum machine_mode mode1
;
8778 bool is_overloaded
= dp
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8779 && dp
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
8784 mode1
= insn_data
[dp
->icode
].operand
[1].mode
;
8789 type
= int_ftype_int_opaque_opaque
;
8792 type
= int_ftype_int_v4si_v4si
;
8795 type
= int_ftype_int_v8hi_v8hi
;
8798 type
= int_ftype_int_v16qi_v16qi
;
8801 type
= int_ftype_int_v4sf_v4sf
;
8807 def_builtin (dp
->mask
, dp
->name
, type
, dp
->code
);
8810 /* Initialize the abs* operators. */
8811 d
= (struct builtin_description
*) bdesc_abs
;
8812 for (i
= 0; i
< ARRAY_SIZE (bdesc_abs
); i
++, d
++)
8814 enum machine_mode mode0
;
8817 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
8822 type
= v4si_ftype_v4si
;
8825 type
= v8hi_ftype_v8hi
;
8828 type
= v16qi_ftype_v16qi
;
8831 type
= v4sf_ftype_v4sf
;
8837 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
8844 /* Initialize target builtin that implements
8845 targetm.vectorize.builtin_mask_for_load. */
8847 decl
= add_builtin_function ("__builtin_altivec_mask_for_load",
8848 v16qi_ftype_long_pcvoid
,
8849 ALTIVEC_BUILTIN_MASK_FOR_LOAD
,
8850 BUILT_IN_MD
, NULL
, NULL_TREE
);
8851 TREE_READONLY (decl
) = 1;
8852 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8853 altivec_builtin_mask_for_load
= decl
;
8856 /* Access to the vec_init patterns. */
8857 ftype
= build_function_type_list (V4SI_type_node
, integer_type_node
,
8858 integer_type_node
, integer_type_node
,
8859 integer_type_node
, NULL_TREE
);
8860 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4si", ftype
,
8861 ALTIVEC_BUILTIN_VEC_INIT_V4SI
);
8863 ftype
= build_function_type_list (V8HI_type_node
, short_integer_type_node
,
8864 short_integer_type_node
,
8865 short_integer_type_node
,
8866 short_integer_type_node
,
8867 short_integer_type_node
,
8868 short_integer_type_node
,
8869 short_integer_type_node
,
8870 short_integer_type_node
, NULL_TREE
);
8871 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v8hi", ftype
,
8872 ALTIVEC_BUILTIN_VEC_INIT_V8HI
);
8874 ftype
= build_function_type_list (V16QI_type_node
, char_type_node
,
8875 char_type_node
, char_type_node
,
8876 char_type_node
, char_type_node
,
8877 char_type_node
, char_type_node
,
8878 char_type_node
, char_type_node
,
8879 char_type_node
, char_type_node
,
8880 char_type_node
, char_type_node
,
8881 char_type_node
, char_type_node
,
8882 char_type_node
, NULL_TREE
);
8883 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v16qi", ftype
,
8884 ALTIVEC_BUILTIN_VEC_INIT_V16QI
);
8886 ftype
= build_function_type_list (V4SF_type_node
, float_type_node
,
8887 float_type_node
, float_type_node
,
8888 float_type_node
, NULL_TREE
);
8889 def_builtin (MASK_ALTIVEC
, "__builtin_vec_init_v4sf", ftype
,
8890 ALTIVEC_BUILTIN_VEC_INIT_V4SF
);
8892 /* Access to the vec_set patterns. */
8893 ftype
= build_function_type_list (V4SI_type_node
, V4SI_type_node
,
8895 integer_type_node
, NULL_TREE
);
8896 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4si", ftype
,
8897 ALTIVEC_BUILTIN_VEC_SET_V4SI
);
8899 ftype
= build_function_type_list (V8HI_type_node
, V8HI_type_node
,
8901 integer_type_node
, NULL_TREE
);
8902 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v8hi", ftype
,
8903 ALTIVEC_BUILTIN_VEC_SET_V8HI
);
8905 ftype
= build_function_type_list (V8HI_type_node
, V16QI_type_node
,
8907 integer_type_node
, NULL_TREE
);
8908 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v16qi", ftype
,
8909 ALTIVEC_BUILTIN_VEC_SET_V16QI
);
8911 ftype
= build_function_type_list (V4SF_type_node
, V4SF_type_node
,
8913 integer_type_node
, NULL_TREE
);
8914 def_builtin (MASK_ALTIVEC
, "__builtin_vec_set_v4sf", ftype
,
8915 ALTIVEC_BUILTIN_VEC_SET_V4SF
);
8917 /* Access to the vec_extract patterns. */
8918 ftype
= build_function_type_list (intSI_type_node
, V4SI_type_node
,
8919 integer_type_node
, NULL_TREE
);
8920 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4si", ftype
,
8921 ALTIVEC_BUILTIN_VEC_EXT_V4SI
);
8923 ftype
= build_function_type_list (intHI_type_node
, V8HI_type_node
,
8924 integer_type_node
, NULL_TREE
);
8925 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v8hi", ftype
,
8926 ALTIVEC_BUILTIN_VEC_EXT_V8HI
);
8928 ftype
= build_function_type_list (intQI_type_node
, V16QI_type_node
,
8929 integer_type_node
, NULL_TREE
);
8930 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v16qi", ftype
,
8931 ALTIVEC_BUILTIN_VEC_EXT_V16QI
);
8933 ftype
= build_function_type_list (float_type_node
, V4SF_type_node
,
8934 integer_type_node
, NULL_TREE
);
8935 def_builtin (MASK_ALTIVEC
, "__builtin_vec_ext_v4sf", ftype
,
8936 ALTIVEC_BUILTIN_VEC_EXT_V4SF
);
8940 rs6000_common_init_builtins (void)
8942 struct builtin_description
*d
;
8945 tree v4sf_ftype_v4sf_v4sf_v16qi
8946 = build_function_type_list (V4SF_type_node
,
8947 V4SF_type_node
, V4SF_type_node
,
8948 V16QI_type_node
, NULL_TREE
);
8949 tree v4si_ftype_v4si_v4si_v16qi
8950 = build_function_type_list (V4SI_type_node
,
8951 V4SI_type_node
, V4SI_type_node
,
8952 V16QI_type_node
, NULL_TREE
);
8953 tree v8hi_ftype_v8hi_v8hi_v16qi
8954 = build_function_type_list (V8HI_type_node
,
8955 V8HI_type_node
, V8HI_type_node
,
8956 V16QI_type_node
, NULL_TREE
);
8957 tree v16qi_ftype_v16qi_v16qi_v16qi
8958 = build_function_type_list (V16QI_type_node
,
8959 V16QI_type_node
, V16QI_type_node
,
8960 V16QI_type_node
, NULL_TREE
);
8962 = build_function_type_list (V4SI_type_node
, integer_type_node
, NULL_TREE
);
8964 = build_function_type_list (V8HI_type_node
, integer_type_node
, NULL_TREE
);
8965 tree v16qi_ftype_int
8966 = build_function_type_list (V16QI_type_node
, integer_type_node
, NULL_TREE
);
8967 tree v8hi_ftype_v16qi
8968 = build_function_type_list (V8HI_type_node
, V16QI_type_node
, NULL_TREE
);
8969 tree v4sf_ftype_v4sf
8970 = build_function_type_list (V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
8972 tree v2si_ftype_v2si_v2si
8973 = build_function_type_list (opaque_V2SI_type_node
,
8974 opaque_V2SI_type_node
,
8975 opaque_V2SI_type_node
, NULL_TREE
);
8977 tree v2sf_ftype_v2sf_v2sf
8978 = build_function_type_list (opaque_V2SF_type_node
,
8979 opaque_V2SF_type_node
,
8980 opaque_V2SF_type_node
, NULL_TREE
);
8982 tree v2si_ftype_int_int
8983 = build_function_type_list (opaque_V2SI_type_node
,
8984 integer_type_node
, integer_type_node
,
8987 tree opaque_ftype_opaque
8988 = build_function_type_list (opaque_V4SI_type_node
,
8989 opaque_V4SI_type_node
, NULL_TREE
);
8991 tree v2si_ftype_v2si
8992 = build_function_type_list (opaque_V2SI_type_node
,
8993 opaque_V2SI_type_node
, NULL_TREE
);
8995 tree v2sf_ftype_v2sf
8996 = build_function_type_list (opaque_V2SF_type_node
,
8997 opaque_V2SF_type_node
, NULL_TREE
);
8999 tree v2sf_ftype_v2si
9000 = build_function_type_list (opaque_V2SF_type_node
,
9001 opaque_V2SI_type_node
, NULL_TREE
);
9003 tree v2si_ftype_v2sf
9004 = build_function_type_list (opaque_V2SI_type_node
,
9005 opaque_V2SF_type_node
, NULL_TREE
);
9007 tree v2si_ftype_v2si_char
9008 = build_function_type_list (opaque_V2SI_type_node
,
9009 opaque_V2SI_type_node
,
9010 char_type_node
, NULL_TREE
);
9012 tree v2si_ftype_int_char
9013 = build_function_type_list (opaque_V2SI_type_node
,
9014 integer_type_node
, char_type_node
, NULL_TREE
);
9016 tree v2si_ftype_char
9017 = build_function_type_list (opaque_V2SI_type_node
,
9018 char_type_node
, NULL_TREE
);
9020 tree int_ftype_int_int
9021 = build_function_type_list (integer_type_node
,
9022 integer_type_node
, integer_type_node
,
9025 tree opaque_ftype_opaque_opaque
9026 = build_function_type_list (opaque_V4SI_type_node
,
9027 opaque_V4SI_type_node
, opaque_V4SI_type_node
, NULL_TREE
);
9028 tree v4si_ftype_v4si_v4si
9029 = build_function_type_list (V4SI_type_node
,
9030 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9031 tree v4sf_ftype_v4si_int
9032 = build_function_type_list (V4SF_type_node
,
9033 V4SI_type_node
, integer_type_node
, NULL_TREE
);
9034 tree v4si_ftype_v4sf_int
9035 = build_function_type_list (V4SI_type_node
,
9036 V4SF_type_node
, integer_type_node
, NULL_TREE
);
9037 tree v4si_ftype_v4si_int
9038 = build_function_type_list (V4SI_type_node
,
9039 V4SI_type_node
, integer_type_node
, NULL_TREE
);
9040 tree v8hi_ftype_v8hi_int
9041 = build_function_type_list (V8HI_type_node
,
9042 V8HI_type_node
, integer_type_node
, NULL_TREE
);
9043 tree v16qi_ftype_v16qi_int
9044 = build_function_type_list (V16QI_type_node
,
9045 V16QI_type_node
, integer_type_node
, NULL_TREE
);
9046 tree v16qi_ftype_v16qi_v16qi_int
9047 = build_function_type_list (V16QI_type_node
,
9048 V16QI_type_node
, V16QI_type_node
,
9049 integer_type_node
, NULL_TREE
);
9050 tree v8hi_ftype_v8hi_v8hi_int
9051 = build_function_type_list (V8HI_type_node
,
9052 V8HI_type_node
, V8HI_type_node
,
9053 integer_type_node
, NULL_TREE
);
9054 tree v4si_ftype_v4si_v4si_int
9055 = build_function_type_list (V4SI_type_node
,
9056 V4SI_type_node
, V4SI_type_node
,
9057 integer_type_node
, NULL_TREE
);
9058 tree v4sf_ftype_v4sf_v4sf_int
9059 = build_function_type_list (V4SF_type_node
,
9060 V4SF_type_node
, V4SF_type_node
,
9061 integer_type_node
, NULL_TREE
);
9062 tree v4sf_ftype_v4sf_v4sf
9063 = build_function_type_list (V4SF_type_node
,
9064 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9065 tree opaque_ftype_opaque_opaque_opaque
9066 = build_function_type_list (opaque_V4SI_type_node
,
9067 opaque_V4SI_type_node
, opaque_V4SI_type_node
,
9068 opaque_V4SI_type_node
, NULL_TREE
);
9069 tree v4sf_ftype_v4sf_v4sf_v4si
9070 = build_function_type_list (V4SF_type_node
,
9071 V4SF_type_node
, V4SF_type_node
,
9072 V4SI_type_node
, NULL_TREE
);
9073 tree v4sf_ftype_v4sf_v4sf_v4sf
9074 = build_function_type_list (V4SF_type_node
,
9075 V4SF_type_node
, V4SF_type_node
,
9076 V4SF_type_node
, NULL_TREE
);
9077 tree v4si_ftype_v4si_v4si_v4si
9078 = build_function_type_list (V4SI_type_node
,
9079 V4SI_type_node
, V4SI_type_node
,
9080 V4SI_type_node
, NULL_TREE
);
9081 tree v8hi_ftype_v8hi_v8hi
9082 = build_function_type_list (V8HI_type_node
,
9083 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9084 tree v8hi_ftype_v8hi_v8hi_v8hi
9085 = build_function_type_list (V8HI_type_node
,
9086 V8HI_type_node
, V8HI_type_node
,
9087 V8HI_type_node
, NULL_TREE
);
9088 tree v4si_ftype_v8hi_v8hi_v4si
9089 = build_function_type_list (V4SI_type_node
,
9090 V8HI_type_node
, V8HI_type_node
,
9091 V4SI_type_node
, NULL_TREE
);
9092 tree v4si_ftype_v16qi_v16qi_v4si
9093 = build_function_type_list (V4SI_type_node
,
9094 V16QI_type_node
, V16QI_type_node
,
9095 V4SI_type_node
, NULL_TREE
);
9096 tree v16qi_ftype_v16qi_v16qi
9097 = build_function_type_list (V16QI_type_node
,
9098 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9099 tree v4si_ftype_v4sf_v4sf
9100 = build_function_type_list (V4SI_type_node
,
9101 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9102 tree v8hi_ftype_v16qi_v16qi
9103 = build_function_type_list (V8HI_type_node
,
9104 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9105 tree v4si_ftype_v8hi_v8hi
9106 = build_function_type_list (V4SI_type_node
,
9107 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9108 tree v8hi_ftype_v4si_v4si
9109 = build_function_type_list (V8HI_type_node
,
9110 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9111 tree v16qi_ftype_v8hi_v8hi
9112 = build_function_type_list (V16QI_type_node
,
9113 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9114 tree v4si_ftype_v16qi_v4si
9115 = build_function_type_list (V4SI_type_node
,
9116 V16QI_type_node
, V4SI_type_node
, NULL_TREE
);
9117 tree v4si_ftype_v16qi_v16qi
9118 = build_function_type_list (V4SI_type_node
,
9119 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9120 tree v4si_ftype_v8hi_v4si
9121 = build_function_type_list (V4SI_type_node
,
9122 V8HI_type_node
, V4SI_type_node
, NULL_TREE
);
9123 tree v4si_ftype_v8hi
9124 = build_function_type_list (V4SI_type_node
, V8HI_type_node
, NULL_TREE
);
9125 tree int_ftype_v4si_v4si
9126 = build_function_type_list (integer_type_node
,
9127 V4SI_type_node
, V4SI_type_node
, NULL_TREE
);
9128 tree int_ftype_v4sf_v4sf
9129 = build_function_type_list (integer_type_node
,
9130 V4SF_type_node
, V4SF_type_node
, NULL_TREE
);
9131 tree int_ftype_v16qi_v16qi
9132 = build_function_type_list (integer_type_node
,
9133 V16QI_type_node
, V16QI_type_node
, NULL_TREE
);
9134 tree int_ftype_v8hi_v8hi
9135 = build_function_type_list (integer_type_node
,
9136 V8HI_type_node
, V8HI_type_node
, NULL_TREE
);
9138 /* Add the simple ternary operators. */
9139 d
= (struct builtin_description
*) bdesc_3arg
;
9140 for (i
= 0; i
< ARRAY_SIZE (bdesc_3arg
); i
++, d
++)
9142 enum machine_mode mode0
, mode1
, mode2
, mode3
;
9144 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9145 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9156 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
9159 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9160 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
9161 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
9162 mode3
= insn_data
[d
->icode
].operand
[3].mode
;
9165 /* When all four are of the same mode. */
9166 if (mode0
== mode1
&& mode1
== mode2
&& mode2
== mode3
)
9171 type
= opaque_ftype_opaque_opaque_opaque
;
9174 type
= v4si_ftype_v4si_v4si_v4si
;
9177 type
= v4sf_ftype_v4sf_v4sf_v4sf
;
9180 type
= v8hi_ftype_v8hi_v8hi_v8hi
;
9183 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
9189 else if (mode0
== mode1
&& mode1
== mode2
&& mode3
== V16QImode
)
9194 type
= v4si_ftype_v4si_v4si_v16qi
;
9197 type
= v4sf_ftype_v4sf_v4sf_v16qi
;
9200 type
= v8hi_ftype_v8hi_v8hi_v16qi
;
9203 type
= v16qi_ftype_v16qi_v16qi_v16qi
;
9209 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
9210 && mode3
== V4SImode
)
9211 type
= v4si_ftype_v16qi_v16qi_v4si
;
9212 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
9213 && mode3
== V4SImode
)
9214 type
= v4si_ftype_v8hi_v8hi_v4si
;
9215 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
9216 && mode3
== V4SImode
)
9217 type
= v4sf_ftype_v4sf_v4sf_v4si
;
9219 /* vchar, vchar, vchar, 4 bit literal. */
9220 else if (mode0
== V16QImode
&& mode1
== mode0
&& mode2
== mode0
9222 type
= v16qi_ftype_v16qi_v16qi_int
;
9224 /* vshort, vshort, vshort, 4 bit literal. */
9225 else if (mode0
== V8HImode
&& mode1
== mode0
&& mode2
== mode0
9227 type
= v8hi_ftype_v8hi_v8hi_int
;
9229 /* vint, vint, vint, 4 bit literal. */
9230 else if (mode0
== V4SImode
&& mode1
== mode0
&& mode2
== mode0
9232 type
= v4si_ftype_v4si_v4si_int
;
9234 /* vfloat, vfloat, vfloat, 4 bit literal. */
9235 else if (mode0
== V4SFmode
&& mode1
== mode0
&& mode2
== mode0
9237 type
= v4sf_ftype_v4sf_v4sf_int
;
9242 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9245 /* Add the simple binary operators. */
9246 d
= (struct builtin_description
*) bdesc_2arg
;
9247 for (i
= 0; i
< ARRAY_SIZE (bdesc_2arg
); i
++, d
++)
9249 enum machine_mode mode0
, mode1
, mode2
;
9251 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9252 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9262 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
9265 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9266 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
9267 mode2
= insn_data
[d
->icode
].operand
[2].mode
;
9270 /* When all three operands are of the same mode. */
9271 if (mode0
== mode1
&& mode1
== mode2
)
9276 type
= opaque_ftype_opaque_opaque
;
9279 type
= v4sf_ftype_v4sf_v4sf
;
9282 type
= v4si_ftype_v4si_v4si
;
9285 type
= v16qi_ftype_v16qi_v16qi
;
9288 type
= v8hi_ftype_v8hi_v8hi
;
9291 type
= v2si_ftype_v2si_v2si
;
9294 type
= v2sf_ftype_v2sf_v2sf
;
9297 type
= int_ftype_int_int
;
9304 /* A few other combos we really don't want to do manually. */
9306 /* vint, vfloat, vfloat. */
9307 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== V4SFmode
)
9308 type
= v4si_ftype_v4sf_v4sf
;
9310 /* vshort, vchar, vchar. */
9311 else if (mode0
== V8HImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
9312 type
= v8hi_ftype_v16qi_v16qi
;
9314 /* vint, vshort, vshort. */
9315 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
9316 type
= v4si_ftype_v8hi_v8hi
;
9318 /* vshort, vint, vint. */
9319 else if (mode0
== V8HImode
&& mode1
== V4SImode
&& mode2
== V4SImode
)
9320 type
= v8hi_ftype_v4si_v4si
;
9322 /* vchar, vshort, vshort. */
9323 else if (mode0
== V16QImode
&& mode1
== V8HImode
&& mode2
== V8HImode
)
9324 type
= v16qi_ftype_v8hi_v8hi
;
9326 /* vint, vchar, vint. */
9327 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V4SImode
)
9328 type
= v4si_ftype_v16qi_v4si
;
9330 /* vint, vchar, vchar. */
9331 else if (mode0
== V4SImode
&& mode1
== V16QImode
&& mode2
== V16QImode
)
9332 type
= v4si_ftype_v16qi_v16qi
;
9334 /* vint, vshort, vint. */
9335 else if (mode0
== V4SImode
&& mode1
== V8HImode
&& mode2
== V4SImode
)
9336 type
= v4si_ftype_v8hi_v4si
;
9338 /* vint, vint, 5 bit literal. */
9339 else if (mode0
== V4SImode
&& mode1
== V4SImode
&& mode2
== QImode
)
9340 type
= v4si_ftype_v4si_int
;
9342 /* vshort, vshort, 5 bit literal. */
9343 else if (mode0
== V8HImode
&& mode1
== V8HImode
&& mode2
== QImode
)
9344 type
= v8hi_ftype_v8hi_int
;
9346 /* vchar, vchar, 5 bit literal. */
9347 else if (mode0
== V16QImode
&& mode1
== V16QImode
&& mode2
== QImode
)
9348 type
= v16qi_ftype_v16qi_int
;
9350 /* vfloat, vint, 5 bit literal. */
9351 else if (mode0
== V4SFmode
&& mode1
== V4SImode
&& mode2
== QImode
)
9352 type
= v4sf_ftype_v4si_int
;
9354 /* vint, vfloat, 5 bit literal. */
9355 else if (mode0
== V4SImode
&& mode1
== V4SFmode
&& mode2
== QImode
)
9356 type
= v4si_ftype_v4sf_int
;
9358 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== SImode
)
9359 type
= v2si_ftype_int_int
;
9361 else if (mode0
== V2SImode
&& mode1
== V2SImode
&& mode2
== QImode
)
9362 type
= v2si_ftype_v2si_char
;
9364 else if (mode0
== V2SImode
&& mode1
== SImode
&& mode2
== QImode
)
9365 type
= v2si_ftype_int_char
;
9370 gcc_assert (mode0
== SImode
);
9374 type
= int_ftype_v4si_v4si
;
9377 type
= int_ftype_v4sf_v4sf
;
9380 type
= int_ftype_v16qi_v16qi
;
9383 type
= int_ftype_v8hi_v8hi
;
9390 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9393 /* Add the simple unary operators. */
9394 d
= (struct builtin_description
*) bdesc_1arg
;
9395 for (i
= 0; i
< ARRAY_SIZE (bdesc_1arg
); i
++, d
++)
9397 enum machine_mode mode0
, mode1
;
9399 bool is_overloaded
= d
->code
>= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9400 && d
->code
<= ALTIVEC_BUILTIN_OVERLOADED_LAST
;
9409 if (d
->name
== 0 || d
->icode
== CODE_FOR_nothing
)
9412 mode0
= insn_data
[d
->icode
].operand
[0].mode
;
9413 mode1
= insn_data
[d
->icode
].operand
[1].mode
;
9416 if (mode0
== V4SImode
&& mode1
== QImode
)
9417 type
= v4si_ftype_int
;
9418 else if (mode0
== V8HImode
&& mode1
== QImode
)
9419 type
= v8hi_ftype_int
;
9420 else if (mode0
== V16QImode
&& mode1
== QImode
)
9421 type
= v16qi_ftype_int
;
9422 else if (mode0
== VOIDmode
&& mode1
== VOIDmode
)
9423 type
= opaque_ftype_opaque
;
9424 else if (mode0
== V4SFmode
&& mode1
== V4SFmode
)
9425 type
= v4sf_ftype_v4sf
;
9426 else if (mode0
== V8HImode
&& mode1
== V16QImode
)
9427 type
= v8hi_ftype_v16qi
;
9428 else if (mode0
== V4SImode
&& mode1
== V8HImode
)
9429 type
= v4si_ftype_v8hi
;
9430 else if (mode0
== V2SImode
&& mode1
== V2SImode
)
9431 type
= v2si_ftype_v2si
;
9432 else if (mode0
== V2SFmode
&& mode1
== V2SFmode
)
9433 type
= v2sf_ftype_v2sf
;
9434 else if (mode0
== V2SFmode
&& mode1
== V2SImode
)
9435 type
= v2sf_ftype_v2si
;
9436 else if (mode0
== V2SImode
&& mode1
== V2SFmode
)
9437 type
= v2si_ftype_v2sf
;
9438 else if (mode0
== V2SImode
&& mode1
== QImode
)
9439 type
= v2si_ftype_char
;
9443 def_builtin (d
->mask
, d
->name
, type
, d
->code
);
9448 rs6000_init_libfuncs (void)
9450 if (DEFAULT_ABI
!= ABI_V4
&& TARGET_XCOFF
9451 && !TARGET_POWER2
&& !TARGET_POWERPC
)
9453 /* AIX library routines for float->int conversion. */
9454 set_conv_libfunc (sfix_optab
, SImode
, DFmode
, "__itrunc");
9455 set_conv_libfunc (ufix_optab
, SImode
, DFmode
, "__uitrunc");
9456 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_qitrunc");
9457 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_quitrunc");
9460 if (!TARGET_IEEEQUAD
)
9461 /* AIX/Darwin/64-bit Linux quad floating point routines. */
9462 if (!TARGET_XL_COMPAT
)
9464 set_optab_libfunc (add_optab
, TFmode
, "__gcc_qadd");
9465 set_optab_libfunc (sub_optab
, TFmode
, "__gcc_qsub");
9466 set_optab_libfunc (smul_optab
, TFmode
, "__gcc_qmul");
9467 set_optab_libfunc (sdiv_optab
, TFmode
, "__gcc_qdiv");
9469 if (!(TARGET_HARD_FLOAT
&& (TARGET_FPRS
|| TARGET_E500_DOUBLE
)))
9471 set_optab_libfunc (neg_optab
, TFmode
, "__gcc_qneg");
9472 set_optab_libfunc (eq_optab
, TFmode
, "__gcc_qeq");
9473 set_optab_libfunc (ne_optab
, TFmode
, "__gcc_qne");
9474 set_optab_libfunc (gt_optab
, TFmode
, "__gcc_qgt");
9475 set_optab_libfunc (ge_optab
, TFmode
, "__gcc_qge");
9476 set_optab_libfunc (lt_optab
, TFmode
, "__gcc_qlt");
9477 set_optab_libfunc (le_optab
, TFmode
, "__gcc_qle");
9478 set_optab_libfunc (unord_optab
, TFmode
, "__gcc_qunord");
9480 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "__gcc_stoq");
9481 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "__gcc_dtoq");
9482 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "__gcc_qtos");
9483 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "__gcc_qtod");
9484 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "__gcc_qtoi");
9485 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "__gcc_qtou");
9486 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "__gcc_itoq");
9487 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "__gcc_utoq");
9492 set_optab_libfunc (add_optab
, TFmode
, "_xlqadd");
9493 set_optab_libfunc (sub_optab
, TFmode
, "_xlqsub");
9494 set_optab_libfunc (smul_optab
, TFmode
, "_xlqmul");
9495 set_optab_libfunc (sdiv_optab
, TFmode
, "_xlqdiv");
9499 /* 32-bit SVR4 quad floating point routines. */
9501 set_optab_libfunc (add_optab
, TFmode
, "_q_add");
9502 set_optab_libfunc (sub_optab
, TFmode
, "_q_sub");
9503 set_optab_libfunc (neg_optab
, TFmode
, "_q_neg");
9504 set_optab_libfunc (smul_optab
, TFmode
, "_q_mul");
9505 set_optab_libfunc (sdiv_optab
, TFmode
, "_q_div");
9506 if (TARGET_PPC_GPOPT
|| TARGET_POWER2
)
9507 set_optab_libfunc (sqrt_optab
, TFmode
, "_q_sqrt");
9509 set_optab_libfunc (eq_optab
, TFmode
, "_q_feq");
9510 set_optab_libfunc (ne_optab
, TFmode
, "_q_fne");
9511 set_optab_libfunc (gt_optab
, TFmode
, "_q_fgt");
9512 set_optab_libfunc (ge_optab
, TFmode
, "_q_fge");
9513 set_optab_libfunc (lt_optab
, TFmode
, "_q_flt");
9514 set_optab_libfunc (le_optab
, TFmode
, "_q_fle");
9516 set_conv_libfunc (sext_optab
, TFmode
, SFmode
, "_q_stoq");
9517 set_conv_libfunc (sext_optab
, TFmode
, DFmode
, "_q_dtoq");
9518 set_conv_libfunc (trunc_optab
, SFmode
, TFmode
, "_q_qtos");
9519 set_conv_libfunc (trunc_optab
, DFmode
, TFmode
, "_q_qtod");
9520 set_conv_libfunc (sfix_optab
, SImode
, TFmode
, "_q_qtoi");
9521 set_conv_libfunc (ufix_optab
, SImode
, TFmode
, "_q_qtou");
9522 set_conv_libfunc (sfloat_optab
, TFmode
, SImode
, "_q_itoq");
9523 set_conv_libfunc (ufloat_optab
, TFmode
, SImode
, "_q_utoq");
9528 /* Expand a block clear operation, and return 1 if successful. Return 0
9529 if we should let the compiler generate normal code.
9531 operands[0] is the destination
9532 operands[1] is the length
9533 operands[3] is the alignment */
9536 expand_block_clear (rtx operands
[])
9538 rtx orig_dest
= operands
[0];
9539 rtx bytes_rtx
= operands
[1];
9540 rtx align_rtx
= operands
[3];
9541 bool constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9542 HOST_WIDE_INT align
;
9543 HOST_WIDE_INT bytes
;
9548 /* If this is not a fixed size move, just call memcpy */
9552 /* This must be a fixed size alignment */
9553 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9554 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9556 /* Anything to clear? */
9557 bytes
= INTVAL (bytes_rtx
);
9561 /* Use the builtin memset after a point, to avoid huge code bloat.
9562 When optimize_size, avoid any significant code bloat; calling
9563 memset is about 4 instructions, so allow for one instruction to
9564 load zero and three to do clearing. */
9565 if (TARGET_ALTIVEC
&& align
>= 128)
9567 else if (TARGET_POWERPC64
&& align
>= 32)
9572 if (optimize_size
&& bytes
> 3 * clear_step
)
9574 if (! optimize_size
&& bytes
> 8 * clear_step
)
9577 for (offset
= 0; bytes
> 0; offset
+= clear_bytes
, bytes
-= clear_bytes
)
9579 enum machine_mode mode
= BLKmode
;
9582 if (bytes
>= 16 && TARGET_ALTIVEC
&& align
>= 128)
9587 else if (bytes
>= 8 && TARGET_POWERPC64
9588 /* 64-bit loads and stores require word-aligned
9590 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9595 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9596 { /* move 4 bytes */
9600 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9601 { /* move 2 bytes */
9605 else /* move 1 byte at a time */
9611 dest
= adjust_address (orig_dest
, mode
, offset
);
9613 emit_move_insn (dest
, CONST0_RTX (mode
));
9620 /* Expand a block move operation, and return 1 if successful. Return 0
9621 if we should let the compiler generate normal code.
9623 operands[0] is the destination
9624 operands[1] is the source
9625 operands[2] is the length
9626 operands[3] is the alignment */
9628 #define MAX_MOVE_REG 4
9631 expand_block_move (rtx operands
[])
9633 rtx orig_dest
= operands
[0];
9634 rtx orig_src
= operands
[1];
9635 rtx bytes_rtx
= operands
[2];
9636 rtx align_rtx
= operands
[3];
9637 int constp
= (GET_CODE (bytes_rtx
) == CONST_INT
);
9642 rtx stores
[MAX_MOVE_REG
];
9645 /* If this is not a fixed size move, just call memcpy */
9649 /* This must be a fixed size alignment */
9650 gcc_assert (GET_CODE (align_rtx
) == CONST_INT
);
9651 align
= INTVAL (align_rtx
) * BITS_PER_UNIT
;
9653 /* Anything to move? */
9654 bytes
= INTVAL (bytes_rtx
);
9658 /* store_one_arg depends on expand_block_move to handle at least the size of
9659 reg_parm_stack_space. */
9660 if (bytes
> (TARGET_POWERPC64
? 64 : 32))
9663 for (offset
= 0; bytes
> 0; offset
+= move_bytes
, bytes
-= move_bytes
)
9666 rtx (*movmemsi
) (rtx
, rtx
, rtx
, rtx
);
9667 rtx (*mov
) (rtx
, rtx
);
9669 enum machine_mode mode
= BLKmode
;
9672 /* Altivec first, since it will be faster than a string move
9673 when it applies, and usually not significantly larger. */
9674 if (TARGET_ALTIVEC
&& bytes
>= 16 && align
>= 128)
9678 gen_func
.mov
= gen_movv4si
;
9680 else if (TARGET_STRING
9681 && bytes
> 24 /* move up to 32 bytes at a time */
9689 && ! fixed_regs
[12])
9691 move_bytes
= (bytes
> 32) ? 32 : bytes
;
9692 gen_func
.movmemsi
= gen_movmemsi_8reg
;
9694 else if (TARGET_STRING
9695 && bytes
> 16 /* move up to 24 bytes at a time */
9701 && ! fixed_regs
[10])
9703 move_bytes
= (bytes
> 24) ? 24 : bytes
;
9704 gen_func
.movmemsi
= gen_movmemsi_6reg
;
9706 else if (TARGET_STRING
9707 && bytes
> 8 /* move up to 16 bytes at a time */
9713 move_bytes
= (bytes
> 16) ? 16 : bytes
;
9714 gen_func
.movmemsi
= gen_movmemsi_4reg
;
9716 else if (bytes
>= 8 && TARGET_POWERPC64
9717 /* 64-bit loads and stores require word-aligned
9719 && (align
>= 64 || (!STRICT_ALIGNMENT
&& align
>= 32)))
9723 gen_func
.mov
= gen_movdi
;
9725 else if (TARGET_STRING
&& bytes
> 4 && !TARGET_POWERPC64
)
9726 { /* move up to 8 bytes at a time */
9727 move_bytes
= (bytes
> 8) ? 8 : bytes
;
9728 gen_func
.movmemsi
= gen_movmemsi_2reg
;
9730 else if (bytes
>= 4 && (align
>= 32 || !STRICT_ALIGNMENT
))
9731 { /* move 4 bytes */
9734 gen_func
.mov
= gen_movsi
;
9736 else if (bytes
>= 2 && (align
>= 16 || !STRICT_ALIGNMENT
))
9737 { /* move 2 bytes */
9740 gen_func
.mov
= gen_movhi
;
9742 else if (TARGET_STRING
&& bytes
> 1)
9743 { /* move up to 4 bytes at a time */
9744 move_bytes
= (bytes
> 4) ? 4 : bytes
;
9745 gen_func
.movmemsi
= gen_movmemsi_1reg
;
9747 else /* move 1 byte at a time */
9751 gen_func
.mov
= gen_movqi
;
9754 src
= adjust_address (orig_src
, mode
, offset
);
9755 dest
= adjust_address (orig_dest
, mode
, offset
);
9757 if (mode
!= BLKmode
)
9759 rtx tmp_reg
= gen_reg_rtx (mode
);
9761 emit_insn ((*gen_func
.mov
) (tmp_reg
, src
));
9762 stores
[num_reg
++] = (*gen_func
.mov
) (dest
, tmp_reg
);
9765 if (mode
== BLKmode
|| num_reg
>= MAX_MOVE_REG
|| bytes
== move_bytes
)
9768 for (i
= 0; i
< num_reg
; i
++)
9769 emit_insn (stores
[i
]);
9773 if (mode
== BLKmode
)
9775 /* Move the address into scratch registers. The movmemsi
9776 patterns require zero offset. */
9777 if (!REG_P (XEXP (src
, 0)))
9779 rtx src_reg
= copy_addr_to_reg (XEXP (src
, 0));
9780 src
= replace_equiv_address (src
, src_reg
);
9782 set_mem_size (src
, GEN_INT (move_bytes
));
9784 if (!REG_P (XEXP (dest
, 0)))
9786 rtx dest_reg
= copy_addr_to_reg (XEXP (dest
, 0));
9787 dest
= replace_equiv_address (dest
, dest_reg
);
9789 set_mem_size (dest
, GEN_INT (move_bytes
));
9791 emit_insn ((*gen_func
.movmemsi
) (dest
, src
,
9792 GEN_INT (move_bytes
& 31),
9801 /* Return a string to perform a load_multiple operation.
9802 operands[0] is the vector.
9803 operands[1] is the source address.
9804 operands[2] is the first destination register. */
9807 rs6000_output_load_multiple (rtx operands
[3])
9809 /* We have to handle the case where the pseudo used to contain the address
9810 is assigned to one of the output registers. */
9812 int words
= XVECLEN (operands
[0], 0);
9815 if (XVECLEN (operands
[0], 0) == 1)
9816 return "{l|lwz} %2,0(%1)";
9818 for (i
= 0; i
< words
; i
++)
9819 if (refers_to_regno_p (REGNO (operands
[2]) + i
,
9820 REGNO (operands
[2]) + i
+ 1, operands
[1], 0))
9824 xop
[0] = GEN_INT (4 * (words
-1));
9825 xop
[1] = operands
[1];
9826 xop
[2] = operands
[2];
9827 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop
);
9832 xop
[0] = GEN_INT (4 * (words
-1));
9833 xop
[1] = operands
[1];
9834 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + 1);
9835 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
);
9840 for (j
= 0; j
< words
; j
++)
9843 xop
[0] = GEN_INT (j
* 4);
9844 xop
[1] = operands
[1];
9845 xop
[2] = gen_rtx_REG (SImode
, REGNO (operands
[2]) + j
);
9846 output_asm_insn ("{l|lwz} %2,%0(%1)", xop
);
9848 xop
[0] = GEN_INT (i
* 4);
9849 xop
[1] = operands
[1];
9850 output_asm_insn ("{l|lwz} %1,%0(%1)", xop
);
9855 return "{lsi|lswi} %2,%1,%N0";
9859 /* A validation routine: say whether CODE, a condition code, and MODE
9860 match. The other alternatives either don't make sense or should
9861 never be generated. */
9864 validate_condition_mode (enum rtx_code code
, enum machine_mode mode
)
9866 gcc_assert ((GET_RTX_CLASS (code
) == RTX_COMPARE
9867 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
9868 && GET_MODE_CLASS (mode
) == MODE_CC
);
9870 /* These don't make sense. */
9871 gcc_assert ((code
!= GT
&& code
!= LT
&& code
!= GE
&& code
!= LE
)
9872 || mode
!= CCUNSmode
);
9874 gcc_assert ((code
!= GTU
&& code
!= LTU
&& code
!= GEU
&& code
!= LEU
)
9875 || mode
== CCUNSmode
);
9877 gcc_assert (mode
== CCFPmode
9878 || (code
!= ORDERED
&& code
!= UNORDERED
9879 && code
!= UNEQ
&& code
!= LTGT
9880 && code
!= UNGT
&& code
!= UNLT
9881 && code
!= UNGE
&& code
!= UNLE
));
9883 /* These should never be generated except for
9884 flag_finite_math_only. */
9885 gcc_assert (mode
!= CCFPmode
9886 || flag_finite_math_only
9887 || (code
!= LE
&& code
!= GE
9888 && code
!= UNEQ
&& code
!= LTGT
9889 && code
!= UNGT
&& code
!= UNLT
));
9891 /* These are invalid; the information is not there. */
9892 gcc_assert (mode
!= CCEQmode
|| code
== EQ
|| code
== NE
);
9896 /* Return 1 if ANDOP is a mask that has no bits on that are not in the
9897 mask required to convert the result of a rotate insn into a shift
9898 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9901 includes_lshift_p (rtx shiftop
, rtx andop
)
9903 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
9905 shift_mask
<<= INTVAL (shiftop
);
9907 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
9910 /* Similar, but for right shift. */
9913 includes_rshift_p (rtx shiftop
, rtx andop
)
9915 unsigned HOST_WIDE_INT shift_mask
= ~(unsigned HOST_WIDE_INT
) 0;
9917 shift_mask
>>= INTVAL (shiftop
);
9919 return (INTVAL (andop
) & 0xffffffff & ~shift_mask
) == 0;
9922 /* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9923 to perform a left shift. It must have exactly SHIFTOP least
9924 significant 0's, then one or more 1's, then zero or more 0's. */
9927 includes_rldic_lshift_p (rtx shiftop
, rtx andop
)
9929 if (GET_CODE (andop
) == CONST_INT
)
9931 HOST_WIDE_INT c
, lsb
, shift_mask
;
9934 if (c
== 0 || c
== ~0)
9938 shift_mask
<<= INTVAL (shiftop
);
9940 /* Find the least significant one bit. */
9943 /* It must coincide with the LSB of the shift mask. */
9944 if (-lsb
!= shift_mask
)
9947 /* Invert to look for the next transition (if any). */
9950 /* Remove the low group of ones (originally low group of zeros). */
9953 /* Again find the lsb, and check we have all 1's above. */
9957 else if (GET_CODE (andop
) == CONST_DOUBLE
9958 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
9960 HOST_WIDE_INT low
, high
, lsb
;
9961 HOST_WIDE_INT shift_mask_low
, shift_mask_high
;
9963 low
= CONST_DOUBLE_LOW (andop
);
9964 if (HOST_BITS_PER_WIDE_INT
< 64)
9965 high
= CONST_DOUBLE_HIGH (andop
);
9967 if ((low
== 0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== 0))
9968 || (low
== ~0 && (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0)))
9971 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
9973 shift_mask_high
= ~0;
9974 if (INTVAL (shiftop
) > 32)
9975 shift_mask_high
<<= INTVAL (shiftop
) - 32;
9979 if (-lsb
!= shift_mask_high
|| INTVAL (shiftop
) < 32)
9986 return high
== -lsb
;
9989 shift_mask_low
= ~0;
9990 shift_mask_low
<<= INTVAL (shiftop
);
9994 if (-lsb
!= shift_mask_low
)
9997 if (HOST_BITS_PER_WIDE_INT
< 64)
10002 if (HOST_BITS_PER_WIDE_INT
< 64 && low
== 0)
10004 lsb
= high
& -high
;
10005 return high
== -lsb
;
10009 return low
== -lsb
&& (HOST_BITS_PER_WIDE_INT
>= 64 || high
== ~0);
10015 /* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
10016 to perform a left shift. It must have SHIFTOP or more least
10017 significant 0's, with the remainder of the word 1's. */
10020 includes_rldicr_lshift_p (rtx shiftop
, rtx andop
)
10022 if (GET_CODE (andop
) == CONST_INT
)
10024 HOST_WIDE_INT c
, lsb
, shift_mask
;
10027 shift_mask
<<= INTVAL (shiftop
);
10028 c
= INTVAL (andop
);
10030 /* Find the least significant one bit. */
10033 /* It must be covered by the shift mask.
10034 This test also rejects c == 0. */
10035 if ((lsb
& shift_mask
) == 0)
10038 /* Check we have all 1's above the transition, and reject all 1's. */
10039 return c
== -lsb
&& lsb
!= 1;
10041 else if (GET_CODE (andop
) == CONST_DOUBLE
10042 && (GET_MODE (andop
) == VOIDmode
|| GET_MODE (andop
) == DImode
))
10044 HOST_WIDE_INT low
, lsb
, shift_mask_low
;
10046 low
= CONST_DOUBLE_LOW (andop
);
10048 if (HOST_BITS_PER_WIDE_INT
< 64)
10050 HOST_WIDE_INT high
, shift_mask_high
;
10052 high
= CONST_DOUBLE_HIGH (andop
);
10056 shift_mask_high
= ~0;
10057 if (INTVAL (shiftop
) > 32)
10058 shift_mask_high
<<= INTVAL (shiftop
) - 32;
10060 lsb
= high
& -high
;
10062 if ((lsb
& shift_mask_high
) == 0)
10065 return high
== -lsb
;
10071 shift_mask_low
= ~0;
10072 shift_mask_low
<<= INTVAL (shiftop
);
10076 if ((lsb
& shift_mask_low
) == 0)
10079 return low
== -lsb
&& lsb
!= 1;
10085 /* Return 1 if operands will generate a valid arguments to rlwimi
10086 instruction for insert with right shift in 64-bit mode. The mask may
10087 not start on the first bit or stop on the last bit because wrap-around
10088 effects of instruction do not correspond to semantics of RTL insn. */
10091 insvdi_rshift_rlwimi_p (rtx sizeop
, rtx startop
, rtx shiftop
)
10093 if (INTVAL (startop
) > 32
10094 && INTVAL (startop
) < 64
10095 && INTVAL (sizeop
) > 1
10096 && INTVAL (sizeop
) + INTVAL (startop
) < 64
10097 && INTVAL (shiftop
) > 0
10098 && INTVAL (sizeop
) + INTVAL (shiftop
) < 32
10099 && (64 - (INTVAL (shiftop
) & 63)) >= INTVAL (sizeop
))
10105 /* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
10106 for lfq and stfq insns iff the registers are hard registers. */
10109 registers_ok_for_quad_peep (rtx reg1
, rtx reg2
)
10111 /* We might have been passed a SUBREG. */
10112 if (GET_CODE (reg1
) != REG
|| GET_CODE (reg2
) != REG
)
10115 /* We might have been passed non floating point registers. */
10116 if (!FP_REGNO_P (REGNO (reg1
))
10117 || !FP_REGNO_P (REGNO (reg2
)))
10120 return (REGNO (reg1
) == REGNO (reg2
) - 1);
10123 /* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
10124 addr1 and addr2 must be in consecutive memory locations
10125 (addr2 == addr1 + 8). */
10128 mems_ok_for_quad_peep (rtx mem1
, rtx mem2
)
10131 unsigned int reg1
, reg2
;
10132 int offset1
, offset2
;
10134 /* The mems cannot be volatile. */
10135 if (MEM_VOLATILE_P (mem1
) || MEM_VOLATILE_P (mem2
))
10138 addr1
= XEXP (mem1
, 0);
10139 addr2
= XEXP (mem2
, 0);
10141 /* Extract an offset (if used) from the first addr. */
10142 if (GET_CODE (addr1
) == PLUS
)
10144 /* If not a REG, return zero. */
10145 if (GET_CODE (XEXP (addr1
, 0)) != REG
)
10149 reg1
= REGNO (XEXP (addr1
, 0));
10150 /* The offset must be constant! */
10151 if (GET_CODE (XEXP (addr1
, 1)) != CONST_INT
)
10153 offset1
= INTVAL (XEXP (addr1
, 1));
10156 else if (GET_CODE (addr1
) != REG
)
10160 reg1
= REGNO (addr1
);
10161 /* This was a simple (mem (reg)) expression. Offset is 0. */
10165 /* And now for the second addr. */
10166 if (GET_CODE (addr2
) == PLUS
)
10168 /* If not a REG, return zero. */
10169 if (GET_CODE (XEXP (addr2
, 0)) != REG
)
10173 reg2
= REGNO (XEXP (addr2
, 0));
10174 /* The offset must be constant. */
10175 if (GET_CODE (XEXP (addr2
, 1)) != CONST_INT
)
10177 offset2
= INTVAL (XEXP (addr2
, 1));
10180 else if (GET_CODE (addr2
) != REG
)
10184 reg2
= REGNO (addr2
);
10185 /* This was a simple (mem (reg)) expression. Offset is 0. */
10189 /* Both of these must have the same base register. */
10193 /* The offset for the second addr must be 8 more than the first addr. */
10194 if (offset2
!= offset1
+ 8)
10197 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
10202 /* Return the register class of a scratch register needed to copy IN into
10203 or out of a register in CLASS in MODE. If it can be done directly,
10204 NO_REGS is returned. */
10207 rs6000_secondary_reload_class (enum reg_class
class,
10208 enum machine_mode mode ATTRIBUTE_UNUSED
,
10213 if (TARGET_ELF
|| (DEFAULT_ABI
== ABI_DARWIN
10215 && MACHOPIC_INDIRECT
10219 /* We cannot copy a symbolic operand directly into anything
10220 other than BASE_REGS for TARGET_ELF. So indicate that a
10221 register from BASE_REGS is needed as an intermediate
10224 On Darwin, pic addresses require a load from memory, which
10225 needs a base register. */
10226 if (class != BASE_REGS
10227 && (GET_CODE (in
) == SYMBOL_REF
10228 || GET_CODE (in
) == HIGH
10229 || GET_CODE (in
) == LABEL_REF
10230 || GET_CODE (in
) == CONST
))
10234 if (GET_CODE (in
) == REG
)
10236 regno
= REGNO (in
);
10237 if (regno
>= FIRST_PSEUDO_REGISTER
)
10239 regno
= true_regnum (in
);
10240 if (regno
>= FIRST_PSEUDO_REGISTER
)
10244 else if (GET_CODE (in
) == SUBREG
)
10246 regno
= true_regnum (in
);
10247 if (regno
>= FIRST_PSEUDO_REGISTER
)
10253 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
10255 if (class == GENERAL_REGS
|| class == BASE_REGS
10256 || (regno
>= 0 && INT_REGNO_P (regno
)))
10259 /* Constants, memory, and FP registers can go into FP registers. */
10260 if ((regno
== -1 || FP_REGNO_P (regno
))
10261 && (class == FLOAT_REGS
|| class == NON_SPECIAL_REGS
))
10264 /* Memory, and AltiVec registers can go into AltiVec registers. */
10265 if ((regno
== -1 || ALTIVEC_REGNO_P (regno
))
10266 && class == ALTIVEC_REGS
)
10269 /* We can copy among the CR registers. */
10270 if ((class == CR_REGS
|| class == CR0_REGS
)
10271 && regno
>= 0 && CR_REGNO_P (regno
))
10274 /* Otherwise, we need GENERAL_REGS. */
10275 return GENERAL_REGS
;
10278 /* Given a comparison operation, return the bit number in CCR to test. We
10279 know this is a valid comparison.
10281 SCC_P is 1 if this is for an scc. That means that %D will have been
10282 used instead of %C, so the bits will be in different places.
10284 Return -1 if OP isn't a valid comparison for some reason. */
10287 ccr_bit (rtx op
, int scc_p
)
10289 enum rtx_code code
= GET_CODE (op
);
10290 enum machine_mode cc_mode
;
10295 if (!COMPARISON_P (op
))
10298 reg
= XEXP (op
, 0);
10300 gcc_assert (GET_CODE (reg
) == REG
&& CR_REGNO_P (REGNO (reg
)));
10302 cc_mode
= GET_MODE (reg
);
10303 cc_regnum
= REGNO (reg
);
10304 base_bit
= 4 * (cc_regnum
- CR0_REGNO
);
10306 validate_condition_mode (code
, cc_mode
);
10308 /* When generating a sCOND operation, only positive conditions are
10311 || code
== EQ
|| code
== GT
|| code
== LT
|| code
== UNORDERED
10312 || code
== GTU
|| code
== LTU
);
10317 return scc_p
? base_bit
+ 3 : base_bit
+ 2;
10319 return base_bit
+ 2;
10320 case GT
: case GTU
: case UNLE
:
10321 return base_bit
+ 1;
10322 case LT
: case LTU
: case UNGE
:
10324 case ORDERED
: case UNORDERED
:
10325 return base_bit
+ 3;
10328 /* If scc, we will have done a cror to put the bit in the
10329 unordered position. So test that bit. For integer, this is ! LT
10330 unless this is an scc insn. */
10331 return scc_p
? base_bit
+ 3 : base_bit
;
10334 return scc_p
? base_bit
+ 3 : base_bit
+ 1;
10337 gcc_unreachable ();
10341 /* Return the GOT register. */
10344 rs6000_got_register (rtx value ATTRIBUTE_UNUSED
)
10346 /* The second flow pass currently (June 1999) can't update
10347 regs_ever_live without disturbing other parts of the compiler, so
10348 update it here to make the prolog/epilogue code happy. */
10349 if (no_new_pseudos
&& ! regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
])
10350 regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
] = 1;
10352 current_function_uses_pic_offset_table
= 1;
10354 return pic_offset_table_rtx
;
10357 /* Function to init struct machine_function.
10358 This will be called, via a pointer variable,
10359 from push_function_context. */
10361 static struct machine_function
*
10362 rs6000_init_machine_status (void)
10364 return ggc_alloc_cleared (sizeof (machine_function
));
10367 /* These macros test for integers and extract the low-order bits. */
10369 ((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
10370 && GET_MODE (X) == VOIDmode)
10372 #define INT_LOWPART(X) \
10373 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
10376 extract_MB (rtx op
)
10379 unsigned long val
= INT_LOWPART (op
);
10381 /* If the high bit is zero, the value is the first 1 bit we find
10383 if ((val
& 0x80000000) == 0)
10385 gcc_assert (val
& 0xffffffff);
10388 while (((val
<<= 1) & 0x80000000) == 0)
10393 /* If the high bit is set and the low bit is not, or the mask is all
10394 1's, the value is zero. */
10395 if ((val
& 1) == 0 || (val
& 0xffffffff) == 0xffffffff)
10398 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10401 while (((val
>>= 1) & 1) != 0)
10408 extract_ME (rtx op
)
10411 unsigned long val
= INT_LOWPART (op
);
10413 /* If the low bit is zero, the value is the first 1 bit we find from
10415 if ((val
& 1) == 0)
10417 gcc_assert (val
& 0xffffffff);
10420 while (((val
>>= 1) & 1) == 0)
10426 /* If the low bit is set and the high bit is not, or the mask is all
10427 1's, the value is 31. */
10428 if ((val
& 0x80000000) == 0 || (val
& 0xffffffff) == 0xffffffff)
10431 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10434 while (((val
<<= 1) & 0x80000000) != 0)
10440 /* Locate some local-dynamic symbol still in use by this function
10441 so that we can print its name in some tls_ld pattern. */
10443 static const char *
10444 rs6000_get_some_local_dynamic_name (void)
10448 if (cfun
->machine
->some_ld_name
)
10449 return cfun
->machine
->some_ld_name
;
10451 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
10453 && for_each_rtx (&PATTERN (insn
),
10454 rs6000_get_some_local_dynamic_name_1
, 0))
10455 return cfun
->machine
->some_ld_name
;
10457 gcc_unreachable ();
10460 /* Helper function for rs6000_get_some_local_dynamic_name. */
10463 rs6000_get_some_local_dynamic_name_1 (rtx
*px
, void *data ATTRIBUTE_UNUSED
)
10467 if (GET_CODE (x
) == SYMBOL_REF
)
10469 const char *str
= XSTR (x
, 0);
10470 if (SYMBOL_REF_TLS_MODEL (x
) == TLS_MODEL_LOCAL_DYNAMIC
)
10472 cfun
->machine
->some_ld_name
= str
;
10480 /* Write out a function code label. */
10483 rs6000_output_function_entry (FILE *file
, const char *fname
)
10485 if (fname
[0] != '.')
10487 switch (DEFAULT_ABI
)
10490 gcc_unreachable ();
10496 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "L.");
10505 RS6000_OUTPUT_BASENAME (file
, fname
);
10507 assemble_name (file
, fname
);
10510 /* Print an operand. Recognize special options, documented below. */
10513 #define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
10514 #define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
10516 #define SMALL_DATA_RELOC "sda21"
10517 #define SMALL_DATA_REG 0
10521 print_operand (FILE *file
, rtx x
, int code
)
10525 unsigned HOST_WIDE_INT uval
;
10530 /* Write out an instruction after the call which may be replaced
10531 with glue code by the loader. This depends on the AIX version. */
10532 asm_fprintf (file
, RS6000_CALL_GLUE
);
10535 /* %a is output_address. */
10538 /* If X is a constant integer whose low-order 5 bits are zero,
10539 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
10540 in the AIX assembler where "sri" with a zero shift count
10541 writes a trash instruction. */
10542 if (GET_CODE (x
) == CONST_INT
&& (INTVAL (x
) & 31) == 0)
10549 /* If constant, low-order 16 bits of constant, unsigned.
10550 Otherwise, write normally. */
10552 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 0xffff);
10554 print_operand (file
, x
, 0);
10558 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10559 for 64-bit mask direction. */
10560 putc (((INT_LOWPART (x
) & 1) == 0 ? 'r' : 'l'), file
);
10563 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10567 /* X is a CR register. Print the number of the GT bit of the CR. */
10568 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10569 output_operand_lossage ("invalid %%E value");
10571 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 1);
10575 /* Like 'J' but get to the GT bit only. */
10576 gcc_assert (GET_CODE (x
) == REG
);
10578 /* Bit 1 is GT bit. */
10579 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 1;
10581 /* Add one for shift count in rlinm for scc. */
10582 fprintf (file
, "%d", i
+ 1);
10586 /* X is a CR register. Print the number of the EQ bit of the CR */
10587 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10588 output_operand_lossage ("invalid %%E value");
10590 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
) + 2);
10594 /* X is a CR register. Print the shift count needed to move it
10595 to the high-order four bits. */
10596 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10597 output_operand_lossage ("invalid %%f value");
10599 fprintf (file
, "%d", 4 * (REGNO (x
) - CR0_REGNO
));
10603 /* Similar, but print the count for the rotate in the opposite
10605 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10606 output_operand_lossage ("invalid %%F value");
10608 fprintf (file
, "%d", 32 - 4 * (REGNO (x
) - CR0_REGNO
));
10612 /* X is a constant integer. If it is negative, print "m",
10613 otherwise print "z". This is to make an aze or ame insn. */
10614 if (GET_CODE (x
) != CONST_INT
)
10615 output_operand_lossage ("invalid %%G value");
10616 else if (INTVAL (x
) >= 0)
10623 /* If constant, output low-order five bits. Otherwise, write
10626 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 31);
10628 print_operand (file
, x
, 0);
10632 /* If constant, output low-order six bits. Otherwise, write
10635 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INT_LOWPART (x
) & 63);
10637 print_operand (file
, x
, 0);
10641 /* Print `i' if this is a constant, else nothing. */
10647 /* Write the bit number in CCR for jump. */
10648 i
= ccr_bit (x
, 0);
10650 output_operand_lossage ("invalid %%j code");
10652 fprintf (file
, "%d", i
);
10656 /* Similar, but add one for shift count in rlinm for scc and pass
10657 scc flag to `ccr_bit'. */
10658 i
= ccr_bit (x
, 1);
10660 output_operand_lossage ("invalid %%J code");
10662 /* If we want bit 31, write a shift count of zero, not 32. */
10663 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10667 /* X must be a constant. Write the 1's complement of the
10670 output_operand_lossage ("invalid %%k value");
10672 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, ~ INT_LOWPART (x
));
10676 /* X must be a symbolic constant on ELF. Write an
10677 expression suitable for an 'addi' that adds in the low 16
10678 bits of the MEM. */
10679 if (GET_CODE (x
) != CONST
)
10681 print_operand_address (file
, x
);
10682 fputs ("@l", file
);
10686 if (GET_CODE (XEXP (x
, 0)) != PLUS
10687 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
10688 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
10689 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
10690 output_operand_lossage ("invalid %%K value");
10691 print_operand_address (file
, XEXP (XEXP (x
, 0), 0));
10692 fputs ("@l", file
);
10693 /* For GNU as, there must be a non-alphanumeric character
10694 between 'l' and the number. The '-' is added by
10695 print_operand() already. */
10696 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
10698 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
10702 /* %l is output_asm_label. */
10705 /* Write second word of DImode or DFmode reference. Works on register
10706 or non-indexed memory only. */
10707 if (GET_CODE (x
) == REG
)
10708 fputs (reg_names
[REGNO (x
) + 1], file
);
10709 else if (GET_CODE (x
) == MEM
)
10711 /* Handle possible auto-increment. Since it is pre-increment and
10712 we have already done it, we can just use an offset of word. */
10713 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
10714 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
10715 output_address (plus_constant (XEXP (XEXP (x
, 0), 0),
10718 output_address (XEXP (adjust_address_nv (x
, SImode
,
10722 if (small_data_operand (x
, GET_MODE (x
)))
10723 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
10724 reg_names
[SMALL_DATA_REG
]);
10729 /* MB value for a mask operand. */
10730 if (! mask_operand (x
, SImode
))
10731 output_operand_lossage ("invalid %%m value");
10733 fprintf (file
, "%d", extract_MB (x
));
10737 /* ME value for a mask operand. */
10738 if (! mask_operand (x
, SImode
))
10739 output_operand_lossage ("invalid %%M value");
10741 fprintf (file
, "%d", extract_ME (x
));
10744 /* %n outputs the negative of its operand. */
10747 /* Write the number of elements in the vector times 4. */
10748 if (GET_CODE (x
) != PARALLEL
)
10749 output_operand_lossage ("invalid %%N value");
10751 fprintf (file
, "%d", XVECLEN (x
, 0) * 4);
10755 /* Similar, but subtract 1 first. */
10756 if (GET_CODE (x
) != PARALLEL
)
10757 output_operand_lossage ("invalid %%O value");
10759 fprintf (file
, "%d", (XVECLEN (x
, 0) - 1) * 4);
10763 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10765 || INT_LOWPART (x
) < 0
10766 || (i
= exact_log2 (INT_LOWPART (x
))) < 0)
10767 output_operand_lossage ("invalid %%p value");
10769 fprintf (file
, "%d", i
);
10773 /* The operand must be an indirect memory reference. The result
10774 is the register name. */
10775 if (GET_CODE (x
) != MEM
|| GET_CODE (XEXP (x
, 0)) != REG
10776 || REGNO (XEXP (x
, 0)) >= 32)
10777 output_operand_lossage ("invalid %%P value");
10779 fputs (reg_names
[REGNO (XEXP (x
, 0))], file
);
10783 /* This outputs the logical code corresponding to a boolean
10784 expression. The expression may have one or both operands
10785 negated (if one, only the first one). For condition register
10786 logical operations, it will also treat the negated
10787 CR codes as NOTs, but not handle NOTs of them. */
10789 const char *const *t
= 0;
10791 enum rtx_code code
= GET_CODE (x
);
10792 static const char * const tbl
[3][3] = {
10793 { "and", "andc", "nor" },
10794 { "or", "orc", "nand" },
10795 { "xor", "eqv", "xor" } };
10799 else if (code
== IOR
)
10801 else if (code
== XOR
)
10804 output_operand_lossage ("invalid %%q value");
10806 if (GET_CODE (XEXP (x
, 0)) != NOT
)
10810 if (GET_CODE (XEXP (x
, 1)) == NOT
)
10828 /* X is a CR register. Print the mask for `mtcrf'. */
10829 if (GET_CODE (x
) != REG
|| ! CR_REGNO_P (REGNO (x
)))
10830 output_operand_lossage ("invalid %%R value");
10832 fprintf (file
, "%d", 128 >> (REGNO (x
) - CR0_REGNO
));
10836 /* Low 5 bits of 32 - value */
10838 output_operand_lossage ("invalid %%s value");
10840 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INT_LOWPART (x
)) & 31);
10844 /* PowerPC64 mask position. All 0's is excluded.
10845 CONST_INT 32-bit mask is considered sign-extended so any
10846 transition must occur within the CONST_INT, not on the boundary. */
10847 if (! mask64_operand (x
, DImode
))
10848 output_operand_lossage ("invalid %%S value");
10850 uval
= INT_LOWPART (x
);
10852 if (uval
& 1) /* Clear Left */
10854 #if HOST_BITS_PER_WIDE_INT > 64
10855 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10859 else /* Clear Right */
10862 #if HOST_BITS_PER_WIDE_INT > 64
10863 uval
&= ((unsigned HOST_WIDE_INT
) 1 << 64) - 1;
10869 gcc_assert (i
>= 0);
10870 fprintf (file
, "%d", i
);
10874 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
10875 gcc_assert (GET_CODE (x
) == REG
&& GET_MODE (x
) == CCmode
);
10877 /* Bit 3 is OV bit. */
10878 i
= 4 * (REGNO (x
) - CR0_REGNO
) + 3;
10880 /* If we want bit 31, write a shift count of zero, not 32. */
10881 fprintf (file
, "%d", i
== 31 ? 0 : i
+ 1);
10885 /* Print the symbolic name of a branch target register. */
10886 if (GET_CODE (x
) != REG
|| (REGNO (x
) != LINK_REGISTER_REGNUM
10887 && REGNO (x
) != COUNT_REGISTER_REGNUM
))
10888 output_operand_lossage ("invalid %%T value");
10889 else if (REGNO (x
) == LINK_REGISTER_REGNUM
)
10890 fputs (TARGET_NEW_MNEMONICS
? "lr" : "r", file
);
10892 fputs ("ctr", file
);
10896 /* High-order 16 bits of constant for use in unsigned operand. */
10898 output_operand_lossage ("invalid %%u value");
10900 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
10901 (INT_LOWPART (x
) >> 16) & 0xffff);
10905 /* High-order 16 bits of constant for use in signed operand. */
10907 output_operand_lossage ("invalid %%v value");
10909 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
,
10910 (INT_LOWPART (x
) >> 16) & 0xffff);
10914 /* Print `u' if this has an auto-increment or auto-decrement. */
10915 if (GET_CODE (x
) == MEM
10916 && (GET_CODE (XEXP (x
, 0)) == PRE_INC
10917 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
))
10922 /* Print the trap code for this operand. */
10923 switch (GET_CODE (x
))
10926 fputs ("eq", file
); /* 4 */
10929 fputs ("ne", file
); /* 24 */
10932 fputs ("lt", file
); /* 16 */
10935 fputs ("le", file
); /* 20 */
10938 fputs ("gt", file
); /* 8 */
10941 fputs ("ge", file
); /* 12 */
10944 fputs ("llt", file
); /* 2 */
10947 fputs ("lle", file
); /* 6 */
10950 fputs ("lgt", file
); /* 1 */
10953 fputs ("lge", file
); /* 5 */
10956 gcc_unreachable ();
10961 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10964 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
,
10965 ((INT_LOWPART (x
) & 0xffff) ^ 0x8000) - 0x8000);
10967 print_operand (file
, x
, 0);
10971 /* MB value for a PowerPC64 rldic operand. */
10972 val
= (GET_CODE (x
) == CONST_INT
10973 ? INTVAL (x
) : CONST_DOUBLE_HIGH (x
));
10978 for (i
= 0; i
< HOST_BITS_PER_WIDE_INT
; i
++)
10979 if ((val
<<= 1) < 0)
10982 #if HOST_BITS_PER_WIDE_INT == 32
10983 if (GET_CODE (x
) == CONST_INT
&& i
>= 0)
10984 i
+= 32; /* zero-extend high-part was all 0's */
10985 else if (GET_CODE (x
) == CONST_DOUBLE
&& i
== 32)
10987 val
= CONST_DOUBLE_LOW (x
);
10993 for ( ; i
< 64; i
++)
10994 if ((val
<<= 1) < 0)
10999 fprintf (file
, "%d", i
+ 1);
11003 if (GET_CODE (x
) == MEM
11004 && legitimate_indexed_address_p (XEXP (x
, 0), 0))
11009 /* Like 'L', for third word of TImode */
11010 if (GET_CODE (x
) == REG
)
11011 fputs (reg_names
[REGNO (x
) + 2], file
);
11012 else if (GET_CODE (x
) == MEM
)
11014 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
11015 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11016 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 8));
11018 output_address (XEXP (adjust_address_nv (x
, SImode
, 8), 0));
11019 if (small_data_operand (x
, GET_MODE (x
)))
11020 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11021 reg_names
[SMALL_DATA_REG
]);
11026 /* X is a SYMBOL_REF. Write out the name preceded by a
11027 period and without any trailing data in brackets. Used for function
11028 names. If we are configured for System V (or the embedded ABI) on
11029 the PowerPC, do not emit the period, since those systems do not use
11030 TOCs and the like. */
11031 gcc_assert (GET_CODE (x
) == SYMBOL_REF
);
11033 /* Mark the decl as referenced so that cgraph will output the
11035 if (SYMBOL_REF_DECL (x
))
11036 mark_decl_referenced (SYMBOL_REF_DECL (x
));
11038 /* For macho, check to see if we need a stub. */
11041 const char *name
= XSTR (x
, 0);
11043 if (MACHOPIC_INDIRECT
11044 && machopic_classify_symbol (x
) == MACHOPIC_UNDEFINED_FUNCTION
)
11045 name
= machopic_indirection_name (x
, /*stub_p=*/true);
11047 assemble_name (file
, name
);
11049 else if (!DOT_SYMBOLS
)
11050 assemble_name (file
, XSTR (x
, 0));
11052 rs6000_output_function_entry (file
, XSTR (x
, 0));
11056 /* Like 'L', for last word of TImode. */
11057 if (GET_CODE (x
) == REG
)
11058 fputs (reg_names
[REGNO (x
) + 3], file
);
11059 else if (GET_CODE (x
) == MEM
)
11061 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
11062 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11063 output_address (plus_constant (XEXP (XEXP (x
, 0), 0), 12));
11065 output_address (XEXP (adjust_address_nv (x
, SImode
, 12), 0));
11066 if (small_data_operand (x
, GET_MODE (x
)))
11067 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11068 reg_names
[SMALL_DATA_REG
]);
11072 /* Print AltiVec or SPE memory operand. */
11077 gcc_assert (GET_CODE (x
) == MEM
);
11081 /* Ugly hack because %y is overloaded. */
11082 if ((TARGET_SPE
|| TARGET_E500_DOUBLE
)
11083 && (GET_MODE_SIZE (GET_MODE (x
)) == 8
11084 || GET_MODE (x
) == TFmode
11085 || GET_MODE (x
) == TImode
))
11087 /* Handle [reg]. */
11088 if (GET_CODE (tmp
) == REG
)
11090 fprintf (file
, "0(%s)", reg_names
[REGNO (tmp
)]);
11093 /* Handle [reg+UIMM]. */
11094 else if (GET_CODE (tmp
) == PLUS
&&
11095 GET_CODE (XEXP (tmp
, 1)) == CONST_INT
)
11099 gcc_assert (GET_CODE (XEXP (tmp
, 0)) == REG
);
11101 x
= INTVAL (XEXP (tmp
, 1));
11102 fprintf (file
, "%d(%s)", x
, reg_names
[REGNO (XEXP (tmp
, 0))]);
11106 /* Fall through. Must be [reg+reg]. */
11109 && GET_CODE (tmp
) == AND
11110 && GET_CODE (XEXP (tmp
, 1)) == CONST_INT
11111 && INTVAL (XEXP (tmp
, 1)) == -16)
11112 tmp
= XEXP (tmp
, 0);
11113 if (GET_CODE (tmp
) == REG
)
11114 fprintf (file
, "0,%s", reg_names
[REGNO (tmp
)]);
11117 gcc_assert (GET_CODE (tmp
) == PLUS
11118 && REG_P (XEXP (tmp
, 0))
11119 && REG_P (XEXP (tmp
, 1)));
11121 if (REGNO (XEXP (tmp
, 0)) == 0)
11122 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 1)) ],
11123 reg_names
[ REGNO (XEXP (tmp
, 0)) ]);
11125 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (tmp
, 0)) ],
11126 reg_names
[ REGNO (XEXP (tmp
, 1)) ]);
11132 if (GET_CODE (x
) == REG
)
11133 fprintf (file
, "%s", reg_names
[REGNO (x
)]);
11134 else if (GET_CODE (x
) == MEM
)
11136 /* We need to handle PRE_INC and PRE_DEC here, since we need to
11137 know the width from the mode. */
11138 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
)
11139 fprintf (file
, "%d(%s)", GET_MODE_SIZE (GET_MODE (x
)),
11140 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
11141 else if (GET_CODE (XEXP (x
, 0)) == PRE_DEC
)
11142 fprintf (file
, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x
)),
11143 reg_names
[REGNO (XEXP (XEXP (x
, 0), 0))]);
11145 output_address (XEXP (x
, 0));
11148 output_addr_const (file
, x
);
11152 assemble_name (file
, rs6000_get_some_local_dynamic_name ());
11156 output_operand_lossage ("invalid %%xn code");
11160 /* Print the address of an operand. */
11163 print_operand_address (FILE *file
, rtx x
)
11165 if (GET_CODE (x
) == REG
)
11166 fprintf (file
, "0(%s)", reg_names
[ REGNO (x
) ]);
11167 else if (GET_CODE (x
) == SYMBOL_REF
|| GET_CODE (x
) == CONST
11168 || GET_CODE (x
) == LABEL_REF
)
11170 output_addr_const (file
, x
);
11171 if (small_data_operand (x
, GET_MODE (x
)))
11172 fprintf (file
, "@%s(%s)", SMALL_DATA_RELOC
,
11173 reg_names
[SMALL_DATA_REG
]);
11175 gcc_assert (!TARGET_TOC
);
11177 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == REG
)
11179 gcc_assert (REG_P (XEXP (x
, 0)));
11180 if (REGNO (XEXP (x
, 0)) == 0)
11181 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 1)) ],
11182 reg_names
[ REGNO (XEXP (x
, 0)) ]);
11184 fprintf (file
, "%s,%s", reg_names
[ REGNO (XEXP (x
, 0)) ],
11185 reg_names
[ REGNO (XEXP (x
, 1)) ]);
11187 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 1)) == CONST_INT
)
11188 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"(%s)",
11189 INTVAL (XEXP (x
, 1)), reg_names
[ REGNO (XEXP (x
, 0)) ]);
11191 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
11192 && CONSTANT_P (XEXP (x
, 1)))
11194 output_addr_const (file
, XEXP (x
, 1));
11195 fprintf (file
, "@l(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
11199 else if (GET_CODE (x
) == LO_SUM
&& GET_CODE (XEXP (x
, 0)) == REG
11200 && CONSTANT_P (XEXP (x
, 1)))
11202 fprintf (file
, "lo16(");
11203 output_addr_const (file
, XEXP (x
, 1));
11204 fprintf (file
, ")(%s)", reg_names
[ REGNO (XEXP (x
, 0)) ]);
11207 else if (legitimate_constant_pool_address_p (x
))
11209 if (TARGET_AIX
&& (!TARGET_ELF
|| !TARGET_MINIMAL_TOC
))
11211 rtx contains_minus
= XEXP (x
, 1);
11215 /* Find the (minus (sym) (toc)) buried in X, and temporarily
11216 turn it into (sym) for output_addr_const. */
11217 while (GET_CODE (XEXP (contains_minus
, 0)) != MINUS
)
11218 contains_minus
= XEXP (contains_minus
, 0);
11220 minus
= XEXP (contains_minus
, 0);
11221 symref
= XEXP (minus
, 0);
11222 XEXP (contains_minus
, 0) = symref
;
11227 name
= XSTR (symref
, 0);
11228 newname
= alloca (strlen (name
) + sizeof ("@toc"));
11229 strcpy (newname
, name
);
11230 strcat (newname
, "@toc");
11231 XSTR (symref
, 0) = newname
;
11233 output_addr_const (file
, XEXP (x
, 1));
11235 XSTR (symref
, 0) = name
;
11236 XEXP (contains_minus
, 0) = minus
;
11239 output_addr_const (file
, XEXP (x
, 1));
11241 fprintf (file
, "(%s)", reg_names
[REGNO (XEXP (x
, 0))]);
11244 gcc_unreachable ();
11247 /* Target hook for assembling integer objects. The PowerPC version has
11248 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
11249 is defined. It also needs to handle DI-mode objects on 64-bit
11253 rs6000_assemble_integer (rtx x
, unsigned int size
, int aligned_p
)
11255 #ifdef RELOCATABLE_NEEDS_FIXUP
11256 /* Special handling for SI values. */
11257 if (RELOCATABLE_NEEDS_FIXUP
&& size
== 4 && aligned_p
)
11259 static int recurse
= 0;
11261 /* For -mrelocatable, we mark all addresses that need to be fixed up
11262 in the .fixup section. */
11263 if (TARGET_RELOCATABLE
11264 && in_section
!= toc_section
11265 && in_section
!= text_section
11266 && !unlikely_text_section_p (in_section
)
11268 && GET_CODE (x
) != CONST_INT
11269 && GET_CODE (x
) != CONST_DOUBLE
11275 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCP", fixuplabelno
);
11277 ASM_OUTPUT_LABEL (asm_out_file
, buf
);
11278 fprintf (asm_out_file
, "\t.long\t(");
11279 output_addr_const (asm_out_file
, x
);
11280 fprintf (asm_out_file
, ")@fixup\n");
11281 fprintf (asm_out_file
, "\t.section\t\".fixup\",\"aw\"\n");
11282 ASM_OUTPUT_ALIGN (asm_out_file
, 2);
11283 fprintf (asm_out_file
, "\t.long\t");
11284 assemble_name (asm_out_file
, buf
);
11285 fprintf (asm_out_file
, "\n\t.previous\n");
11289 /* Remove initial .'s to turn a -mcall-aixdesc function
11290 address into the address of the descriptor, not the function
11292 else if (GET_CODE (x
) == SYMBOL_REF
11293 && XSTR (x
, 0)[0] == '.'
11294 && DEFAULT_ABI
== ABI_AIX
)
11296 const char *name
= XSTR (x
, 0);
11297 while (*name
== '.')
11300 fprintf (asm_out_file
, "\t.long\t%s\n", name
);
11304 #endif /* RELOCATABLE_NEEDS_FIXUP */
11305 return default_assemble_integer (x
, size
, aligned_p
);
11308 #ifdef HAVE_GAS_HIDDEN
11309 /* Emit an assembler directive to set symbol visibility for DECL to
11310 VISIBILITY_TYPE. */
11313 rs6000_assemble_visibility (tree decl
, int vis
)
11315 /* Functions need to have their entry point symbol visibility set as
11316 well as their descriptor symbol visibility. */
11317 if (DEFAULT_ABI
== ABI_AIX
11319 && TREE_CODE (decl
) == FUNCTION_DECL
)
11321 static const char * const visibility_types
[] = {
11322 NULL
, "internal", "hidden", "protected"
11325 const char *name
, *type
;
11327 name
= ((* targetm
.strip_name_encoding
)
11328 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
))));
11329 type
= visibility_types
[vis
];
11331 fprintf (asm_out_file
, "\t.%s\t%s\n", type
, name
);
11332 fprintf (asm_out_file
, "\t.%s\t.%s\n", type
, name
);
11335 default_assemble_visibility (decl
, vis
);
11340 rs6000_reverse_condition (enum machine_mode mode
, enum rtx_code code
)
11342 /* Reversal of FP compares takes care -- an ordered compare
11343 becomes an unordered compare and vice versa. */
11344 if (mode
== CCFPmode
11345 && (!flag_finite_math_only
11346 || code
== UNLT
|| code
== UNLE
|| code
== UNGT
|| code
== UNGE
11347 || code
== UNEQ
|| code
== LTGT
))
11348 return reverse_condition_maybe_unordered (code
);
11350 return reverse_condition (code
);
11353 /* Generate a compare for CODE. Return a brand-new rtx that
11354 represents the result of the compare. */
11357 rs6000_generate_compare (enum rtx_code code
)
11359 enum machine_mode comp_mode
;
11360 rtx compare_result
;
11362 if (rs6000_compare_fp_p
)
11363 comp_mode
= CCFPmode
;
11364 else if (code
== GTU
|| code
== LTU
11365 || code
== GEU
|| code
== LEU
)
11366 comp_mode
= CCUNSmode
;
11367 else if ((code
== EQ
|| code
== NE
)
11368 && GET_CODE (rs6000_compare_op0
) == SUBREG
11369 && GET_CODE (rs6000_compare_op1
) == SUBREG
11370 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0
)
11371 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1
))
11372 /* These are unsigned values, perhaps there will be a later
11373 ordering compare that can be shared with this one.
11374 Unfortunately we cannot detect the signedness of the operands
11375 for non-subregs. */
11376 comp_mode
= CCUNSmode
;
11378 comp_mode
= CCmode
;
11380 /* First, the compare. */
11381 compare_result
= gen_reg_rtx (comp_mode
);
11383 /* E500 FP compare instructions on the GPRs. Yuck! */
11384 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
)
11385 && rs6000_compare_fp_p
)
11387 rtx cmp
, or_result
, compare_result2
;
11388 enum machine_mode op_mode
= GET_MODE (rs6000_compare_op0
);
11390 if (op_mode
== VOIDmode
)
11391 op_mode
= GET_MODE (rs6000_compare_op1
);
11393 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
11394 This explains the following mess. */
11398 case EQ
: case UNEQ
: case NE
: case LTGT
:
11402 cmp
= flag_unsafe_math_optimizations
11403 ? gen_tstsfeq_gpr (compare_result
, rs6000_compare_op0
,
11404 rs6000_compare_op1
)
11405 : gen_cmpsfeq_gpr (compare_result
, rs6000_compare_op0
,
11406 rs6000_compare_op1
);
11410 cmp
= flag_unsafe_math_optimizations
11411 ? gen_tstdfeq_gpr (compare_result
, rs6000_compare_op0
,
11412 rs6000_compare_op1
)
11413 : gen_cmpdfeq_gpr (compare_result
, rs6000_compare_op0
,
11414 rs6000_compare_op1
);
11418 cmp
= flag_unsafe_math_optimizations
11419 ? gen_tsttfeq_gpr (compare_result
, rs6000_compare_op0
,
11420 rs6000_compare_op1
)
11421 : gen_cmptfeq_gpr (compare_result
, rs6000_compare_op0
,
11422 rs6000_compare_op1
);
11426 gcc_unreachable ();
11430 case GT
: case GTU
: case UNGT
: case UNGE
: case GE
: case GEU
:
11434 cmp
= flag_unsafe_math_optimizations
11435 ? gen_tstsfgt_gpr (compare_result
, rs6000_compare_op0
,
11436 rs6000_compare_op1
)
11437 : gen_cmpsfgt_gpr (compare_result
, rs6000_compare_op0
,
11438 rs6000_compare_op1
);
11442 cmp
= flag_unsafe_math_optimizations
11443 ? gen_tstdfgt_gpr (compare_result
, rs6000_compare_op0
,
11444 rs6000_compare_op1
)
11445 : gen_cmpdfgt_gpr (compare_result
, rs6000_compare_op0
,
11446 rs6000_compare_op1
);
11450 cmp
= flag_unsafe_math_optimizations
11451 ? gen_tsttfgt_gpr (compare_result
, rs6000_compare_op0
,
11452 rs6000_compare_op1
)
11453 : gen_cmptfgt_gpr (compare_result
, rs6000_compare_op0
,
11454 rs6000_compare_op1
);
11458 gcc_unreachable ();
11462 case LT
: case LTU
: case UNLT
: case UNLE
: case LE
: case LEU
:
11466 cmp
= flag_unsafe_math_optimizations
11467 ? gen_tstsflt_gpr (compare_result
, rs6000_compare_op0
,
11468 rs6000_compare_op1
)
11469 : gen_cmpsflt_gpr (compare_result
, rs6000_compare_op0
,
11470 rs6000_compare_op1
);
11474 cmp
= flag_unsafe_math_optimizations
11475 ? gen_tstdflt_gpr (compare_result
, rs6000_compare_op0
,
11476 rs6000_compare_op1
)
11477 : gen_cmpdflt_gpr (compare_result
, rs6000_compare_op0
,
11478 rs6000_compare_op1
);
11482 cmp
= flag_unsafe_math_optimizations
11483 ? gen_tsttflt_gpr (compare_result
, rs6000_compare_op0
,
11484 rs6000_compare_op1
)
11485 : gen_cmptflt_gpr (compare_result
, rs6000_compare_op0
,
11486 rs6000_compare_op1
);
11490 gcc_unreachable ();
11494 gcc_unreachable ();
11497 /* Synthesize LE and GE from LT/GT || EQ. */
11498 if (code
== LE
|| code
== GE
|| code
== LEU
|| code
== GEU
)
11504 case LE
: code
= LT
; break;
11505 case GE
: code
= GT
; break;
11506 case LEU
: code
= LT
; break;
11507 case GEU
: code
= GT
; break;
11508 default: gcc_unreachable ();
11511 compare_result2
= gen_reg_rtx (CCFPmode
);
11517 cmp
= flag_unsafe_math_optimizations
11518 ? gen_tstsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11519 rs6000_compare_op1
)
11520 : gen_cmpsfeq_gpr (compare_result2
, rs6000_compare_op0
,
11521 rs6000_compare_op1
);
11525 cmp
= flag_unsafe_math_optimizations
11526 ? gen_tstdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11527 rs6000_compare_op1
)
11528 : gen_cmpdfeq_gpr (compare_result2
, rs6000_compare_op0
,
11529 rs6000_compare_op1
);
11533 cmp
= flag_unsafe_math_optimizations
11534 ? gen_tsttfeq_gpr (compare_result2
, rs6000_compare_op0
,
11535 rs6000_compare_op1
)
11536 : gen_cmptfeq_gpr (compare_result2
, rs6000_compare_op0
,
11537 rs6000_compare_op1
);
11541 gcc_unreachable ();
11545 /* OR them together. */
11546 or_result
= gen_reg_rtx (CCFPmode
);
11547 cmp
= gen_e500_cr_ior_compare (or_result
, compare_result
,
11549 compare_result
= or_result
;
11554 if (code
== NE
|| code
== LTGT
)
11564 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11565 CLOBBERs to match cmptf_internal2 pattern. */
11566 if (comp_mode
== CCFPmode
&& TARGET_XL_COMPAT
11567 && GET_MODE (rs6000_compare_op0
) == TFmode
11568 && !TARGET_IEEEQUAD
11569 && TARGET_HARD_FLOAT
&& TARGET_FPRS
&& TARGET_LONG_DOUBLE_128
)
11570 emit_insn (gen_rtx_PARALLEL (VOIDmode
,
11572 gen_rtx_SET (VOIDmode
,
11574 gen_rtx_COMPARE (comp_mode
,
11575 rs6000_compare_op0
,
11576 rs6000_compare_op1
)),
11577 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11578 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11579 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11580 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11581 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11582 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11583 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)),
11584 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (DFmode
)))));
11585 else if (GET_CODE (rs6000_compare_op1
) == UNSPEC
11586 && XINT (rs6000_compare_op1
, 1) == UNSPEC_SP_TEST
)
11588 rtx op1
= XVECEXP (rs6000_compare_op1
, 0, 0);
11589 comp_mode
= CCEQmode
;
11590 compare_result
= gen_reg_rtx (CCEQmode
);
11592 emit_insn (gen_stack_protect_testdi (compare_result
,
11593 rs6000_compare_op0
, op1
));
11595 emit_insn (gen_stack_protect_testsi (compare_result
,
11596 rs6000_compare_op0
, op1
));
11599 emit_insn (gen_rtx_SET (VOIDmode
, compare_result
,
11600 gen_rtx_COMPARE (comp_mode
,
11601 rs6000_compare_op0
,
11602 rs6000_compare_op1
)));
11605 /* Some kinds of FP comparisons need an OR operation;
11606 under flag_finite_math_only we don't bother. */
11607 if (rs6000_compare_fp_p
11608 && !flag_finite_math_only
11609 && !(TARGET_HARD_FLOAT
&& !TARGET_FPRS
)
11610 && (code
== LE
|| code
== GE
11611 || code
== UNEQ
|| code
== LTGT
11612 || code
== UNGT
|| code
== UNLT
))
11614 enum rtx_code or1
, or2
;
11615 rtx or1_rtx
, or2_rtx
, compare2_rtx
;
11616 rtx or_result
= gen_reg_rtx (CCEQmode
);
11620 case LE
: or1
= LT
; or2
= EQ
; break;
11621 case GE
: or1
= GT
; or2
= EQ
; break;
11622 case UNEQ
: or1
= UNORDERED
; or2
= EQ
; break;
11623 case LTGT
: or1
= LT
; or2
= GT
; break;
11624 case UNGT
: or1
= UNORDERED
; or2
= GT
; break;
11625 case UNLT
: or1
= UNORDERED
; or2
= LT
; break;
11626 default: gcc_unreachable ();
11628 validate_condition_mode (or1
, comp_mode
);
11629 validate_condition_mode (or2
, comp_mode
);
11630 or1_rtx
= gen_rtx_fmt_ee (or1
, SImode
, compare_result
, const0_rtx
);
11631 or2_rtx
= gen_rtx_fmt_ee (or2
, SImode
, compare_result
, const0_rtx
);
11632 compare2_rtx
= gen_rtx_COMPARE (CCEQmode
,
11633 gen_rtx_IOR (SImode
, or1_rtx
, or2_rtx
),
11635 emit_insn (gen_rtx_SET (VOIDmode
, or_result
, compare2_rtx
));
11637 compare_result
= or_result
;
11641 validate_condition_mode (code
, GET_MODE (compare_result
));
11643 return gen_rtx_fmt_ee (code
, VOIDmode
, compare_result
, const0_rtx
);
11647 /* Emit the RTL for an sCOND pattern. */
11650 rs6000_emit_sCOND (enum rtx_code code
, rtx result
)
11653 enum machine_mode op_mode
;
11654 enum rtx_code cond_code
;
11656 condition_rtx
= rs6000_generate_compare (code
);
11657 cond_code
= GET_CODE (condition_rtx
);
11659 if (rs6000_compare_fp_p
11660 && !TARGET_FPRS
&& TARGET_HARD_FLOAT
)
11664 PUT_MODE (condition_rtx
, SImode
);
11665 t
= XEXP (condition_rtx
, 0);
11667 gcc_assert (cond_code
== NE
|| cond_code
== EQ
);
11669 if (cond_code
== NE
)
11670 emit_insn (gen_e500_flip_gt_bit (t
, t
));
11672 emit_insn (gen_move_from_CR_gt_bit (result
, t
));
11676 if (cond_code
== NE
11677 || cond_code
== GE
|| cond_code
== LE
11678 || cond_code
== GEU
|| cond_code
== LEU
11679 || cond_code
== ORDERED
|| cond_code
== UNGE
|| cond_code
== UNLE
)
11681 rtx not_result
= gen_reg_rtx (CCEQmode
);
11682 rtx not_op
, rev_cond_rtx
;
11683 enum machine_mode cc_mode
;
11685 cc_mode
= GET_MODE (XEXP (condition_rtx
, 0));
11687 rev_cond_rtx
= gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode
, cond_code
),
11688 SImode
, XEXP (condition_rtx
, 0), const0_rtx
);
11689 not_op
= gen_rtx_COMPARE (CCEQmode
, rev_cond_rtx
, const0_rtx
);
11690 emit_insn (gen_rtx_SET (VOIDmode
, not_result
, not_op
));
11691 condition_rtx
= gen_rtx_EQ (VOIDmode
, not_result
, const0_rtx
);
11694 op_mode
= GET_MODE (rs6000_compare_op0
);
11695 if (op_mode
== VOIDmode
)
11696 op_mode
= GET_MODE (rs6000_compare_op1
);
11698 if (TARGET_POWERPC64
&& (op_mode
== DImode
|| rs6000_compare_fp_p
))
11700 PUT_MODE (condition_rtx
, DImode
);
11701 convert_move (result
, condition_rtx
, 0);
11705 PUT_MODE (condition_rtx
, SImode
);
11706 emit_insn (gen_rtx_SET (VOIDmode
, result
, condition_rtx
));
11710 /* Emit a branch of kind CODE to location LOC. */
11713 rs6000_emit_cbranch (enum rtx_code code
, rtx loc
)
11715 rtx condition_rtx
, loc_ref
;
11717 condition_rtx
= rs6000_generate_compare (code
);
11718 loc_ref
= gen_rtx_LABEL_REF (VOIDmode
, loc
);
11719 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
11720 gen_rtx_IF_THEN_ELSE (VOIDmode
, condition_rtx
,
11721 loc_ref
, pc_rtx
)));
11724 /* Return the string to output a conditional branch to LABEL, which is
11725 the operand number of the label, or -1 if the branch is really a
11726 conditional return.
11728 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11729 condition code register and its mode specifies what kind of
11730 comparison we made.
11732 REVERSED is nonzero if we should reverse the sense of the comparison.
11734 INSN is the insn. */
11737 output_cbranch (rtx op
, const char *label
, int reversed
, rtx insn
)
11739 static char string
[64];
11740 enum rtx_code code
= GET_CODE (op
);
11741 rtx cc_reg
= XEXP (op
, 0);
11742 enum machine_mode mode
= GET_MODE (cc_reg
);
11743 int cc_regno
= REGNO (cc_reg
) - CR0_REGNO
;
11744 int need_longbranch
= label
!= NULL
&& get_attr_length (insn
) == 8;
11745 int really_reversed
= reversed
^ need_longbranch
;
11751 validate_condition_mode (code
, mode
);
11753 /* Work out which way this really branches. We could use
11754 reverse_condition_maybe_unordered here always but this
11755 makes the resulting assembler clearer. */
11756 if (really_reversed
)
11758 /* Reversal of FP compares takes care -- an ordered compare
11759 becomes an unordered compare and vice versa. */
11760 if (mode
== CCFPmode
)
11761 code
= reverse_condition_maybe_unordered (code
);
11763 code
= reverse_condition (code
);
11766 if ((!TARGET_FPRS
&& TARGET_HARD_FLOAT
) && mode
== CCFPmode
)
11768 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11773 /* Opposite of GT. */
11782 gcc_unreachable ();
11788 /* Not all of these are actually distinct opcodes, but
11789 we distinguish them for clarity of the resulting assembler. */
11790 case NE
: case LTGT
:
11791 ccode
= "ne"; break;
11792 case EQ
: case UNEQ
:
11793 ccode
= "eq"; break;
11795 ccode
= "ge"; break;
11796 case GT
: case GTU
: case UNGT
:
11797 ccode
= "gt"; break;
11799 ccode
= "le"; break;
11800 case LT
: case LTU
: case UNLT
:
11801 ccode
= "lt"; break;
11802 case UNORDERED
: ccode
= "un"; break;
11803 case ORDERED
: ccode
= "nu"; break;
11804 case UNGE
: ccode
= "nl"; break;
11805 case UNLE
: ccode
= "ng"; break;
11807 gcc_unreachable ();
11810 /* Maybe we have a guess as to how likely the branch is.
11811 The old mnemonics don't have a way to specify this information. */
11813 note
= find_reg_note (insn
, REG_BR_PROB
, NULL_RTX
);
11814 if (note
!= NULL_RTX
)
11816 /* PROB is the difference from 50%. */
11817 int prob
= INTVAL (XEXP (note
, 0)) - REG_BR_PROB_BASE
/ 2;
11819 /* Only hint for highly probable/improbable branches on newer
11820 cpus as static prediction overrides processor dynamic
11821 prediction. For older cpus we may as well always hint, but
11822 assume not taken for branches that are very close to 50% as a
11823 mispredicted taken branch is more expensive than a
11824 mispredicted not-taken branch. */
11825 if (rs6000_always_hint
11826 || (abs (prob
) > REG_BR_PROB_BASE
/ 100 * 48
11827 && br_prob_note_reliable_p (note
)))
11829 if (abs (prob
) > REG_BR_PROB_BASE
/ 20
11830 && ((prob
> 0) ^ need_longbranch
))
11838 s
+= sprintf (s
, "{b%sr|b%slr%s} ", ccode
, ccode
, pred
);
11840 s
+= sprintf (s
, "{b%s|b%s%s} ", ccode
, ccode
, pred
);
11842 /* We need to escape any '%' characters in the reg_names string.
11843 Assume they'd only be the first character.... */
11844 if (reg_names
[cc_regno
+ CR0_REGNO
][0] == '%')
11846 s
+= sprintf (s
, "%s", reg_names
[cc_regno
+ CR0_REGNO
]);
11850 /* If the branch distance was too far, we may have to use an
11851 unconditional branch to go the distance. */
11852 if (need_longbranch
)
11853 s
+= sprintf (s
, ",$+8\n\tb %s", label
);
11855 s
+= sprintf (s
, ",%s", label
);
11861 /* Return the string to flip the GT bit on a CR. */
11863 output_e500_flip_gt_bit (rtx dst
, rtx src
)
11865 static char string
[64];
11868 gcc_assert (GET_CODE (dst
) == REG
&& CR_REGNO_P (REGNO (dst
))
11869 && GET_CODE (src
) == REG
&& CR_REGNO_P (REGNO (src
)));
11872 a
= 4 * (REGNO (dst
) - CR0_REGNO
) + 1;
11873 b
= 4 * (REGNO (src
) - CR0_REGNO
) + 1;
11875 sprintf (string
, "crnot %d,%d", a
, b
);
11879 /* Return insn index for the vector compare instruction for given CODE,
11880 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11884 get_vec_cmp_insn (enum rtx_code code
,
11885 enum machine_mode dest_mode
,
11886 enum machine_mode op_mode
)
11888 if (!TARGET_ALTIVEC
)
11889 return INSN_NOT_AVAILABLE
;
11894 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11895 return UNSPEC_VCMPEQUB
;
11896 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11897 return UNSPEC_VCMPEQUH
;
11898 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11899 return UNSPEC_VCMPEQUW
;
11900 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11901 return UNSPEC_VCMPEQFP
;
11904 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11905 return UNSPEC_VCMPGEFP
;
11907 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11908 return UNSPEC_VCMPGTSB
;
11909 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11910 return UNSPEC_VCMPGTSH
;
11911 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11912 return UNSPEC_VCMPGTSW
;
11913 if (dest_mode
== V4SImode
&& op_mode
== V4SFmode
)
11914 return UNSPEC_VCMPGTFP
;
11917 if (dest_mode
== V16QImode
&& op_mode
== V16QImode
)
11918 return UNSPEC_VCMPGTUB
;
11919 if (dest_mode
== V8HImode
&& op_mode
== V8HImode
)
11920 return UNSPEC_VCMPGTUH
;
11921 if (dest_mode
== V4SImode
&& op_mode
== V4SImode
)
11922 return UNSPEC_VCMPGTUW
;
11927 return INSN_NOT_AVAILABLE
;
11930 /* Emit vector compare for operands OP0 and OP1 using code RCODE.
11931 DMODE is expected destination mode. This is a recursive function. */
11934 rs6000_emit_vector_compare (enum rtx_code rcode
,
11936 enum machine_mode dmode
)
11940 enum machine_mode dest_mode
;
11941 enum machine_mode op_mode
= GET_MODE (op1
);
11943 gcc_assert (TARGET_ALTIVEC
);
11944 gcc_assert (GET_MODE (op0
) == GET_MODE (op1
));
11946 /* Floating point vector compare instructions uses destination V4SImode.
11947 Move destination to appropriate mode later. */
11948 if (dmode
== V4SFmode
)
11949 dest_mode
= V4SImode
;
11953 mask
= gen_reg_rtx (dest_mode
);
11954 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
11956 if (vec_cmp_insn
== INSN_NOT_AVAILABLE
)
11958 bool swap_operands
= false;
11959 bool try_again
= false;
11964 swap_operands
= true;
11969 swap_operands
= true;
11977 /* Invert condition and try again.
11978 e.g., A != B becomes ~(A==B). */
11980 enum rtx_code rev_code
;
11981 enum insn_code nor_code
;
11984 rev_code
= reverse_condition_maybe_unordered (rcode
);
11985 eq_rtx
= rs6000_emit_vector_compare (rev_code
, op0
, op1
,
11988 nor_code
= one_cmpl_optab
->handlers
[(int)dest_mode
].insn_code
;
11989 gcc_assert (nor_code
!= CODE_FOR_nothing
);
11990 emit_insn (GEN_FCN (nor_code
) (mask
, eq_rtx
));
11992 if (dmode
!= dest_mode
)
11994 rtx temp
= gen_reg_rtx (dest_mode
);
11995 convert_move (temp
, mask
, 0);
12005 /* Try GT/GTU/LT/LTU OR EQ */
12008 enum insn_code ior_code
;
12009 enum rtx_code new_code
;
12030 gcc_unreachable ();
12033 c_rtx
= rs6000_emit_vector_compare (new_code
,
12034 op0
, op1
, dest_mode
);
12035 eq_rtx
= rs6000_emit_vector_compare (EQ
, op0
, op1
,
12038 ior_code
= ior_optab
->handlers
[(int)dest_mode
].insn_code
;
12039 gcc_assert (ior_code
!= CODE_FOR_nothing
);
12040 emit_insn (GEN_FCN (ior_code
) (mask
, c_rtx
, eq_rtx
));
12041 if (dmode
!= dest_mode
)
12043 rtx temp
= gen_reg_rtx (dest_mode
);
12044 convert_move (temp
, mask
, 0);
12051 gcc_unreachable ();
12056 vec_cmp_insn
= get_vec_cmp_insn (rcode
, dest_mode
, op_mode
);
12057 /* You only get two chances. */
12058 gcc_assert (vec_cmp_insn
!= INSN_NOT_AVAILABLE
);
12070 emit_insn (gen_rtx_SET (VOIDmode
, mask
,
12071 gen_rtx_UNSPEC (dest_mode
,
12072 gen_rtvec (2, op0
, op1
),
12074 if (dmode
!= dest_mode
)
12076 rtx temp
= gen_reg_rtx (dest_mode
);
12077 convert_move (temp
, mask
, 0);
12083 /* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
12084 valid insn doesn exist for given mode. */
12087 get_vsel_insn (enum machine_mode mode
)
12092 return UNSPEC_VSEL4SI
;
12095 return UNSPEC_VSEL4SF
;
12098 return UNSPEC_VSEL8HI
;
12101 return UNSPEC_VSEL16QI
;
12104 return INSN_NOT_AVAILABLE
;
12107 return INSN_NOT_AVAILABLE
;
12110 /* Emit vector select insn where DEST is destination using
12111 operands OP1, OP2 and MASK. */
12114 rs6000_emit_vector_select (rtx dest
, rtx op1
, rtx op2
, rtx mask
)
12117 enum machine_mode dest_mode
= GET_MODE (dest
);
12118 int vsel_insn_index
= get_vsel_insn (GET_MODE (dest
));
12120 temp
= gen_reg_rtx (dest_mode
);
12122 /* For each vector element, select op1 when mask is 1 otherwise
12124 t
= gen_rtx_SET (VOIDmode
, temp
,
12125 gen_rtx_UNSPEC (dest_mode
,
12126 gen_rtvec (3, op2
, op1
, mask
),
12129 emit_move_insn (dest
, temp
);
12133 /* Emit vector conditional expression.
12134 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
12135 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
12138 rs6000_emit_vector_cond_expr (rtx dest
, rtx op1
, rtx op2
,
12139 rtx cond
, rtx cc_op0
, rtx cc_op1
)
12141 enum machine_mode dest_mode
= GET_MODE (dest
);
12142 enum rtx_code rcode
= GET_CODE (cond
);
12145 if (!TARGET_ALTIVEC
)
12148 /* Get the vector mask for the given relational operations. */
12149 mask
= rs6000_emit_vector_compare (rcode
, cc_op0
, cc_op1
, dest_mode
);
12151 rs6000_emit_vector_select (dest
, op1
, op2
, mask
);
12156 /* Emit a conditional move: move TRUE_COND to DEST if OP of the
12157 operands of the last comparison is nonzero/true, FALSE_COND if it
12158 is zero/false. Return 0 if the hardware has no such operation. */
12161 rs6000_emit_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
12163 enum rtx_code code
= GET_CODE (op
);
12164 rtx op0
= rs6000_compare_op0
;
12165 rtx op1
= rs6000_compare_op1
;
12166 REAL_VALUE_TYPE c1
;
12167 enum machine_mode compare_mode
= GET_MODE (op0
);
12168 enum machine_mode result_mode
= GET_MODE (dest
);
12170 bool is_against_zero
;
12172 /* These modes should always match. */
12173 if (GET_MODE (op1
) != compare_mode
12174 /* In the isel case however, we can use a compare immediate, so
12175 op1 may be a small constant. */
12176 && (!TARGET_ISEL
|| !short_cint_operand (op1
, VOIDmode
)))
12178 if (GET_MODE (true_cond
) != result_mode
)
12180 if (GET_MODE (false_cond
) != result_mode
)
12183 /* First, work out if the hardware can do this at all, or
12184 if it's too slow.... */
12185 if (! rs6000_compare_fp_p
)
12188 return rs6000_emit_int_cmove (dest
, op
, true_cond
, false_cond
);
12191 else if (TARGET_HARD_FLOAT
&& !TARGET_FPRS
12192 && SCALAR_FLOAT_MODE_P (compare_mode
))
12195 is_against_zero
= op1
== CONST0_RTX (compare_mode
);
12197 /* A floating-point subtract might overflow, underflow, or produce
12198 an inexact result, thus changing the floating-point flags, so it
12199 can't be generated if we care about that. It's safe if one side
12200 of the construct is zero, since then no subtract will be
12202 if (SCALAR_FLOAT_MODE_P (compare_mode
)
12203 && flag_trapping_math
&& ! is_against_zero
)
12206 /* Eliminate half of the comparisons by switching operands, this
12207 makes the remaining code simpler. */
12208 if (code
== UNLT
|| code
== UNGT
|| code
== UNORDERED
|| code
== NE
12209 || code
== LTGT
|| code
== LT
|| code
== UNLE
)
12211 code
= reverse_condition_maybe_unordered (code
);
12213 true_cond
= false_cond
;
12217 /* UNEQ and LTGT take four instructions for a comparison with zero,
12218 it'll probably be faster to use a branch here too. */
12219 if (code
== UNEQ
&& HONOR_NANS (compare_mode
))
12222 if (GET_CODE (op1
) == CONST_DOUBLE
)
12223 REAL_VALUE_FROM_CONST_DOUBLE (c1
, op1
);
12225 /* We're going to try to implement comparisons by performing
12226 a subtract, then comparing against zero. Unfortunately,
12227 Inf - Inf is NaN which is not zero, and so if we don't
12228 know that the operand is finite and the comparison
12229 would treat EQ different to UNORDERED, we can't do it. */
12230 if (HONOR_INFINITIES (compare_mode
)
12231 && code
!= GT
&& code
!= UNGE
12232 && (GET_CODE (op1
) != CONST_DOUBLE
|| real_isinf (&c1
))
12233 /* Constructs of the form (a OP b ? a : b) are safe. */
12234 && ((! rtx_equal_p (op0
, false_cond
) && ! rtx_equal_p (op1
, false_cond
))
12235 || (! rtx_equal_p (op0
, true_cond
)
12236 && ! rtx_equal_p (op1
, true_cond
))))
12239 /* At this point we know we can use fsel. */
12241 /* Reduce the comparison to a comparison against zero. */
12242 if (! is_against_zero
)
12244 temp
= gen_reg_rtx (compare_mode
);
12245 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12246 gen_rtx_MINUS (compare_mode
, op0
, op1
)));
12248 op1
= CONST0_RTX (compare_mode
);
12251 /* If we don't care about NaNs we can reduce some of the comparisons
12252 down to faster ones. */
12253 if (! HONOR_NANS (compare_mode
))
12259 true_cond
= false_cond
;
12272 /* Now, reduce everything down to a GE. */
12279 temp
= gen_reg_rtx (compare_mode
);
12280 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
12285 temp
= gen_reg_rtx (compare_mode
);
12286 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_ABS (compare_mode
, op0
)));
12291 temp
= gen_reg_rtx (compare_mode
);
12292 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12293 gen_rtx_NEG (compare_mode
,
12294 gen_rtx_ABS (compare_mode
, op0
))));
12299 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
12300 temp
= gen_reg_rtx (result_mode
);
12301 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12302 gen_rtx_IF_THEN_ELSE (result_mode
,
12303 gen_rtx_GE (VOIDmode
,
12305 true_cond
, false_cond
)));
12306 false_cond
= true_cond
;
12309 temp
= gen_reg_rtx (compare_mode
);
12310 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
12315 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
12316 temp
= gen_reg_rtx (result_mode
);
12317 emit_insn (gen_rtx_SET (VOIDmode
, temp
,
12318 gen_rtx_IF_THEN_ELSE (result_mode
,
12319 gen_rtx_GE (VOIDmode
,
12321 true_cond
, false_cond
)));
12322 true_cond
= false_cond
;
12325 temp
= gen_reg_rtx (compare_mode
);
12326 emit_insn (gen_rtx_SET (VOIDmode
, temp
, gen_rtx_NEG (compare_mode
, op0
)));
12331 gcc_unreachable ();
12334 emit_insn (gen_rtx_SET (VOIDmode
, dest
,
12335 gen_rtx_IF_THEN_ELSE (result_mode
,
12336 gen_rtx_GE (VOIDmode
,
12338 true_cond
, false_cond
)));
12342 /* Same as above, but for ints (isel). */
12345 rs6000_emit_int_cmove (rtx dest
, rtx op
, rtx true_cond
, rtx false_cond
)
12347 rtx condition_rtx
, cr
;
12349 /* All isel implementations thus far are 32-bits. */
12350 if (GET_MODE (rs6000_compare_op0
) != SImode
)
12353 /* We still have to do the compare, because isel doesn't do a
12354 compare, it just looks at the CRx bits set by a previous compare
12356 condition_rtx
= rs6000_generate_compare (GET_CODE (op
));
12357 cr
= XEXP (condition_rtx
, 0);
12359 if (GET_MODE (cr
) == CCmode
)
12360 emit_insn (gen_isel_signed (dest
, condition_rtx
,
12361 true_cond
, false_cond
, cr
));
12363 emit_insn (gen_isel_unsigned (dest
, condition_rtx
,
12364 true_cond
, false_cond
, cr
));
12370 output_isel (rtx
*operands
)
12372 enum rtx_code code
;
12374 code
= GET_CODE (operands
[1]);
12375 if (code
== GE
|| code
== GEU
|| code
== LE
|| code
== LEU
|| code
== NE
)
12377 PUT_CODE (operands
[1], reverse_condition (code
));
12378 return "isel %0,%3,%2,%j1";
12381 return "isel %0,%2,%3,%j1";
12385 rs6000_emit_minmax (rtx dest
, enum rtx_code code
, rtx op0
, rtx op1
)
12387 enum machine_mode mode
= GET_MODE (op0
);
12391 if (code
== SMAX
|| code
== SMIN
)
12396 if (code
== SMAX
|| code
== UMAX
)
12397 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
12398 op0
, op1
, mode
, 0);
12400 target
= emit_conditional_move (dest
, c
, op0
, op1
, mode
,
12401 op1
, op0
, mode
, 0);
12402 gcc_assert (target
);
12403 if (target
!= dest
)
12404 emit_move_insn (dest
, target
);
12407 /* Emit instructions to perform a load-reserved/store-conditional operation.
12408 The operation performed is an atomic
12409 (set M (CODE:MODE M OP))
12410 If not NULL, BEFORE is atomically set to M before the operation, and
12411 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
12412 If SYNC_P then a memory barrier is emitted before the operation.
12413 Either OP or M may be wrapped in a NOT operation. */
12416 rs6000_emit_sync (enum rtx_code code
, enum machine_mode mode
,
12417 rtx m
, rtx op
, rtx before_param
, rtx after_param
,
12420 enum machine_mode used_mode
;
12421 rtx the_op
, set_before
, set_after
, set_atomic
, cc_scratch
, before
, after
;
12424 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
12425 rtx shift
= NULL_RTX
;
12428 emit_insn (gen_memory_barrier ());
12430 if (GET_CODE (m
) == NOT
)
12431 used_m
= XEXP (m
, 0);
12435 /* If this is smaller than SImode, we'll have to use SImode with
12437 if (mode
== QImode
|| mode
== HImode
)
12441 if (MEM_ALIGN (used_m
) >= 32)
12444 if (BYTES_BIG_ENDIAN
)
12445 ishift
= GET_MODE_BITSIZE (SImode
) - GET_MODE_BITSIZE (mode
);
12447 shift
= GEN_INT (ishift
);
12451 rtx addrSI
, aligned_addr
;
12452 int shift_mask
= mode
== QImode
? 0x18 : 0x10;
12454 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
,
12455 XEXP (used_m
, 0)));
12456 shift
= gen_reg_rtx (SImode
);
12458 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
12459 GEN_INT (shift_mask
)));
12460 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
12462 aligned_addr
= expand_binop (Pmode
, and_optab
,
12464 GEN_INT (-4), NULL_RTX
,
12465 1, OPTAB_LIB_WIDEN
);
12466 used_m
= change_address (used_m
, SImode
, aligned_addr
);
12467 set_mem_align (used_m
, 32);
12468 /* It's safe to keep the old alias set of USED_M, because
12469 the operation is atomic and only affects the original
12471 if (GET_CODE (m
) == NOT
)
12472 m
= gen_rtx_NOT (SImode
, used_m
);
12477 if (GET_CODE (op
) == NOT
)
12479 oldop
= lowpart_subreg (SImode
, XEXP (op
, 0), mode
);
12480 oldop
= gen_rtx_NOT (SImode
, oldop
);
12483 oldop
= lowpart_subreg (SImode
, op
, mode
);
12489 newop
= expand_binop (SImode
, and_optab
,
12490 oldop
, GEN_INT (imask
), NULL_RTX
,
12491 1, OPTAB_LIB_WIDEN
);
12492 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12496 newop
= expand_binop (SImode
, ior_optab
,
12497 oldop
, GEN_INT (~imask
), NULL_RTX
,
12498 1, OPTAB_LIB_WIDEN
);
12499 emit_insn (gen_rotlsi3 (newop
, newop
, shift
));
12507 newop
= expand_binop (SImode
, and_optab
,
12508 oldop
, GEN_INT (imask
), NULL_RTX
,
12509 1, OPTAB_LIB_WIDEN
);
12510 emit_insn (gen_ashlsi3 (newop
, newop
, shift
));
12512 mask
= gen_reg_rtx (SImode
);
12513 emit_move_insn (mask
, GEN_INT (imask
));
12514 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12517 newop
= gen_rtx_PLUS (SImode
, m
, newop
);
12519 newop
= gen_rtx_MINUS (SImode
, m
, newop
);
12520 newop
= gen_rtx_AND (SImode
, newop
, mask
);
12521 newop
= gen_rtx_IOR (SImode
, newop
,
12522 gen_rtx_AND (SImode
,
12523 gen_rtx_NOT (SImode
, mask
),
12529 gcc_unreachable ();
12532 if (GET_CODE (m
) == NOT
)
12536 mask
= gen_reg_rtx (SImode
);
12537 emit_move_insn (mask
, GEN_INT (imask
));
12538 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12540 xorm
= gen_rtx_XOR (SImode
, used_m
, mask
);
12541 /* Depending on the value of 'op', the XOR or the operation might
12542 be able to be simplified away. */
12543 newop
= simplify_gen_binary (code
, SImode
, xorm
, newop
);
12546 used_mode
= SImode
;
12547 before
= gen_reg_rtx (used_mode
);
12548 after
= gen_reg_rtx (used_mode
);
12553 before
= before_param
;
12554 after
= after_param
;
12556 if (before
== NULL_RTX
)
12557 before
= gen_reg_rtx (used_mode
);
12558 if (after
== NULL_RTX
)
12559 after
= gen_reg_rtx (used_mode
);
12562 if ((code
== PLUS
|| code
== MINUS
|| GET_CODE (m
) == NOT
)
12563 && used_mode
!= mode
)
12564 the_op
= op
; /* Computed above. */
12565 else if (GET_CODE (op
) == NOT
&& GET_CODE (m
) != NOT
)
12566 the_op
= gen_rtx_fmt_ee (code
, used_mode
, op
, m
);
12568 the_op
= gen_rtx_fmt_ee (code
, used_mode
, m
, op
);
12570 set_after
= gen_rtx_SET (VOIDmode
, after
, the_op
);
12571 set_before
= gen_rtx_SET (VOIDmode
, before
, used_m
);
12572 set_atomic
= gen_rtx_SET (VOIDmode
, used_m
,
12573 gen_rtx_UNSPEC (used_mode
,
12574 gen_rtvec (1, the_op
),
12576 cc_scratch
= gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (CCmode
));
12578 if ((code
== PLUS
|| code
== MINUS
) && used_mode
!= mode
)
12579 vec
= gen_rtvec (5, set_after
, set_before
, set_atomic
, cc_scratch
,
12580 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_SCRATCH (SImode
)));
12582 vec
= gen_rtvec (4, set_after
, set_before
, set_atomic
, cc_scratch
);
12583 emit_insn (gen_rtx_PARALLEL (VOIDmode
, vec
));
12585 /* Shift and mask the return values properly. */
12586 if (used_mode
!= mode
&& before_param
)
12588 emit_insn (gen_lshrsi3 (before
, before
, shift
));
12589 convert_move (before_param
, before
, 1);
12592 if (used_mode
!= mode
&& after_param
)
12594 emit_insn (gen_lshrsi3 (after
, after
, shift
));
12595 convert_move (after_param
, after
, 1);
12598 /* The previous sequence will end with a branch that's dependent on
12599 the conditional store, so placing an isync will ensure that no
12600 other instructions (especially, no load or store instructions)
12601 can start before the atomic operation completes. */
12603 emit_insn (gen_isync ());
12606 /* A subroutine of the atomic operation splitters. Jump to LABEL if
12607 COND is true. Mark the jump as unlikely to be taken. */
12610 emit_unlikely_jump (rtx cond
, rtx label
)
12612 rtx very_unlikely
= GEN_INT (REG_BR_PROB_BASE
/ 100 - 1);
12615 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, label
, pc_rtx
);
12616 x
= emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
, x
));
12617 REG_NOTES (x
) = gen_rtx_EXPR_LIST (REG_BR_PROB
, very_unlikely
, NULL_RTX
);
12620 /* A subroutine of the atomic operation splitters. Emit a load-locked
12621 instruction in MODE. */
12624 emit_load_locked (enum machine_mode mode
, rtx reg
, rtx mem
)
12626 rtx (*fn
) (rtx
, rtx
) = NULL
;
12627 if (mode
== SImode
)
12628 fn
= gen_load_locked_si
;
12629 else if (mode
== DImode
)
12630 fn
= gen_load_locked_di
;
12631 emit_insn (fn (reg
, mem
));
12634 /* A subroutine of the atomic operation splitters. Emit a store-conditional
12635 instruction in MODE. */
12638 emit_store_conditional (enum machine_mode mode
, rtx res
, rtx mem
, rtx val
)
12640 rtx (*fn
) (rtx
, rtx
, rtx
) = NULL
;
12641 if (mode
== SImode
)
12642 fn
= gen_store_conditional_si
;
12643 else if (mode
== DImode
)
12644 fn
= gen_store_conditional_di
;
12646 /* Emit sync before stwcx. to address PPC405 Erratum. */
12647 if (PPC405_ERRATUM77
)
12648 emit_insn (gen_memory_barrier ());
12650 emit_insn (fn (res
, mem
, val
));
12653 /* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
12654 to perform. MEM is the memory on which to operate. VAL is the second
12655 operand of the binary operator. BEFORE and AFTER are optional locations to
12656 return the value of MEM either before of after the operation. SCRATCH is
12657 a scratch register. */
12660 rs6000_split_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
12661 rtx before
, rtx after
, rtx scratch
)
12663 enum machine_mode mode
= GET_MODE (mem
);
12664 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12666 emit_insn (gen_memory_barrier ());
12668 label
= gen_label_rtx ();
12669 emit_label (label
);
12670 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
12672 if (before
== NULL_RTX
)
12674 emit_load_locked (mode
, before
, mem
);
12677 x
= gen_rtx_AND (mode
, gen_rtx_NOT (mode
, before
), val
);
12678 else if (code
== AND
)
12679 x
= gen_rtx_UNSPEC (mode
, gen_rtvec (2, before
, val
), UNSPEC_AND
);
12681 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
12683 if (after
!= NULL_RTX
)
12684 emit_insn (gen_rtx_SET (VOIDmode
, after
, copy_rtx (x
)));
12685 emit_insn (gen_rtx_SET (VOIDmode
, scratch
, x
));
12687 emit_store_conditional (mode
, cond
, mem
, scratch
);
12689 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12690 emit_unlikely_jump (x
, label
);
12692 emit_insn (gen_isync ());
12695 /* Expand an atomic compare and swap operation. MEM is the memory on which
12696 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12697 value to be stored. SCRATCH is a scratch GPR. */
12700 rs6000_split_compare_and_swap (rtx retval
, rtx mem
, rtx oldval
, rtx newval
,
12703 enum machine_mode mode
= GET_MODE (mem
);
12704 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12706 emit_insn (gen_memory_barrier ());
12708 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12709 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12710 emit_label (XEXP (label1
, 0));
12712 emit_load_locked (mode
, retval
, mem
);
12714 x
= gen_rtx_COMPARE (CCmode
, retval
, oldval
);
12715 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
12717 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12718 emit_unlikely_jump (x
, label2
);
12720 emit_move_insn (scratch
, newval
);
12721 emit_store_conditional (mode
, cond
, mem
, scratch
);
12723 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12724 emit_unlikely_jump (x
, label1
);
12726 emit_insn (gen_isync ());
12727 emit_label (XEXP (label2
, 0));
12730 /* Expand an atomic test and set operation. MEM is the memory on which
12731 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12734 rs6000_split_lock_test_and_set (rtx retval
, rtx mem
, rtx val
, rtx scratch
)
12736 enum machine_mode mode
= GET_MODE (mem
);
12737 rtx label
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12739 emit_insn (gen_memory_barrier ());
12741 label
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12742 emit_label (XEXP (label
, 0));
12744 emit_load_locked (mode
, retval
, mem
);
12745 emit_move_insn (scratch
, val
);
12746 emit_store_conditional (mode
, cond
, mem
, scratch
);
12748 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12749 emit_unlikely_jump (x
, label
);
12751 emit_insn (gen_isync ());
12755 rs6000_expand_compare_and_swapqhi (rtx dst
, rtx mem
, rtx oldval
, rtx newval
)
12757 enum machine_mode mode
= GET_MODE (mem
);
12758 rtx addrSI
, align
, wdst
, shift
, mask
;
12759 HOST_WIDE_INT shift_mask
= mode
== QImode
? 0x18 : 0x10;
12760 HOST_WIDE_INT imask
= GET_MODE_MASK (mode
);
12762 /* Shift amount for subword relative to aligned word. */
12763 addrSI
= force_reg (SImode
, gen_lowpart_common (SImode
, XEXP (mem
, 0)));
12764 shift
= gen_reg_rtx (SImode
);
12765 emit_insn (gen_rlwinm (shift
, addrSI
, GEN_INT (3),
12766 GEN_INT (shift_mask
)));
12767 emit_insn (gen_xorsi3 (shift
, shift
, GEN_INT (shift_mask
)));
12769 /* Shift and mask old value into position within word. */
12770 oldval
= convert_modes (SImode
, mode
, oldval
, 1);
12771 oldval
= expand_binop (SImode
, and_optab
,
12772 oldval
, GEN_INT (imask
), NULL_RTX
,
12773 1, OPTAB_LIB_WIDEN
);
12774 emit_insn (gen_ashlsi3 (oldval
, oldval
, shift
));
12776 /* Shift and mask new value into position within word. */
12777 newval
= convert_modes (SImode
, mode
, newval
, 1);
12778 newval
= expand_binop (SImode
, and_optab
,
12779 newval
, GEN_INT (imask
), NULL_RTX
,
12780 1, OPTAB_LIB_WIDEN
);
12781 emit_insn (gen_ashlsi3 (newval
, newval
, shift
));
12783 /* Mask for insertion. */
12784 mask
= gen_reg_rtx (SImode
);
12785 emit_move_insn (mask
, GEN_INT (imask
));
12786 emit_insn (gen_ashlsi3 (mask
, mask
, shift
));
12788 /* Address of aligned word containing subword. */
12789 align
= expand_binop (Pmode
, and_optab
, XEXP (mem
, 0), GEN_INT (-4),
12790 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
12791 mem
= change_address (mem
, SImode
, align
);
12792 set_mem_align (mem
, 32);
12793 MEM_VOLATILE_P (mem
) = 1;
12795 wdst
= gen_reg_rtx (SImode
);
12796 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst
, mask
,
12797 oldval
, newval
, mem
));
12799 emit_move_insn (dst
, gen_lowpart (mode
, wdst
));
12803 rs6000_split_compare_and_swapqhi (rtx dest
, rtx mask
,
12804 rtx oldval
, rtx newval
, rtx mem
,
12807 rtx label1
, label2
, x
, cond
= gen_rtx_REG (CCmode
, CR0_REGNO
);
12809 emit_insn (gen_memory_barrier ());
12810 label1
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12811 label2
= gen_rtx_LABEL_REF (VOIDmode
, gen_label_rtx ());
12812 emit_label (XEXP (label1
, 0));
12814 emit_load_locked (SImode
, scratch
, mem
);
12816 /* Mask subword within loaded value for comparison with oldval.
12817 Use UNSPEC_AND to avoid clobber.*/
12818 emit_insn (gen_rtx_SET (SImode
, dest
,
12819 gen_rtx_UNSPEC (SImode
,
12820 gen_rtvec (2, scratch
, mask
),
12823 x
= gen_rtx_COMPARE (CCmode
, dest
, oldval
);
12824 emit_insn (gen_rtx_SET (VOIDmode
, cond
, x
));
12826 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12827 emit_unlikely_jump (x
, label2
);
12829 /* Clear subword within loaded value for insertion of new value. */
12830 emit_insn (gen_rtx_SET (SImode
, scratch
,
12831 gen_rtx_AND (SImode
,
12832 gen_rtx_NOT (SImode
, mask
), scratch
)));
12833 emit_insn (gen_iorsi3 (scratch
, scratch
, newval
));
12834 emit_store_conditional (SImode
, cond
, mem
, scratch
);
12836 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
12837 emit_unlikely_jump (x
, label1
);
12839 emit_insn (gen_isync ());
12840 emit_label (XEXP (label2
, 0));
12844 /* Emit instructions to move SRC to DST. Called by splitters for
12845 multi-register moves. It will emit at most one instruction for
12846 each register that is accessed; that is, it won't emit li/lis pairs
12847 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12851 rs6000_split_multireg_move (rtx dst
, rtx src
)
12853 /* The register number of the first register being moved. */
12855 /* The mode that is to be moved. */
12856 enum machine_mode mode
;
12857 /* The mode that the move is being done in, and its size. */
12858 enum machine_mode reg_mode
;
12860 /* The number of registers that will be moved. */
12863 reg
= REG_P (dst
) ? REGNO (dst
) : REGNO (src
);
12864 mode
= GET_MODE (dst
);
12865 nregs
= hard_regno_nregs
[reg
][mode
];
12866 if (FP_REGNO_P (reg
))
12868 else if (ALTIVEC_REGNO_P (reg
))
12869 reg_mode
= V16QImode
;
12870 else if (TARGET_E500_DOUBLE
&& mode
== TFmode
)
12873 reg_mode
= word_mode
;
12874 reg_mode_size
= GET_MODE_SIZE (reg_mode
);
12876 gcc_assert (reg_mode_size
* nregs
== GET_MODE_SIZE (mode
));
12878 if (REG_P (src
) && REG_P (dst
) && (REGNO (src
) < REGNO (dst
)))
12880 /* Move register range backwards, if we might have destructive
12883 for (i
= nregs
- 1; i
>= 0; i
--)
12884 emit_insn (gen_rtx_SET (VOIDmode
,
12885 simplify_gen_subreg (reg_mode
, dst
, mode
,
12886 i
* reg_mode_size
),
12887 simplify_gen_subreg (reg_mode
, src
, mode
,
12888 i
* reg_mode_size
)));
12894 bool used_update
= false;
12896 if (MEM_P (src
) && INT_REGNO_P (reg
))
12900 if (GET_CODE (XEXP (src
, 0)) == PRE_INC
12901 || GET_CODE (XEXP (src
, 0)) == PRE_DEC
)
12904 breg
= XEXP (XEXP (src
, 0), 0);
12905 delta_rtx
= (GET_CODE (XEXP (src
, 0)) == PRE_INC
12906 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src
)))
12907 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src
))));
12908 emit_insn (TARGET_32BIT
12909 ? gen_addsi3 (breg
, breg
, delta_rtx
)
12910 : gen_adddi3 (breg
, breg
, delta_rtx
));
12911 src
= replace_equiv_address (src
, breg
);
12913 else if (! rs6000_offsettable_memref_p (src
))
12916 basereg
= gen_rtx_REG (Pmode
, reg
);
12917 emit_insn (gen_rtx_SET (VOIDmode
, basereg
, XEXP (src
, 0)));
12918 src
= replace_equiv_address (src
, basereg
);
12921 breg
= XEXP (src
, 0);
12922 if (GET_CODE (breg
) == PLUS
|| GET_CODE (breg
) == LO_SUM
)
12923 breg
= XEXP (breg
, 0);
12925 /* If the base register we are using to address memory is
12926 also a destination reg, then change that register last. */
12928 && REGNO (breg
) >= REGNO (dst
)
12929 && REGNO (breg
) < REGNO (dst
) + nregs
)
12930 j
= REGNO (breg
) - REGNO (dst
);
12933 if (GET_CODE (dst
) == MEM
&& INT_REGNO_P (reg
))
12937 if (GET_CODE (XEXP (dst
, 0)) == PRE_INC
12938 || GET_CODE (XEXP (dst
, 0)) == PRE_DEC
)
12941 breg
= XEXP (XEXP (dst
, 0), 0);
12942 delta_rtx
= (GET_CODE (XEXP (dst
, 0)) == PRE_INC
12943 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst
)))
12944 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst
))));
12946 /* We have to update the breg before doing the store.
12947 Use store with update, if available. */
12951 rtx nsrc
= simplify_gen_subreg (reg_mode
, src
, mode
, 0);
12952 emit_insn (TARGET_32BIT
12953 ? (TARGET_POWERPC64
12954 ? gen_movdi_si_update (breg
, breg
, delta_rtx
, nsrc
)
12955 : gen_movsi_update (breg
, breg
, delta_rtx
, nsrc
))
12956 : gen_movdi_di_update (breg
, breg
, delta_rtx
, nsrc
));
12957 used_update
= true;
12960 emit_insn (TARGET_32BIT
12961 ? gen_addsi3 (breg
, breg
, delta_rtx
)
12962 : gen_adddi3 (breg
, breg
, delta_rtx
));
12963 dst
= replace_equiv_address (dst
, breg
);
12966 gcc_assert (rs6000_offsettable_memref_p (dst
));
12969 for (i
= 0; i
< nregs
; i
++)
12971 /* Calculate index to next subword. */
12976 /* If compiler already emitted move of first word by
12977 store with update, no need to do anything. */
12978 if (j
== 0 && used_update
)
12981 emit_insn (gen_rtx_SET (VOIDmode
,
12982 simplify_gen_subreg (reg_mode
, dst
, mode
,
12983 j
* reg_mode_size
),
12984 simplify_gen_subreg (reg_mode
, src
, mode
,
12985 j
* reg_mode_size
)));
12991 /* This page contains routines that are used to determine what the
12992 function prologue and epilogue code will do and write them out. */
12994 /* Return the first fixed-point register that is required to be
12995 saved. 32 if none. */
12998 first_reg_to_save (void)
13002 /* Find lowest numbered live register. */
13003 for (first_reg
= 13; first_reg
<= 31; first_reg
++)
13004 if (regs_ever_live
[first_reg
]
13005 && (! call_used_regs
[first_reg
]
13006 || (first_reg
== RS6000_PIC_OFFSET_TABLE_REGNUM
13007 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
13008 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
)
13009 || (TARGET_TOC
&& TARGET_MINIMAL_TOC
)))))
13014 && current_function_uses_pic_offset_table
13015 && first_reg
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
13016 return RS6000_PIC_OFFSET_TABLE_REGNUM
;
13022 /* Similar, for FP regs. */
13025 first_fp_reg_to_save (void)
13029 /* Find lowest numbered live register. */
13030 for (first_reg
= 14 + 32; first_reg
<= 63; first_reg
++)
13031 if (regs_ever_live
[first_reg
])
13037 /* Similar, for AltiVec regs. */
13040 first_altivec_reg_to_save (void)
13044 /* Stack frame remains as is unless we are in AltiVec ABI. */
13045 if (! TARGET_ALTIVEC_ABI
)
13046 return LAST_ALTIVEC_REGNO
+ 1;
13048 /* On Darwin, the unwind routines are compiled without
13049 TARGET_ALTIVEC, and use save_world to save/restore the
13050 altivec registers when necessary. */
13051 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
13052 && ! TARGET_ALTIVEC
)
13053 return FIRST_ALTIVEC_REGNO
+ 20;
13055 /* Find lowest numbered live register. */
13056 for (i
= FIRST_ALTIVEC_REGNO
+ 20; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13057 if (regs_ever_live
[i
])
13063 /* Return a 32-bit mask of the AltiVec registers we need to set in
13064 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
13065 the 32-bit word is 0. */
13067 static unsigned int
13068 compute_vrsave_mask (void)
13070 unsigned int i
, mask
= 0;
13072 /* On Darwin, the unwind routines are compiled without
13073 TARGET_ALTIVEC, and use save_world to save/restore the
13074 call-saved altivec registers when necessary. */
13075 if (DEFAULT_ABI
== ABI_DARWIN
&& current_function_calls_eh_return
13076 && ! TARGET_ALTIVEC
)
13079 /* First, find out if we use _any_ altivec registers. */
13080 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
13081 if (regs_ever_live
[i
])
13082 mask
|= ALTIVEC_REG_BIT (i
);
13087 /* Next, remove the argument registers from the set. These must
13088 be in the VRSAVE mask set by the caller, so we don't need to add
13089 them in again. More importantly, the mask we compute here is
13090 used to generate CLOBBERs in the set_vrsave insn, and we do not
13091 wish the argument registers to die. */
13092 for (i
= cfun
->args_info
.vregno
- 1; i
>= ALTIVEC_ARG_MIN_REG
; --i
)
13093 mask
&= ~ALTIVEC_REG_BIT (i
);
13095 /* Similarly, remove the return value from the set. */
13098 diddle_return_value (is_altivec_return_reg
, &yes
);
13100 mask
&= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN
);
13106 /* For a very restricted set of circumstances, we can cut down the
13107 size of prologues/epilogues by calling our own save/restore-the-world
13111 compute_save_world_info (rs6000_stack_t
*info_ptr
)
13113 info_ptr
->world_save_p
= 1;
13114 info_ptr
->world_save_p
13115 = (WORLD_SAVE_P (info_ptr
)
13116 && DEFAULT_ABI
== ABI_DARWIN
13117 && ! (current_function_calls_setjmp
&& flag_exceptions
)
13118 && info_ptr
->first_fp_reg_save
== FIRST_SAVED_FP_REGNO
13119 && info_ptr
->first_gp_reg_save
== FIRST_SAVED_GP_REGNO
13120 && info_ptr
->first_altivec_reg_save
== FIRST_SAVED_ALTIVEC_REGNO
13121 && info_ptr
->cr_save_p
);
13123 /* This will not work in conjunction with sibcalls. Make sure there
13124 are none. (This check is expensive, but seldom executed.) */
13125 if (WORLD_SAVE_P (info_ptr
))
13128 for ( insn
= get_last_insn_anywhere (); insn
; insn
= PREV_INSN (insn
))
13129 if ( GET_CODE (insn
) == CALL_INSN
13130 && SIBLING_CALL_P (insn
))
13132 info_ptr
->world_save_p
= 0;
13137 if (WORLD_SAVE_P (info_ptr
))
13139 /* Even if we're not touching VRsave, make sure there's room on the
13140 stack for it, if it looks like we're calling SAVE_WORLD, which
13141 will attempt to save it. */
13142 info_ptr
->vrsave_size
= 4;
13144 /* "Save" the VRsave register too if we're saving the world. */
13145 if (info_ptr
->vrsave_mask
== 0)
13146 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
13148 /* Because the Darwin register save/restore routines only handle
13149 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
13151 gcc_assert (info_ptr
->first_fp_reg_save
>= FIRST_SAVED_FP_REGNO
13152 && (info_ptr
->first_altivec_reg_save
13153 >= FIRST_SAVED_ALTIVEC_REGNO
));
13160 is_altivec_return_reg (rtx reg
, void *xyes
)
13162 bool *yes
= (bool *) xyes
;
13163 if (REGNO (reg
) == ALTIVEC_ARG_RETURN
)
13168 /* Calculate the stack information for the current function. This is
13169 complicated by having two separate calling sequences, the AIX calling
13170 sequence and the V.4 calling sequence.
13172 AIX (and Darwin/Mac OS X) stack frames look like:
13174 SP----> +---------------------------------------+
13175 | back chain to caller | 0 0
13176 +---------------------------------------+
13177 | saved CR | 4 8 (8-11)
13178 +---------------------------------------+
13180 +---------------------------------------+
13181 | reserved for compilers | 12 24
13182 +---------------------------------------+
13183 | reserved for binders | 16 32
13184 +---------------------------------------+
13185 | saved TOC pointer | 20 40
13186 +---------------------------------------+
13187 | Parameter save area (P) | 24 48
13188 +---------------------------------------+
13189 | Alloca space (A) | 24+P etc.
13190 +---------------------------------------+
13191 | Local variable space (L) | 24+P+A
13192 +---------------------------------------+
13193 | Float/int conversion temporary (X) | 24+P+A+L
13194 +---------------------------------------+
13195 | Save area for AltiVec registers (W) | 24+P+A+L+X
13196 +---------------------------------------+
13197 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
13198 +---------------------------------------+
13199 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
13200 +---------------------------------------+
13201 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
13202 +---------------------------------------+
13203 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
13204 +---------------------------------------+
13205 old SP->| back chain to caller's caller |
13206 +---------------------------------------+
13208 The required alignment for AIX configurations is two words (i.e., 8
13212 V.4 stack frames look like:
13214 SP----> +---------------------------------------+
13215 | back chain to caller | 0
13216 +---------------------------------------+
13217 | caller's saved LR | 4
13218 +---------------------------------------+
13219 | Parameter save area (P) | 8
13220 +---------------------------------------+
13221 | Alloca space (A) | 8+P
13222 +---------------------------------------+
13223 | Varargs save area (V) | 8+P+A
13224 +---------------------------------------+
13225 | Local variable space (L) | 8+P+A+V
13226 +---------------------------------------+
13227 | Float/int conversion temporary (X) | 8+P+A+V+L
13228 +---------------------------------------+
13229 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
13230 +---------------------------------------+
13231 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
13232 +---------------------------------------+
13233 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
13234 +---------------------------------------+
13235 | SPE: area for 64-bit GP registers |
13236 +---------------------------------------+
13237 | SPE alignment padding |
13238 +---------------------------------------+
13239 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
13240 +---------------------------------------+
13241 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
13242 +---------------------------------------+
13243 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
13244 +---------------------------------------+
13245 old SP->| back chain to caller's caller |
13246 +---------------------------------------+
13248 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
13249 given. (But note below and in sysv4.h that we require only 8 and
13250 may round up the size of our stack frame anyways. The historical
13251 reason is early versions of powerpc-linux which didn't properly
13252 align the stack at program startup. A happy side-effect is that
13253 -mno-eabi libraries can be used with -meabi programs.)
13255 The EABI configuration defaults to the V.4 layout. However,
13256 the stack alignment requirements may differ. If -mno-eabi is not
13257 given, the required stack alignment is 8 bytes; if -mno-eabi is
13258 given, the required alignment is 16 bytes. (But see V.4 comment
13261 #ifndef ABI_STACK_BOUNDARY
13262 #define ABI_STACK_BOUNDARY STACK_BOUNDARY
13265 static rs6000_stack_t
*
13266 rs6000_stack_info (void)
13268 static rs6000_stack_t info
;
13269 rs6000_stack_t
*info_ptr
= &info
;
13270 int reg_size
= TARGET_32BIT
? 4 : 8;
13273 HOST_WIDE_INT non_fixed_size
;
13275 memset (&info
, 0, sizeof (info
));
13279 /* Cache value so we don't rescan instruction chain over and over. */
13280 if (cfun
->machine
->insn_chain_scanned_p
== 0)
13281 cfun
->machine
->insn_chain_scanned_p
13282 = spe_func_has_64bit_regs_p () + 1;
13283 info_ptr
->spe_64bit_regs_used
= cfun
->machine
->insn_chain_scanned_p
- 1;
13286 /* Select which calling sequence. */
13287 info_ptr
->abi
= DEFAULT_ABI
;
13289 /* Calculate which registers need to be saved & save area size. */
13290 info_ptr
->first_gp_reg_save
= first_reg_to_save ();
13291 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
13292 even if it currently looks like we won't. */
13293 if (((TARGET_TOC
&& TARGET_MINIMAL_TOC
)
13294 || (flag_pic
== 1 && DEFAULT_ABI
== ABI_V4
)
13295 || (flag_pic
&& DEFAULT_ABI
== ABI_DARWIN
))
13296 && info_ptr
->first_gp_reg_save
> RS6000_PIC_OFFSET_TABLE_REGNUM
)
13297 info_ptr
->gp_size
= reg_size
* (32 - RS6000_PIC_OFFSET_TABLE_REGNUM
);
13299 info_ptr
->gp_size
= reg_size
* (32 - info_ptr
->first_gp_reg_save
);
13301 /* For the SPE, we have an additional upper 32-bits on each GPR.
13302 Ideally we should save the entire 64-bits only when the upper
13303 half is used in SIMD instructions. Since we only record
13304 registers live (not the size they are used in), this proves
13305 difficult because we'd have to traverse the instruction chain at
13306 the right time, taking reload into account. This is a real pain,
13307 so we opt to save the GPRs in 64-bits always if but one register
13308 gets used in 64-bits. Otherwise, all the registers in the frame
13309 get saved in 32-bits.
13311 So... since when we save all GPRs (except the SP) in 64-bits, the
13312 traditional GP save area will be empty. */
13313 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
13314 info_ptr
->gp_size
= 0;
13316 info_ptr
->first_fp_reg_save
= first_fp_reg_to_save ();
13317 info_ptr
->fp_size
= 8 * (64 - info_ptr
->first_fp_reg_save
);
13319 info_ptr
->first_altivec_reg_save
= first_altivec_reg_to_save ();
13320 info_ptr
->altivec_size
= 16 * (LAST_ALTIVEC_REGNO
+ 1
13321 - info_ptr
->first_altivec_reg_save
);
13323 /* Does this function call anything? */
13324 info_ptr
->calls_p
= (! current_function_is_leaf
13325 || cfun
->machine
->ra_needs_full_frame
);
13327 /* Determine if we need to save the link register. */
13328 if ((DEFAULT_ABI
== ABI_AIX
13329 && current_function_profile
13330 && !TARGET_PROFILE_KERNEL
)
13331 #ifdef TARGET_RELOCATABLE
13332 || (TARGET_RELOCATABLE
&& (get_pool_size () != 0))
13334 || (info_ptr
->first_fp_reg_save
!= 64
13335 && !FP_SAVE_INLINE (info_ptr
->first_fp_reg_save
))
13336 || info_ptr
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
13337 || (DEFAULT_ABI
== ABI_V4
&& current_function_calls_alloca
)
13338 || info_ptr
->calls_p
13339 || rs6000_ra_ever_killed ())
13341 info_ptr
->lr_save_p
= 1;
13342 regs_ever_live
[LINK_REGISTER_REGNUM
] = 1;
13345 /* Determine if we need to save the condition code registers. */
13346 if (regs_ever_live
[CR2_REGNO
]
13347 || regs_ever_live
[CR3_REGNO
]
13348 || regs_ever_live
[CR4_REGNO
])
13350 info_ptr
->cr_save_p
= 1;
13351 if (DEFAULT_ABI
== ABI_V4
)
13352 info_ptr
->cr_size
= reg_size
;
13355 /* If the current function calls __builtin_eh_return, then we need
13356 to allocate stack space for registers that will hold data for
13357 the exception handler. */
13358 if (current_function_calls_eh_return
)
13361 for (i
= 0; EH_RETURN_DATA_REGNO (i
) != INVALID_REGNUM
; ++i
)
13364 /* SPE saves EH registers in 64-bits. */
13365 ehrd_size
= i
* (TARGET_SPE_ABI
13366 && info_ptr
->spe_64bit_regs_used
!= 0
13367 ? UNITS_PER_SPE_WORD
: UNITS_PER_WORD
);
13372 /* Determine various sizes. */
13373 info_ptr
->reg_size
= reg_size
;
13374 info_ptr
->fixed_size
= RS6000_SAVE_AREA
;
13375 info_ptr
->vars_size
= RS6000_ALIGN (get_frame_size (), 8);
13376 info_ptr
->parm_size
= RS6000_ALIGN (current_function_outgoing_args_size
,
13377 TARGET_ALTIVEC
? 16 : 8);
13378 if (FRAME_GROWS_DOWNWARD
)
13379 info_ptr
->vars_size
13380 += RS6000_ALIGN (info_ptr
->fixed_size
+ info_ptr
->vars_size
13381 + info_ptr
->parm_size
,
13382 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
)
13383 - (info_ptr
->fixed_size
+ info_ptr
->vars_size
13384 + info_ptr
->parm_size
);
13386 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
13387 info_ptr
->spe_gp_size
= 8 * (32 - info_ptr
->first_gp_reg_save
);
13389 info_ptr
->spe_gp_size
= 0;
13391 if (TARGET_ALTIVEC_ABI
)
13392 info_ptr
->vrsave_mask
= compute_vrsave_mask ();
13394 info_ptr
->vrsave_mask
= 0;
13396 if (TARGET_ALTIVEC_VRSAVE
&& info_ptr
->vrsave_mask
)
13397 info_ptr
->vrsave_size
= 4;
13399 info_ptr
->vrsave_size
= 0;
13401 compute_save_world_info (info_ptr
);
13403 /* Calculate the offsets. */
13404 switch (DEFAULT_ABI
)
13408 gcc_unreachable ();
13412 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
13413 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
13415 if (TARGET_ALTIVEC_ABI
)
13417 info_ptr
->vrsave_save_offset
13418 = info_ptr
->gp_save_offset
- info_ptr
->vrsave_size
;
13420 /* Align stack so vector save area is on a quadword boundary.
13421 The padding goes above the vectors. */
13422 if (info_ptr
->altivec_size
!= 0)
13423 info_ptr
->altivec_padding_size
13424 = info_ptr
->vrsave_save_offset
& 0xF;
13426 info_ptr
->altivec_padding_size
= 0;
13428 info_ptr
->altivec_save_offset
13429 = info_ptr
->vrsave_save_offset
13430 - info_ptr
->altivec_padding_size
13431 - info_ptr
->altivec_size
;
13432 gcc_assert (info_ptr
->altivec_size
== 0
13433 || info_ptr
->altivec_save_offset
% 16 == 0);
13435 /* Adjust for AltiVec case. */
13436 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
- ehrd_size
;
13439 info_ptr
->ehrd_offset
= info_ptr
->gp_save_offset
- ehrd_size
;
13440 info_ptr
->cr_save_offset
= reg_size
; /* first word when 64-bit. */
13441 info_ptr
->lr_save_offset
= 2*reg_size
;
13445 info_ptr
->fp_save_offset
= - info_ptr
->fp_size
;
13446 info_ptr
->gp_save_offset
= info_ptr
->fp_save_offset
- info_ptr
->gp_size
;
13447 info_ptr
->cr_save_offset
= info_ptr
->gp_save_offset
- info_ptr
->cr_size
;
13449 if (TARGET_SPE_ABI
&& info_ptr
->spe_64bit_regs_used
!= 0)
13451 /* Align stack so SPE GPR save area is aligned on a
13452 double-word boundary. */
13453 if (info_ptr
->spe_gp_size
!= 0)
13454 info_ptr
->spe_padding_size
13455 = 8 - (-info_ptr
->cr_save_offset
% 8);
13457 info_ptr
->spe_padding_size
= 0;
13459 info_ptr
->spe_gp_save_offset
13460 = info_ptr
->cr_save_offset
13461 - info_ptr
->spe_padding_size
13462 - info_ptr
->spe_gp_size
;
13464 /* Adjust for SPE case. */
13465 info_ptr
->ehrd_offset
= info_ptr
->spe_gp_save_offset
;
13467 else if (TARGET_ALTIVEC_ABI
)
13469 info_ptr
->vrsave_save_offset
13470 = info_ptr
->cr_save_offset
- info_ptr
->vrsave_size
;
13472 /* Align stack so vector save area is on a quadword boundary. */
13473 if (info_ptr
->altivec_size
!= 0)
13474 info_ptr
->altivec_padding_size
13475 = 16 - (-info_ptr
->vrsave_save_offset
% 16);
13477 info_ptr
->altivec_padding_size
= 0;
13479 info_ptr
->altivec_save_offset
13480 = info_ptr
->vrsave_save_offset
13481 - info_ptr
->altivec_padding_size
13482 - info_ptr
->altivec_size
;
13484 /* Adjust for AltiVec case. */
13485 info_ptr
->ehrd_offset
= info_ptr
->altivec_save_offset
;
13488 info_ptr
->ehrd_offset
= info_ptr
->cr_save_offset
;
13489 info_ptr
->ehrd_offset
-= ehrd_size
;
13490 info_ptr
->lr_save_offset
= reg_size
;
13494 save_align
= (TARGET_ALTIVEC_ABI
|| DEFAULT_ABI
== ABI_DARWIN
) ? 16 : 8;
13495 info_ptr
->save_size
= RS6000_ALIGN (info_ptr
->fp_size
13496 + info_ptr
->gp_size
13497 + info_ptr
->altivec_size
13498 + info_ptr
->altivec_padding_size
13499 + info_ptr
->spe_gp_size
13500 + info_ptr
->spe_padding_size
13502 + info_ptr
->cr_size
13503 + info_ptr
->vrsave_size
,
13506 non_fixed_size
= (info_ptr
->vars_size
13507 + info_ptr
->parm_size
13508 + info_ptr
->save_size
);
13510 info_ptr
->total_size
= RS6000_ALIGN (non_fixed_size
+ info_ptr
->fixed_size
,
13511 ABI_STACK_BOUNDARY
/ BITS_PER_UNIT
);
13513 /* Determine if we need to allocate any stack frame:
13515 For AIX we need to push the stack if a frame pointer is needed
13516 (because the stack might be dynamically adjusted), if we are
13517 debugging, if we make calls, or if the sum of fp_save, gp_save,
13518 and local variables are more than the space needed to save all
13519 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13520 + 18*8 = 288 (GPR13 reserved).
13522 For V.4 we don't have the stack cushion that AIX uses, but assume
13523 that the debugger can handle stackless frames. */
13525 if (info_ptr
->calls_p
)
13526 info_ptr
->push_p
= 1;
13528 else if (DEFAULT_ABI
== ABI_V4
)
13529 info_ptr
->push_p
= non_fixed_size
!= 0;
13531 else if (frame_pointer_needed
)
13532 info_ptr
->push_p
= 1;
13534 else if (TARGET_XCOFF
&& write_symbols
!= NO_DEBUG
)
13535 info_ptr
->push_p
= 1;
13538 info_ptr
->push_p
= non_fixed_size
> (TARGET_32BIT
? 220 : 288);
13540 /* Zero offsets if we're not saving those registers. */
13541 if (info_ptr
->fp_size
== 0)
13542 info_ptr
->fp_save_offset
= 0;
13544 if (info_ptr
->gp_size
== 0)
13545 info_ptr
->gp_save_offset
= 0;
13547 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->altivec_size
== 0)
13548 info_ptr
->altivec_save_offset
= 0;
13550 if (! TARGET_ALTIVEC_ABI
|| info_ptr
->vrsave_mask
== 0)
13551 info_ptr
->vrsave_save_offset
= 0;
13553 if (! TARGET_SPE_ABI
13554 || info_ptr
->spe_64bit_regs_used
== 0
13555 || info_ptr
->spe_gp_size
== 0)
13556 info_ptr
->spe_gp_save_offset
= 0;
13558 if (! info_ptr
->lr_save_p
)
13559 info_ptr
->lr_save_offset
= 0;
13561 if (! info_ptr
->cr_save_p
)
13562 info_ptr
->cr_save_offset
= 0;
13567 /* Return true if the current function uses any GPRs in 64-bit SIMD
13571 spe_func_has_64bit_regs_p (void)
13575 /* Functions that save and restore all the call-saved registers will
13576 need to save/restore the registers in 64-bits. */
13577 if (current_function_calls_eh_return
13578 || current_function_calls_setjmp
13579 || current_function_has_nonlocal_goto
)
13582 insns
= get_insns ();
13584 for (insn
= NEXT_INSN (insns
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13590 /* FIXME: This should be implemented with attributes...
13592 (set_attr "spe64" "true")....then,
13593 if (get_spe64(insn)) return true;
13595 It's the only reliable way to do the stuff below. */
13597 i
= PATTERN (insn
);
13598 if (GET_CODE (i
) == SET
)
13600 enum machine_mode mode
= GET_MODE (SET_SRC (i
));
13602 if (SPE_VECTOR_MODE (mode
))
13604 if (TARGET_E500_DOUBLE
&& (mode
== DFmode
|| mode
== TFmode
))
13614 debug_stack_info (rs6000_stack_t
*info
)
13616 const char *abi_string
;
13619 info
= rs6000_stack_info ();
13621 fprintf (stderr
, "\nStack information for function %s:\n",
13622 ((current_function_decl
&& DECL_NAME (current_function_decl
))
13623 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl
))
13628 default: abi_string
= "Unknown"; break;
13629 case ABI_NONE
: abi_string
= "NONE"; break;
13630 case ABI_AIX
: abi_string
= "AIX"; break;
13631 case ABI_DARWIN
: abi_string
= "Darwin"; break;
13632 case ABI_V4
: abi_string
= "V.4"; break;
13635 fprintf (stderr
, "\tABI = %5s\n", abi_string
);
13637 if (TARGET_ALTIVEC_ABI
)
13638 fprintf (stderr
, "\tALTIVEC ABI extensions enabled.\n");
13640 if (TARGET_SPE_ABI
)
13641 fprintf (stderr
, "\tSPE ABI extensions enabled.\n");
13643 if (info
->first_gp_reg_save
!= 32)
13644 fprintf (stderr
, "\tfirst_gp_reg_save = %5d\n", info
->first_gp_reg_save
);
13646 if (info
->first_fp_reg_save
!= 64)
13647 fprintf (stderr
, "\tfirst_fp_reg_save = %5d\n", info
->first_fp_reg_save
);
13649 if (info
->first_altivec_reg_save
<= LAST_ALTIVEC_REGNO
)
13650 fprintf (stderr
, "\tfirst_altivec_reg_save = %5d\n",
13651 info
->first_altivec_reg_save
);
13653 if (info
->lr_save_p
)
13654 fprintf (stderr
, "\tlr_save_p = %5d\n", info
->lr_save_p
);
13656 if (info
->cr_save_p
)
13657 fprintf (stderr
, "\tcr_save_p = %5d\n", info
->cr_save_p
);
13659 if (info
->vrsave_mask
)
13660 fprintf (stderr
, "\tvrsave_mask = 0x%x\n", info
->vrsave_mask
);
13663 fprintf (stderr
, "\tpush_p = %5d\n", info
->push_p
);
13666 fprintf (stderr
, "\tcalls_p = %5d\n", info
->calls_p
);
13668 if (info
->gp_save_offset
)
13669 fprintf (stderr
, "\tgp_save_offset = %5d\n", info
->gp_save_offset
);
13671 if (info
->fp_save_offset
)
13672 fprintf (stderr
, "\tfp_save_offset = %5d\n", info
->fp_save_offset
);
13674 if (info
->altivec_save_offset
)
13675 fprintf (stderr
, "\taltivec_save_offset = %5d\n",
13676 info
->altivec_save_offset
);
13678 if (info
->spe_gp_save_offset
)
13679 fprintf (stderr
, "\tspe_gp_save_offset = %5d\n",
13680 info
->spe_gp_save_offset
);
13682 if (info
->vrsave_save_offset
)
13683 fprintf (stderr
, "\tvrsave_save_offset = %5d\n",
13684 info
->vrsave_save_offset
);
13686 if (info
->lr_save_offset
)
13687 fprintf (stderr
, "\tlr_save_offset = %5d\n", info
->lr_save_offset
);
13689 if (info
->cr_save_offset
)
13690 fprintf (stderr
, "\tcr_save_offset = %5d\n", info
->cr_save_offset
);
13692 if (info
->varargs_save_offset
)
13693 fprintf (stderr
, "\tvarargs_save_offset = %5d\n", info
->varargs_save_offset
);
13695 if (info
->total_size
)
13696 fprintf (stderr
, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13699 if (info
->vars_size
)
13700 fprintf (stderr
, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC
"\n",
13703 if (info
->parm_size
)
13704 fprintf (stderr
, "\tparm_size = %5d\n", info
->parm_size
);
13706 if (info
->fixed_size
)
13707 fprintf (stderr
, "\tfixed_size = %5d\n", info
->fixed_size
);
13710 fprintf (stderr
, "\tgp_size = %5d\n", info
->gp_size
);
13712 if (info
->spe_gp_size
)
13713 fprintf (stderr
, "\tspe_gp_size = %5d\n", info
->spe_gp_size
);
13716 fprintf (stderr
, "\tfp_size = %5d\n", info
->fp_size
);
13718 if (info
->altivec_size
)
13719 fprintf (stderr
, "\taltivec_size = %5d\n", info
->altivec_size
);
13721 if (info
->vrsave_size
)
13722 fprintf (stderr
, "\tvrsave_size = %5d\n", info
->vrsave_size
);
13724 if (info
->altivec_padding_size
)
13725 fprintf (stderr
, "\taltivec_padding_size= %5d\n",
13726 info
->altivec_padding_size
);
13728 if (info
->spe_padding_size
)
13729 fprintf (stderr
, "\tspe_padding_size = %5d\n",
13730 info
->spe_padding_size
);
13733 fprintf (stderr
, "\tcr_size = %5d\n", info
->cr_size
);
13735 if (info
->save_size
)
13736 fprintf (stderr
, "\tsave_size = %5d\n", info
->save_size
);
13738 if (info
->reg_size
!= 4)
13739 fprintf (stderr
, "\treg_size = %5d\n", info
->reg_size
);
13741 fprintf (stderr
, "\n");
13745 rs6000_return_addr (int count
, rtx frame
)
13747 /* Currently we don't optimize very well between prolog and body
13748 code and for PIC code the code can be actually quite bad, so
13749 don't try to be too clever here. */
13750 if (count
!= 0 || (DEFAULT_ABI
!= ABI_AIX
&& flag_pic
))
13752 cfun
->machine
->ra_needs_full_frame
= 1;
13759 plus_constant (copy_to_reg
13760 (gen_rtx_MEM (Pmode
,
13761 memory_address (Pmode
, frame
))),
13762 RETURN_ADDRESS_OFFSET
)));
13765 cfun
->machine
->ra_need_lr
= 1;
13766 return get_hard_reg_initial_val (Pmode
, LINK_REGISTER_REGNUM
);
13769 /* Say whether a function is a candidate for sibcall handling or not.
13770 We do not allow indirect calls to be optimized into sibling calls.
13771 Also, we can't do it if there are any vector parameters; there's
13772 nowhere to put the VRsave code so it works; note that functions with
13773 vector parameters are required to have a prototype, so the argument
13774 type info must be available here. (The tail recursion case can work
13775 with vector parameters, but there's no way to distinguish here.) */
13777 rs6000_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
13782 if (TARGET_ALTIVEC_VRSAVE
)
13784 for (type
= TYPE_ARG_TYPES (TREE_TYPE (decl
));
13785 type
; type
= TREE_CHAIN (type
))
13787 if (TREE_CODE (TREE_VALUE (type
)) == VECTOR_TYPE
)
13791 if (DEFAULT_ABI
== ABI_DARWIN
13792 || (*targetm
.binds_local_p
) (decl
))
13794 tree attr_list
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
13796 if (!lookup_attribute ("longcall", attr_list
)
13797 || lookup_attribute ("shortcall", attr_list
))
13804 /* NULL if INSN insn is valid within a low-overhead loop.
13805 Otherwise return why doloop cannot be applied.
13806 PowerPC uses the COUNT register for branch on table instructions. */
13808 static const char *
13809 rs6000_invalid_within_doloop (rtx insn
)
13812 return "Function call in the loop.";
13815 && (GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
13816 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
))
13817 return "Computed branch in the loop.";
13823 rs6000_ra_ever_killed (void)
13829 if (current_function_is_thunk
)
13832 /* regs_ever_live has LR marked as used if any sibcalls are present,
13833 but this should not force saving and restoring in the
13834 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
13835 clobbers LR, so that is inappropriate. */
13837 /* Also, the prologue can generate a store into LR that
13838 doesn't really count, like this:
13841 bcl to set PIC register
13845 When we're called from the epilogue, we need to avoid counting
13846 this as a store. */
13848 push_topmost_sequence ();
13849 top
= get_insns ();
13850 pop_topmost_sequence ();
13851 reg
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
13853 for (insn
= NEXT_INSN (top
); insn
!= NULL_RTX
; insn
= NEXT_INSN (insn
))
13859 if (!SIBLING_CALL_P (insn
))
13862 else if (find_regno_note (insn
, REG_INC
, LINK_REGISTER_REGNUM
))
13864 else if (set_of (reg
, insn
) != NULL_RTX
13865 && !prologue_epilogue_contains (insn
))
13872 /* Add a REG_MAYBE_DEAD note to the insn. */
13874 rs6000_maybe_dead (rtx insn
)
13876 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD
,
13881 /* Emit instructions needed to load the TOC register.
13882 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
13883 a constant pool; or for SVR4 -fpic. */
13886 rs6000_emit_load_toc_table (int fromprolog
)
13889 dest
= gen_rtx_REG (Pmode
, RS6000_PIC_OFFSET_TABLE_REGNUM
);
13891 if (TARGET_ELF
&& TARGET_SECURE_PLT
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
)
13894 rtx lab
, tmp1
, tmp2
, got
, tempLR
;
13896 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
13897 lab
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13899 got
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
13901 got
= rs6000_got_sym ();
13902 tmp1
= tmp2
= dest
;
13905 tmp1
= gen_reg_rtx (Pmode
);
13906 tmp2
= gen_reg_rtx (Pmode
);
13908 tempLR
= (fromprolog
13909 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13910 : gen_reg_rtx (Pmode
));
13911 insn
= emit_insn (gen_load_toc_v4_PIC_1 (tempLR
, lab
));
13913 rs6000_maybe_dead (insn
);
13914 insn
= emit_move_insn (tmp1
, tempLR
);
13916 rs6000_maybe_dead (insn
);
13917 insn
= emit_insn (gen_load_toc_v4_PIC_3b (tmp2
, tmp1
, got
, lab
));
13919 rs6000_maybe_dead (insn
);
13920 insn
= emit_insn (gen_load_toc_v4_PIC_3c (dest
, tmp2
, got
, lab
));
13922 rs6000_maybe_dead (insn
);
13924 else if (TARGET_ELF
&& DEFAULT_ABI
== ABI_V4
&& flag_pic
== 1)
13926 rtx tempLR
= (fromprolog
13927 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13928 : gen_reg_rtx (Pmode
));
13930 insn
= emit_insn (gen_load_toc_v4_pic_si (tempLR
));
13932 rs6000_maybe_dead (insn
);
13933 insn
= emit_move_insn (dest
, tempLR
);
13935 rs6000_maybe_dead (insn
);
13937 else if (TARGET_ELF
&& DEFAULT_ABI
!= ABI_AIX
&& flag_pic
== 2)
13940 rtx tempLR
= (fromprolog
13941 ? gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
)
13942 : gen_reg_rtx (Pmode
));
13943 rtx temp0
= (fromprolog
13944 ? gen_rtx_REG (Pmode
, 0)
13945 : gen_reg_rtx (Pmode
));
13951 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
13952 symF
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13954 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCL", rs6000_pic_labelno
);
13955 symL
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13957 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR
,
13959 rs6000_maybe_dead (emit_move_insn (dest
, tempLR
));
13960 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0
, dest
,
13968 tocsym
= gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
);
13969 emit_insn (gen_load_toc_v4_PIC_1b (tempLR
, tocsym
));
13970 emit_move_insn (dest
, tempLR
);
13971 emit_move_insn (temp0
, gen_rtx_MEM (Pmode
, dest
));
13973 insn
= emit_insn (gen_addsi3 (dest
, temp0
, dest
));
13975 rs6000_maybe_dead (insn
);
13977 else if (TARGET_ELF
&& !TARGET_AIX
&& flag_pic
== 0 && TARGET_MINIMAL_TOC
)
13979 /* This is for AIX code running in non-PIC ELF32. */
13982 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
13983 realsym
= gen_rtx_SYMBOL_REF (Pmode
, ggc_strdup (buf
));
13985 insn
= emit_insn (gen_elf_high (dest
, realsym
));
13987 rs6000_maybe_dead (insn
);
13988 insn
= emit_insn (gen_elf_low (dest
, dest
, realsym
));
13990 rs6000_maybe_dead (insn
);
13994 gcc_assert (DEFAULT_ABI
== ABI_AIX
);
13997 insn
= emit_insn (gen_load_toc_aix_si (dest
));
13999 insn
= emit_insn (gen_load_toc_aix_di (dest
));
14001 rs6000_maybe_dead (insn
);
14005 /* Emit instructions to restore the link register after determining where
14006 its value has been stored. */
14009 rs6000_emit_eh_reg_restore (rtx source
, rtx scratch
)
14011 rs6000_stack_t
*info
= rs6000_stack_info ();
14014 operands
[0] = source
;
14015 operands
[1] = scratch
;
14017 if (info
->lr_save_p
)
14019 rtx frame_rtx
= stack_pointer_rtx
;
14020 HOST_WIDE_INT sp_offset
= 0;
14023 if (frame_pointer_needed
14024 || current_function_calls_alloca
14025 || info
->total_size
> 32767)
14027 tmp
= gen_frame_mem (Pmode
, frame_rtx
);
14028 emit_move_insn (operands
[1], tmp
);
14029 frame_rtx
= operands
[1];
14031 else if (info
->push_p
)
14032 sp_offset
= info
->total_size
;
14034 tmp
= plus_constant (frame_rtx
, info
->lr_save_offset
+ sp_offset
);
14035 tmp
= gen_frame_mem (Pmode
, tmp
);
14036 emit_move_insn (tmp
, operands
[0]);
14039 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
), operands
[0]);
14042 static GTY(()) int set
= -1;
14045 get_TOC_alias_set (void)
14048 set
= new_alias_set ();
14052 /* This returns nonzero if the current function uses the TOC. This is
14053 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
14054 is generated by the ABI_V4 load_toc_* patterns. */
14061 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
14064 rtx pat
= PATTERN (insn
);
14067 if (GET_CODE (pat
) == PARALLEL
)
14068 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
14070 rtx sub
= XVECEXP (pat
, 0, i
);
14071 if (GET_CODE (sub
) == USE
)
14073 sub
= XEXP (sub
, 0);
14074 if (GET_CODE (sub
) == UNSPEC
14075 && XINT (sub
, 1) == UNSPEC_TOC
)
14085 create_TOC_reference (rtx symbol
)
14087 if (no_new_pseudos
)
14088 regs_ever_live
[TOC_REGISTER
] = 1;
14089 return gen_rtx_PLUS (Pmode
,
14090 gen_rtx_REG (Pmode
, TOC_REGISTER
),
14091 gen_rtx_CONST (Pmode
,
14092 gen_rtx_MINUS (Pmode
, symbol
,
14093 gen_rtx_SYMBOL_REF (Pmode
, toc_label_name
))));
14096 /* If _Unwind_* has been called from within the same module,
14097 toc register is not guaranteed to be saved to 40(1) on function
14098 entry. Save it there in that case. */
14101 rs6000_aix_emit_builtin_unwind_init (void)
14104 rtx stack_top
= gen_reg_rtx (Pmode
);
14105 rtx opcode_addr
= gen_reg_rtx (Pmode
);
14106 rtx opcode
= gen_reg_rtx (SImode
);
14107 rtx tocompare
= gen_reg_rtx (SImode
);
14108 rtx no_toc_save_needed
= gen_label_rtx ();
14110 mem
= gen_frame_mem (Pmode
, hard_frame_pointer_rtx
);
14111 emit_move_insn (stack_top
, mem
);
14113 mem
= gen_frame_mem (Pmode
,
14114 gen_rtx_PLUS (Pmode
, stack_top
,
14115 GEN_INT (2 * GET_MODE_SIZE (Pmode
))));
14116 emit_move_insn (opcode_addr
, mem
);
14117 emit_move_insn (opcode
, gen_rtx_MEM (SImode
, opcode_addr
));
14118 emit_move_insn (tocompare
, gen_int_mode (TARGET_32BIT
? 0x80410014
14119 : 0xE8410028, SImode
));
14121 do_compare_rtx_and_jump (opcode
, tocompare
, EQ
, 1,
14122 SImode
, NULL_RTX
, NULL_RTX
,
14123 no_toc_save_needed
);
14125 mem
= gen_frame_mem (Pmode
,
14126 gen_rtx_PLUS (Pmode
, stack_top
,
14127 GEN_INT (5 * GET_MODE_SIZE (Pmode
))));
14128 emit_move_insn (mem
, gen_rtx_REG (Pmode
, 2));
14129 emit_label (no_toc_save_needed
);
14132 /* This ties together stack memory (MEM with an alias set of frame_alias_set)
14133 and the change to the stack pointer. */
14136 rs6000_emit_stack_tie (void)
14138 rtx mem
= gen_frame_mem (BLKmode
,
14139 gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
));
14141 emit_insn (gen_stack_tie (mem
));
14144 /* Emit the correct code for allocating stack space, as insns.
14145 If COPY_R12, make sure a copy of the old frame is left in r12.
14146 The generated code may use hard register 0 as a temporary. */
14149 rs6000_emit_allocate_stack (HOST_WIDE_INT size
, int copy_r12
)
14152 rtx stack_reg
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
14153 rtx tmp_reg
= gen_rtx_REG (Pmode
, 0);
14154 rtx todec
= gen_int_mode (-size
, Pmode
);
14156 if (INTVAL (todec
) != -size
)
14158 warning (0, "stack frame too large");
14159 emit_insn (gen_trap ());
14163 if (current_function_limit_stack
)
14165 if (REG_P (stack_limit_rtx
)
14166 && REGNO (stack_limit_rtx
) > 1
14167 && REGNO (stack_limit_rtx
) <= 31)
14169 emit_insn (TARGET_32BIT
14170 ? gen_addsi3 (tmp_reg
,
14173 : gen_adddi3 (tmp_reg
,
14177 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
14180 else if (GET_CODE (stack_limit_rtx
) == SYMBOL_REF
14182 && DEFAULT_ABI
== ABI_V4
)
14184 rtx toload
= gen_rtx_CONST (VOIDmode
,
14185 gen_rtx_PLUS (Pmode
,
14189 emit_insn (gen_elf_high (tmp_reg
, toload
));
14190 emit_insn (gen_elf_low (tmp_reg
, tmp_reg
, toload
));
14191 emit_insn (gen_cond_trap (LTU
, stack_reg
, tmp_reg
,
14195 warning (0, "stack limit expression is not supported");
14198 if (copy_r12
|| ! TARGET_UPDATE
)
14199 emit_move_insn (gen_rtx_REG (Pmode
, 12), stack_reg
);
14205 /* Need a note here so that try_split doesn't get confused. */
14206 if (get_last_insn () == NULL_RTX
)
14207 emit_note (NOTE_INSN_DELETED
);
14208 insn
= emit_move_insn (tmp_reg
, todec
);
14209 try_split (PATTERN (insn
), insn
, 0);
14213 insn
= emit_insn (TARGET_32BIT
14214 ? gen_movsi_update (stack_reg
, stack_reg
,
14216 : gen_movdi_di_update (stack_reg
, stack_reg
,
14217 todec
, stack_reg
));
14221 insn
= emit_insn (TARGET_32BIT
14222 ? gen_addsi3 (stack_reg
, stack_reg
, todec
)
14223 : gen_adddi3 (stack_reg
, stack_reg
, todec
));
14224 emit_move_insn (gen_rtx_MEM (Pmode
, stack_reg
),
14225 gen_rtx_REG (Pmode
, 12));
14228 RTX_FRAME_RELATED_P (insn
) = 1;
14230 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14231 gen_rtx_SET (VOIDmode
, stack_reg
,
14232 gen_rtx_PLUS (Pmode
, stack_reg
,
14237 /* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
14238 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
14239 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
14240 deduce these equivalences by itself so it wasn't necessary to hold
14241 its hand so much. */
14244 rs6000_frame_related (rtx insn
, rtx reg
, HOST_WIDE_INT val
,
14245 rtx reg2
, rtx rreg
)
14249 /* copy_rtx will not make unique copies of registers, so we need to
14250 ensure we don't have unwanted sharing here. */
14252 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
14255 reg
= gen_raw_REG (GET_MODE (reg
), REGNO (reg
));
14257 real
= copy_rtx (PATTERN (insn
));
14259 if (reg2
!= NULL_RTX
)
14260 real
= replace_rtx (real
, reg2
, rreg
);
14262 real
= replace_rtx (real
, reg
,
14263 gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
,
14264 STACK_POINTER_REGNUM
),
14267 /* We expect that 'real' is either a SET or a PARALLEL containing
14268 SETs (and possibly other stuff). In a PARALLEL, all the SETs
14269 are important so they all have to be marked RTX_FRAME_RELATED_P. */
14271 if (GET_CODE (real
) == SET
)
14275 temp
= simplify_rtx (SET_SRC (set
));
14277 SET_SRC (set
) = temp
;
14278 temp
= simplify_rtx (SET_DEST (set
));
14280 SET_DEST (set
) = temp
;
14281 if (GET_CODE (SET_DEST (set
)) == MEM
)
14283 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
14285 XEXP (SET_DEST (set
), 0) = temp
;
14292 gcc_assert (GET_CODE (real
) == PARALLEL
);
14293 for (i
= 0; i
< XVECLEN (real
, 0); i
++)
14294 if (GET_CODE (XVECEXP (real
, 0, i
)) == SET
)
14296 rtx set
= XVECEXP (real
, 0, i
);
14298 temp
= simplify_rtx (SET_SRC (set
));
14300 SET_SRC (set
) = temp
;
14301 temp
= simplify_rtx (SET_DEST (set
));
14303 SET_DEST (set
) = temp
;
14304 if (GET_CODE (SET_DEST (set
)) == MEM
)
14306 temp
= simplify_rtx (XEXP (SET_DEST (set
), 0));
14308 XEXP (SET_DEST (set
), 0) = temp
;
14310 RTX_FRAME_RELATED_P (set
) = 1;
14315 real
= spe_synthesize_frame_save (real
);
14317 RTX_FRAME_RELATED_P (insn
) = 1;
14318 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14323 /* Given an SPE frame note, return a PARALLEL of SETs with the
14324 original note, plus a synthetic register save. */
14327 spe_synthesize_frame_save (rtx real
)
14329 rtx synth
, offset
, reg
, real2
;
14331 if (GET_CODE (real
) != SET
14332 || GET_MODE (SET_SRC (real
)) != V2SImode
)
14335 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
14336 frame related note. The parallel contains a set of the register
14337 being saved, and another set to a synthetic register (n+1200).
14338 This is so we can differentiate between 64-bit and 32-bit saves.
14339 Words cannot describe this nastiness. */
14341 gcc_assert (GET_CODE (SET_DEST (real
)) == MEM
14342 && GET_CODE (XEXP (SET_DEST (real
), 0)) == PLUS
14343 && GET_CODE (SET_SRC (real
)) == REG
);
14346 (set (mem (plus (reg x) (const y)))
14349 (set (mem (plus (reg x) (const y+4)))
14353 real2
= copy_rtx (real
);
14354 PUT_MODE (SET_DEST (real2
), SImode
);
14355 reg
= SET_SRC (real2
);
14356 real2
= replace_rtx (real2
, reg
, gen_rtx_REG (SImode
, REGNO (reg
)));
14357 synth
= copy_rtx (real2
);
14359 if (BYTES_BIG_ENDIAN
)
14361 offset
= XEXP (XEXP (SET_DEST (real2
), 0), 1);
14362 real2
= replace_rtx (real2
, offset
, GEN_INT (INTVAL (offset
) + 4));
14365 reg
= SET_SRC (synth
);
14367 synth
= replace_rtx (synth
, reg
,
14368 gen_rtx_REG (SImode
, REGNO (reg
) + 1200));
14370 offset
= XEXP (XEXP (SET_DEST (synth
), 0), 1);
14371 synth
= replace_rtx (synth
, offset
,
14372 GEN_INT (INTVAL (offset
)
14373 + (BYTES_BIG_ENDIAN
? 0 : 4)));
14375 RTX_FRAME_RELATED_P (synth
) = 1;
14376 RTX_FRAME_RELATED_P (real2
) = 1;
14377 if (BYTES_BIG_ENDIAN
)
14378 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, synth
, real2
));
14380 real
= gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, real2
, synth
));
14385 /* Returns an insn that has a vrsave set operation with the
14386 appropriate CLOBBERs. */
14389 generate_set_vrsave (rtx reg
, rs6000_stack_t
*info
, int epiloguep
)
14392 rtx insn
, clobs
[TOTAL_ALTIVEC_REGS
+ 1];
14393 rtx vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
14396 = gen_rtx_SET (VOIDmode
,
14398 gen_rtx_UNSPEC_VOLATILE (SImode
,
14399 gen_rtvec (2, reg
, vrsave
),
14400 UNSPECV_SET_VRSAVE
));
14404 /* We need to clobber the registers in the mask so the scheduler
14405 does not move sets to VRSAVE before sets of AltiVec registers.
14407 However, if the function receives nonlocal gotos, reload will set
14408 all call saved registers live. We will end up with:
14410 (set (reg 999) (mem))
14411 (parallel [ (set (reg vrsave) (unspec blah))
14412 (clobber (reg 999))])
14414 The clobber will cause the store into reg 999 to be dead, and
14415 flow will attempt to delete an epilogue insn. In this case, we
14416 need an unspec use/set of the register. */
14418 for (i
= FIRST_ALTIVEC_REGNO
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14419 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14421 if (!epiloguep
|| call_used_regs
[i
])
14422 clobs
[nclobs
++] = gen_rtx_CLOBBER (VOIDmode
,
14423 gen_rtx_REG (V4SImode
, i
));
14426 rtx reg
= gen_rtx_REG (V4SImode
, i
);
14429 = gen_rtx_SET (VOIDmode
,
14431 gen_rtx_UNSPEC (V4SImode
,
14432 gen_rtvec (1, reg
), 27));
14436 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nclobs
));
14438 for (i
= 0; i
< nclobs
; ++i
)
14439 XVECEXP (insn
, 0, i
) = clobs
[i
];
14444 /* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
14445 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
14448 emit_frame_save (rtx frame_reg
, rtx frame_ptr
, enum machine_mode mode
,
14449 unsigned int regno
, int offset
, HOST_WIDE_INT total_size
)
14451 rtx reg
, offset_rtx
, insn
, mem
, addr
, int_rtx
;
14452 rtx replacea
, replaceb
;
14454 int_rtx
= GEN_INT (offset
);
14456 /* Some cases that need register indexed addressing. */
14457 if ((TARGET_ALTIVEC_ABI
&& ALTIVEC_VECTOR_MODE (mode
))
14458 || (TARGET_E500_DOUBLE
&& mode
== DFmode
)
14460 && SPE_VECTOR_MODE (mode
)
14461 && !SPE_CONST_OFFSET_OK (offset
)))
14463 /* Whomever calls us must make sure r11 is available in the
14464 flow path of instructions in the prologue. */
14465 offset_rtx
= gen_rtx_REG (Pmode
, 11);
14466 emit_move_insn (offset_rtx
, int_rtx
);
14468 replacea
= offset_rtx
;
14469 replaceb
= int_rtx
;
14473 offset_rtx
= int_rtx
;
14474 replacea
= NULL_RTX
;
14475 replaceb
= NULL_RTX
;
14478 reg
= gen_rtx_REG (mode
, regno
);
14479 addr
= gen_rtx_PLUS (Pmode
, frame_reg
, offset_rtx
);
14480 mem
= gen_frame_mem (mode
, addr
);
14482 insn
= emit_move_insn (mem
, reg
);
14484 rs6000_frame_related (insn
, frame_ptr
, total_size
, replacea
, replaceb
);
14487 /* Emit an offset memory reference suitable for a frame store, while
14488 converting to a valid addressing mode. */
14491 gen_frame_mem_offset (enum machine_mode mode
, rtx reg
, int offset
)
14493 rtx int_rtx
, offset_rtx
;
14495 int_rtx
= GEN_INT (offset
);
14497 if ((TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode
))
14498 || (TARGET_E500_DOUBLE
&& mode
== DFmode
))
14500 offset_rtx
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14501 emit_move_insn (offset_rtx
, int_rtx
);
14504 offset_rtx
= int_rtx
;
14506 return gen_frame_mem (mode
, gen_rtx_PLUS (Pmode
, reg
, offset_rtx
));
14509 /* Look for user-defined global regs. We should not save and restore these,
14510 and cannot use stmw/lmw if there are any in its range. */
14513 no_global_regs_above (int first_greg
)
14516 for (i
= 0; i
< 32 - first_greg
; i
++)
14517 if (global_regs
[first_greg
+ i
])
14522 #ifndef TARGET_FIX_AND_CONTINUE
14523 #define TARGET_FIX_AND_CONTINUE 0
14526 /* Emit function prologue as insns. */
14529 rs6000_emit_prologue (void)
14531 rs6000_stack_t
*info
= rs6000_stack_info ();
14532 enum machine_mode reg_mode
= Pmode
;
14533 int reg_size
= TARGET_32BIT
? 4 : 8;
14534 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, STACK_POINTER_REGNUM
);
14535 rtx frame_ptr_rtx
= gen_rtx_REG (Pmode
, 12);
14536 rtx frame_reg_rtx
= sp_reg_rtx
;
14537 rtx cr_save_rtx
= NULL_RTX
;
14539 int saving_FPRs_inline
;
14540 int using_store_multiple
;
14541 HOST_WIDE_INT sp_offset
= 0;
14543 if (TARGET_FIX_AND_CONTINUE
)
14545 /* gdb on darwin arranges to forward a function from the old
14546 address by modifying the first 5 instructions of the function
14547 to branch to the overriding function. This is necessary to
14548 permit function pointers that point to the old function to
14549 actually forward to the new function. */
14550 emit_insn (gen_nop ());
14551 emit_insn (gen_nop ());
14552 emit_insn (gen_nop ());
14553 emit_insn (gen_nop ());
14554 emit_insn (gen_nop ());
14557 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14559 reg_mode
= V2SImode
;
14563 using_store_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
14564 && (!TARGET_SPE_ABI
14565 || info
->spe_64bit_regs_used
== 0)
14566 && info
->first_gp_reg_save
< 31
14567 && no_global_regs_above (info
->first_gp_reg_save
));
14568 saving_FPRs_inline
= (info
->first_fp_reg_save
== 64
14569 || FP_SAVE_INLINE (info
->first_fp_reg_save
)
14570 || current_function_calls_eh_return
14571 || cfun
->machine
->ra_need_lr
);
14573 /* For V.4, update stack before we do any saving and set back pointer. */
14574 if (! WORLD_SAVE_P (info
)
14576 && (DEFAULT_ABI
== ABI_V4
14577 || current_function_calls_eh_return
))
14579 if (info
->total_size
< 32767)
14580 sp_offset
= info
->total_size
;
14582 frame_reg_rtx
= frame_ptr_rtx
;
14583 rs6000_emit_allocate_stack (info
->total_size
,
14584 (frame_reg_rtx
!= sp_reg_rtx
14585 && (info
->cr_save_p
14587 || info
->first_fp_reg_save
< 64
14588 || info
->first_gp_reg_save
< 32
14590 if (frame_reg_rtx
!= sp_reg_rtx
)
14591 rs6000_emit_stack_tie ();
14594 /* Handle world saves specially here. */
14595 if (WORLD_SAVE_P (info
))
14602 /* save_world expects lr in r0. */
14603 reg0
= gen_rtx_REG (Pmode
, 0);
14604 if (info
->lr_save_p
)
14606 insn
= emit_move_insn (reg0
,
14607 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14608 RTX_FRAME_RELATED_P (insn
) = 1;
14611 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
14612 assumptions about the offsets of various bits of the stack
14614 gcc_assert (info
->gp_save_offset
== -220
14615 && info
->fp_save_offset
== -144
14616 && info
->lr_save_offset
== 8
14617 && info
->cr_save_offset
== 4
14620 && (!current_function_calls_eh_return
14621 || info
->ehrd_offset
== -432)
14622 && info
->vrsave_save_offset
== -224
14623 && info
->altivec_save_offset
== -416);
14625 treg
= gen_rtx_REG (SImode
, 11);
14626 emit_move_insn (treg
, GEN_INT (-info
->total_size
));
14628 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
14629 in R11. It also clobbers R12, so beware! */
14631 /* Preserve CR2 for save_world prologues */
14633 sz
+= 32 - info
->first_gp_reg_save
;
14634 sz
+= 64 - info
->first_fp_reg_save
;
14635 sz
+= LAST_ALTIVEC_REGNO
- info
->first_altivec_reg_save
+ 1;
14636 p
= rtvec_alloc (sz
);
14638 RTVEC_ELT (p
, j
++) = gen_rtx_CLOBBER (VOIDmode
,
14639 gen_rtx_REG (Pmode
,
14640 LINK_REGISTER_REGNUM
));
14641 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
14642 gen_rtx_SYMBOL_REF (Pmode
,
14644 /* We do floats first so that the instruction pattern matches
14646 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14648 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14649 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14650 GEN_INT (info
->fp_save_offset
14651 + sp_offset
+ 8 * i
));
14652 rtx mem
= gen_frame_mem (DFmode
, addr
);
14654 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14656 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
14658 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
14659 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14660 GEN_INT (info
->altivec_save_offset
14661 + sp_offset
+ 16 * i
));
14662 rtx mem
= gen_frame_mem (V4SImode
, addr
);
14664 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14666 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14668 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14669 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14670 GEN_INT (info
->gp_save_offset
14671 + sp_offset
+ reg_size
* i
));
14672 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14674 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14678 /* CR register traditionally saved as CR2. */
14679 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
14680 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14681 GEN_INT (info
->cr_save_offset
14683 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14685 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14687 /* Explain about use of R0. */
14688 if (info
->lr_save_p
)
14690 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14691 GEN_INT (info
->lr_save_offset
14693 rtx mem
= gen_frame_mem (reg_mode
, addr
);
14695 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, mem
, reg0
);
14697 /* Explain what happens to the stack pointer. */
14699 rtx newval
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
, treg
);
14700 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, sp_reg_rtx
, newval
);
14703 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14704 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14705 treg
, GEN_INT (-info
->total_size
));
14706 sp_offset
= info
->total_size
;
14709 /* Save AltiVec registers if needed. */
14710 if (!WORLD_SAVE_P (info
) && TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
14714 /* There should be a non inline version of this, for when we
14715 are saving lots of vector registers. */
14716 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
14717 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
14719 rtx areg
, savereg
, mem
;
14722 offset
= info
->altivec_save_offset
+ sp_offset
14723 + 16 * (i
- info
->first_altivec_reg_save
);
14725 savereg
= gen_rtx_REG (V4SImode
, i
);
14727 areg
= gen_rtx_REG (Pmode
, 0);
14728 emit_move_insn (areg
, GEN_INT (offset
));
14730 /* AltiVec addressing mode is [reg+reg]. */
14731 mem
= gen_frame_mem (V4SImode
,
14732 gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
));
14734 insn
= emit_move_insn (mem
, savereg
);
14736 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14737 areg
, GEN_INT (offset
));
14741 /* VRSAVE is a bit vector representing which AltiVec registers
14742 are used. The OS uses this to determine which vector
14743 registers to save on a context switch. We need to save
14744 VRSAVE on the stack frame, add whatever AltiVec registers we
14745 used in this function, and do the corresponding magic in the
14748 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
14749 && info
->vrsave_mask
!= 0)
14751 rtx reg
, mem
, vrsave
;
14754 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14755 as frame_reg_rtx and r11 as the static chain pointer for
14756 nested functions. */
14757 reg
= gen_rtx_REG (SImode
, 0);
14758 vrsave
= gen_rtx_REG (SImode
, VRSAVE_REGNO
);
14760 emit_insn (gen_get_vrsave_internal (reg
));
14762 emit_insn (gen_rtx_SET (VOIDmode
, reg
, vrsave
));
14764 if (!WORLD_SAVE_P (info
))
14767 offset
= info
->vrsave_save_offset
+ sp_offset
;
14768 mem
= gen_frame_mem (SImode
,
14769 gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14770 GEN_INT (offset
)));
14771 insn
= emit_move_insn (mem
, reg
);
14774 /* Include the registers in the mask. */
14775 emit_insn (gen_iorsi3 (reg
, reg
, GEN_INT ((int) info
->vrsave_mask
)));
14777 insn
= emit_insn (generate_set_vrsave (reg
, info
, 0));
14780 /* If we use the link register, get it into r0. */
14781 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
14783 insn
= emit_move_insn (gen_rtx_REG (Pmode
, 0),
14784 gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
));
14785 RTX_FRAME_RELATED_P (insn
) = 1;
14788 /* If we need to save CR, put it into r12. */
14789 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
&& frame_reg_rtx
!= frame_ptr_rtx
)
14793 cr_save_rtx
= gen_rtx_REG (SImode
, 12);
14794 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
14795 RTX_FRAME_RELATED_P (insn
) = 1;
14796 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14797 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14798 But that's OK. All we have to do is specify that _one_ condition
14799 code register is saved in this stack slot. The thrower's epilogue
14800 will then restore all the call-saved registers.
14801 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14802 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
,
14803 gen_rtx_REG (SImode
, CR2_REGNO
));
14804 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
14809 /* Do any required saving of fpr's. If only one or two to save, do
14810 it ourselves. Otherwise, call function. */
14811 if (!WORLD_SAVE_P (info
) && saving_FPRs_inline
)
14814 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14815 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
14816 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
14817 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, DFmode
,
14818 info
->first_fp_reg_save
+ i
,
14819 info
->fp_save_offset
+ sp_offset
+ 8 * i
,
14822 else if (!WORLD_SAVE_P (info
) && info
->first_fp_reg_save
!= 64)
14826 const char *alloc_rname
;
14828 p
= rtvec_alloc (2 + 64 - info
->first_fp_reg_save
);
14830 RTVEC_ELT (p
, 0) = gen_rtx_CLOBBER (VOIDmode
,
14831 gen_rtx_REG (Pmode
,
14832 LINK_REGISTER_REGNUM
));
14833 sprintf (rname
, "%s%d%s", SAVE_FP_PREFIX
,
14834 info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
);
14835 alloc_rname
= ggc_strdup (rname
);
14836 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
14837 gen_rtx_SYMBOL_REF (Pmode
,
14839 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
14841 rtx addr
, reg
, mem
;
14842 reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
14843 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14844 GEN_INT (info
->fp_save_offset
14845 + sp_offset
+ 8*i
));
14846 mem
= gen_frame_mem (DFmode
, addr
);
14848 RTVEC_ELT (p
, i
+ 2) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14850 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14851 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14852 NULL_RTX
, NULL_RTX
);
14855 /* Save GPRs. This is done as a PARALLEL if we are using
14856 the store-multiple instructions. */
14857 if (!WORLD_SAVE_P (info
) && using_store_multiple
)
14861 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
14862 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14864 rtx addr
, reg
, mem
;
14865 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14866 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14867 GEN_INT (info
->gp_save_offset
14870 mem
= gen_frame_mem (reg_mode
, addr
);
14872 RTVEC_ELT (p
, i
) = gen_rtx_SET (VOIDmode
, mem
, reg
);
14874 insn
= emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
14875 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14876 NULL_RTX
, NULL_RTX
);
14878 else if (!WORLD_SAVE_P (info
))
14881 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
14882 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
14883 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
14884 || (i
+ info
->first_gp_reg_save
14885 == RS6000_PIC_OFFSET_TABLE_REGNUM
14886 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
14887 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
14888 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
14889 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
14891 rtx addr
, reg
, mem
;
14892 reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
14894 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
14896 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
14899 if (!SPE_CONST_OFFSET_OK (offset
))
14901 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
14902 emit_move_insn (b
, GEN_INT (offset
));
14905 b
= GEN_INT (offset
);
14907 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
14908 mem
= gen_frame_mem (V2SImode
, addr
);
14909 insn
= emit_move_insn (mem
, reg
);
14911 if (GET_CODE (b
) == CONST_INT
)
14912 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14913 NULL_RTX
, NULL_RTX
);
14915 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14916 b
, GEN_INT (offset
));
14920 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14921 GEN_INT (info
->gp_save_offset
14924 mem
= gen_frame_mem (reg_mode
, addr
);
14926 insn
= emit_move_insn (mem
, reg
);
14927 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14928 NULL_RTX
, NULL_RTX
);
14933 /* ??? There's no need to emit actual instructions here, but it's the
14934 easiest way to get the frame unwind information emitted. */
14935 if (current_function_calls_eh_return
)
14937 unsigned int i
, regno
;
14939 /* In AIX ABI we need to pretend we save r2 here. */
14942 rtx addr
, reg
, mem
;
14944 reg
= gen_rtx_REG (reg_mode
, 2);
14945 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14946 GEN_INT (sp_offset
+ 5 * reg_size
));
14947 mem
= gen_frame_mem (reg_mode
, addr
);
14949 insn
= emit_move_insn (mem
, reg
);
14950 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14951 NULL_RTX
, NULL_RTX
);
14952 PATTERN (insn
) = gen_blockage ();
14957 regno
= EH_RETURN_DATA_REGNO (i
);
14958 if (regno
== INVALID_REGNUM
)
14961 emit_frame_save (frame_reg_rtx
, frame_ptr_rtx
, reg_mode
, regno
,
14962 info
->ehrd_offset
+ sp_offset
14963 + reg_size
* (int) i
,
14968 /* Save lr if we used it. */
14969 if (!WORLD_SAVE_P (info
) && info
->lr_save_p
)
14971 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14972 GEN_INT (info
->lr_save_offset
+ sp_offset
));
14973 rtx reg
= gen_rtx_REG (Pmode
, 0);
14974 rtx mem
= gen_rtx_MEM (Pmode
, addr
);
14975 /* This should not be of frame_alias_set, because of
14976 __builtin_return_address. */
14978 insn
= emit_move_insn (mem
, reg
);
14979 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
14980 NULL_RTX
, NULL_RTX
);
14983 /* Save CR if we use any that must be preserved. */
14984 if (!WORLD_SAVE_P (info
) && info
->cr_save_p
)
14986 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
14987 GEN_INT (info
->cr_save_offset
+ sp_offset
));
14988 rtx mem
= gen_frame_mem (SImode
, addr
);
14989 /* See the large comment above about why CR2_REGNO is used. */
14990 rtx magic_eh_cr_reg
= gen_rtx_REG (SImode
, CR2_REGNO
);
14992 /* If r12 was used to hold the original sp, copy cr into r0 now
14994 if (REGNO (frame_reg_rtx
) == 12)
14998 cr_save_rtx
= gen_rtx_REG (SImode
, 0);
14999 insn
= emit_insn (gen_movesi_from_cr (cr_save_rtx
));
15000 RTX_FRAME_RELATED_P (insn
) = 1;
15001 set
= gen_rtx_SET (VOIDmode
, cr_save_rtx
, magic_eh_cr_reg
);
15002 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
15007 insn
= emit_move_insn (mem
, cr_save_rtx
);
15009 rs6000_frame_related (insn
, frame_ptr_rtx
, info
->total_size
,
15010 NULL_RTX
, NULL_RTX
);
15013 /* Update stack and set back pointer unless this is V.4,
15014 for which it was done previously. */
15015 if (!WORLD_SAVE_P (info
) && info
->push_p
15016 && !(DEFAULT_ABI
== ABI_V4
|| current_function_calls_eh_return
))
15017 rs6000_emit_allocate_stack (info
->total_size
, FALSE
);
15019 /* Set frame pointer, if needed. */
15020 if (frame_pointer_needed
)
15022 insn
= emit_move_insn (gen_rtx_REG (Pmode
, HARD_FRAME_POINTER_REGNUM
),
15024 RTX_FRAME_RELATED_P (insn
) = 1;
15027 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
15028 if ((TARGET_TOC
&& TARGET_MINIMAL_TOC
&& get_pool_size () != 0)
15029 || (DEFAULT_ABI
== ABI_V4
15030 && (flag_pic
== 1 || (flag_pic
&& TARGET_SECURE_PLT
))
15031 && regs_ever_live
[RS6000_PIC_OFFSET_TABLE_REGNUM
]))
15033 /* If emit_load_toc_table will use the link register, we need to save
15034 it. We use R12 for this purpose because emit_load_toc_table
15035 can use register 0. This allows us to use a plain 'blr' to return
15036 from the procedure more often. */
15037 int save_LR_around_toc_setup
= (TARGET_ELF
15038 && DEFAULT_ABI
!= ABI_AIX
15040 && ! info
->lr_save_p
15041 && EDGE_COUNT (EXIT_BLOCK_PTR
->preds
) > 0);
15042 if (save_LR_around_toc_setup
)
15044 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
15046 insn
= emit_move_insn (frame_ptr_rtx
, lr
);
15047 rs6000_maybe_dead (insn
);
15048 RTX_FRAME_RELATED_P (insn
) = 1;
15050 rs6000_emit_load_toc_table (TRUE
);
15052 insn
= emit_move_insn (lr
, frame_ptr_rtx
);
15053 rs6000_maybe_dead (insn
);
15054 RTX_FRAME_RELATED_P (insn
) = 1;
15057 rs6000_emit_load_toc_table (TRUE
);
15061 if (DEFAULT_ABI
== ABI_DARWIN
15062 && flag_pic
&& current_function_uses_pic_offset_table
)
15064 rtx lr
= gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
);
15065 rtx src
= machopic_function_base_sym ();
15067 /* Save and restore LR locally around this call (in R0). */
15068 if (!info
->lr_save_p
)
15069 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode
, 0), lr
));
15071 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr
, src
)));
15073 insn
= emit_move_insn (gen_rtx_REG (Pmode
,
15074 RS6000_PIC_OFFSET_TABLE_REGNUM
),
15076 rs6000_maybe_dead (insn
);
15078 if (!info
->lr_save_p
)
15079 rs6000_maybe_dead (emit_move_insn (lr
, gen_rtx_REG (Pmode
, 0)));
15084 /* Write function prologue. */
15087 rs6000_output_function_prologue (FILE *file
,
15088 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
15090 rs6000_stack_t
*info
= rs6000_stack_info ();
15092 if (TARGET_DEBUG_STACK
)
15093 debug_stack_info (info
);
15095 /* Write .extern for any function we will call to save and restore
15097 if (info
->first_fp_reg_save
< 64
15098 && !FP_SAVE_INLINE (info
->first_fp_reg_save
))
15099 fprintf (file
, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
15100 SAVE_FP_PREFIX
, info
->first_fp_reg_save
- 32, SAVE_FP_SUFFIX
,
15101 RESTORE_FP_PREFIX
, info
->first_fp_reg_save
- 32,
15102 RESTORE_FP_SUFFIX
);
15104 /* Write .extern for AIX common mode routines, if needed. */
15105 if (! TARGET_POWER
&& ! TARGET_POWERPC
&& ! common_mode_defined
)
15107 fputs ("\t.extern __mulh\n", file
);
15108 fputs ("\t.extern __mull\n", file
);
15109 fputs ("\t.extern __divss\n", file
);
15110 fputs ("\t.extern __divus\n", file
);
15111 fputs ("\t.extern __quoss\n", file
);
15112 fputs ("\t.extern __quous\n", file
);
15113 common_mode_defined
= 1;
15116 if (! HAVE_prologue
)
15120 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
15121 the "toplevel" insn chain. */
15122 emit_note (NOTE_INSN_DELETED
);
15123 rs6000_emit_prologue ();
15124 emit_note (NOTE_INSN_DELETED
);
15126 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15130 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
15132 INSN_ADDRESSES_NEW (insn
, addr
);
15137 if (TARGET_DEBUG_STACK
)
15138 debug_rtx_list (get_insns (), 100);
15139 final (get_insns (), file
, FALSE
);
15143 rs6000_pic_labelno
++;
15146 /* Emit function epilogue as insns.
15148 At present, dwarf2out_frame_debug_expr doesn't understand
15149 register restores, so we don't bother setting RTX_FRAME_RELATED_P
15150 anywhere in the epilogue. Most of the insns below would in any case
15151 need special notes to explain where r11 is in relation to the stack. */
15154 rs6000_emit_epilogue (int sibcall
)
15156 rs6000_stack_t
*info
;
15157 int restoring_FPRs_inline
;
15158 int using_load_multiple
;
15159 int using_mtcr_multiple
;
15160 int use_backchain_to_restore_sp
;
15162 rtx sp_reg_rtx
= gen_rtx_REG (Pmode
, 1);
15163 rtx frame_reg_rtx
= sp_reg_rtx
;
15164 enum machine_mode reg_mode
= Pmode
;
15165 int reg_size
= TARGET_32BIT
? 4 : 8;
15168 info
= rs6000_stack_info ();
15170 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
15172 reg_mode
= V2SImode
;
15176 using_load_multiple
= (TARGET_MULTIPLE
&& ! TARGET_POWERPC64
15177 && (!TARGET_SPE_ABI
15178 || info
->spe_64bit_regs_used
== 0)
15179 && info
->first_gp_reg_save
< 31
15180 && no_global_regs_above (info
->first_gp_reg_save
));
15181 restoring_FPRs_inline
= (sibcall
15182 || current_function_calls_eh_return
15183 || info
->first_fp_reg_save
== 64
15184 || FP_SAVE_INLINE (info
->first_fp_reg_save
));
15185 use_backchain_to_restore_sp
= (frame_pointer_needed
15186 || current_function_calls_alloca
15187 || info
->total_size
> 32767);
15188 using_mtcr_multiple
= (rs6000_cpu
== PROCESSOR_PPC601
15189 || rs6000_cpu
== PROCESSOR_PPC603
15190 || rs6000_cpu
== PROCESSOR_PPC750
15193 if (WORLD_SAVE_P (info
))
15197 const char *alloc_rname
;
15200 /* eh_rest_world_r10 will return to the location saved in the LR
15201 stack slot (which is not likely to be our caller.)
15202 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
15203 rest_world is similar, except any R10 parameter is ignored.
15204 The exception-handling stuff that was here in 2.95 is no
15205 longer necessary. */
15209 + 32 - info
->first_gp_reg_save
15210 + LAST_ALTIVEC_REGNO
+ 1 - info
->first_altivec_reg_save
15211 + 63 + 1 - info
->first_fp_reg_save
);
15213 strcpy (rname
, ((current_function_calls_eh_return
) ?
15214 "*eh_rest_world_r10" : "*rest_world"));
15215 alloc_rname
= ggc_strdup (rname
);
15218 RTVEC_ELT (p
, j
++) = gen_rtx_RETURN (VOIDmode
);
15219 RTVEC_ELT (p
, j
++) = gen_rtx_USE (VOIDmode
,
15220 gen_rtx_REG (Pmode
,
15221 LINK_REGISTER_REGNUM
));
15223 = gen_rtx_USE (VOIDmode
, gen_rtx_SYMBOL_REF (Pmode
, alloc_rname
));
15224 /* The instruction pattern requires a clobber here;
15225 it is shared with the restVEC helper. */
15227 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 11));
15230 /* CR register traditionally saved as CR2. */
15231 rtx reg
= gen_rtx_REG (reg_mode
, CR2_REGNO
);
15232 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15233 GEN_INT (info
->cr_save_offset
));
15234 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15236 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15239 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15241 rtx reg
= gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
);
15242 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15243 GEN_INT (info
->gp_save_offset
15245 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15247 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15249 for (i
= 0; info
->first_altivec_reg_save
+ i
<= LAST_ALTIVEC_REGNO
; i
++)
15251 rtx reg
= gen_rtx_REG (V4SImode
, info
->first_altivec_reg_save
+ i
);
15252 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15253 GEN_INT (info
->altivec_save_offset
15255 rtx mem
= gen_frame_mem (V4SImode
, addr
);
15257 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15259 for (i
= 0; info
->first_fp_reg_save
+ i
<= 63; i
++)
15261 rtx reg
= gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
);
15262 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15263 GEN_INT (info
->fp_save_offset
15265 rtx mem
= gen_frame_mem (DFmode
, addr
);
15267 RTVEC_ELT (p
, j
++) = gen_rtx_SET (VOIDmode
, reg
, mem
);
15270 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, 0));
15272 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 12));
15274 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 7));
15276 = gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (SImode
, 8));
15278 = gen_rtx_USE (VOIDmode
, gen_rtx_REG (SImode
, 10));
15279 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15284 /* If we have a frame pointer, a call to alloca, or a large stack
15285 frame, restore the old stack pointer using the backchain. Otherwise,
15286 we know what size to update it with. */
15287 if (use_backchain_to_restore_sp
)
15289 /* Under V.4, don't reset the stack pointer until after we're done
15290 loading the saved registers. */
15291 if (DEFAULT_ABI
== ABI_V4
)
15292 frame_reg_rtx
= gen_rtx_REG (Pmode
, 11);
15294 emit_move_insn (frame_reg_rtx
,
15295 gen_rtx_MEM (Pmode
, sp_reg_rtx
));
15297 else if (info
->push_p
)
15299 if (DEFAULT_ABI
== ABI_V4
15300 || current_function_calls_eh_return
)
15301 sp_offset
= info
->total_size
;
15304 emit_insn (TARGET_32BIT
15305 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
15306 GEN_INT (info
->total_size
))
15307 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
15308 GEN_INT (info
->total_size
)));
15312 /* Restore AltiVec registers if needed. */
15313 if (TARGET_ALTIVEC_ABI
&& info
->altivec_size
!= 0)
15317 for (i
= info
->first_altivec_reg_save
; i
<= LAST_ALTIVEC_REGNO
; ++i
)
15318 if (info
->vrsave_mask
& ALTIVEC_REG_BIT (i
))
15320 rtx addr
, areg
, mem
;
15322 areg
= gen_rtx_REG (Pmode
, 0);
15324 (areg
, GEN_INT (info
->altivec_save_offset
15326 + 16 * (i
- info
->first_altivec_reg_save
)));
15328 /* AltiVec addressing mode is [reg+reg]. */
15329 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, areg
);
15330 mem
= gen_frame_mem (V4SImode
, addr
);
15332 emit_move_insn (gen_rtx_REG (V4SImode
, i
), mem
);
15336 /* Restore VRSAVE if needed. */
15337 if (TARGET_ALTIVEC
&& TARGET_ALTIVEC_VRSAVE
15338 && info
->vrsave_mask
!= 0)
15340 rtx addr
, mem
, reg
;
15342 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15343 GEN_INT (info
->vrsave_save_offset
+ sp_offset
));
15344 mem
= gen_frame_mem (SImode
, addr
);
15345 reg
= gen_rtx_REG (SImode
, 12);
15346 emit_move_insn (reg
, mem
);
15348 emit_insn (generate_set_vrsave (reg
, info
, 1));
15351 /* Get the old lr if we saved it. */
15352 if (info
->lr_save_p
)
15354 rtx mem
= gen_frame_mem_offset (Pmode
, frame_reg_rtx
,
15355 info
->lr_save_offset
+ sp_offset
);
15357 emit_move_insn (gen_rtx_REG (Pmode
, 0), mem
);
15360 /* Get the old cr if we saved it. */
15361 if (info
->cr_save_p
)
15363 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15364 GEN_INT (info
->cr_save_offset
+ sp_offset
));
15365 rtx mem
= gen_frame_mem (SImode
, addr
);
15367 emit_move_insn (gen_rtx_REG (SImode
, 12), mem
);
15370 /* Set LR here to try to overlap restores below. */
15371 if (info
->lr_save_p
)
15372 emit_move_insn (gen_rtx_REG (Pmode
, LINK_REGISTER_REGNUM
),
15373 gen_rtx_REG (Pmode
, 0));
15375 /* Load exception handler data registers, if needed. */
15376 if (current_function_calls_eh_return
)
15378 unsigned int i
, regno
;
15382 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15383 GEN_INT (sp_offset
+ 5 * reg_size
));
15384 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15386 emit_move_insn (gen_rtx_REG (reg_mode
, 2), mem
);
15393 regno
= EH_RETURN_DATA_REGNO (i
);
15394 if (regno
== INVALID_REGNUM
)
15397 mem
= gen_frame_mem_offset (reg_mode
, frame_reg_rtx
,
15398 info
->ehrd_offset
+ sp_offset
15399 + reg_size
* (int) i
);
15401 emit_move_insn (gen_rtx_REG (reg_mode
, regno
), mem
);
15405 /* Restore GPRs. This is done as a PARALLEL if we are using
15406 the load-multiple instructions. */
15407 if (using_load_multiple
)
15410 p
= rtvec_alloc (32 - info
->first_gp_reg_save
);
15411 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15413 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15414 GEN_INT (info
->gp_save_offset
15417 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15420 gen_rtx_SET (VOIDmode
,
15421 gen_rtx_REG (reg_mode
, info
->first_gp_reg_save
+ i
),
15424 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15427 for (i
= 0; i
< 32 - info
->first_gp_reg_save
; i
++)
15428 if ((regs_ever_live
[info
->first_gp_reg_save
+ i
]
15429 && (!call_used_regs
[info
->first_gp_reg_save
+ i
]
15430 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
15431 && TARGET_TOC
&& TARGET_MINIMAL_TOC
)))
15432 || (i
+ info
->first_gp_reg_save
== RS6000_PIC_OFFSET_TABLE_REGNUM
15433 && ((DEFAULT_ABI
== ABI_V4
&& flag_pic
!= 0)
15434 || (DEFAULT_ABI
== ABI_DARWIN
&& flag_pic
))))
15436 rtx addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15437 GEN_INT (info
->gp_save_offset
15440 rtx mem
= gen_frame_mem (reg_mode
, addr
);
15442 /* Restore 64-bit quantities for SPE. */
15443 if (TARGET_SPE_ABI
&& info
->spe_64bit_regs_used
!= 0)
15445 int offset
= info
->spe_gp_save_offset
+ sp_offset
+ 8 * i
;
15448 if (!SPE_CONST_OFFSET_OK (offset
))
15450 b
= gen_rtx_REG (Pmode
, FIXED_SCRATCH
);
15451 emit_move_insn (b
, GEN_INT (offset
));
15454 b
= GEN_INT (offset
);
15456 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
, b
);
15457 mem
= gen_frame_mem (V2SImode
, addr
);
15460 emit_move_insn (gen_rtx_REG (reg_mode
,
15461 info
->first_gp_reg_save
+ i
), mem
);
15464 /* Restore fpr's if we need to do it without calling a function. */
15465 if (restoring_FPRs_inline
)
15466 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15467 if ((regs_ever_live
[info
->first_fp_reg_save
+i
]
15468 && ! call_used_regs
[info
->first_fp_reg_save
+i
]))
15471 addr
= gen_rtx_PLUS (Pmode
, frame_reg_rtx
,
15472 GEN_INT (info
->fp_save_offset
15475 mem
= gen_frame_mem (DFmode
, addr
);
15477 emit_move_insn (gen_rtx_REG (DFmode
,
15478 info
->first_fp_reg_save
+ i
),
15482 /* If we saved cr, restore it here. Just those that were used. */
15483 if (info
->cr_save_p
)
15485 rtx r12_rtx
= gen_rtx_REG (SImode
, 12);
15488 if (using_mtcr_multiple
)
15490 for (i
= 0; i
< 8; i
++)
15491 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15493 gcc_assert (count
);
15496 if (using_mtcr_multiple
&& count
> 1)
15501 p
= rtvec_alloc (count
);
15504 for (i
= 0; i
< 8; i
++)
15505 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15507 rtvec r
= rtvec_alloc (2);
15508 RTVEC_ELT (r
, 0) = r12_rtx
;
15509 RTVEC_ELT (r
, 1) = GEN_INT (1 << (7-i
));
15510 RTVEC_ELT (p
, ndx
) =
15511 gen_rtx_SET (VOIDmode
, gen_rtx_REG (CCmode
, CR0_REGNO
+i
),
15512 gen_rtx_UNSPEC (CCmode
, r
, UNSPEC_MOVESI_TO_CR
));
15515 emit_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15516 gcc_assert (ndx
== count
);
15519 for (i
= 0; i
< 8; i
++)
15520 if (regs_ever_live
[CR0_REGNO
+i
] && ! call_used_regs
[CR0_REGNO
+i
])
15522 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode
,
15528 /* If this is V.4, unwind the stack pointer after all of the loads
15530 if (frame_reg_rtx
!= sp_reg_rtx
)
15532 /* This blockage is needed so that sched doesn't decide to move
15533 the sp change before the register restores. */
15534 rs6000_emit_stack_tie ();
15535 emit_move_insn (sp_reg_rtx
, frame_reg_rtx
);
15537 else if (sp_offset
!= 0)
15538 emit_insn (TARGET_32BIT
15539 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
,
15540 GEN_INT (sp_offset
))
15541 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
,
15542 GEN_INT (sp_offset
)));
15544 if (current_function_calls_eh_return
)
15546 rtx sa
= EH_RETURN_STACKADJ_RTX
;
15547 emit_insn (TARGET_32BIT
15548 ? gen_addsi3 (sp_reg_rtx
, sp_reg_rtx
, sa
)
15549 : gen_adddi3 (sp_reg_rtx
, sp_reg_rtx
, sa
));
15555 if (! restoring_FPRs_inline
)
15556 p
= rtvec_alloc (3 + 64 - info
->first_fp_reg_save
);
15558 p
= rtvec_alloc (2);
15560 RTVEC_ELT (p
, 0) = gen_rtx_RETURN (VOIDmode
);
15561 RTVEC_ELT (p
, 1) = gen_rtx_USE (VOIDmode
,
15562 gen_rtx_REG (Pmode
,
15563 LINK_REGISTER_REGNUM
));
15565 /* If we have to restore more than two FP registers, branch to the
15566 restore function. It will return to our caller. */
15567 if (! restoring_FPRs_inline
)
15571 const char *alloc_rname
;
15573 sprintf (rname
, "%s%d%s", RESTORE_FP_PREFIX
,
15574 info
->first_fp_reg_save
- 32, RESTORE_FP_SUFFIX
);
15575 alloc_rname
= ggc_strdup (rname
);
15576 RTVEC_ELT (p
, 2) = gen_rtx_USE (VOIDmode
,
15577 gen_rtx_SYMBOL_REF (Pmode
,
15580 for (i
= 0; i
< 64 - info
->first_fp_reg_save
; i
++)
15583 addr
= gen_rtx_PLUS (Pmode
, sp_reg_rtx
,
15584 GEN_INT (info
->fp_save_offset
+ 8*i
));
15585 mem
= gen_frame_mem (DFmode
, addr
);
15587 RTVEC_ELT (p
, i
+3) =
15588 gen_rtx_SET (VOIDmode
,
15589 gen_rtx_REG (DFmode
, info
->first_fp_reg_save
+ i
),
15594 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode
, p
));
15598 /* Write function epilogue. */
15601 rs6000_output_function_epilogue (FILE *file
,
15602 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
15604 if (! HAVE_epilogue
)
15606 rtx insn
= get_last_insn ();
15607 /* If the last insn was a BARRIER, we don't have to write anything except
15608 the trace table. */
15609 if (GET_CODE (insn
) == NOTE
)
15610 insn
= prev_nonnote_insn (insn
);
15611 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
15613 /* This is slightly ugly, but at least we don't have two
15614 copies of the epilogue-emitting code. */
15617 /* A NOTE_INSN_DELETED is supposed to be at the start
15618 and end of the "toplevel" insn chain. */
15619 emit_note (NOTE_INSN_DELETED
);
15620 rs6000_emit_epilogue (FALSE
);
15621 emit_note (NOTE_INSN_DELETED
);
15623 /* Expand INSN_ADDRESSES so final() doesn't crash. */
15627 for (insn
= get_insns (); insn
!= 0; insn
= NEXT_INSN (insn
))
15629 INSN_ADDRESSES_NEW (insn
, addr
);
15634 if (TARGET_DEBUG_STACK
)
15635 debug_rtx_list (get_insns (), 100);
15636 final (get_insns (), file
, FALSE
);
15642 macho_branch_islands ();
15643 /* Mach-O doesn't support labels at the end of objects, so if
15644 it looks like we might want one, insert a NOP. */
15646 rtx insn
= get_last_insn ();
15649 && NOTE_LINE_NUMBER (insn
) != NOTE_INSN_DELETED_LABEL
)
15650 insn
= PREV_INSN (insn
);
15654 && NOTE_LINE_NUMBER (insn
) == NOTE_INSN_DELETED_LABEL
)))
15655 fputs ("\tnop\n", file
);
15659 /* Output a traceback table here. See /usr/include/sys/debug.h for info
15662 We don't output a traceback table if -finhibit-size-directive was
15663 used. The documentation for -finhibit-size-directive reads
15664 ``don't output a @code{.size} assembler directive, or anything
15665 else that would cause trouble if the function is split in the
15666 middle, and the two halves are placed at locations far apart in
15667 memory.'' The traceback table has this property, since it
15668 includes the offset from the start of the function to the
15669 traceback table itself.
15671 System V.4 Powerpc's (and the embedded ABI derived from it) use a
15672 different traceback table. */
15673 if (DEFAULT_ABI
== ABI_AIX
&& ! flag_inhibit_size_directive
15674 && rs6000_traceback
!= traceback_none
&& !current_function_is_thunk
)
15676 const char *fname
= NULL
;
15677 const char *language_string
= lang_hooks
.name
;
15678 int fixed_parms
= 0, float_parms
= 0, parm_info
= 0;
15680 int optional_tbtab
;
15681 rs6000_stack_t
*info
= rs6000_stack_info ();
15683 if (rs6000_traceback
== traceback_full
)
15684 optional_tbtab
= 1;
15685 else if (rs6000_traceback
== traceback_part
)
15686 optional_tbtab
= 0;
15688 optional_tbtab
= !optimize_size
&& !TARGET_ELF
;
15690 if (optional_tbtab
)
15692 fname
= XSTR (XEXP (DECL_RTL (current_function_decl
), 0), 0);
15693 while (*fname
== '.') /* V.4 encodes . in the name */
15696 /* Need label immediately before tbtab, so we can compute
15697 its offset from the function start. */
15698 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15699 ASM_OUTPUT_LABEL (file
, fname
);
15702 /* The .tbtab pseudo-op can only be used for the first eight
15703 expressions, since it can't handle the possibly variable
15704 length fields that follow. However, if you omit the optional
15705 fields, the assembler outputs zeros for all optional fields
15706 anyways, giving each variable length field is minimum length
15707 (as defined in sys/debug.h). Thus we can not use the .tbtab
15708 pseudo-op at all. */
15710 /* An all-zero word flags the start of the tbtab, for debuggers
15711 that have to find it by searching forward from the entry
15712 point or from the current pc. */
15713 fputs ("\t.long 0\n", file
);
15715 /* Tbtab format type. Use format type 0. */
15716 fputs ("\t.byte 0,", file
);
15718 /* Language type. Unfortunately, there does not seem to be any
15719 official way to discover the language being compiled, so we
15720 use language_string.
15721 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15722 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
15723 a number, so for now use 9. */
15724 if (! strcmp (language_string
, "GNU C"))
15726 else if (! strcmp (language_string
, "GNU F77")
15727 || ! strcmp (language_string
, "GNU F95"))
15729 else if (! strcmp (language_string
, "GNU Pascal"))
15731 else if (! strcmp (language_string
, "GNU Ada"))
15733 else if (! strcmp (language_string
, "GNU C++")
15734 || ! strcmp (language_string
, "GNU Objective-C++"))
15736 else if (! strcmp (language_string
, "GNU Java"))
15738 else if (! strcmp (language_string
, "GNU Objective-C"))
15741 gcc_unreachable ();
15742 fprintf (file
, "%d,", i
);
15744 /* 8 single bit fields: global linkage (not set for C extern linkage,
15745 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15746 from start of procedure stored in tbtab, internal function, function
15747 has controlled storage, function has no toc, function uses fp,
15748 function logs/aborts fp operations. */
15749 /* Assume that fp operations are used if any fp reg must be saved. */
15750 fprintf (file
, "%d,",
15751 (optional_tbtab
<< 5) | ((info
->first_fp_reg_save
!= 64) << 1));
15753 /* 6 bitfields: function is interrupt handler, name present in
15754 proc table, function calls alloca, on condition directives
15755 (controls stack walks, 3 bits), saves condition reg, saves
15757 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15758 set up as a frame pointer, even when there is no alloca call. */
15759 fprintf (file
, "%d,",
15760 ((optional_tbtab
<< 6)
15761 | ((optional_tbtab
& frame_pointer_needed
) << 5)
15762 | (info
->cr_save_p
<< 1)
15763 | (info
->lr_save_p
)));
15765 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
15767 fprintf (file
, "%d,",
15768 (info
->push_p
<< 7) | (64 - info
->first_fp_reg_save
));
15770 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15771 fprintf (file
, "%d,", (32 - first_reg_to_save ()));
15773 if (optional_tbtab
)
15775 /* Compute the parameter info from the function decl argument
15778 int next_parm_info_bit
= 31;
15780 for (decl
= DECL_ARGUMENTS (current_function_decl
);
15781 decl
; decl
= TREE_CHAIN (decl
))
15783 rtx parameter
= DECL_INCOMING_RTL (decl
);
15784 enum machine_mode mode
= GET_MODE (parameter
);
15786 if (GET_CODE (parameter
) == REG
)
15788 if (SCALAR_FLOAT_MODE_P (mode
))
15806 gcc_unreachable ();
15809 /* If only one bit will fit, don't or in this entry. */
15810 if (next_parm_info_bit
> 0)
15811 parm_info
|= (bits
<< (next_parm_info_bit
- 1));
15812 next_parm_info_bit
-= 2;
15816 fixed_parms
+= ((GET_MODE_SIZE (mode
)
15817 + (UNITS_PER_WORD
- 1))
15819 next_parm_info_bit
-= 1;
15825 /* Number of fixed point parameters. */
15826 /* This is actually the number of words of fixed point parameters; thus
15827 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15828 fprintf (file
, "%d,", fixed_parms
);
15830 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15832 /* This is actually the number of fp registers that hold parameters;
15833 and thus the maximum value is 13. */
15834 /* Set parameters on stack bit if parameters are not in their original
15835 registers, regardless of whether they are on the stack? Xlc
15836 seems to set the bit when not optimizing. */
15837 fprintf (file
, "%d\n", ((float_parms
<< 1) | (! optimize
)));
15839 if (! optional_tbtab
)
15842 /* Optional fields follow. Some are variable length. */
15844 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15845 11 double float. */
15846 /* There is an entry for each parameter in a register, in the order that
15847 they occur in the parameter list. Any intervening arguments on the
15848 stack are ignored. If the list overflows a long (max possible length
15849 34 bits) then completely leave off all elements that don't fit. */
15850 /* Only emit this long if there was at least one parameter. */
15851 if (fixed_parms
|| float_parms
)
15852 fprintf (file
, "\t.long %d\n", parm_info
);
15854 /* Offset from start of code to tb table. */
15855 fputs ("\t.long ", file
);
15856 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LT");
15858 RS6000_OUTPUT_BASENAME (file
, fname
);
15860 assemble_name (file
, fname
);
15862 rs6000_output_function_entry (file
, fname
);
15865 /* Interrupt handler mask. */
15866 /* Omit this long, since we never set the interrupt handler bit
15869 /* Number of CTL (controlled storage) anchors. */
15870 /* Omit this long, since the has_ctl bit is never set above. */
15872 /* Displacement into stack of each CTL anchor. */
15873 /* Omit this list of longs, because there are no CTL anchors. */
15875 /* Length of function name. */
15878 fprintf (file
, "\t.short %d\n", (int) strlen (fname
));
15880 /* Function name. */
15881 assemble_string (fname
, strlen (fname
));
15883 /* Register for alloca automatic storage; this is always reg 31.
15884 Only emit this if the alloca bit was set above. */
15885 if (frame_pointer_needed
)
15886 fputs ("\t.byte 31\n", file
);
15888 fputs ("\t.align 2\n", file
);
15892 /* A C compound statement that outputs the assembler code for a thunk
15893 function, used to implement C++ virtual function calls with
15894 multiple inheritance. The thunk acts as a wrapper around a virtual
15895 function, adjusting the implicit object parameter before handing
15896 control off to the real function.
15898 First, emit code to add the integer DELTA to the location that
15899 contains the incoming first argument. Assume that this argument
15900 contains a pointer, and is the one used to pass the `this' pointer
15901 in C++. This is the incoming argument *before* the function
15902 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15903 values of all other incoming arguments.
15905 After the addition, emit code to jump to FUNCTION, which is a
15906 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15907 not touch the return address. Hence returning from FUNCTION will
15908 return to whoever called the current `thunk'.
15910 The effect must be as if FUNCTION had been called directly with the
15911 adjusted first argument. This macro is responsible for emitting
15912 all of the code for a thunk function; output_function_prologue()
15913 and output_function_epilogue() are not invoked.
15915 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15916 been extracted from it.) It might possibly be useful on some
15917 targets, but probably not.
15919 If you do not define this macro, the target-independent code in the
15920 C++ frontend will generate a less efficient heavyweight thunk that
15921 calls FUNCTION instead of jumping to it. The generic approach does
15922 not support varargs. */
15925 rs6000_output_mi_thunk (FILE *file
, tree thunk_fndecl ATTRIBUTE_UNUSED
,
15926 HOST_WIDE_INT delta
, HOST_WIDE_INT vcall_offset
,
15929 rtx
this, insn
, funexp
;
15931 reload_completed
= 1;
15932 epilogue_completed
= 1;
15933 no_new_pseudos
= 1;
15934 reset_block_changes ();
15936 /* Mark the end of the (empty) prologue. */
15937 emit_note (NOTE_INSN_PROLOGUE_END
);
15939 /* Find the "this" pointer. If the function returns a structure,
15940 the structure return pointer is in r3. */
15941 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
))
15942 this = gen_rtx_REG (Pmode
, 4);
15944 this = gen_rtx_REG (Pmode
, 3);
15946 /* Apply the constant offset, if required. */
15949 rtx delta_rtx
= GEN_INT (delta
);
15950 emit_insn (TARGET_32BIT
15951 ? gen_addsi3 (this, this, delta_rtx
)
15952 : gen_adddi3 (this, this, delta_rtx
));
15955 /* Apply the offset from the vtable, if required. */
15958 rtx vcall_offset_rtx
= GEN_INT (vcall_offset
);
15959 rtx tmp
= gen_rtx_REG (Pmode
, 12);
15961 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, this));
15962 if (((unsigned HOST_WIDE_INT
) vcall_offset
) + 0x8000 >= 0x10000)
15964 emit_insn (TARGET_32BIT
15965 ? gen_addsi3 (tmp
, tmp
, vcall_offset_rtx
)
15966 : gen_adddi3 (tmp
, tmp
, vcall_offset_rtx
));
15967 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, tmp
));
15971 rtx loc
= gen_rtx_PLUS (Pmode
, tmp
, vcall_offset_rtx
);
15973 emit_move_insn (tmp
, gen_rtx_MEM (Pmode
, loc
));
15975 emit_insn (TARGET_32BIT
15976 ? gen_addsi3 (this, this, tmp
)
15977 : gen_adddi3 (this, this, tmp
));
15980 /* Generate a tail call to the target function. */
15981 if (!TREE_USED (function
))
15983 assemble_external (function
);
15984 TREE_USED (function
) = 1;
15986 funexp
= XEXP (DECL_RTL (function
), 0);
15987 funexp
= gen_rtx_MEM (FUNCTION_MODE
, funexp
);
15990 if (MACHOPIC_INDIRECT
)
15991 funexp
= machopic_indirect_call_target (funexp
);
15994 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
15995 generate sibcall RTL explicitly. */
15996 insn
= emit_call_insn (
15997 gen_rtx_PARALLEL (VOIDmode
,
15999 gen_rtx_CALL (VOIDmode
,
16000 funexp
, const0_rtx
),
16001 gen_rtx_USE (VOIDmode
, const0_rtx
),
16002 gen_rtx_USE (VOIDmode
,
16003 gen_rtx_REG (SImode
,
16004 LINK_REGISTER_REGNUM
)),
16005 gen_rtx_RETURN (VOIDmode
))));
16006 SIBLING_CALL_P (insn
) = 1;
16009 /* Run just enough of rest_of_compilation to get the insns emitted.
16010 There's not really enough bulk here to make other passes such as
16011 instruction scheduling worth while. Note that use_thunk calls
16012 assemble_start_function and assemble_end_function. */
16013 insn
= get_insns ();
16014 insn_locators_initialize ();
16015 shorten_branches (insn
);
16016 final_start_function (insn
, file
, 1);
16017 final (insn
, file
, 1);
16018 final_end_function ();
16020 reload_completed
= 0;
16021 epilogue_completed
= 0;
16022 no_new_pseudos
= 0;
16025 /* A quick summary of the various types of 'constant-pool tables'
16028 Target Flags Name One table per
16029 AIX (none) AIX TOC object file
16030 AIX -mfull-toc AIX TOC object file
16031 AIX -mminimal-toc AIX minimal TOC translation unit
16032 SVR4/EABI (none) SVR4 SDATA object file
16033 SVR4/EABI -fpic SVR4 pic object file
16034 SVR4/EABI -fPIC SVR4 PIC translation unit
16035 SVR4/EABI -mrelocatable EABI TOC function
16036 SVR4/EABI -maix AIX TOC object file
16037 SVR4/EABI -maix -mminimal-toc
16038 AIX minimal TOC translation unit
16040 Name Reg. Set by entries contains:
16041 made by addrs? fp? sum?
16043 AIX TOC 2 crt0 as Y option option
16044 AIX minimal TOC 30 prolog gcc Y Y option
16045 SVR4 SDATA 13 crt0 gcc N Y N
16046 SVR4 pic 30 prolog ld Y not yet N
16047 SVR4 PIC 30 prolog gcc Y option option
16048 EABI TOC 30 prolog gcc Y option option
16052 /* Hash functions for the hash table. */
16055 rs6000_hash_constant (rtx k
)
16057 enum rtx_code code
= GET_CODE (k
);
16058 enum machine_mode mode
= GET_MODE (k
);
16059 unsigned result
= (code
<< 3) ^ mode
;
16060 const char *format
;
16063 format
= GET_RTX_FORMAT (code
);
16064 flen
= strlen (format
);
16070 return result
* 1231 + (unsigned) INSN_UID (XEXP (k
, 0));
16073 if (mode
!= VOIDmode
)
16074 return real_hash (CONST_DOUBLE_REAL_VALUE (k
)) * result
;
16086 for (; fidx
< flen
; fidx
++)
16087 switch (format
[fidx
])
16092 const char *str
= XSTR (k
, fidx
);
16093 len
= strlen (str
);
16094 result
= result
* 613 + len
;
16095 for (i
= 0; i
< len
; i
++)
16096 result
= result
* 613 + (unsigned) str
[i
];
16101 result
= result
* 1231 + rs6000_hash_constant (XEXP (k
, fidx
));
16105 result
= result
* 613 + (unsigned) XINT (k
, fidx
);
16108 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT
))
16109 result
= result
* 613 + (unsigned) XWINT (k
, fidx
);
16113 for (i
= 0; i
< sizeof (HOST_WIDE_INT
) / sizeof (unsigned); i
++)
16114 result
= result
* 613 + (unsigned) (XWINT (k
, fidx
)
16121 gcc_unreachable ();
16128 toc_hash_function (const void *hash_entry
)
16130 const struct toc_hash_struct
*thc
=
16131 (const struct toc_hash_struct
*) hash_entry
;
16132 return rs6000_hash_constant (thc
->key
) ^ thc
->key_mode
;
16135 /* Compare H1 and H2 for equivalence. */
16138 toc_hash_eq (const void *h1
, const void *h2
)
16140 rtx r1
= ((const struct toc_hash_struct
*) h1
)->key
;
16141 rtx r2
= ((const struct toc_hash_struct
*) h2
)->key
;
16143 if (((const struct toc_hash_struct
*) h1
)->key_mode
16144 != ((const struct toc_hash_struct
*) h2
)->key_mode
)
16147 return rtx_equal_p (r1
, r2
);
16150 /* These are the names given by the C++ front-end to vtables, and
16151 vtable-like objects. Ideally, this logic should not be here;
16152 instead, there should be some programmatic way of inquiring as
16153 to whether or not an object is a vtable. */
16155 #define VTABLE_NAME_P(NAME) \
16156 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
16157 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
16158 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
16159 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
16160 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
16163 rs6000_output_symbol_ref (FILE *file
, rtx x
)
16165 /* Currently C++ toc references to vtables can be emitted before it
16166 is decided whether the vtable is public or private. If this is
16167 the case, then the linker will eventually complain that there is
16168 a reference to an unknown section. Thus, for vtables only,
16169 we emit the TOC reference to reference the symbol and not the
16171 const char *name
= XSTR (x
, 0);
16173 if (VTABLE_NAME_P (name
))
16175 RS6000_OUTPUT_BASENAME (file
, name
);
16178 assemble_name (file
, name
);
16181 /* Output a TOC entry. We derive the entry name from what is being
16185 output_toc (FILE *file
, rtx x
, int labelno
, enum machine_mode mode
)
16188 const char *name
= buf
;
16189 const char *real_name
;
16191 HOST_WIDE_INT offset
= 0;
16193 gcc_assert (!TARGET_NO_TOC
);
16195 /* When the linker won't eliminate them, don't output duplicate
16196 TOC entries (this happens on AIX if there is any kind of TOC,
16197 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
16199 if (TARGET_TOC
&& GET_CODE (x
) != LABEL_REF
)
16201 struct toc_hash_struct
*h
;
16204 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
16205 time because GGC is not initialized at that point. */
16206 if (toc_hash_table
== NULL
)
16207 toc_hash_table
= htab_create_ggc (1021, toc_hash_function
,
16208 toc_hash_eq
, NULL
);
16210 h
= ggc_alloc (sizeof (*h
));
16212 h
->key_mode
= mode
;
16213 h
->labelno
= labelno
;
16215 found
= htab_find_slot (toc_hash_table
, h
, 1);
16216 if (*found
== NULL
)
16218 else /* This is indeed a duplicate.
16219 Set this label equal to that label. */
16221 fputs ("\t.set ", file
);
16222 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
16223 fprintf (file
, "%d,", labelno
);
16224 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file
, "LC");
16225 fprintf (file
, "%d\n", ((*(const struct toc_hash_struct
**)
16231 /* If we're going to put a double constant in the TOC, make sure it's
16232 aligned properly when strict alignment is on. */
16233 if (GET_CODE (x
) == CONST_DOUBLE
16234 && STRICT_ALIGNMENT
16235 && GET_MODE_BITSIZE (mode
) >= 64
16236 && ! (TARGET_NO_FP_IN_TOC
&& ! TARGET_MINIMAL_TOC
)) {
16237 ASM_OUTPUT_ALIGN (file
, 3);
16240 (*targetm
.asm_out
.internal_label
) (file
, "LC", labelno
);
16242 /* Handle FP constants specially. Note that if we have a minimal
16243 TOC, things we put here aren't actually in the TOC, so we can allow
16245 if (GET_CODE (x
) == CONST_DOUBLE
&&
16246 (GET_MODE (x
) == TFmode
|| GET_MODE (x
) == TDmode
))
16248 REAL_VALUE_TYPE rv
;
16251 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
16252 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
16253 REAL_VALUE_TO_TARGET_DECIMAL128 (rv
, k
);
16255 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv
, k
);
16259 if (TARGET_MINIMAL_TOC
)
16260 fputs (DOUBLE_INT_ASM_OP
, file
);
16262 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16263 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16264 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16265 fprintf (file
, "0x%lx%08lx,0x%lx%08lx\n",
16266 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16267 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16272 if (TARGET_MINIMAL_TOC
)
16273 fputs ("\t.long ", file
);
16275 fprintf (file
, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
16276 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16277 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16278 fprintf (file
, "0x%lx,0x%lx,0x%lx,0x%lx\n",
16279 k
[0] & 0xffffffff, k
[1] & 0xffffffff,
16280 k
[2] & 0xffffffff, k
[3] & 0xffffffff);
16284 else if (GET_CODE (x
) == CONST_DOUBLE
&&
16285 (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DDmode
))
16287 REAL_VALUE_TYPE rv
;
16290 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
16292 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
16293 REAL_VALUE_TO_TARGET_DECIMAL64 (rv
, k
);
16295 REAL_VALUE_TO_TARGET_DOUBLE (rv
, k
);
16299 if (TARGET_MINIMAL_TOC
)
16300 fputs (DOUBLE_INT_ASM_OP
, file
);
16302 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
16303 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16304 fprintf (file
, "0x%lx%08lx\n",
16305 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16310 if (TARGET_MINIMAL_TOC
)
16311 fputs ("\t.long ", file
);
16313 fprintf (file
, "\t.tc FD_%lx_%lx[TC],",
16314 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16315 fprintf (file
, "0x%lx,0x%lx\n",
16316 k
[0] & 0xffffffff, k
[1] & 0xffffffff);
16320 else if (GET_CODE (x
) == CONST_DOUBLE
&&
16321 (GET_MODE (x
) == SFmode
|| GET_MODE (x
) == SDmode
))
16323 REAL_VALUE_TYPE rv
;
16326 REAL_VALUE_FROM_CONST_DOUBLE (rv
, x
);
16327 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x
)))
16328 REAL_VALUE_TO_TARGET_DECIMAL32 (rv
, l
);
16330 REAL_VALUE_TO_TARGET_SINGLE (rv
, l
);
16334 if (TARGET_MINIMAL_TOC
)
16335 fputs (DOUBLE_INT_ASM_OP
, file
);
16337 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
16338 fprintf (file
, "0x%lx00000000\n", l
& 0xffffffff);
16343 if (TARGET_MINIMAL_TOC
)
16344 fputs ("\t.long ", file
);
16346 fprintf (file
, "\t.tc FS_%lx[TC],", l
& 0xffffffff);
16347 fprintf (file
, "0x%lx\n", l
& 0xffffffff);
16351 else if (GET_MODE (x
) == VOIDmode
16352 && (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
))
16354 unsigned HOST_WIDE_INT low
;
16355 HOST_WIDE_INT high
;
16357 if (GET_CODE (x
) == CONST_DOUBLE
)
16359 low
= CONST_DOUBLE_LOW (x
);
16360 high
= CONST_DOUBLE_HIGH (x
);
16363 #if HOST_BITS_PER_WIDE_INT == 32
16366 high
= (low
& 0x80000000) ? ~0 : 0;
16370 low
= INTVAL (x
) & 0xffffffff;
16371 high
= (HOST_WIDE_INT
) INTVAL (x
) >> 32;
16375 /* TOC entries are always Pmode-sized, but since this
16376 is a bigendian machine then if we're putting smaller
16377 integer constants in the TOC we have to pad them.
16378 (This is still a win over putting the constants in
16379 a separate constant pool, because then we'd have
16380 to have both a TOC entry _and_ the actual constant.)
16382 For a 32-bit target, CONST_INT values are loaded and shifted
16383 entirely within `low' and can be stored in one TOC entry. */
16385 /* It would be easy to make this work, but it doesn't now. */
16386 gcc_assert (!TARGET_64BIT
|| POINTER_SIZE
>= GET_MODE_BITSIZE (mode
));
16388 if (POINTER_SIZE
> GET_MODE_BITSIZE (mode
))
16390 #if HOST_BITS_PER_WIDE_INT == 32
16391 lshift_double (low
, high
, POINTER_SIZE
- GET_MODE_BITSIZE (mode
),
16392 POINTER_SIZE
, &low
, &high
, 0);
16395 low
<<= POINTER_SIZE
- GET_MODE_BITSIZE (mode
);
16396 high
= (HOST_WIDE_INT
) low
>> 32;
16403 if (TARGET_MINIMAL_TOC
)
16404 fputs (DOUBLE_INT_ASM_OP
, file
);
16406 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
16407 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16408 fprintf (file
, "0x%lx%08lx\n",
16409 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16414 if (POINTER_SIZE
< GET_MODE_BITSIZE (mode
))
16416 if (TARGET_MINIMAL_TOC
)
16417 fputs ("\t.long ", file
);
16419 fprintf (file
, "\t.tc ID_%lx_%lx[TC],",
16420 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16421 fprintf (file
, "0x%lx,0x%lx\n",
16422 (long) high
& 0xffffffff, (long) low
& 0xffffffff);
16426 if (TARGET_MINIMAL_TOC
)
16427 fputs ("\t.long ", file
);
16429 fprintf (file
, "\t.tc IS_%lx[TC],", (long) low
& 0xffffffff);
16430 fprintf (file
, "0x%lx\n", (long) low
& 0xffffffff);
16436 if (GET_CODE (x
) == CONST
)
16438 gcc_assert (GET_CODE (XEXP (x
, 0)) == PLUS
);
16440 base
= XEXP (XEXP (x
, 0), 0);
16441 offset
= INTVAL (XEXP (XEXP (x
, 0), 1));
16444 switch (GET_CODE (base
))
16447 name
= XSTR (base
, 0);
16451 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
16452 CODE_LABEL_NUMBER (XEXP (base
, 0)));
16456 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (base
));
16460 gcc_unreachable ();
16463 real_name
= (*targetm
.strip_name_encoding
) (name
);
16464 if (TARGET_MINIMAL_TOC
)
16465 fputs (TARGET_32BIT
? "\t.long " : DOUBLE_INT_ASM_OP
, file
);
16468 fprintf (file
, "\t.tc %s", real_name
);
16471 fprintf (file
, ".N" HOST_WIDE_INT_PRINT_UNSIGNED
, - offset
);
16473 fprintf (file
, ".P" HOST_WIDE_INT_PRINT_UNSIGNED
, offset
);
16475 fputs ("[TC],", file
);
16478 /* Currently C++ toc references to vtables can be emitted before it
16479 is decided whether the vtable is public or private. If this is
16480 the case, then the linker will eventually complain that there is
16481 a TOC reference to an unknown section. Thus, for vtables only,
16482 we emit the TOC reference to reference the symbol and not the
16484 if (VTABLE_NAME_P (name
))
16486 RS6000_OUTPUT_BASENAME (file
, name
);
16488 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, offset
);
16489 else if (offset
> 0)
16490 fprintf (file
, "+" HOST_WIDE_INT_PRINT_DEC
, offset
);
16493 output_addr_const (file
, x
);
16497 /* Output an assembler pseudo-op to write an ASCII string of N characters
16498 starting at P to FILE.
16500 On the RS/6000, we have to do this using the .byte operation and
16501 write out special characters outside the quoted string.
16502 Also, the assembler is broken; very long strings are truncated,
16503 so we must artificially break them up early. */
16506 output_ascii (FILE *file
, const char *p
, int n
)
16509 int i
, count_string
;
16510 const char *for_string
= "\t.byte \"";
16511 const char *for_decimal
= "\t.byte ";
16512 const char *to_close
= NULL
;
16515 for (i
= 0; i
< n
; i
++)
16518 if (c
>= ' ' && c
< 0177)
16521 fputs (for_string
, file
);
16524 /* Write two quotes to get one. */
16532 for_decimal
= "\"\n\t.byte ";
16536 if (count_string
>= 512)
16538 fputs (to_close
, file
);
16540 for_string
= "\t.byte \"";
16541 for_decimal
= "\t.byte ";
16549 fputs (for_decimal
, file
);
16550 fprintf (file
, "%d", c
);
16552 for_string
= "\n\t.byte \"";
16553 for_decimal
= ", ";
16559 /* Now close the string if we have written one. Then end the line. */
16561 fputs (to_close
, file
);
16564 /* Generate a unique section name for FILENAME for a section type
16565 represented by SECTION_DESC. Output goes into BUF.
16567 SECTION_DESC can be any string, as long as it is different for each
16568 possible section type.
16570 We name the section in the same manner as xlc. The name begins with an
16571 underscore followed by the filename (after stripping any leading directory
16572 names) with the last period replaced by the string SECTION_DESC. If
16573 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16577 rs6000_gen_section_name (char **buf
, const char *filename
,
16578 const char *section_desc
)
16580 const char *q
, *after_last_slash
, *last_period
= 0;
16584 after_last_slash
= filename
;
16585 for (q
= filename
; *q
; q
++)
16588 after_last_slash
= q
+ 1;
16589 else if (*q
== '.')
16593 len
= strlen (after_last_slash
) + strlen (section_desc
) + 2;
16594 *buf
= (char *) xmalloc (len
);
16599 for (q
= after_last_slash
; *q
; q
++)
16601 if (q
== last_period
)
16603 strcpy (p
, section_desc
);
16604 p
+= strlen (section_desc
);
16608 else if (ISALNUM (*q
))
16612 if (last_period
== 0)
16613 strcpy (p
, section_desc
);
16618 /* Emit profile function. */
16621 output_profile_hook (int labelno ATTRIBUTE_UNUSED
)
16623 /* Non-standard profiling for kernels, which just saves LR then calls
16624 _mcount without worrying about arg saves. The idea is to change
16625 the function prologue as little as possible as it isn't easy to
16626 account for arg save/restore code added just for _mcount. */
16627 if (TARGET_PROFILE_KERNEL
)
16630 if (DEFAULT_ABI
== ABI_AIX
)
16632 #ifndef NO_PROFILE_COUNTERS
16633 # define NO_PROFILE_COUNTERS 0
16635 if (NO_PROFILE_COUNTERS
)
16636 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 0);
16640 const char *label_name
;
16643 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16644 label_name
= (*targetm
.strip_name_encoding
) (ggc_strdup (buf
));
16645 fun
= gen_rtx_SYMBOL_REF (Pmode
, label_name
);
16647 emit_library_call (init_one_libfunc (RS6000_MCOUNT
), 0, VOIDmode
, 1,
16651 else if (DEFAULT_ABI
== ABI_DARWIN
)
16653 const char *mcount_name
= RS6000_MCOUNT
;
16654 int caller_addr_regno
= LINK_REGISTER_REGNUM
;
16656 /* Be conservative and always set this, at least for now. */
16657 current_function_uses_pic_offset_table
= 1;
16660 /* For PIC code, set up a stub and collect the caller's address
16661 from r0, which is where the prologue puts it. */
16662 if (MACHOPIC_INDIRECT
16663 && current_function_uses_pic_offset_table
)
16664 caller_addr_regno
= 0;
16666 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, mcount_name
),
16668 gen_rtx_REG (Pmode
, caller_addr_regno
), Pmode
);
16672 /* Write function profiler code. */
16675 output_function_profiler (FILE *file
, int labelno
)
16679 switch (DEFAULT_ABI
)
16682 gcc_unreachable ();
16687 warning (0, "no profiling of 64-bit code for this ABI");
16690 ASM_GENERATE_INTERNAL_LABEL (buf
, "LP", labelno
);
16691 fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16692 if (NO_PROFILE_COUNTERS
)
16694 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16695 reg_names
[0], reg_names
[1]);
16697 else if (TARGET_SECURE_PLT
&& flag_pic
)
16699 asm_fprintf (file
, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16700 reg_names
[0], reg_names
[1]);
16701 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16702 asm_fprintf (file
, "\t{cau|addis} %s,%s,",
16703 reg_names
[12], reg_names
[12]);
16704 assemble_name (file
, buf
);
16705 asm_fprintf (file
, "-1b@ha\n\t{cal|la} %s,", reg_names
[0]);
16706 assemble_name (file
, buf
);
16707 asm_fprintf (file
, "-1b@l(%s)\n", reg_names
[12]);
16709 else if (flag_pic
== 1)
16711 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file
);
16712 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16713 reg_names
[0], reg_names
[1]);
16714 asm_fprintf (file
, "\tmflr %s\n", reg_names
[12]);
16715 asm_fprintf (file
, "\t{l|lwz} %s,", reg_names
[0]);
16716 assemble_name (file
, buf
);
16717 asm_fprintf (file
, "@got(%s)\n", reg_names
[12]);
16719 else if (flag_pic
> 1)
16721 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16722 reg_names
[0], reg_names
[1]);
16723 /* Now, we need to get the address of the label. */
16724 fputs ("\tbcl 20,31,1f\n\t.long ", file
);
16725 assemble_name (file
, buf
);
16726 fputs ("-.\n1:", file
);
16727 asm_fprintf (file
, "\tmflr %s\n", reg_names
[11]);
16728 asm_fprintf (file
, "\t{l|lwz} %s,0(%s)\n",
16729 reg_names
[0], reg_names
[11]);
16730 asm_fprintf (file
, "\t{cax|add} %s,%s,%s\n",
16731 reg_names
[0], reg_names
[0], reg_names
[11]);
16735 asm_fprintf (file
, "\t{liu|lis} %s,", reg_names
[12]);
16736 assemble_name (file
, buf
);
16737 fputs ("@ha\n", file
);
16738 asm_fprintf (file
, "\t{st|stw} %s,4(%s)\n",
16739 reg_names
[0], reg_names
[1]);
16740 asm_fprintf (file
, "\t{cal|la} %s,", reg_names
[0]);
16741 assemble_name (file
, buf
);
16742 asm_fprintf (file
, "@l(%s)\n", reg_names
[12]);
16745 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
16746 fprintf (file
, "\tbl %s%s\n",
16747 RS6000_MCOUNT
, flag_pic
? "@plt" : "");
16752 if (!TARGET_PROFILE_KERNEL
)
16754 /* Don't do anything, done in output_profile_hook (). */
16758 gcc_assert (!TARGET_32BIT
);
16760 asm_fprintf (file
, "\tmflr %s\n", reg_names
[0]);
16761 asm_fprintf (file
, "\tstd %s,16(%s)\n", reg_names
[0], reg_names
[1]);
16763 if (cfun
->static_chain_decl
!= NULL
)
16765 asm_fprintf (file
, "\tstd %s,24(%s)\n",
16766 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16767 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16768 asm_fprintf (file
, "\tld %s,24(%s)\n",
16769 reg_names
[STATIC_CHAIN_REGNUM
], reg_names
[1]);
16772 fprintf (file
, "\tbl %s\n", RS6000_MCOUNT
);
16780 /* The following variable value is the last issued insn. */
16782 static rtx last_scheduled_insn
;
16784 /* The following variable helps to balance issuing of load and
16785 store instructions */
16787 static int load_store_pendulum
;
16789 /* Power4 load update and store update instructions are cracked into a
16790 load or store and an integer insn which are executed in the same cycle.
16791 Branches have their own dispatch slot which does not count against the
16792 GCC issue rate, but it changes the program flow so there are no other
16793 instructions to issue in this cycle. */
16796 rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED
,
16797 int verbose ATTRIBUTE_UNUSED
,
16798 rtx insn
, int more
)
16800 last_scheduled_insn
= insn
;
16801 if (GET_CODE (PATTERN (insn
)) == USE
16802 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
16804 cached_can_issue_more
= more
;
16805 return cached_can_issue_more
;
16808 if (insn_terminates_group_p (insn
, current_group
))
16810 cached_can_issue_more
= 0;
16811 return cached_can_issue_more
;
16814 /* If no reservation, but reach here */
16815 if (recog_memoized (insn
) < 0)
16818 if (rs6000_sched_groups
)
16820 if (is_microcoded_insn (insn
))
16821 cached_can_issue_more
= 0;
16822 else if (is_cracked_insn (insn
))
16823 cached_can_issue_more
= more
> 2 ? more
- 2 : 0;
16825 cached_can_issue_more
= more
- 1;
16827 return cached_can_issue_more
;
16830 if (rs6000_cpu_attr
== CPU_CELL
&& is_nonpipeline_insn (insn
))
16833 cached_can_issue_more
= more
- 1;
16834 return cached_can_issue_more
;
16837 /* Adjust the cost of a scheduling dependency. Return the new cost of
16838 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16841 rs6000_adjust_cost (rtx insn
, rtx link
, rtx dep_insn
, int cost
)
16843 enum attr_type attr_type
;
16845 if (! recog_memoized (insn
))
16848 switch (REG_NOTE_KIND (link
))
16852 /* Data dependency; DEP_INSN writes a register that INSN reads
16853 some cycles later. */
16855 /* Separate a load from a narrower, dependent store. */
16856 if (rs6000_sched_groups
16857 && GET_CODE (PATTERN (insn
)) == SET
16858 && GET_CODE (PATTERN (dep_insn
)) == SET
16859 && GET_CODE (XEXP (PATTERN (insn
), 1)) == MEM
16860 && GET_CODE (XEXP (PATTERN (dep_insn
), 0)) == MEM
16861 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn
), 1)))
16862 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn
), 0)))))
16865 attr_type
= get_attr_type (insn
);
16870 /* Tell the first scheduling pass about the latency between
16871 a mtctr and bctr (and mtlr and br/blr). The first
16872 scheduling pass will not know about this latency since
16873 the mtctr instruction, which has the latency associated
16874 to it, will be generated by reload. */
16875 return TARGET_POWER
? 5 : 4;
16877 /* Leave some extra cycles between a compare and its
16878 dependent branch, to inhibit expensive mispredicts. */
16879 if ((rs6000_cpu_attr
== CPU_PPC603
16880 || rs6000_cpu_attr
== CPU_PPC604
16881 || rs6000_cpu_attr
== CPU_PPC604E
16882 || rs6000_cpu_attr
== CPU_PPC620
16883 || rs6000_cpu_attr
== CPU_PPC630
16884 || rs6000_cpu_attr
== CPU_PPC750
16885 || rs6000_cpu_attr
== CPU_PPC7400
16886 || rs6000_cpu_attr
== CPU_PPC7450
16887 || rs6000_cpu_attr
== CPU_POWER4
16888 || rs6000_cpu_attr
== CPU_POWER5
16889 || rs6000_cpu_attr
== CPU_CELL
)
16890 && recog_memoized (dep_insn
)
16891 && (INSN_CODE (dep_insn
) >= 0))
16893 switch (get_attr_type (dep_insn
))
16897 case TYPE_DELAYED_COMPARE
:
16898 case TYPE_IMUL_COMPARE
:
16899 case TYPE_LMUL_COMPARE
:
16900 case TYPE_FPCOMPARE
:
16901 case TYPE_CR_LOGICAL
:
16902 case TYPE_DELAYED_CR
:
16911 case TYPE_STORE_UX
:
16913 case TYPE_FPSTORE_U
:
16914 case TYPE_FPSTORE_UX
:
16915 if ((rs6000_cpu
== PROCESSOR_POWER6
)
16916 && recog_memoized (dep_insn
)
16917 && (INSN_CODE (dep_insn
) >= 0))
16920 if (GET_CODE (PATTERN (insn
)) != SET
)
16921 /* If this happens, we have to extend this to schedule
16922 optimally. Return default for now. */
16925 /* Adjust the cost for the case where the value written
16926 by a fixed point operation is used as the address
16927 gen value on a store. */
16928 switch (get_attr_type (dep_insn
))
16935 if (! store_data_bypass_p (dep_insn
, insn
))
16939 case TYPE_LOAD_EXT
:
16940 case TYPE_LOAD_EXT_U
:
16941 case TYPE_LOAD_EXT_UX
:
16942 case TYPE_VAR_SHIFT_ROTATE
:
16943 case TYPE_VAR_DELAYED_COMPARE
:
16945 if (! store_data_bypass_p (dep_insn
, insn
))
16951 case TYPE_FAST_COMPARE
:
16954 case TYPE_INSERT_WORD
:
16955 case TYPE_INSERT_DWORD
:
16956 case TYPE_FPLOAD_U
:
16957 case TYPE_FPLOAD_UX
:
16959 case TYPE_STORE_UX
:
16960 case TYPE_FPSTORE_U
:
16961 case TYPE_FPSTORE_UX
:
16963 if (! store_data_bypass_p (dep_insn
, insn
))
16971 case TYPE_IMUL_COMPARE
:
16972 case TYPE_LMUL_COMPARE
:
16974 if (! store_data_bypass_p (dep_insn
, insn
))
16980 if (! store_data_bypass_p (dep_insn
, insn
))
16986 if (! store_data_bypass_p (dep_insn
, insn
))
16999 case TYPE_LOAD_EXT
:
17000 case TYPE_LOAD_EXT_U
:
17001 case TYPE_LOAD_EXT_UX
:
17002 if ((rs6000_cpu
== PROCESSOR_POWER6
)
17003 && recog_memoized (dep_insn
)
17004 && (INSN_CODE (dep_insn
) >= 0))
17007 /* Adjust the cost for the case where the value written
17008 by a fixed point instruction is used within the address
17009 gen portion of a subsequent load(u)(x) */
17010 switch (get_attr_type (dep_insn
))
17017 if (set_to_load_agen (dep_insn
, insn
))
17021 case TYPE_LOAD_EXT
:
17022 case TYPE_LOAD_EXT_U
:
17023 case TYPE_LOAD_EXT_UX
:
17024 case TYPE_VAR_SHIFT_ROTATE
:
17025 case TYPE_VAR_DELAYED_COMPARE
:
17027 if (set_to_load_agen (dep_insn
, insn
))
17033 case TYPE_FAST_COMPARE
:
17036 case TYPE_INSERT_WORD
:
17037 case TYPE_INSERT_DWORD
:
17038 case TYPE_FPLOAD_U
:
17039 case TYPE_FPLOAD_UX
:
17041 case TYPE_STORE_UX
:
17042 case TYPE_FPSTORE_U
:
17043 case TYPE_FPSTORE_UX
:
17045 if (set_to_load_agen (dep_insn
, insn
))
17053 case TYPE_IMUL_COMPARE
:
17054 case TYPE_LMUL_COMPARE
:
17056 if (set_to_load_agen (dep_insn
, insn
))
17062 if (set_to_load_agen (dep_insn
, insn
))
17068 if (set_to_load_agen (dep_insn
, insn
))
17079 if ((rs6000_cpu
== PROCESSOR_POWER6
)
17080 && recog_memoized (dep_insn
)
17081 && (INSN_CODE (dep_insn
) >= 0)
17082 && (get_attr_type (dep_insn
) == TYPE_MFFGPR
))
17089 /* Fall out to return default cost. */
17093 case REG_DEP_OUTPUT
:
17094 /* Output dependency; DEP_INSN writes a register that INSN writes some
17096 if ((rs6000_cpu
== PROCESSOR_POWER6
)
17097 && recog_memoized (dep_insn
)
17098 && (INSN_CODE (dep_insn
) >= 0))
17100 attr_type
= get_attr_type (insn
);
17105 if (get_attr_type (dep_insn
) == TYPE_FP
)
17109 if (get_attr_type (dep_insn
) == TYPE_MFFGPR
)
17117 /* Anti dependency; DEP_INSN reads a register that INSN writes some
17122 gcc_unreachable ();
17128 /* The function returns a true if INSN is microcoded.
17129 Return false otherwise. */
17132 is_microcoded_insn (rtx insn
)
17134 if (!insn
|| !INSN_P (insn
)
17135 || GET_CODE (PATTERN (insn
)) == USE
17136 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17139 if (rs6000_cpu_attr
== CPU_CELL
)
17140 return get_attr_cell_micro (insn
) == CELL_MICRO_ALWAYS
;
17142 if (rs6000_sched_groups
)
17144 enum attr_type type
= get_attr_type (insn
);
17145 if (type
== TYPE_LOAD_EXT_U
17146 || type
== TYPE_LOAD_EXT_UX
17147 || type
== TYPE_LOAD_UX
17148 || type
== TYPE_STORE_UX
17149 || type
== TYPE_MFCR
)
17156 /* The function returns true if INSN is cracked into 2 instructions
17157 by the processor (and therefore occupies 2 issue slots). */
17160 is_cracked_insn (rtx insn
)
17162 if (!insn
|| !INSN_P (insn
)
17163 || GET_CODE (PATTERN (insn
)) == USE
17164 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17167 if (rs6000_sched_groups
)
17169 enum attr_type type
= get_attr_type (insn
);
17170 if (type
== TYPE_LOAD_U
|| type
== TYPE_STORE_U
17171 || type
== TYPE_FPLOAD_U
|| type
== TYPE_FPSTORE_U
17172 || type
== TYPE_FPLOAD_UX
|| type
== TYPE_FPSTORE_UX
17173 || type
== TYPE_LOAD_EXT
|| type
== TYPE_DELAYED_CR
17174 || type
== TYPE_COMPARE
|| type
== TYPE_DELAYED_COMPARE
17175 || type
== TYPE_IMUL_COMPARE
|| type
== TYPE_LMUL_COMPARE
17176 || type
== TYPE_IDIV
|| type
== TYPE_LDIV
17177 || type
== TYPE_INSERT_WORD
)
17184 /* The function returns true if INSN can be issued only from
17185 the branch slot. */
17188 is_branch_slot_insn (rtx insn
)
17190 if (!insn
|| !INSN_P (insn
)
17191 || GET_CODE (PATTERN (insn
)) == USE
17192 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17195 if (rs6000_sched_groups
)
17197 enum attr_type type
= get_attr_type (insn
);
17198 if (type
== TYPE_BRANCH
|| type
== TYPE_JMPREG
)
17206 /* The function returns true if out_inst sets a value that is
17207 used in the address generation computation of in_insn */
17209 set_to_load_agen (rtx out_insn
, rtx in_insn
)
17211 rtx out_set
, in_set
;
17213 /* For performance reasons, only handle the simple case where
17214 both loads are a single_set. */
17215 out_set
= single_set (out_insn
);
17218 in_set
= single_set (in_insn
);
17220 return reg_mentioned_p (SET_DEST (out_set
), SET_SRC (in_set
));
17226 /* The function returns true if the target storage location of
17227 out_insn is adjacent to the target storage location of in_insn */
17228 /* Return 1 if memory locations are adjacent. */
17231 adjacent_mem_locations (rtx insn1
, rtx insn2
)
17234 rtx a
= get_store_dest (PATTERN (insn1
));
17235 rtx b
= get_store_dest (PATTERN (insn2
));
17237 if ((GET_CODE (XEXP (a
, 0)) == REG
17238 || (GET_CODE (XEXP (a
, 0)) == PLUS
17239 && GET_CODE (XEXP (XEXP (a
, 0), 1)) == CONST_INT
))
17240 && (GET_CODE (XEXP (b
, 0)) == REG
17241 || (GET_CODE (XEXP (b
, 0)) == PLUS
17242 && GET_CODE (XEXP (XEXP (b
, 0), 1)) == CONST_INT
)))
17244 HOST_WIDE_INT val0
= 0, val1
= 0;
17248 if (GET_CODE (XEXP (a
, 0)) == PLUS
)
17250 reg0
= XEXP (XEXP (a
, 0), 0);
17251 val0
= INTVAL (XEXP (XEXP (a
, 0), 1));
17254 reg0
= XEXP (a
, 0);
17256 if (GET_CODE (XEXP (b
, 0)) == PLUS
)
17258 reg1
= XEXP (XEXP (b
, 0), 0);
17259 val1
= INTVAL (XEXP (XEXP (b
, 0), 1));
17262 reg1
= XEXP (b
, 0);
17264 val_diff
= val1
- val0
;
17266 return ((REGNO (reg0
) == REGNO (reg1
))
17267 && (val_diff
== INTVAL (MEM_SIZE (a
))
17268 || val_diff
== -INTVAL (MEM_SIZE (b
))));
17274 /* A C statement (sans semicolon) to update the integer scheduling
17275 priority INSN_PRIORITY (INSN). Increase the priority to execute the
17276 INSN earlier, reduce the priority to execute INSN later. Do not
17277 define this macro if you do not need to adjust the scheduling
17278 priorities of insns. */
17281 rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED
, int priority
)
17283 /* On machines (like the 750) which have asymmetric integer units,
17284 where one integer unit can do multiply and divides and the other
17285 can't, reduce the priority of multiply/divide so it is scheduled
17286 before other integer operations. */
17289 if (! INSN_P (insn
))
17292 if (GET_CODE (PATTERN (insn
)) == USE
)
17295 switch (rs6000_cpu_attr
) {
17297 switch (get_attr_type (insn
))
17304 fprintf (stderr
, "priority was %#x (%d) before adjustment\n",
17305 priority
, priority
);
17306 if (priority
>= 0 && priority
< 0x01000000)
17313 if (insn_must_be_first_in_group (insn
)
17314 && reload_completed
17315 && current_sched_info
->sched_max_insns_priority
17316 && rs6000_sched_restricted_insns_priority
)
17319 /* Prioritize insns that can be dispatched only in the first
17321 if (rs6000_sched_restricted_insns_priority
== 1)
17322 /* Attach highest priority to insn. This means that in
17323 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
17324 precede 'priority' (critical path) considerations. */
17325 return current_sched_info
->sched_max_insns_priority
;
17326 else if (rs6000_sched_restricted_insns_priority
== 2)
17327 /* Increase priority of insn by a minimal amount. This means that in
17328 haifa-sched.c:ready_sort(), only 'priority' (critical path)
17329 considerations precede dispatch-slot restriction considerations. */
17330 return (priority
+ 1);
17333 if (rs6000_cpu
== PROCESSOR_POWER6
17334 && ((load_store_pendulum
== -2 && is_load_insn (insn
))
17335 || (load_store_pendulum
== 2 && is_store_insn (insn
))))
17336 /* Attach highest priority to insn if the scheduler has just issued two
17337 stores and this instruction is a load, or two loads and this instruction
17338 is a store. Power6 wants loads and stores scheduled alternately
17340 return current_sched_info
->sched_max_insns_priority
;
17345 /* Return true if the instruction is nonpipelined on the Cell. */
17347 is_nonpipeline_insn (rtx insn
)
17349 enum attr_type type
;
17350 if (!insn
|| !INSN_P (insn
)
17351 || GET_CODE (PATTERN (insn
)) == USE
17352 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17355 type
= get_attr_type (insn
);
17356 if (type
== TYPE_IMUL
17357 || type
== TYPE_IMUL2
17358 || type
== TYPE_IMUL3
17359 || type
== TYPE_LMUL
17360 || type
== TYPE_IDIV
17361 || type
== TYPE_LDIV
17362 || type
== TYPE_SDIV
17363 || type
== TYPE_DDIV
17364 || type
== TYPE_SSQRT
17365 || type
== TYPE_DSQRT
17366 || type
== TYPE_MFCR
17367 || type
== TYPE_MFCRF
17368 || type
== TYPE_MFJMPR
)
17376 /* Return how many instructions the machine can issue per cycle. */
17379 rs6000_issue_rate (void)
17381 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
17382 if (!reload_completed
)
17385 switch (rs6000_cpu_attr
) {
17386 case CPU_RIOS1
: /* ? */
17388 case CPU_PPC601
: /* ? */
17413 /* Return how many instructions to look ahead for better insn
17417 rs6000_use_sched_lookahead (void)
17419 if (rs6000_cpu_attr
== CPU_PPC8540
)
17421 if (rs6000_cpu_attr
== CPU_CELL
)
17422 return (reload_completed
? 8 : 0);
17426 /* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
17428 rs6000_use_sched_lookahead_guard (rtx insn
)
17430 if (rs6000_cpu_attr
!= CPU_CELL
)
17433 if (insn
== NULL_RTX
|| !INSN_P (insn
))
17436 if (!reload_completed
17437 || is_nonpipeline_insn (insn
)
17438 || is_microcoded_insn (insn
))
17444 /* Determine is PAT refers to memory. */
17447 is_mem_ref (rtx pat
)
17453 if (GET_CODE (pat
) == MEM
)
17456 /* Recursively process the pattern. */
17457 fmt
= GET_RTX_FORMAT (GET_CODE (pat
));
17459 for (i
= GET_RTX_LENGTH (GET_CODE (pat
)) - 1; i
>= 0 && !ret
; i
--)
17462 ret
|= is_mem_ref (XEXP (pat
, i
));
17463 else if (fmt
[i
] == 'E')
17464 for (j
= XVECLEN (pat
, i
) - 1; j
>= 0; j
--)
17465 ret
|= is_mem_ref (XVECEXP (pat
, i
, j
));
17471 /* Determine if PAT is a PATTERN of a load insn. */
17474 is_load_insn1 (rtx pat
)
17476 if (!pat
|| pat
== NULL_RTX
)
17479 if (GET_CODE (pat
) == SET
)
17480 return is_mem_ref (SET_SRC (pat
));
17482 if (GET_CODE (pat
) == PARALLEL
)
17486 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
17487 if (is_load_insn1 (XVECEXP (pat
, 0, i
)))
17494 /* Determine if INSN loads from memory. */
17497 is_load_insn (rtx insn
)
17499 if (!insn
|| !INSN_P (insn
))
17502 if (GET_CODE (insn
) == CALL_INSN
)
17505 return is_load_insn1 (PATTERN (insn
));
17508 /* Determine if PAT is a PATTERN of a store insn. */
17511 is_store_insn1 (rtx pat
)
17513 if (!pat
|| pat
== NULL_RTX
)
17516 if (GET_CODE (pat
) == SET
)
17517 return is_mem_ref (SET_DEST (pat
));
17519 if (GET_CODE (pat
) == PARALLEL
)
17523 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
17524 if (is_store_insn1 (XVECEXP (pat
, 0, i
)))
17531 /* Determine if INSN stores to memory. */
17534 is_store_insn (rtx insn
)
17536 if (!insn
|| !INSN_P (insn
))
17539 return is_store_insn1 (PATTERN (insn
));
17542 /* Return the dest of a store insn. */
17545 get_store_dest (rtx pat
)
17547 gcc_assert (is_store_insn1 (pat
));
17549 if (GET_CODE (pat
) == SET
)
17550 return SET_DEST (pat
);
17551 else if (GET_CODE (pat
) == PARALLEL
)
17555 for (i
= 0; i
< XVECLEN (pat
, 0); i
++)
17557 rtx inner_pat
= XVECEXP (pat
, 0, i
);
17558 if (GET_CODE (inner_pat
) == SET
17559 && is_mem_ref (SET_DEST (inner_pat
)))
17563 /* We shouldn't get here, because we should have either a simple
17564 store insn or a store with update which are covered above. */
17568 /* Returns whether the dependence between INSN and NEXT is considered
17569 costly by the given target. */
17572 rs6000_is_costly_dependence (dep_t dep
, int cost
, int distance
)
17577 /* If the flag is not enabled - no dependence is considered costly;
17578 allow all dependent insns in the same group.
17579 This is the most aggressive option. */
17580 if (rs6000_sched_costly_dep
== no_dep_costly
)
17583 /* If the flag is set to 1 - a dependence is always considered costly;
17584 do not allow dependent instructions in the same group.
17585 This is the most conservative option. */
17586 if (rs6000_sched_costly_dep
== all_deps_costly
)
17589 insn
= DEP_PRO (dep
);
17590 next
= DEP_CON (dep
);
17592 if (rs6000_sched_costly_dep
== store_to_load_dep_costly
17593 && is_load_insn (next
)
17594 && is_store_insn (insn
))
17595 /* Prevent load after store in the same group. */
17598 if (rs6000_sched_costly_dep
== true_store_to_load_dep_costly
17599 && is_load_insn (next
)
17600 && is_store_insn (insn
)
17601 && DEP_KIND (dep
) == REG_DEP_TRUE
)
17602 /* Prevent load after store in the same group if it is a true
17606 /* The flag is set to X; dependences with latency >= X are considered costly,
17607 and will not be scheduled in the same group. */
17608 if (rs6000_sched_costly_dep
<= max_dep_latency
17609 && ((cost
- distance
) >= (int)rs6000_sched_costly_dep
))
17615 /* Return the next insn after INSN that is found before TAIL is reached,
17616 skipping any "non-active" insns - insns that will not actually occupy
17617 an issue slot. Return NULL_RTX if such an insn is not found. */
17620 get_next_active_insn (rtx insn
, rtx tail
)
17622 if (insn
== NULL_RTX
|| insn
== tail
)
17627 insn
= NEXT_INSN (insn
);
17628 if (insn
== NULL_RTX
|| insn
== tail
)
17633 || (NONJUMP_INSN_P (insn
)
17634 && GET_CODE (PATTERN (insn
)) != USE
17635 && GET_CODE (PATTERN (insn
)) != CLOBBER
17636 && INSN_CODE (insn
) != CODE_FOR_stack_tie
))
17642 /* We are about to begin issuing insns for this clock cycle. */
17645 rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED
, int sched_verbose
,
17646 rtx
*ready ATTRIBUTE_UNUSED
,
17647 int *pn_ready ATTRIBUTE_UNUSED
,
17648 int clock_var ATTRIBUTE_UNUSED
)
17650 int n_ready
= *pn_ready
;
17653 fprintf (dump
, "// rs6000_sched_reorder :\n");
17655 /* Reorder the ready list, if the second to last ready insn
17656 is a nonepipeline insn. */
17657 if (rs6000_cpu_attr
== CPU_CELL
&& n_ready
> 1)
17659 if (is_nonpipeline_insn (ready
[n_ready
- 1])
17660 && (recog_memoized (ready
[n_ready
- 2]) > 0))
17661 /* Simply swap first two insns. */
17663 rtx tmp
= ready
[n_ready
- 1];
17664 ready
[n_ready
- 1] = ready
[n_ready
- 2];
17665 ready
[n_ready
- 2] = tmp
;
17669 if (rs6000_cpu
== PROCESSOR_POWER6
)
17670 load_store_pendulum
= 0;
17672 return rs6000_issue_rate ();
17675 /* Like rs6000_sched_reorder, but called after issuing each insn. */
17678 rs6000_sched_reorder2 (FILE *dump
, int sched_verbose
, rtx
*ready
,
17679 int *pn_ready
, int clock_var ATTRIBUTE_UNUSED
)
17682 fprintf (dump
, "// rs6000_sched_reorder2 :\n");
17684 /* For Power6, we need to handle some special cases to try and keep the
17685 store queue from overflowing and triggering expensive flushes.
17687 This code monitors how load and store instructions are being issued
17688 and skews the ready list one way or the other to increase the likelihood
17689 that a desired instruction is issued at the proper time.
17691 A couple of things are done. First, we maintain a "load_store_pendulum"
17692 to track the current state of load/store issue.
17694 - If the pendulum is at zero, then no loads or stores have been
17695 issued in the current cycle so we do nothing.
17697 - If the pendulum is 1, then a single load has been issued in this
17698 cycle and we attempt to locate another load in the ready list to
17701 - If the pendulum is -2, then two stores have already been
17702 issued in this cycle, so we increase the priority of the first load
17703 in the ready list to increase it's likelihood of being chosen first
17706 - If the pendulum is -1, then a single store has been issued in this
17707 cycle and we attempt to locate another store in the ready list to
17708 issue with it, preferring a store to an adjacent memory location to
17709 facilitate store pairing in the store queue.
17711 - If the pendulum is 2, then two loads have already been
17712 issued in this cycle, so we increase the priority of the first store
17713 in the ready list to increase it's likelihood of being chosen first
17716 - If the pendulum < -2 or > 2, then do nothing.
17718 Note: This code covers the most common scenarios. There exist non
17719 load/store instructions which make use of the LSU and which
17720 would need to be accounted for to strictly model the behavior
17721 of the machine. Those instructions are currently unaccounted
17722 for to help minimize compile time overhead of this code.
17724 if (rs6000_cpu
== PROCESSOR_POWER6
&& last_scheduled_insn
)
17730 if (is_store_insn (last_scheduled_insn
))
17731 /* Issuing a store, swing the load_store_pendulum to the left */
17732 load_store_pendulum
--;
17733 else if (is_load_insn (last_scheduled_insn
))
17734 /* Issuing a load, swing the load_store_pendulum to the right */
17735 load_store_pendulum
++;
17737 return cached_can_issue_more
;
17739 /* If the pendulum is balanced, or there is only one instruction on
17740 the ready list, then all is well, so return. */
17741 if ((load_store_pendulum
== 0) || (*pn_ready
<= 1))
17742 return cached_can_issue_more
;
17744 if (load_store_pendulum
== 1)
17746 /* A load has been issued in this cycle. Scan the ready list
17747 for another load to issue with it */
17752 if (is_load_insn (ready
[pos
]))
17754 /* Found a load. Move it to the head of the ready list,
17755 and adjust it's priority so that it is more likely to
17758 for (i
=pos
; i
<*pn_ready
-1; i
++)
17759 ready
[i
] = ready
[i
+ 1];
17760 ready
[*pn_ready
-1] = tmp
;
17761 if INSN_PRIORITY_KNOWN (tmp
)
17762 INSN_PRIORITY (tmp
)++;
17768 else if (load_store_pendulum
== -2)
17770 /* Two stores have been issued in this cycle. Increase the
17771 priority of the first load in the ready list to favor it for
17772 issuing in the next cycle. */
17777 if (is_load_insn (ready
[pos
])
17778 && INSN_PRIORITY_KNOWN (ready
[pos
]))
17780 INSN_PRIORITY (ready
[pos
])++;
17782 /* Adjust the pendulum to account for the fact that a load
17783 was found and increased in priority. This is to prevent
17784 increasing the priority of multiple loads */
17785 load_store_pendulum
--;
17792 else if (load_store_pendulum
== -1)
17794 /* A store has been issued in this cycle. Scan the ready list for
17795 another store to issue with it, preferring a store to an adjacent
17797 int first_store_pos
= -1;
17803 if (is_store_insn (ready
[pos
]))
17805 /* Maintain the index of the first store found on the
17807 if (first_store_pos
== -1)
17808 first_store_pos
= pos
;
17810 if (is_store_insn (last_scheduled_insn
)
17811 && adjacent_mem_locations (last_scheduled_insn
,ready
[pos
]))
17813 /* Found an adjacent store. Move it to the head of the
17814 ready list, and adjust it's priority so that it is
17815 more likely to stay there */
17817 for (i
=pos
; i
<*pn_ready
-1; i
++)
17818 ready
[i
] = ready
[i
+ 1];
17819 ready
[*pn_ready
-1] = tmp
;
17820 if INSN_PRIORITY_KNOWN (tmp
)
17821 INSN_PRIORITY (tmp
)++;
17822 first_store_pos
= -1;
17830 if (first_store_pos
>= 0)
17832 /* An adjacent store wasn't found, but a non-adjacent store was,
17833 so move the non-adjacent store to the front of the ready
17834 list, and adjust its priority so that it is more likely to
17836 tmp
= ready
[first_store_pos
];
17837 for (i
=first_store_pos
; i
<*pn_ready
-1; i
++)
17838 ready
[i
] = ready
[i
+ 1];
17839 ready
[*pn_ready
-1] = tmp
;
17840 if INSN_PRIORITY_KNOWN (tmp
)
17841 INSN_PRIORITY (tmp
)++;
17844 else if (load_store_pendulum
== 2)
17846 /* Two loads have been issued in this cycle. Increase the priority
17847 of the first store in the ready list to favor it for issuing in
17853 if (is_store_insn (ready
[pos
])
17854 && INSN_PRIORITY_KNOWN (ready
[pos
]))
17856 INSN_PRIORITY (ready
[pos
])++;
17858 /* Adjust the pendulum to account for the fact that a store
17859 was found and increased in priority. This is to prevent
17860 increasing the priority of multiple stores */
17861 load_store_pendulum
++;
17870 return cached_can_issue_more
;
17873 /* Return whether the presence of INSN causes a dispatch group termination
17874 of group WHICH_GROUP.
17876 If WHICH_GROUP == current_group, this function will return true if INSN
17877 causes the termination of the current group (i.e, the dispatch group to
17878 which INSN belongs). This means that INSN will be the last insn in the
17879 group it belongs to.
17881 If WHICH_GROUP == previous_group, this function will return true if INSN
17882 causes the termination of the previous group (i.e, the dispatch group that
17883 precedes the group to which INSN belongs). This means that INSN will be
17884 the first insn in the group it belongs to). */
17887 insn_terminates_group_p (rtx insn
, enum group_termination which_group
)
17894 first
= insn_must_be_first_in_group (insn
);
17895 last
= insn_must_be_last_in_group (insn
);
17900 if (which_group
== current_group
)
17902 else if (which_group
== previous_group
)
17910 insn_must_be_first_in_group (rtx insn
)
17912 enum attr_type type
;
17915 || insn
== NULL_RTX
17916 || GET_CODE (insn
) == NOTE
17917 || GET_CODE (PATTERN (insn
)) == USE
17918 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
17921 switch (rs6000_cpu
)
17923 case PROCESSOR_POWER5
:
17924 if (is_cracked_insn (insn
))
17926 case PROCESSOR_POWER4
:
17927 if (is_microcoded_insn (insn
))
17930 if (!rs6000_sched_groups
)
17933 type
= get_attr_type (insn
);
17940 case TYPE_DELAYED_CR
:
17941 case TYPE_CR_LOGICAL
:
17955 case PROCESSOR_POWER6
:
17956 type
= get_attr_type (insn
);
17960 case TYPE_INSERT_DWORD
:
17964 case TYPE_VAR_SHIFT_ROTATE
:
17971 case TYPE_INSERT_WORD
:
17972 case TYPE_DELAYED_COMPARE
:
17973 case TYPE_IMUL_COMPARE
:
17974 case TYPE_LMUL_COMPARE
:
17975 case TYPE_FPCOMPARE
:
17986 case TYPE_LOAD_EXT_UX
:
17988 case TYPE_STORE_UX
:
17989 case TYPE_FPLOAD_U
:
17990 case TYPE_FPLOAD_UX
:
17991 case TYPE_FPSTORE_U
:
17992 case TYPE_FPSTORE_UX
:
18006 insn_must_be_last_in_group (rtx insn
)
18008 enum attr_type type
;
18011 || insn
== NULL_RTX
18012 || GET_CODE (insn
) == NOTE
18013 || GET_CODE (PATTERN (insn
)) == USE
18014 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
18017 switch (rs6000_cpu
) {
18018 case PROCESSOR_POWER4
:
18019 case PROCESSOR_POWER5
:
18020 if (is_microcoded_insn (insn
))
18023 if (is_branch_slot_insn (insn
))
18027 case PROCESSOR_POWER6
:
18028 type
= get_attr_type (insn
);
18035 case TYPE_VAR_SHIFT_ROTATE
:
18042 case TYPE_DELAYED_COMPARE
:
18043 case TYPE_IMUL_COMPARE
:
18044 case TYPE_LMUL_COMPARE
:
18045 case TYPE_FPCOMPARE
:
18066 /* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
18067 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
18070 is_costly_group (rtx
*group_insns
, rtx next_insn
)
18073 int issue_rate
= rs6000_issue_rate ();
18075 for (i
= 0; i
< issue_rate
; i
++)
18078 rtx insn
= group_insns
[i
];
18083 FOR_EACH_DEP_LINK (link
, INSN_FORW_DEPS (insn
))
18085 dep_t dep
= DEP_LINK_DEP (link
);
18086 rtx next
= DEP_CON (dep
);
18088 if (next
== next_insn
18089 && rs6000_is_costly_dependence (dep
, dep_cost (dep
), 0))
18097 /* Utility of the function redefine_groups.
18098 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
18099 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
18100 to keep it "far" (in a separate group) from GROUP_INSNS, following
18101 one of the following schemes, depending on the value of the flag
18102 -minsert_sched_nops = X:
18103 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
18104 in order to force NEXT_INSN into a separate group.
18105 (2) X < sched_finish_regroup_exact: insert exactly X nops.
18106 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
18107 insertion (has a group just ended, how many vacant issue slots remain in the
18108 last group, and how many dispatch groups were encountered so far). */
18111 force_new_group (int sched_verbose
, FILE *dump
, rtx
*group_insns
,
18112 rtx next_insn
, bool *group_end
, int can_issue_more
,
18117 int issue_rate
= rs6000_issue_rate ();
18118 bool end
= *group_end
;
18121 if (next_insn
== NULL_RTX
)
18122 return can_issue_more
;
18124 if (rs6000_sched_insert_nops
> sched_finish_regroup_exact
)
18125 return can_issue_more
;
18127 force
= is_costly_group (group_insns
, next_insn
);
18129 return can_issue_more
;
18131 if (sched_verbose
> 6)
18132 fprintf (dump
,"force: group count = %d, can_issue_more = %d\n",
18133 *group_count
,can_issue_more
);
18135 if (rs6000_sched_insert_nops
== sched_finish_regroup_exact
)
18138 can_issue_more
= 0;
18140 /* Since only a branch can be issued in the last issue_slot, it is
18141 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
18142 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
18143 in this case the last nop will start a new group and the branch
18144 will be forced to the new group. */
18145 if (can_issue_more
&& !is_branch_slot_insn (next_insn
))
18148 while (can_issue_more
> 0)
18151 emit_insn_before (nop
, next_insn
);
18159 if (rs6000_sched_insert_nops
< sched_finish_regroup_exact
)
18161 int n_nops
= rs6000_sched_insert_nops
;
18163 /* Nops can't be issued from the branch slot, so the effective
18164 issue_rate for nops is 'issue_rate - 1'. */
18165 if (can_issue_more
== 0)
18166 can_issue_more
= issue_rate
;
18168 if (can_issue_more
== 0)
18170 can_issue_more
= issue_rate
- 1;
18173 for (i
= 0; i
< issue_rate
; i
++)
18175 group_insns
[i
] = 0;
18182 emit_insn_before (nop
, next_insn
);
18183 if (can_issue_more
== issue_rate
- 1) /* new group begins */
18186 if (can_issue_more
== 0)
18188 can_issue_more
= issue_rate
- 1;
18191 for (i
= 0; i
< issue_rate
; i
++)
18193 group_insns
[i
] = 0;
18199 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
18202 /* Is next_insn going to start a new group? */
18205 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
18206 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
18207 || (can_issue_more
< issue_rate
&&
18208 insn_terminates_group_p (next_insn
, previous_group
)));
18209 if (*group_end
&& end
)
18212 if (sched_verbose
> 6)
18213 fprintf (dump
, "done force: group count = %d, can_issue_more = %d\n",
18214 *group_count
, can_issue_more
);
18215 return can_issue_more
;
18218 return can_issue_more
;
18221 /* This function tries to synch the dispatch groups that the compiler "sees"
18222 with the dispatch groups that the processor dispatcher is expected to
18223 form in practice. It tries to achieve this synchronization by forcing the
18224 estimated processor grouping on the compiler (as opposed to the function
18225 'pad_goups' which tries to force the scheduler's grouping on the processor).
18227 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
18228 examines the (estimated) dispatch groups that will be formed by the processor
18229 dispatcher. It marks these group boundaries to reflect the estimated
18230 processor grouping, overriding the grouping that the scheduler had marked.
18231 Depending on the value of the flag '-minsert-sched-nops' this function can
18232 force certain insns into separate groups or force a certain distance between
18233 them by inserting nops, for example, if there exists a "costly dependence"
18236 The function estimates the group boundaries that the processor will form as
18237 follows: It keeps track of how many vacant issue slots are available after
18238 each insn. A subsequent insn will start a new group if one of the following
18240 - no more vacant issue slots remain in the current dispatch group.
18241 - only the last issue slot, which is the branch slot, is vacant, but the next
18242 insn is not a branch.
18243 - only the last 2 or less issue slots, including the branch slot, are vacant,
18244 which means that a cracked insn (which occupies two issue slots) can't be
18245 issued in this group.
18246 - less than 'issue_rate' slots are vacant, and the next insn always needs to
18247 start a new group. */
18250 redefine_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
18252 rtx insn
, next_insn
;
18254 int can_issue_more
;
18257 int group_count
= 0;
18261 issue_rate
= rs6000_issue_rate ();
18262 group_insns
= alloca (issue_rate
* sizeof (rtx
));
18263 for (i
= 0; i
< issue_rate
; i
++)
18265 group_insns
[i
] = 0;
18267 can_issue_more
= issue_rate
;
18269 insn
= get_next_active_insn (prev_head_insn
, tail
);
18272 while (insn
!= NULL_RTX
)
18274 slot
= (issue_rate
- can_issue_more
);
18275 group_insns
[slot
] = insn
;
18277 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
18278 if (insn_terminates_group_p (insn
, current_group
))
18279 can_issue_more
= 0;
18281 next_insn
= get_next_active_insn (insn
, tail
);
18282 if (next_insn
== NULL_RTX
)
18283 return group_count
+ 1;
18285 /* Is next_insn going to start a new group? */
18287 = (can_issue_more
== 0
18288 || (can_issue_more
== 1 && !is_branch_slot_insn (next_insn
))
18289 || (can_issue_more
<= 2 && is_cracked_insn (next_insn
))
18290 || (can_issue_more
< issue_rate
&&
18291 insn_terminates_group_p (next_insn
, previous_group
)));
18293 can_issue_more
= force_new_group (sched_verbose
, dump
, group_insns
,
18294 next_insn
, &group_end
, can_issue_more
,
18300 can_issue_more
= 0;
18301 for (i
= 0; i
< issue_rate
; i
++)
18303 group_insns
[i
] = 0;
18307 if (GET_MODE (next_insn
) == TImode
&& can_issue_more
)
18308 PUT_MODE (next_insn
, VOIDmode
);
18309 else if (!can_issue_more
&& GET_MODE (next_insn
) != TImode
)
18310 PUT_MODE (next_insn
, TImode
);
18313 if (can_issue_more
== 0)
18314 can_issue_more
= issue_rate
;
18317 return group_count
;
18320 /* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
18321 dispatch group boundaries that the scheduler had marked. Pad with nops
18322 any dispatch groups which have vacant issue slots, in order to force the
18323 scheduler's grouping on the processor dispatcher. The function
18324 returns the number of dispatch groups found. */
18327 pad_groups (FILE *dump
, int sched_verbose
, rtx prev_head_insn
, rtx tail
)
18329 rtx insn
, next_insn
;
18332 int can_issue_more
;
18334 int group_count
= 0;
18336 /* Initialize issue_rate. */
18337 issue_rate
= rs6000_issue_rate ();
18338 can_issue_more
= issue_rate
;
18340 insn
= get_next_active_insn (prev_head_insn
, tail
);
18341 next_insn
= get_next_active_insn (insn
, tail
);
18343 while (insn
!= NULL_RTX
)
18346 rs6000_variable_issue (dump
, sched_verbose
, insn
, can_issue_more
);
18348 group_end
= (next_insn
== NULL_RTX
|| GET_MODE (next_insn
) == TImode
);
18350 if (next_insn
== NULL_RTX
)
18355 /* If the scheduler had marked group termination at this location
18356 (between insn and next_indn), and neither insn nor next_insn will
18357 force group termination, pad the group with nops to force group
18360 && (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
18361 && !insn_terminates_group_p (insn
, current_group
)
18362 && !insn_terminates_group_p (next_insn
, previous_group
))
18364 if (!is_branch_slot_insn (next_insn
))
18367 while (can_issue_more
)
18370 emit_insn_before (nop
, next_insn
);
18375 can_issue_more
= issue_rate
;
18380 next_insn
= get_next_active_insn (insn
, tail
);
18383 return group_count
;
18386 /* We're beginning a new block. Initialize data structures as necessary. */
18389 rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED
,
18390 int sched_verbose ATTRIBUTE_UNUSED
,
18391 int max_ready ATTRIBUTE_UNUSED
)
18393 last_scheduled_insn
= NULL_RTX
;
18394 load_store_pendulum
= 0;
18397 /* The following function is called at the end of scheduling BB.
18398 After reload, it inserts nops at insn group bundling. */
18401 rs6000_sched_finish (FILE *dump
, int sched_verbose
)
18406 fprintf (dump
, "=== Finishing schedule.\n");
18408 if (reload_completed
&& rs6000_sched_groups
)
18410 if (rs6000_sched_insert_nops
== sched_finish_none
)
18413 if (rs6000_sched_insert_nops
== sched_finish_pad_groups
)
18414 n_groups
= pad_groups (dump
, sched_verbose
,
18415 current_sched_info
->prev_head
,
18416 current_sched_info
->next_tail
);
18418 n_groups
= redefine_groups (dump
, sched_verbose
,
18419 current_sched_info
->prev_head
,
18420 current_sched_info
->next_tail
);
18422 if (sched_verbose
>= 6)
18424 fprintf (dump
, "ngroups = %d\n", n_groups
);
18425 print_rtl (dump
, current_sched_info
->prev_head
);
18426 fprintf (dump
, "Done finish_sched\n");
18431 /* Length in units of the trampoline for entering a nested function. */
18434 rs6000_trampoline_size (void)
18438 switch (DEFAULT_ABI
)
18441 gcc_unreachable ();
18444 ret
= (TARGET_32BIT
) ? 12 : 24;
18449 ret
= (TARGET_32BIT
) ? 40 : 48;
18456 /* Emit RTL insns to initialize the variable parts of a trampoline.
18457 FNADDR is an RTX for the address of the function's pure code.
18458 CXT is an RTX for the static chain value for the function. */
18461 rs6000_initialize_trampoline (rtx addr
, rtx fnaddr
, rtx cxt
)
18463 int regsize
= (TARGET_32BIT
) ? 4 : 8;
18464 rtx ctx_reg
= force_reg (Pmode
, cxt
);
18466 switch (DEFAULT_ABI
)
18469 gcc_unreachable ();
18471 /* Macros to shorten the code expansions below. */
18472 #define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
18473 #define MEM_PLUS(addr,offset) \
18474 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
18476 /* Under AIX, just build the 3 word function descriptor */
18479 rtx fn_reg
= gen_reg_rtx (Pmode
);
18480 rtx toc_reg
= gen_reg_rtx (Pmode
);
18481 emit_move_insn (fn_reg
, MEM_DEREF (fnaddr
));
18482 emit_move_insn (toc_reg
, MEM_PLUS (fnaddr
, regsize
));
18483 emit_move_insn (MEM_DEREF (addr
), fn_reg
);
18484 emit_move_insn (MEM_PLUS (addr
, regsize
), toc_reg
);
18485 emit_move_insn (MEM_PLUS (addr
, 2*regsize
), ctx_reg
);
18489 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
18492 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__trampoline_setup"),
18493 FALSE
, VOIDmode
, 4,
18495 GEN_INT (rs6000_trampoline_size ()), SImode
,
18505 /* Table of valid machine attributes. */
18507 const struct attribute_spec rs6000_attribute_table
[] =
18509 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
18510 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute
},
18511 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
18512 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute
},
18513 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
18514 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute
},
18515 #ifdef SUBTARGET_ATTRIBUTE_TABLE
18516 SUBTARGET_ATTRIBUTE_TABLE
,
18518 { NULL
, 0, 0, false, false, false, NULL
}
18521 /* Handle the "altivec" attribute. The attribute may have
18522 arguments as follows:
18524 __attribute__((altivec(vector__)))
18525 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
18526 __attribute__((altivec(bool__))) (always followed by 'unsigned')
18528 and may appear more than once (e.g., 'vector bool char') in a
18529 given declaration. */
18532 rs6000_handle_altivec_attribute (tree
*node
,
18533 tree name ATTRIBUTE_UNUSED
,
18535 int flags ATTRIBUTE_UNUSED
,
18536 bool *no_add_attrs
)
18538 tree type
= *node
, result
= NULL_TREE
;
18539 enum machine_mode mode
;
18542 = ((args
&& TREE_CODE (args
) == TREE_LIST
&& TREE_VALUE (args
)
18543 && TREE_CODE (TREE_VALUE (args
)) == IDENTIFIER_NODE
)
18544 ? *IDENTIFIER_POINTER (TREE_VALUE (args
))
18547 while (POINTER_TYPE_P (type
)
18548 || TREE_CODE (type
) == FUNCTION_TYPE
18549 || TREE_CODE (type
) == METHOD_TYPE
18550 || TREE_CODE (type
) == ARRAY_TYPE
)
18551 type
= TREE_TYPE (type
);
18553 mode
= TYPE_MODE (type
);
18555 /* Check for invalid AltiVec type qualifiers. */
18556 if (type
== long_unsigned_type_node
|| type
== long_integer_type_node
)
18559 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
18560 else if (rs6000_warn_altivec_long
)
18561 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
18563 else if (type
== long_long_unsigned_type_node
18564 || type
== long_long_integer_type_node
)
18565 error ("use of %<long long%> in AltiVec types is invalid");
18566 else if (type
== double_type_node
)
18567 error ("use of %<double%> in AltiVec types is invalid");
18568 else if (type
== long_double_type_node
)
18569 error ("use of %<long double%> in AltiVec types is invalid");
18570 else if (type
== boolean_type_node
)
18571 error ("use of boolean types in AltiVec types is invalid");
18572 else if (TREE_CODE (type
) == COMPLEX_TYPE
)
18573 error ("use of %<complex%> in AltiVec types is invalid");
18574 else if (DECIMAL_FLOAT_MODE_P (mode
))
18575 error ("use of decimal floating point types in AltiVec types is invalid");
18577 switch (altivec_type
)
18580 unsigned_p
= TYPE_UNSIGNED (type
);
18584 result
= (unsigned_p
? unsigned_V4SI_type_node
: V4SI_type_node
);
18587 result
= (unsigned_p
? unsigned_V8HI_type_node
: V8HI_type_node
);
18590 result
= (unsigned_p
? unsigned_V16QI_type_node
: V16QI_type_node
);
18592 case SFmode
: result
= V4SF_type_node
; break;
18593 /* If the user says 'vector int bool', we may be handed the 'bool'
18594 attribute _before_ the 'vector' attribute, and so select the
18595 proper type in the 'b' case below. */
18596 case V4SImode
: case V8HImode
: case V16QImode
: case V4SFmode
:
18604 case SImode
: case V4SImode
: result
= bool_V4SI_type_node
; break;
18605 case HImode
: case V8HImode
: result
= bool_V8HI_type_node
; break;
18606 case QImode
: case V16QImode
: result
= bool_V16QI_type_node
;
18613 case V8HImode
: result
= pixel_V8HI_type_node
;
18619 if (result
&& result
!= type
&& TYPE_READONLY (type
))
18620 result
= build_qualified_type (result
, TYPE_QUAL_CONST
);
18622 *no_add_attrs
= true; /* No need to hang on to the attribute. */
18625 *node
= reconstruct_complex_type (*node
, result
);
18630 /* AltiVec defines four built-in scalar types that serve as vector
18631 elements; we must teach the compiler how to mangle them. */
18633 static const char *
18634 rs6000_mangle_fundamental_type (tree type
)
18636 if (type
== bool_char_type_node
) return "U6__boolc";
18637 if (type
== bool_short_type_node
) return "U6__bools";
18638 if (type
== pixel_type_node
) return "u7__pixel";
18639 if (type
== bool_int_type_node
) return "U6__booli";
18641 /* Mangle IBM extended float long double as `g' (__float128) on
18642 powerpc*-linux where long-double-64 previously was the default. */
18643 if (TYPE_MAIN_VARIANT (type
) == long_double_type_node
18645 && TARGET_LONG_DOUBLE_128
18646 && !TARGET_IEEEQUAD
)
18649 /* For all other types, use normal C++ mangling. */
18653 /* Handle a "longcall" or "shortcall" attribute; arguments as in
18654 struct attribute_spec.handler. */
18657 rs6000_handle_longcall_attribute (tree
*node
, tree name
,
18658 tree args ATTRIBUTE_UNUSED
,
18659 int flags ATTRIBUTE_UNUSED
,
18660 bool *no_add_attrs
)
18662 if (TREE_CODE (*node
) != FUNCTION_TYPE
18663 && TREE_CODE (*node
) != FIELD_DECL
18664 && TREE_CODE (*node
) != TYPE_DECL
)
18666 warning (OPT_Wattributes
, "%qs attribute only applies to functions",
18667 IDENTIFIER_POINTER (name
));
18668 *no_add_attrs
= true;
18674 /* Set longcall attributes on all functions declared when
18675 rs6000_default_long_calls is true. */
18677 rs6000_set_default_type_attributes (tree type
)
18679 if (rs6000_default_long_calls
18680 && (TREE_CODE (type
) == FUNCTION_TYPE
18681 || TREE_CODE (type
) == METHOD_TYPE
))
18682 TYPE_ATTRIBUTES (type
) = tree_cons (get_identifier ("longcall"),
18684 TYPE_ATTRIBUTES (type
));
18687 darwin_set_default_type_attributes (type
);
18691 /* Return a reference suitable for calling a function with the
18692 longcall attribute. */
18695 rs6000_longcall_ref (rtx call_ref
)
18697 const char *call_name
;
18700 if (GET_CODE (call_ref
) != SYMBOL_REF
)
18703 /* System V adds '.' to the internal name, so skip them. */
18704 call_name
= XSTR (call_ref
, 0);
18705 if (*call_name
== '.')
18707 while (*call_name
== '.')
18710 node
= get_identifier (call_name
);
18711 call_ref
= gen_rtx_SYMBOL_REF (VOIDmode
, IDENTIFIER_POINTER (node
));
18714 return force_reg (Pmode
, call_ref
);
18717 #ifndef TARGET_USE_MS_BITFIELD_LAYOUT
18718 #define TARGET_USE_MS_BITFIELD_LAYOUT 0
18721 /* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
18722 struct attribute_spec.handler. */
18724 rs6000_handle_struct_attribute (tree
*node
, tree name
,
18725 tree args ATTRIBUTE_UNUSED
,
18726 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
18729 if (DECL_P (*node
))
18731 if (TREE_CODE (*node
) == TYPE_DECL
)
18732 type
= &TREE_TYPE (*node
);
18737 if (!(type
&& (TREE_CODE (*type
) == RECORD_TYPE
18738 || TREE_CODE (*type
) == UNION_TYPE
)))
18740 warning (OPT_Wattributes
, "%qs attribute ignored", IDENTIFIER_POINTER (name
));
18741 *no_add_attrs
= true;
18744 else if ((is_attribute_p ("ms_struct", name
)
18745 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type
)))
18746 || ((is_attribute_p ("gcc_struct", name
)
18747 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type
)))))
18749 warning (OPT_Wattributes
, "%qs incompatible attribute ignored",
18750 IDENTIFIER_POINTER (name
));
18751 *no_add_attrs
= true;
18758 rs6000_ms_bitfield_layout_p (tree record_type
)
18760 return (TARGET_USE_MS_BITFIELD_LAYOUT
&&
18761 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type
)))
18762 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type
));
18765 #ifdef USING_ELFOS_H
18767 /* A get_unnamed_section callback, used for switching to toc_section. */
18770 rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
18772 if (DEFAULT_ABI
== ABI_AIX
18773 && TARGET_MINIMAL_TOC
18774 && !TARGET_RELOCATABLE
)
18776 if (!toc_initialized
)
18778 toc_initialized
= 1;
18779 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
18780 (*targetm
.asm_out
.internal_label
) (asm_out_file
, "LCTOC", 0);
18781 fprintf (asm_out_file
, "\t.tc ");
18782 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1[TC],");
18783 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
18784 fprintf (asm_out_file
, "\n");
18786 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18787 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
18788 fprintf (asm_out_file
, " = .+32768\n");
18791 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18793 else if (DEFAULT_ABI
== ABI_AIX
&& !TARGET_RELOCATABLE
)
18794 fprintf (asm_out_file
, "%s\n", TOC_SECTION_ASM_OP
);
18797 fprintf (asm_out_file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
18798 if (!toc_initialized
)
18800 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file
, "LCTOC1");
18801 fprintf (asm_out_file
, " = .+32768\n");
18802 toc_initialized
= 1;
18807 /* Implement TARGET_ASM_INIT_SECTIONS. */
18810 rs6000_elf_asm_init_sections (void)
18813 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op
, NULL
);
18816 = get_unnamed_section (SECTION_WRITE
, output_section_asm_op
,
18817 SDATA2_SECTION_ASM_OP
);
18820 /* Implement TARGET_SELECT_RTX_SECTION. */
18823 rs6000_elf_select_rtx_section (enum machine_mode mode
, rtx x
,
18824 unsigned HOST_WIDE_INT align
)
18826 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
18827 return toc_section
;
18829 return default_elf_select_rtx_section (mode
, x
, align
);
18832 /* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */
18835 rs6000_elf_select_section (tree decl
, int reloc
,
18836 unsigned HOST_WIDE_INT align
)
18838 /* Pretend that we're always building for a shared library when
18839 ABI_AIX, because otherwise we end up with dynamic relocations
18840 in read-only sections. This happens for function pointers,
18841 references to vtables in typeinfo, and probably other cases. */
18842 return default_elf_select_section_1 (decl
, reloc
, align
,
18843 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
18846 /* A C statement to build up a unique section name, expressed as a
18847 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
18848 RELOC indicates whether the initial value of EXP requires
18849 link-time relocations. If you do not define this macro, GCC will use
18850 the symbol name prefixed by `.' as the section name. Note - this
18851 macro can now be called for uninitialized data items as well as
18852 initialized data and functions. */
18855 rs6000_elf_unique_section (tree decl
, int reloc
)
18857 /* As above, pretend that we're always building for a shared library
18858 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
18859 default_unique_section_1 (decl
, reloc
,
18860 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
18863 /* For a SYMBOL_REF, set generic flags and then perform some
18864 target-specific processing.
18866 When the AIX ABI is requested on a non-AIX system, replace the
18867 function name with the real name (with a leading .) rather than the
18868 function descriptor name. This saves a lot of overriding code to
18869 read the prefixes. */
18872 rs6000_elf_encode_section_info (tree decl
, rtx rtl
, int first
)
18874 default_encode_section_info (decl
, rtl
, first
);
18877 && TREE_CODE (decl
) == FUNCTION_DECL
18879 && DEFAULT_ABI
== ABI_AIX
)
18881 rtx sym_ref
= XEXP (rtl
, 0);
18882 size_t len
= strlen (XSTR (sym_ref
, 0));
18883 char *str
= alloca (len
+ 2);
18885 memcpy (str
+ 1, XSTR (sym_ref
, 0), len
+ 1);
18886 XSTR (sym_ref
, 0) = ggc_alloc_string (str
, len
+ 1);
18891 rs6000_elf_in_small_data_p (tree decl
)
18893 if (rs6000_sdata
== SDATA_NONE
)
18896 /* We want to merge strings, so we never consider them small data. */
18897 if (TREE_CODE (decl
) == STRING_CST
)
18900 /* Functions are never in the small data area. */
18901 if (TREE_CODE (decl
) == FUNCTION_DECL
)
18904 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
))
18906 const char *section
= TREE_STRING_POINTER (DECL_SECTION_NAME (decl
));
18907 if (strcmp (section
, ".sdata") == 0
18908 || strcmp (section
, ".sdata2") == 0
18909 || strcmp (section
, ".sbss") == 0
18910 || strcmp (section
, ".sbss2") == 0
18911 || strcmp (section
, ".PPC.EMB.sdata0") == 0
18912 || strcmp (section
, ".PPC.EMB.sbss0") == 0)
18917 HOST_WIDE_INT size
= int_size_in_bytes (TREE_TYPE (decl
));
18920 && (unsigned HOST_WIDE_INT
) size
<= g_switch_value
18921 /* If it's not public, and we're not going to reference it there,
18922 there's no need to put it in the small data section. */
18923 && (rs6000_sdata
!= SDATA_DATA
|| TREE_PUBLIC (decl
)))
18930 #endif /* USING_ELFOS_H */
18932 /* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
18935 rs6000_use_blocks_for_constant_p (enum machine_mode mode
, rtx x
)
18937 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
);
18940 /* Return a REG that occurs in ADDR with coefficient 1.
18941 ADDR can be effectively incremented by incrementing REG.
18943 r0 is special and we must not select it as an address
18944 register by this routine since our caller will try to
18945 increment the returned register via an "la" instruction. */
18948 find_addr_reg (rtx addr
)
18950 while (GET_CODE (addr
) == PLUS
)
18952 if (GET_CODE (XEXP (addr
, 0)) == REG
18953 && REGNO (XEXP (addr
, 0)) != 0)
18954 addr
= XEXP (addr
, 0);
18955 else if (GET_CODE (XEXP (addr
, 1)) == REG
18956 && REGNO (XEXP (addr
, 1)) != 0)
18957 addr
= XEXP (addr
, 1);
18958 else if (CONSTANT_P (XEXP (addr
, 0)))
18959 addr
= XEXP (addr
, 1);
18960 else if (CONSTANT_P (XEXP (addr
, 1)))
18961 addr
= XEXP (addr
, 0);
18963 gcc_unreachable ();
18965 gcc_assert (GET_CODE (addr
) == REG
&& REGNO (addr
) != 0);
18970 rs6000_fatal_bad_address (rtx op
)
18972 fatal_insn ("bad address", op
);
18977 static tree branch_island_list
= 0;
18979 /* Remember to generate a branch island for far calls to the given
18983 add_compiler_branch_island (tree label_name
, tree function_name
,
18986 tree branch_island
= build_tree_list (function_name
, label_name
);
18987 TREE_TYPE (branch_island
) = build_int_cst (NULL_TREE
, line_number
);
18988 TREE_CHAIN (branch_island
) = branch_island_list
;
18989 branch_island_list
= branch_island
;
18992 #define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
18993 #define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
18994 #define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
18995 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
18997 /* Generate far-jump branch islands for everything on the
18998 branch_island_list. Invoked immediately after the last instruction
18999 of the epilogue has been emitted; the branch-islands must be
19000 appended to, and contiguous with, the function body. Mach-O stubs
19001 are generated in machopic_output_stub(). */
19004 macho_branch_islands (void)
19007 tree branch_island
;
19009 for (branch_island
= branch_island_list
;
19011 branch_island
= TREE_CHAIN (branch_island
))
19013 const char *label
=
19014 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island
));
19016 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island
));
19017 char name_buf
[512];
19018 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
19019 if (name
[0] == '*' || name
[0] == '&')
19020 strcpy (name_buf
, name
+1);
19024 strcpy (name_buf
+1, name
);
19026 strcpy (tmp_buf
, "\n");
19027 strcat (tmp_buf
, label
);
19028 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
19029 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
19030 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
19031 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
19034 strcat (tmp_buf
, ":\n\tmflr r0\n\tbcl 20,31,");
19035 strcat (tmp_buf
, label
);
19036 strcat (tmp_buf
, "_pic\n");
19037 strcat (tmp_buf
, label
);
19038 strcat (tmp_buf
, "_pic:\n\tmflr r11\n");
19040 strcat (tmp_buf
, "\taddis r11,r11,ha16(");
19041 strcat (tmp_buf
, name_buf
);
19042 strcat (tmp_buf
, " - ");
19043 strcat (tmp_buf
, label
);
19044 strcat (tmp_buf
, "_pic)\n");
19046 strcat (tmp_buf
, "\tmtlr r0\n");
19048 strcat (tmp_buf
, "\taddi r12,r11,lo16(");
19049 strcat (tmp_buf
, name_buf
);
19050 strcat (tmp_buf
, " - ");
19051 strcat (tmp_buf
, label
);
19052 strcat (tmp_buf
, "_pic)\n");
19054 strcat (tmp_buf
, "\tmtctr r12\n\tbctr\n");
19058 strcat (tmp_buf
, ":\nlis r12,hi16(");
19059 strcat (tmp_buf
, name_buf
);
19060 strcat (tmp_buf
, ")\n\tori r12,r12,lo16(");
19061 strcat (tmp_buf
, name_buf
);
19062 strcat (tmp_buf
, ")\n\tmtctr r12\n\tbctr");
19064 output_asm_insn (tmp_buf
, 0);
19065 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
19066 if (write_symbols
== DBX_DEBUG
|| write_symbols
== XCOFF_DEBUG
)
19067 dbxout_stabd (N_SLINE
, BRANCH_ISLAND_LINE_NUMBER (branch_island
));
19068 #endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
19071 branch_island_list
= 0;
19074 /* NO_PREVIOUS_DEF checks in the link list whether the function name is
19075 already there or not. */
19078 no_previous_def (tree function_name
)
19080 tree branch_island
;
19081 for (branch_island
= branch_island_list
;
19083 branch_island
= TREE_CHAIN (branch_island
))
19084 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
19089 /* GET_PREV_LABEL gets the label name from the previous definition of
19093 get_prev_label (tree function_name
)
19095 tree branch_island
;
19096 for (branch_island
= branch_island_list
;
19098 branch_island
= TREE_CHAIN (branch_island
))
19099 if (function_name
== BRANCH_ISLAND_FUNCTION_NAME (branch_island
))
19100 return BRANCH_ISLAND_LABEL_NAME (branch_island
);
19104 #ifndef DARWIN_LINKER_GENERATES_ISLANDS
19105 #define DARWIN_LINKER_GENERATES_ISLANDS 0
19108 /* KEXTs still need branch islands. */
19109 #define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
19110 || flag_mkernel || flag_apple_kext)
19112 /* INSN is either a function call or a millicode call. It may have an
19113 unconditional jump in its delay slot.
19115 CALL_DEST is the routine we are calling. */
19118 output_call (rtx insn
, rtx
*operands
, int dest_operand_number
,
19119 int cookie_operand_number
)
19121 static char buf
[256];
19122 if (DARWIN_GENERATE_ISLANDS
19123 && GET_CODE (operands
[dest_operand_number
]) == SYMBOL_REF
19124 && (INTVAL (operands
[cookie_operand_number
]) & CALL_LONG
))
19127 tree funname
= get_identifier (XSTR (operands
[dest_operand_number
], 0));
19129 if (no_previous_def (funname
))
19131 int line_number
= 0;
19132 rtx label_rtx
= gen_label_rtx ();
19133 char *label_buf
, temp_buf
[256];
19134 ASM_GENERATE_INTERNAL_LABEL (temp_buf
, "L",
19135 CODE_LABEL_NUMBER (label_rtx
));
19136 label_buf
= temp_buf
[0] == '*' ? temp_buf
+ 1 : temp_buf
;
19137 labelname
= get_identifier (label_buf
);
19138 for (; insn
&& GET_CODE (insn
) != NOTE
; insn
= PREV_INSN (insn
));
19140 line_number
= NOTE_LINE_NUMBER (insn
);
19141 add_compiler_branch_island (labelname
, funname
, line_number
);
19144 labelname
= get_prev_label (funname
);
19146 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
19147 instruction will reach 'foo', otherwise link as 'bl L42'".
19148 "L42" should be a 'branch island', that will do a far jump to
19149 'foo'. Branch islands are generated in
19150 macho_branch_islands(). */
19151 sprintf (buf
, "jbsr %%z%d,%.246s",
19152 dest_operand_number
, IDENTIFIER_POINTER (labelname
));
19155 sprintf (buf
, "bl %%z%d", dest_operand_number
);
19159 /* Generate PIC and indirect symbol stubs. */
19162 machopic_output_stub (FILE *file
, const char *symb
, const char *stub
)
19164 unsigned int length
;
19165 char *symbol_name
, *lazy_ptr_name
;
19166 char *local_label_0
;
19167 static int label
= 0;
19169 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
19170 symb
= (*targetm
.strip_name_encoding
) (symb
);
19173 length
= strlen (symb
);
19174 symbol_name
= alloca (length
+ 32);
19175 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name
, symb
, length
);
19177 lazy_ptr_name
= alloca (length
+ 32);
19178 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name
, symb
, length
);
19181 switch_to_section (darwin_sections
[machopic_picsymbol_stub1_section
]);
19183 switch_to_section (darwin_sections
[machopic_symbol_stub1_section
]);
19187 fprintf (file
, "\t.align 5\n");
19189 fprintf (file
, "%s:\n", stub
);
19190 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
19193 local_label_0
= alloca (sizeof ("\"L00000000000$spb\""));
19194 sprintf (local_label_0
, "\"L%011d$spb\"", label
);
19196 fprintf (file
, "\tmflr r0\n");
19197 fprintf (file
, "\tbcl 20,31,%s\n", local_label_0
);
19198 fprintf (file
, "%s:\n\tmflr r11\n", local_label_0
);
19199 fprintf (file
, "\taddis r11,r11,ha16(%s-%s)\n",
19200 lazy_ptr_name
, local_label_0
);
19201 fprintf (file
, "\tmtlr r0\n");
19202 fprintf (file
, "\t%s r12,lo16(%s-%s)(r11)\n",
19203 (TARGET_64BIT
? "ldu" : "lwzu"),
19204 lazy_ptr_name
, local_label_0
);
19205 fprintf (file
, "\tmtctr r12\n");
19206 fprintf (file
, "\tbctr\n");
19210 fprintf (file
, "\t.align 4\n");
19212 fprintf (file
, "%s:\n", stub
);
19213 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
19215 fprintf (file
, "\tlis r11,ha16(%s)\n", lazy_ptr_name
);
19216 fprintf (file
, "\t%s r12,lo16(%s)(r11)\n",
19217 (TARGET_64BIT
? "ldu" : "lwzu"),
19219 fprintf (file
, "\tmtctr r12\n");
19220 fprintf (file
, "\tbctr\n");
19223 switch_to_section (darwin_sections
[machopic_lazy_symbol_ptr_section
]);
19224 fprintf (file
, "%s:\n", lazy_ptr_name
);
19225 fprintf (file
, "\t.indirect_symbol %s\n", symbol_name
);
19226 fprintf (file
, "%sdyld_stub_binding_helper\n",
19227 (TARGET_64BIT
? DOUBLE_INT_ASM_OP
: "\t.long\t"));
19230 /* Legitimize PIC addresses. If the address is already
19231 position-independent, we return ORIG. Newly generated
19232 position-independent addresses go into a reg. This is REG if non
19233 zero, otherwise we allocate register(s) as necessary. */
19235 #define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
19238 rs6000_machopic_legitimize_pic_address (rtx orig
, enum machine_mode mode
,
19243 if (reg
== NULL
&& ! reload_in_progress
&& ! reload_completed
)
19244 reg
= gen_reg_rtx (Pmode
);
19246 if (GET_CODE (orig
) == CONST
)
19250 if (GET_CODE (XEXP (orig
, 0)) == PLUS
19251 && XEXP (XEXP (orig
, 0), 0) == pic_offset_table_rtx
)
19254 gcc_assert (GET_CODE (XEXP (orig
, 0)) == PLUS
);
19256 /* Use a different reg for the intermediate value, as
19257 it will be marked UNCHANGING. */
19258 reg_temp
= no_new_pseudos
? reg
: gen_reg_rtx (Pmode
);
19259 base
= rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 0),
19262 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig
, 0), 1),
19265 if (GET_CODE (offset
) == CONST_INT
)
19267 if (SMALL_INT (offset
))
19268 return plus_constant (base
, INTVAL (offset
));
19269 else if (! reload_in_progress
&& ! reload_completed
)
19270 offset
= force_reg (Pmode
, offset
);
19273 rtx mem
= force_const_mem (Pmode
, orig
);
19274 return machopic_legitimize_pic_address (mem
, Pmode
, reg
);
19277 return gen_rtx_PLUS (Pmode
, base
, offset
);
19280 /* Fall back on generic machopic code. */
19281 return machopic_legitimize_pic_address (orig
, mode
, reg
);
19284 /* Output a .machine directive for the Darwin assembler, and call
19285 the generic start_file routine. */
19288 rs6000_darwin_file_start (void)
19290 static const struct
19296 { "ppc64", "ppc64", MASK_64BIT
},
19297 { "970", "ppc970", MASK_PPC_GPOPT
| MASK_MFCRF
| MASK_POWERPC64
},
19298 { "power4", "ppc970", 0 },
19299 { "G5", "ppc970", 0 },
19300 { "7450", "ppc7450", 0 },
19301 { "7400", "ppc7400", MASK_ALTIVEC
},
19302 { "G4", "ppc7400", 0 },
19303 { "750", "ppc750", 0 },
19304 { "740", "ppc750", 0 },
19305 { "G3", "ppc750", 0 },
19306 { "604e", "ppc604e", 0 },
19307 { "604", "ppc604", 0 },
19308 { "603e", "ppc603", 0 },
19309 { "603", "ppc603", 0 },
19310 { "601", "ppc601", 0 },
19311 { NULL
, "ppc", 0 } };
19312 const char *cpu_id
= "";
19315 rs6000_file_start ();
19316 darwin_file_start ();
19318 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
19319 for (i
= 0; i
< ARRAY_SIZE (rs6000_select
); i
++)
19320 if (rs6000_select
[i
].set_arch_p
&& rs6000_select
[i
].string
19321 && rs6000_select
[i
].string
[0] != '\0')
19322 cpu_id
= rs6000_select
[i
].string
;
19324 /* Look through the mapping array. Pick the first name that either
19325 matches the argument, has a bit set in IF_SET that is also set
19326 in the target flags, or has a NULL name. */
19329 while (mapping
[i
].arg
!= NULL
19330 && strcmp (mapping
[i
].arg
, cpu_id
) != 0
19331 && (mapping
[i
].if_set
& target_flags
) == 0)
19334 fprintf (asm_out_file
, "\t.machine %s\n", mapping
[i
].name
);
19337 #endif /* TARGET_MACHO */
19340 static unsigned int
19341 rs6000_elf_section_type_flags (tree decl
, const char *name
, int reloc
)
19343 return default_section_type_flags_1 (decl
, name
, reloc
,
19344 flag_pic
|| DEFAULT_ABI
== ABI_AIX
);
19347 /* Record an element in the table of global constructors. SYMBOL is
19348 a SYMBOL_REF of the function to be called; PRIORITY is a number
19349 between 0 and MAX_INIT_PRIORITY.
19351 This differs from default_named_section_asm_out_constructor in
19352 that we have special handling for -mrelocatable. */
19355 rs6000_elf_asm_out_constructor (rtx symbol
, int priority
)
19357 const char *section
= ".ctors";
19360 if (priority
!= DEFAULT_INIT_PRIORITY
)
19362 sprintf (buf
, ".ctors.%.5u",
19363 /* Invert the numbering so the linker puts us in the proper
19364 order; constructors are run from right to left, and the
19365 linker sorts in increasing order. */
19366 MAX_INIT_PRIORITY
- priority
);
19370 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
19371 assemble_align (POINTER_SIZE
);
19373 if (TARGET_RELOCATABLE
)
19375 fputs ("\t.long (", asm_out_file
);
19376 output_addr_const (asm_out_file
, symbol
);
19377 fputs (")@fixup\n", asm_out_file
);
19380 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
19384 rs6000_elf_asm_out_destructor (rtx symbol
, int priority
)
19386 const char *section
= ".dtors";
19389 if (priority
!= DEFAULT_INIT_PRIORITY
)
19391 sprintf (buf
, ".dtors.%.5u",
19392 /* Invert the numbering so the linker puts us in the proper
19393 order; constructors are run from right to left, and the
19394 linker sorts in increasing order. */
19395 MAX_INIT_PRIORITY
- priority
);
19399 switch_to_section (get_section (section
, SECTION_WRITE
, NULL
));
19400 assemble_align (POINTER_SIZE
);
19402 if (TARGET_RELOCATABLE
)
19404 fputs ("\t.long (", asm_out_file
);
19405 output_addr_const (asm_out_file
, symbol
);
19406 fputs (")@fixup\n", asm_out_file
);
19409 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
19413 rs6000_elf_declare_function_name (FILE *file
, const char *name
, tree decl
)
19417 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file
);
19418 ASM_OUTPUT_LABEL (file
, name
);
19419 fputs (DOUBLE_INT_ASM_OP
, file
);
19420 rs6000_output_function_entry (file
, name
);
19421 fputs (",.TOC.@tocbase,0\n\t.previous\n", file
);
19424 fputs ("\t.size\t", file
);
19425 assemble_name (file
, name
);
19426 fputs (",24\n\t.type\t.", file
);
19427 assemble_name (file
, name
);
19428 fputs (",@function\n", file
);
19429 if (TREE_PUBLIC (decl
) && ! DECL_WEAK (decl
))
19431 fputs ("\t.globl\t.", file
);
19432 assemble_name (file
, name
);
19437 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
19438 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
19439 rs6000_output_function_entry (file
, name
);
19440 fputs (":\n", file
);
19444 if (TARGET_RELOCATABLE
19445 && !TARGET_SECURE_PLT
19446 && (get_pool_size () != 0 || current_function_profile
)
19451 (*targetm
.asm_out
.internal_label
) (file
, "LCL", rs6000_pic_labelno
);
19453 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCTOC", 1);
19454 fprintf (file
, "\t.long ");
19455 assemble_name (file
, buf
);
19457 ASM_GENERATE_INTERNAL_LABEL (buf
, "LCF", rs6000_pic_labelno
);
19458 assemble_name (file
, buf
);
19462 ASM_OUTPUT_TYPE_DIRECTIVE (file
, name
, "function");
19463 ASM_DECLARE_RESULT (file
, DECL_RESULT (decl
));
19465 if (DEFAULT_ABI
== ABI_AIX
)
19467 const char *desc_name
, *orig_name
;
19469 orig_name
= (*targetm
.strip_name_encoding
) (name
);
19470 desc_name
= orig_name
;
19471 while (*desc_name
== '.')
19474 if (TREE_PUBLIC (decl
))
19475 fprintf (file
, "\t.globl %s\n", desc_name
);
19477 fprintf (file
, "%s\n", MINIMAL_TOC_SECTION_ASM_OP
);
19478 fprintf (file
, "%s:\n", desc_name
);
19479 fprintf (file
, "\t.long %s\n", orig_name
);
19480 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file
);
19481 if (DEFAULT_ABI
== ABI_AIX
)
19482 fputs ("\t.long 0\n", file
);
19483 fprintf (file
, "\t.previous\n");
19485 ASM_OUTPUT_LABEL (file
, name
);
19489 rs6000_elf_end_indicate_exec_stack (void)
19492 file_end_indicate_exec_stack ();
19498 rs6000_xcoff_asm_output_anchor (rtx symbol
)
19502 sprintf (buffer
, "$ + " HOST_WIDE_INT_PRINT_DEC
,
19503 SYMBOL_REF_BLOCK_OFFSET (symbol
));
19504 ASM_OUTPUT_DEF (asm_out_file
, XSTR (symbol
, 0), buffer
);
19508 rs6000_xcoff_asm_globalize_label (FILE *stream
, const char *name
)
19510 fputs (GLOBAL_ASM_OP
, stream
);
19511 RS6000_OUTPUT_BASENAME (stream
, name
);
19512 putc ('\n', stream
);
19515 /* A get_unnamed_decl callback, used for read-only sections. PTR
19516 points to the section string variable. */
19519 rs6000_xcoff_output_readonly_section_asm_op (const void *directive
)
19521 fprintf (asm_out_file
, "\t.csect %s[RO],3\n",
19522 *(const char *const *) directive
);
19525 /* Likewise for read-write sections. */
19528 rs6000_xcoff_output_readwrite_section_asm_op (const void *directive
)
19530 fprintf (asm_out_file
, "\t.csect %s[RW],3\n",
19531 *(const char *const *) directive
);
19534 /* A get_unnamed_section callback, used for switching to toc_section. */
19537 rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED
)
19539 if (TARGET_MINIMAL_TOC
)
19541 /* toc_section is always selected at least once from
19542 rs6000_xcoff_file_start, so this is guaranteed to
19543 always be defined once and only once in each file. */
19544 if (!toc_initialized
)
19546 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file
);
19547 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file
);
19548 toc_initialized
= 1;
19550 fprintf (asm_out_file
, "\t.csect toc_table[RW]%s\n",
19551 (TARGET_32BIT
? "" : ",3"));
19554 fputs ("\t.toc\n", asm_out_file
);
19557 /* Implement TARGET_ASM_INIT_SECTIONS. */
19560 rs6000_xcoff_asm_init_sections (void)
19562 read_only_data_section
19563 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
19564 &xcoff_read_only_section_name
);
19566 private_data_section
19567 = get_unnamed_section (SECTION_WRITE
,
19568 rs6000_xcoff_output_readwrite_section_asm_op
,
19569 &xcoff_private_data_section_name
);
19571 read_only_private_data_section
19572 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op
,
19573 &xcoff_private_data_section_name
);
19576 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op
, NULL
);
19578 readonly_data_section
= read_only_data_section
;
19579 exception_section
= data_section
;
19583 rs6000_xcoff_asm_named_section (const char *name
, unsigned int flags
,
19584 tree decl ATTRIBUTE_UNUSED
)
19587 static const char * const suffix
[3] = { "PR", "RO", "RW" };
19589 if (flags
& SECTION_CODE
)
19591 else if (flags
& SECTION_WRITE
)
19596 fprintf (asm_out_file
, "\t.csect %s%s[%s],%u\n",
19597 (flags
& SECTION_CODE
) ? "." : "",
19598 name
, suffix
[smclass
], flags
& SECTION_ENTSIZE
);
19602 rs6000_xcoff_select_section (tree decl
, int reloc
,
19603 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
19605 if (decl_readonly_section_1 (decl
, reloc
, 1))
19607 if (TREE_PUBLIC (decl
))
19608 return read_only_data_section
;
19610 return read_only_private_data_section
;
19614 if (TREE_PUBLIC (decl
))
19615 return data_section
;
19617 return private_data_section
;
19622 rs6000_xcoff_unique_section (tree decl
, int reloc ATTRIBUTE_UNUSED
)
19626 /* Use select_section for private and uninitialized data. */
19627 if (!TREE_PUBLIC (decl
)
19628 || DECL_COMMON (decl
)
19629 || DECL_INITIAL (decl
) == NULL_TREE
19630 || DECL_INITIAL (decl
) == error_mark_node
19631 || (flag_zero_initialized_in_bss
19632 && initializer_zerop (DECL_INITIAL (decl
))))
19635 name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl
));
19636 name
= (*targetm
.strip_name_encoding
) (name
);
19637 DECL_SECTION_NAME (decl
) = build_string (strlen (name
), name
);
19640 /* Select section for constant in constant pool.
19642 On RS/6000, all constants are in the private read-only data area.
19643 However, if this is being placed in the TOC it must be output as a
19647 rs6000_xcoff_select_rtx_section (enum machine_mode mode
, rtx x
,
19648 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
19650 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x
, mode
))
19651 return toc_section
;
19653 return read_only_private_data_section
;
19656 /* Remove any trailing [DS] or the like from the symbol name. */
19658 static const char *
19659 rs6000_xcoff_strip_name_encoding (const char *name
)
19664 len
= strlen (name
);
19665 if (name
[len
- 1] == ']')
19666 return ggc_alloc_string (name
, len
- 4);
19671 /* Section attributes. AIX is always PIC. */
19673 static unsigned int
19674 rs6000_xcoff_section_type_flags (tree decl
, const char *name
, int reloc
)
19676 unsigned int align
;
19677 unsigned int flags
= default_section_type_flags_1 (decl
, name
, reloc
, 1);
19679 /* Align to at least UNIT size. */
19680 if (flags
& SECTION_CODE
)
19681 align
= MIN_UNITS_PER_WORD
;
19683 /* Increase alignment of large objects if not already stricter. */
19684 align
= MAX ((DECL_ALIGN (decl
) / BITS_PER_UNIT
),
19685 int_size_in_bytes (TREE_TYPE (decl
)) > MIN_UNITS_PER_WORD
19686 ? UNITS_PER_FP_WORD
: MIN_UNITS_PER_WORD
);
19688 return flags
| (exact_log2 (align
) & SECTION_ENTSIZE
);
19691 /* Output at beginning of assembler file.
19693 Initialize the section names for the RS/6000 at this point.
19695 Specify filename, including full path, to assembler.
19697 We want to go into the TOC section so at least one .toc will be emitted.
19698 Also, in order to output proper .bs/.es pairs, we need at least one static
19699 [RW] section emitted.
19701 Finally, declare mcount when profiling to make the assembler happy. */
19704 rs6000_xcoff_file_start (void)
19706 rs6000_gen_section_name (&xcoff_bss_section_name
,
19707 main_input_filename
, ".bss_");
19708 rs6000_gen_section_name (&xcoff_private_data_section_name
,
19709 main_input_filename
, ".rw_");
19710 rs6000_gen_section_name (&xcoff_read_only_section_name
,
19711 main_input_filename
, ".ro_");
19713 fputs ("\t.file\t", asm_out_file
);
19714 output_quoted_string (asm_out_file
, main_input_filename
);
19715 fputc ('\n', asm_out_file
);
19716 if (write_symbols
!= NO_DEBUG
)
19717 switch_to_section (private_data_section
);
19718 switch_to_section (text_section
);
19720 fprintf (asm_out_file
, "\t.extern %s\n", RS6000_MCOUNT
);
19721 rs6000_file_start ();
19724 /* Output at end of assembler file.
19725 On the RS/6000, referencing data should automatically pull in text. */
19728 rs6000_xcoff_file_end (void)
19730 switch_to_section (text_section
);
19731 fputs ("_section_.text:\n", asm_out_file
);
19732 switch_to_section (data_section
);
19733 fputs (TARGET_32BIT
19734 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
19737 #endif /* TARGET_XCOFF */
19739 /* Compute a (partial) cost for rtx X. Return true if the complete
19740 cost has been computed, and false if subexpressions should be
19741 scanned. In either case, *TOTAL contains the cost result. */
19744 rs6000_rtx_costs (rtx x
, int code
, int outer_code
, int *total
)
19746 enum machine_mode mode
= GET_MODE (x
);
19750 /* On the RS/6000, if it is valid in the insn, it is free. */
19752 if (((outer_code
== SET
19753 || outer_code
== PLUS
19754 || outer_code
== MINUS
)
19755 && (satisfies_constraint_I (x
)
19756 || satisfies_constraint_L (x
)))
19757 || (outer_code
== AND
19758 && (satisfies_constraint_K (x
)
19760 ? satisfies_constraint_L (x
)
19761 : satisfies_constraint_J (x
))
19762 || mask_operand (x
, mode
)
19764 && mask64_operand (x
, DImode
))))
19765 || ((outer_code
== IOR
|| outer_code
== XOR
)
19766 && (satisfies_constraint_K (x
)
19768 ? satisfies_constraint_L (x
)
19769 : satisfies_constraint_J (x
))))
19770 || outer_code
== ASHIFT
19771 || outer_code
== ASHIFTRT
19772 || outer_code
== LSHIFTRT
19773 || outer_code
== ROTATE
19774 || outer_code
== ROTATERT
19775 || outer_code
== ZERO_EXTRACT
19776 || (outer_code
== MULT
19777 && satisfies_constraint_I (x
))
19778 || ((outer_code
== DIV
|| outer_code
== UDIV
19779 || outer_code
== MOD
|| outer_code
== UMOD
)
19780 && exact_log2 (INTVAL (x
)) >= 0)
19781 || (outer_code
== COMPARE
19782 && (satisfies_constraint_I (x
)
19783 || satisfies_constraint_K (x
)))
19784 || (outer_code
== EQ
19785 && (satisfies_constraint_I (x
)
19786 || satisfies_constraint_K (x
)
19788 ? satisfies_constraint_L (x
)
19789 : satisfies_constraint_J (x
))))
19790 || (outer_code
== GTU
19791 && satisfies_constraint_I (x
))
19792 || (outer_code
== LTU
19793 && satisfies_constraint_P (x
)))
19798 else if ((outer_code
== PLUS
19799 && reg_or_add_cint_operand (x
, VOIDmode
))
19800 || (outer_code
== MINUS
19801 && reg_or_sub_cint_operand (x
, VOIDmode
))
19802 || ((outer_code
== SET
19803 || outer_code
== IOR
19804 || outer_code
== XOR
)
19806 & ~ (unsigned HOST_WIDE_INT
) 0xffffffff) == 0))
19808 *total
= COSTS_N_INSNS (1);
19814 if (mode
== DImode
&& code
== CONST_DOUBLE
)
19816 if ((outer_code
== IOR
|| outer_code
== XOR
)
19817 && CONST_DOUBLE_HIGH (x
) == 0
19818 && (CONST_DOUBLE_LOW (x
)
19819 & ~ (unsigned HOST_WIDE_INT
) 0xffff) == 0)
19824 else if ((outer_code
== AND
&& and64_2_operand (x
, DImode
))
19825 || ((outer_code
== SET
19826 || outer_code
== IOR
19827 || outer_code
== XOR
)
19828 && CONST_DOUBLE_HIGH (x
) == 0))
19830 *total
= COSTS_N_INSNS (1);
19840 /* When optimizing for size, MEM should be slightly more expensive
19841 than generating address, e.g., (plus (reg) (const)).
19842 L1 cache latency is about two instructions. */
19843 *total
= optimize_size
? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
19851 if (mode
== DFmode
)
19853 if (GET_CODE (XEXP (x
, 0)) == MULT
)
19855 /* FNMA accounted in outer NEG. */
19856 if (outer_code
== NEG
)
19857 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
19859 *total
= rs6000_cost
->dmul
;
19862 *total
= rs6000_cost
->fp
;
19864 else if (mode
== SFmode
)
19866 /* FNMA accounted in outer NEG. */
19867 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
19870 *total
= rs6000_cost
->fp
;
19873 *total
= COSTS_N_INSNS (1);
19877 if (mode
== DFmode
)
19879 if (GET_CODE (XEXP (x
, 0)) == MULT
19880 || GET_CODE (XEXP (x
, 1)) == MULT
)
19882 /* FNMA accounted in outer NEG. */
19883 if (outer_code
== NEG
)
19884 *total
= rs6000_cost
->dmul
- rs6000_cost
->fp
;
19886 *total
= rs6000_cost
->dmul
;
19889 *total
= rs6000_cost
->fp
;
19891 else if (mode
== SFmode
)
19893 /* FNMA accounted in outer NEG. */
19894 if (outer_code
== NEG
&& GET_CODE (XEXP (x
, 0)) == MULT
)
19897 *total
= rs6000_cost
->fp
;
19900 *total
= COSTS_N_INSNS (1);
19904 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
19905 && satisfies_constraint_I (XEXP (x
, 1)))
19907 if (INTVAL (XEXP (x
, 1)) >= -256
19908 && INTVAL (XEXP (x
, 1)) <= 255)
19909 *total
= rs6000_cost
->mulsi_const9
;
19911 *total
= rs6000_cost
->mulsi_const
;
19913 /* FMA accounted in outer PLUS/MINUS. */
19914 else if ((mode
== DFmode
|| mode
== SFmode
)
19915 && (outer_code
== PLUS
|| outer_code
== MINUS
))
19917 else if (mode
== DFmode
)
19918 *total
= rs6000_cost
->dmul
;
19919 else if (mode
== SFmode
)
19920 *total
= rs6000_cost
->fp
;
19921 else if (mode
== DImode
)
19922 *total
= rs6000_cost
->muldi
;
19924 *total
= rs6000_cost
->mulsi
;
19929 if (FLOAT_MODE_P (mode
))
19931 *total
= mode
== DFmode
? rs6000_cost
->ddiv
19932 : rs6000_cost
->sdiv
;
19939 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
19940 && exact_log2 (INTVAL (XEXP (x
, 1))) >= 0)
19942 if (code
== DIV
|| code
== MOD
)
19944 *total
= COSTS_N_INSNS (2);
19947 *total
= COSTS_N_INSNS (1);
19951 if (GET_MODE (XEXP (x
, 1)) == DImode
)
19952 *total
= rs6000_cost
->divdi
;
19954 *total
= rs6000_cost
->divsi
;
19956 /* Add in shift and subtract for MOD. */
19957 if (code
== MOD
|| code
== UMOD
)
19958 *total
+= COSTS_N_INSNS (2);
19962 *total
= COSTS_N_INSNS (4);
19966 if (outer_code
== AND
|| outer_code
== IOR
|| outer_code
== XOR
)
19977 *total
= COSTS_N_INSNS (1);
19985 /* Handle mul_highpart. */
19986 if (outer_code
== TRUNCATE
19987 && GET_CODE (XEXP (x
, 0)) == MULT
)
19989 if (mode
== DImode
)
19990 *total
= rs6000_cost
->muldi
;
19992 *total
= rs6000_cost
->mulsi
;
19995 else if (outer_code
== AND
)
19998 *total
= COSTS_N_INSNS (1);
20003 if (GET_CODE (XEXP (x
, 0)) == MEM
)
20006 *total
= COSTS_N_INSNS (1);
20012 if (!FLOAT_MODE_P (mode
))
20014 *total
= COSTS_N_INSNS (1);
20020 case UNSIGNED_FLOAT
:
20023 case FLOAT_TRUNCATE
:
20024 *total
= rs6000_cost
->fp
;
20028 if (mode
== DFmode
)
20031 *total
= rs6000_cost
->fp
;
20035 switch (XINT (x
, 1))
20038 *total
= rs6000_cost
->fp
;
20050 *total
= COSTS_N_INSNS (1);
20053 else if (FLOAT_MODE_P (mode
)
20054 && TARGET_PPC_GFXOPT
&& TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20056 *total
= rs6000_cost
->fp
;
20064 /* Carry bit requires mode == Pmode.
20065 NEG or PLUS already counted so only add one. */
20067 && (outer_code
== NEG
|| outer_code
== PLUS
))
20069 *total
= COSTS_N_INSNS (1);
20072 if (outer_code
== SET
)
20074 if (XEXP (x
, 1) == const0_rtx
)
20076 *total
= COSTS_N_INSNS (2);
20079 else if (mode
== Pmode
)
20081 *total
= COSTS_N_INSNS (3);
20090 if (outer_code
== SET
&& (XEXP (x
, 1) == const0_rtx
))
20092 *total
= COSTS_N_INSNS (2);
20096 if (outer_code
== COMPARE
)
20110 /* A C expression returning the cost of moving data from a register of class
20111 CLASS1 to one of CLASS2. */
20114 rs6000_register_move_cost (enum machine_mode mode
,
20115 enum reg_class from
, enum reg_class to
)
20117 /* Moves from/to GENERAL_REGS. */
20118 if (reg_classes_intersect_p (to
, GENERAL_REGS
)
20119 || reg_classes_intersect_p (from
, GENERAL_REGS
))
20121 if (! reg_classes_intersect_p (to
, GENERAL_REGS
))
20124 if (from
== FLOAT_REGS
|| from
== ALTIVEC_REGS
)
20125 return (rs6000_memory_move_cost (mode
, from
, 0)
20126 + rs6000_memory_move_cost (mode
, GENERAL_REGS
, 0));
20128 /* It's more expensive to move CR_REGS than CR0_REGS because of the
20130 else if (from
== CR_REGS
)
20134 /* A move will cost one instruction per GPR moved. */
20135 return 2 * hard_regno_nregs
[0][mode
];
20138 /* Moving between two similar registers is just one instruction. */
20139 else if (reg_classes_intersect_p (to
, from
))
20140 return mode
== TFmode
? 4 : 2;
20142 /* Everything else has to go through GENERAL_REGS. */
20144 return (rs6000_register_move_cost (mode
, GENERAL_REGS
, to
)
20145 + rs6000_register_move_cost (mode
, from
, GENERAL_REGS
));
20148 /* A C expressions returning the cost of moving data of MODE from a register to
20152 rs6000_memory_move_cost (enum machine_mode mode
, enum reg_class
class,
20153 int in ATTRIBUTE_UNUSED
)
20155 if (reg_classes_intersect_p (class, GENERAL_REGS
))
20156 return 4 * hard_regno_nregs
[0][mode
];
20157 else if (reg_classes_intersect_p (class, FLOAT_REGS
))
20158 return 4 * hard_regno_nregs
[32][mode
];
20159 else if (reg_classes_intersect_p (class, ALTIVEC_REGS
))
20160 return 4 * hard_regno_nregs
[FIRST_ALTIVEC_REGNO
][mode
];
20162 return 4 + rs6000_register_move_cost (mode
, class, GENERAL_REGS
);
20165 /* Newton-Raphson approximation of single-precision floating point divide n/d.
20166 Assumes no trapping math and finite arguments. */
20169 rs6000_emit_swdivsf (rtx res
, rtx n
, rtx d
)
20171 rtx x0
, e0
, e1
, y1
, u0
, v0
, one
;
20173 x0
= gen_reg_rtx (SFmode
);
20174 e0
= gen_reg_rtx (SFmode
);
20175 e1
= gen_reg_rtx (SFmode
);
20176 y1
= gen_reg_rtx (SFmode
);
20177 u0
= gen_reg_rtx (SFmode
);
20178 v0
= gen_reg_rtx (SFmode
);
20179 one
= force_reg (SFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, SFmode
));
20181 /* x0 = 1./d estimate */
20182 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
20183 gen_rtx_UNSPEC (SFmode
, gen_rtvec (1, d
),
20185 /* e0 = 1. - d * x0 */
20186 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
20187 gen_rtx_MINUS (SFmode
, one
,
20188 gen_rtx_MULT (SFmode
, d
, x0
))));
20189 /* e1 = e0 + e0 * e0 */
20190 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
20191 gen_rtx_PLUS (SFmode
,
20192 gen_rtx_MULT (SFmode
, e0
, e0
), e0
)));
20193 /* y1 = x0 + e1 * x0 */
20194 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
20195 gen_rtx_PLUS (SFmode
,
20196 gen_rtx_MULT (SFmode
, e1
, x0
), x0
)));
20198 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
20199 gen_rtx_MULT (SFmode
, n
, y1
)));
20200 /* v0 = n - d * u0 */
20201 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
20202 gen_rtx_MINUS (SFmode
, n
,
20203 gen_rtx_MULT (SFmode
, d
, u0
))));
20204 /* res = u0 + v0 * y1 */
20205 emit_insn (gen_rtx_SET (VOIDmode
, res
,
20206 gen_rtx_PLUS (SFmode
,
20207 gen_rtx_MULT (SFmode
, v0
, y1
), u0
)));
20210 /* Newton-Raphson approximation of double-precision floating point divide n/d.
20211 Assumes no trapping math and finite arguments. */
20214 rs6000_emit_swdivdf (rtx res
, rtx n
, rtx d
)
20216 rtx x0
, e0
, e1
, e2
, y1
, y2
, y3
, u0
, v0
, one
;
20218 x0
= gen_reg_rtx (DFmode
);
20219 e0
= gen_reg_rtx (DFmode
);
20220 e1
= gen_reg_rtx (DFmode
);
20221 e2
= gen_reg_rtx (DFmode
);
20222 y1
= gen_reg_rtx (DFmode
);
20223 y2
= gen_reg_rtx (DFmode
);
20224 y3
= gen_reg_rtx (DFmode
);
20225 u0
= gen_reg_rtx (DFmode
);
20226 v0
= gen_reg_rtx (DFmode
);
20227 one
= force_reg (DFmode
, CONST_DOUBLE_FROM_REAL_VALUE (dconst1
, DFmode
));
20229 /* x0 = 1./d estimate */
20230 emit_insn (gen_rtx_SET (VOIDmode
, x0
,
20231 gen_rtx_UNSPEC (DFmode
, gen_rtvec (1, d
),
20233 /* e0 = 1. - d * x0 */
20234 emit_insn (gen_rtx_SET (VOIDmode
, e0
,
20235 gen_rtx_MINUS (DFmode
, one
,
20236 gen_rtx_MULT (SFmode
, d
, x0
))));
20237 /* y1 = x0 + e0 * x0 */
20238 emit_insn (gen_rtx_SET (VOIDmode
, y1
,
20239 gen_rtx_PLUS (DFmode
,
20240 gen_rtx_MULT (DFmode
, e0
, x0
), x0
)));
20242 emit_insn (gen_rtx_SET (VOIDmode
, e1
,
20243 gen_rtx_MULT (DFmode
, e0
, e0
)));
20244 /* y2 = y1 + e1 * y1 */
20245 emit_insn (gen_rtx_SET (VOIDmode
, y2
,
20246 gen_rtx_PLUS (DFmode
,
20247 gen_rtx_MULT (DFmode
, e1
, y1
), y1
)));
20249 emit_insn (gen_rtx_SET (VOIDmode
, e2
,
20250 gen_rtx_MULT (DFmode
, e1
, e1
)));
20251 /* y3 = y2 + e2 * y2 */
20252 emit_insn (gen_rtx_SET (VOIDmode
, y3
,
20253 gen_rtx_PLUS (DFmode
,
20254 gen_rtx_MULT (DFmode
, e2
, y2
), y2
)));
20256 emit_insn (gen_rtx_SET (VOIDmode
, u0
,
20257 gen_rtx_MULT (DFmode
, n
, y3
)));
20258 /* v0 = n - d * u0 */
20259 emit_insn (gen_rtx_SET (VOIDmode
, v0
,
20260 gen_rtx_MINUS (DFmode
, n
,
20261 gen_rtx_MULT (DFmode
, d
, u0
))));
20262 /* res = u0 + v0 * y3 */
20263 emit_insn (gen_rtx_SET (VOIDmode
, res
,
20264 gen_rtx_PLUS (DFmode
,
20265 gen_rtx_MULT (DFmode
, v0
, y3
), u0
)));
20269 /* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
20270 target, and SRC is the argument operand. */
20273 rs6000_emit_popcount (rtx dst
, rtx src
)
20275 enum machine_mode mode
= GET_MODE (dst
);
20278 tmp1
= gen_reg_rtx (mode
);
20280 if (mode
== SImode
)
20282 emit_insn (gen_popcntbsi2 (tmp1
, src
));
20283 tmp2
= expand_mult (SImode
, tmp1
, GEN_INT (0x01010101),
20285 tmp2
= force_reg (SImode
, tmp2
);
20286 emit_insn (gen_lshrsi3 (dst
, tmp2
, GEN_INT (24)));
20290 emit_insn (gen_popcntbdi2 (tmp1
, src
));
20291 tmp2
= expand_mult (DImode
, tmp1
,
20292 GEN_INT ((HOST_WIDE_INT
)
20293 0x01010101 << 32 | 0x01010101),
20295 tmp2
= force_reg (DImode
, tmp2
);
20296 emit_insn (gen_lshrdi3 (dst
, tmp2
, GEN_INT (56)));
20301 /* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
20302 target, and SRC is the argument operand. */
20305 rs6000_emit_parity (rtx dst
, rtx src
)
20307 enum machine_mode mode
= GET_MODE (dst
);
20310 tmp
= gen_reg_rtx (mode
);
20311 if (mode
== SImode
)
20313 /* Is mult+shift >= shift+xor+shift+xor? */
20314 if (rs6000_cost
->mulsi_const
>= COSTS_N_INSNS (3))
20316 rtx tmp1
, tmp2
, tmp3
, tmp4
;
20318 tmp1
= gen_reg_rtx (SImode
);
20319 emit_insn (gen_popcntbsi2 (tmp1
, src
));
20321 tmp2
= gen_reg_rtx (SImode
);
20322 emit_insn (gen_lshrsi3 (tmp2
, tmp1
, GEN_INT (16)));
20323 tmp3
= gen_reg_rtx (SImode
);
20324 emit_insn (gen_xorsi3 (tmp3
, tmp1
, tmp2
));
20326 tmp4
= gen_reg_rtx (SImode
);
20327 emit_insn (gen_lshrsi3 (tmp4
, tmp3
, GEN_INT (8)));
20328 emit_insn (gen_xorsi3 (tmp
, tmp3
, tmp4
));
20331 rs6000_emit_popcount (tmp
, src
);
20332 emit_insn (gen_andsi3 (dst
, tmp
, const1_rtx
));
20336 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
20337 if (rs6000_cost
->muldi
>= COSTS_N_INSNS (5))
20339 rtx tmp1
, tmp2
, tmp3
, tmp4
, tmp5
, tmp6
;
20341 tmp1
= gen_reg_rtx (DImode
);
20342 emit_insn (gen_popcntbdi2 (tmp1
, src
));
20344 tmp2
= gen_reg_rtx (DImode
);
20345 emit_insn (gen_lshrdi3 (tmp2
, tmp1
, GEN_INT (32)));
20346 tmp3
= gen_reg_rtx (DImode
);
20347 emit_insn (gen_xordi3 (tmp3
, tmp1
, tmp2
));
20349 tmp4
= gen_reg_rtx (DImode
);
20350 emit_insn (gen_lshrdi3 (tmp4
, tmp3
, GEN_INT (16)));
20351 tmp5
= gen_reg_rtx (DImode
);
20352 emit_insn (gen_xordi3 (tmp5
, tmp3
, tmp4
));
20354 tmp6
= gen_reg_rtx (DImode
);
20355 emit_insn (gen_lshrdi3 (tmp6
, tmp5
, GEN_INT (8)));
20356 emit_insn (gen_xordi3 (tmp
, tmp5
, tmp6
));
20359 rs6000_emit_popcount (tmp
, src
);
20360 emit_insn (gen_anddi3 (dst
, tmp
, const1_rtx
));
20364 /* Return an RTX representing where to find the function value of a
20365 function returning MODE. */
20367 rs6000_complex_function_value (enum machine_mode mode
)
20369 unsigned int regno
;
20371 enum machine_mode inner
= GET_MODE_INNER (mode
);
20372 unsigned int inner_bytes
= GET_MODE_SIZE (inner
);
20374 if (FLOAT_MODE_P (mode
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20375 regno
= FP_ARG_RETURN
;
20378 regno
= GP_ARG_RETURN
;
20380 /* 32-bit is OK since it'll go in r3/r4. */
20381 if (TARGET_32BIT
&& inner_bytes
>= 4)
20382 return gen_rtx_REG (mode
, regno
);
20385 if (inner_bytes
>= 8)
20386 return gen_rtx_REG (mode
, regno
);
20388 r1
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
),
20390 r2
= gen_rtx_EXPR_LIST (inner
, gen_rtx_REG (inner
, regno
+ 1),
20391 GEN_INT (inner_bytes
));
20392 return gen_rtx_PARALLEL (mode
, gen_rtvec (2, r1
, r2
));
20395 /* Define how to find the value returned by a function.
20396 VALTYPE is the data type of the value (as a tree).
20397 If the precise function being called is known, FUNC is its FUNCTION_DECL;
20398 otherwise, FUNC is 0.
20400 On the SPE, both FPs and vectors are returned in r3.
20402 On RS/6000 an integer value is in r3 and a floating-point value is in
20403 fp1, unless -msoft-float. */
20406 rs6000_function_value (tree valtype
, tree func ATTRIBUTE_UNUSED
)
20408 enum machine_mode mode
;
20409 unsigned int regno
;
20411 /* Special handling for structs in darwin64. */
20412 if (rs6000_darwin64_abi
20413 && TYPE_MODE (valtype
) == BLKmode
20414 && TREE_CODE (valtype
) == RECORD_TYPE
20415 && int_size_in_bytes (valtype
) > 0)
20417 CUMULATIVE_ARGS valcum
;
20421 valcum
.fregno
= FP_ARG_MIN_REG
;
20422 valcum
.vregno
= ALTIVEC_ARG_MIN_REG
;
20423 /* Do a trial code generation as if this were going to be passed as
20424 an argument; if any part goes in memory, we return NULL. */
20425 valret
= rs6000_darwin64_record_arg (&valcum
, valtype
, 1, true);
20428 /* Otherwise fall through to standard ABI rules. */
20431 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DImode
)
20433 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20434 return gen_rtx_PARALLEL (DImode
,
20436 gen_rtx_EXPR_LIST (VOIDmode
,
20437 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
20439 gen_rtx_EXPR_LIST (VOIDmode
,
20440 gen_rtx_REG (SImode
,
20441 GP_ARG_RETURN
+ 1),
20444 if (TARGET_32BIT
&& TARGET_POWERPC64
&& TYPE_MODE (valtype
) == DCmode
)
20446 return gen_rtx_PARALLEL (DCmode
,
20448 gen_rtx_EXPR_LIST (VOIDmode
,
20449 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
20451 gen_rtx_EXPR_LIST (VOIDmode
,
20452 gen_rtx_REG (SImode
,
20453 GP_ARG_RETURN
+ 1),
20455 gen_rtx_EXPR_LIST (VOIDmode
,
20456 gen_rtx_REG (SImode
,
20457 GP_ARG_RETURN
+ 2),
20459 gen_rtx_EXPR_LIST (VOIDmode
,
20460 gen_rtx_REG (SImode
,
20461 GP_ARG_RETURN
+ 3),
20465 if ((INTEGRAL_TYPE_P (valtype
)
20466 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
20467 || POINTER_TYPE_P (valtype
))
20468 mode
= TARGET_32BIT
? SImode
: DImode
;
20470 mode
= TYPE_MODE (valtype
);
20472 if (DECIMAL_FLOAT_MODE_P (mode
))
20473 regno
= GP_ARG_RETURN
;
20474 else if (SCALAR_FLOAT_TYPE_P (valtype
) && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20475 regno
= FP_ARG_RETURN
;
20476 else if (TREE_CODE (valtype
) == COMPLEX_TYPE
20477 && targetm
.calls
.split_complex_arg
)
20478 return rs6000_complex_function_value (mode
);
20479 else if (TREE_CODE (valtype
) == VECTOR_TYPE
20480 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
20481 && ALTIVEC_VECTOR_MODE (mode
))
20482 regno
= ALTIVEC_ARG_RETURN
;
20483 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
20484 && (mode
== DFmode
|| mode
== DCmode
20485 || mode
== TFmode
|| mode
== TCmode
))
20486 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
20488 regno
= GP_ARG_RETURN
;
20490 return gen_rtx_REG (mode
, regno
);
20493 /* Define how to find the value returned by a library function
20494 assuming the value has mode MODE. */
20496 rs6000_libcall_value (enum machine_mode mode
)
20498 unsigned int regno
;
20500 if (TARGET_32BIT
&& TARGET_POWERPC64
&& mode
== DImode
)
20502 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
20503 return gen_rtx_PARALLEL (DImode
,
20505 gen_rtx_EXPR_LIST (VOIDmode
,
20506 gen_rtx_REG (SImode
, GP_ARG_RETURN
),
20508 gen_rtx_EXPR_LIST (VOIDmode
,
20509 gen_rtx_REG (SImode
,
20510 GP_ARG_RETURN
+ 1),
20514 if (DECIMAL_FLOAT_MODE_P (mode
))
20515 regno
= GP_ARG_RETURN
;
20516 else if (SCALAR_FLOAT_MODE_P (mode
)
20517 && TARGET_HARD_FLOAT
&& TARGET_FPRS
)
20518 regno
= FP_ARG_RETURN
;
20519 else if (ALTIVEC_VECTOR_MODE (mode
)
20520 && TARGET_ALTIVEC
&& TARGET_ALTIVEC_ABI
)
20521 regno
= ALTIVEC_ARG_RETURN
;
20522 else if (COMPLEX_MODE_P (mode
) && targetm
.calls
.split_complex_arg
)
20523 return rs6000_complex_function_value (mode
);
20524 else if (TARGET_E500_DOUBLE
&& TARGET_HARD_FLOAT
20525 && (mode
== DFmode
|| mode
== DCmode
20526 || mode
== TFmode
|| mode
== TCmode
))
20527 return spe_build_register_parallel (mode
, GP_ARG_RETURN
);
20529 regno
= GP_ARG_RETURN
;
20531 return gen_rtx_REG (mode
, regno
);
20534 /* Define the offset between two registers, FROM to be eliminated and its
20535 replacement TO, at the start of a routine. */
20537 rs6000_initial_elimination_offset (int from
, int to
)
20539 rs6000_stack_t
*info
= rs6000_stack_info ();
20540 HOST_WIDE_INT offset
;
20542 if (from
== HARD_FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
20543 offset
= info
->push_p
? 0 : -info
->total_size
;
20544 else if (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
20546 offset
= info
->push_p
? 0 : -info
->total_size
;
20547 if (FRAME_GROWS_DOWNWARD
)
20548 offset
+= info
->fixed_size
+ info
->vars_size
+ info
->parm_size
;
20550 else if (from
== FRAME_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
20551 offset
= FRAME_GROWS_DOWNWARD
20552 ? info
->fixed_size
+ info
->vars_size
+ info
->parm_size
20554 else if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
20555 offset
= info
->total_size
;
20556 else if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
20557 offset
= info
->push_p
? info
->total_size
: 0;
20558 else if (from
== RS6000_PIC_OFFSET_TABLE_REGNUM
)
20561 gcc_unreachable ();
20566 /* Return true if TYPE is a SPE or AltiVec opaque type. */
20569 rs6000_is_opaque_type (tree type
)
20571 return (type
== opaque_V2SI_type_node
20572 || type
== opaque_V2SF_type_node
20573 || type
== opaque_p_V2SI_type_node
20574 || type
== opaque_V4SI_type_node
);
20578 rs6000_dwarf_register_span (rtx reg
)
20583 && (SPE_VECTOR_MODE (GET_MODE (reg
))
20584 || (TARGET_E500_DOUBLE
&& GET_MODE (reg
) == DFmode
)))
20589 regno
= REGNO (reg
);
20591 /* The duality of the SPE register size wreaks all kinds of havoc.
20592 This is a way of distinguishing r0 in 32-bits from r0 in
20595 gen_rtx_PARALLEL (VOIDmode
,
20598 gen_rtx_REG (SImode
, regno
+ 1200),
20599 gen_rtx_REG (SImode
, regno
))
20601 gen_rtx_REG (SImode
, regno
),
20602 gen_rtx_REG (SImode
, regno
+ 1200)));
20605 /* Map internal gcc register numbers to DWARF2 register numbers. */
20608 rs6000_dbx_register_number (unsigned int regno
)
20610 if (regno
<= 63 || write_symbols
!= DWARF2_DEBUG
)
20612 if (regno
== MQ_REGNO
)
20614 if (regno
== LINK_REGISTER_REGNUM
)
20616 if (regno
== COUNT_REGISTER_REGNUM
)
20618 if (CR_REGNO_P (regno
))
20619 return regno
- CR0_REGNO
+ 86;
20620 if (regno
== XER_REGNO
)
20622 if (ALTIVEC_REGNO_P (regno
))
20623 return regno
- FIRST_ALTIVEC_REGNO
+ 1124;
20624 if (regno
== VRSAVE_REGNO
)
20626 if (regno
== VSCR_REGNO
)
20628 if (regno
== SPE_ACC_REGNO
)
20630 if (regno
== SPEFSCR_REGNO
)
20632 /* SPE high reg number. We get these values of regno from
20633 rs6000_dwarf_register_span. */
20634 gcc_assert (regno
>= 1200 && regno
< 1232);
20638 /* target hook eh_return_filter_mode */
20639 static enum machine_mode
20640 rs6000_eh_return_filter_mode (void)
20642 return TARGET_32BIT
? SImode
: word_mode
;
20645 /* Target hook for scalar_mode_supported_p. */
20647 rs6000_scalar_mode_supported_p (enum machine_mode mode
)
20649 if (DECIMAL_FLOAT_MODE_P (mode
))
20652 return default_scalar_mode_supported_p (mode
);
20655 /* Target hook for vector_mode_supported_p. */
20657 rs6000_vector_mode_supported_p (enum machine_mode mode
)
20660 if (TARGET_SPE
&& SPE_VECTOR_MODE (mode
))
20663 else if (TARGET_ALTIVEC
&& ALTIVEC_VECTOR_MODE (mode
))
20670 /* Target hook for invalid_arg_for_unprototyped_fn. */
20671 static const char *
20672 invalid_arg_for_unprototyped_fn (tree typelist
, tree funcdecl
, tree val
)
20674 return (!rs6000_darwin64_abi
20676 && TREE_CODE (TREE_TYPE (val
)) == VECTOR_TYPE
20677 && (funcdecl
== NULL_TREE
20678 || (TREE_CODE (funcdecl
) == FUNCTION_DECL
20679 && DECL_BUILT_IN_CLASS (funcdecl
) != BUILT_IN_MD
)))
20680 ? N_("AltiVec argument passed to unprototyped function")
20684 /* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
20685 setup by using __stack_chk_fail_local hidden function instead of
20686 calling __stack_chk_fail directly. Otherwise it is better to call
20687 __stack_chk_fail directly. */
20690 rs6000_stack_protect_fail (void)
20692 return (DEFAULT_ABI
== ABI_V4
&& TARGET_SECURE_PLT
&& flag_pic
)
20693 ? default_hidden_stack_protect_fail ()
20694 : default_external_stack_protect_fail ();
20697 #include "gt-rs6000.h"