]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
tree-ssa-dom.c (propagate_rhs_into_lhs): Temporarily work around bug in immediate...
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
CommitLineData
9878760c 1/* Subroutines used for code generation on IBM RS/6000.
f676971a 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
337bde91
DE
3 2000, 2001, 2002, 2003, 2004, 2005, 2006
4 Free Software Foundation, Inc.
fab3bcc3 5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
9878760c 6
5de601cf 7 This file is part of GCC.
9878760c 8
5de601cf
NC
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.
9878760c 13
5de601cf
NC
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.
9878760c 18
5de601cf
NC
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
39d14dda
KC
21 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
22 MA 02110-1301, USA. */
9878760c 23
956d6950 24#include "config.h"
c4d38ccb 25#include "system.h"
4977bab6
ZW
26#include "coretypes.h"
27#include "tm.h"
9878760c
RK
28#include "rtl.h"
29#include "regs.h"
30#include "hard-reg-set.h"
31#include "real.h"
32#include "insn-config.h"
33#include "conditions.h"
9878760c
RK
34#include "insn-attr.h"
35#include "flags.h"
36#include "recog.h"
9878760c 37#include "obstack.h"
9b30bae2 38#include "tree.h"
dfafc897 39#include "expr.h"
2fc1c679 40#include "optabs.h"
2a430ec1 41#include "except.h"
a7df97e6 42#include "function.h"
296b8152 43#include "output.h"
d5fa86ba 44#include "basic-block.h"
d0101753 45#include "integrate.h"
296b8152 46#include "toplev.h"
c8023011 47#include "ggc.h"
9ebbca7d
GK
48#include "hashtab.h"
49#include "tm_p.h"
672a6f42
NB
50#include "target.h"
51#include "target-def.h"
3ac88239 52#include "langhooks.h"
24ea750e 53#include "reload.h"
117dca74 54#include "cfglayout.h"
79ae11c4 55#include "sched-int.h"
cd3ce9b4 56#include "tree-gimple.h"
4d3e6fae 57#include "intl.h"
59d6560b 58#include "params.h"
1bc7c5b6
ZW
59#if TARGET_XCOFF
60#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
61#endif
93a27b7b
ZW
62#if TARGET_MACHO
63#include "gstab.h" /* for N_SLINE */
64#endif
9b30bae2 65
7509c759
MM
66#ifndef TARGET_NO_PROTOTYPE
67#define TARGET_NO_PROTOTYPE 0
68#endif
69
9878760c
RK
70#define min(A,B) ((A) < (B) ? (A) : (B))
71#define max(A,B) ((A) > (B) ? (A) : (B))
72
d1d0c603
JJ
73/* Structure used to define the rs6000 stack */
74typedef struct rs6000_stack {
75 int first_gp_reg_save; /* first callee saved GP register used */
76 int first_fp_reg_save; /* first callee saved FP register used */
77 int first_altivec_reg_save; /* first callee saved AltiVec register used */
78 int lr_save_p; /* true if the link reg needs to be saved */
79 int cr_save_p; /* true if the CR reg needs to be saved */
80 unsigned int vrsave_mask; /* mask of vec registers to save */
d1d0c603
JJ
81 int push_p; /* true if we need to allocate stack space */
82 int calls_p; /* true if the function makes any calls */
c4ad648e 83 int world_save_p; /* true if we're saving *everything*:
d62294f5 84 r13-r31, cr, f14-f31, vrsave, v20-v31 */
d1d0c603
JJ
85 enum rs6000_abi abi; /* which ABI to use */
86 int gp_save_offset; /* offset to save GP regs from initial SP */
87 int fp_save_offset; /* offset to save FP regs from initial SP */
88 int altivec_save_offset; /* offset to save AltiVec regs from initial SP */
89 int lr_save_offset; /* offset to save LR from initial SP */
90 int cr_save_offset; /* offset to save CR from initial SP */
91 int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
92 int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
d1d0c603
JJ
93 int varargs_save_offset; /* offset to save the varargs registers */
94 int ehrd_offset; /* offset to EH return data */
95 int reg_size; /* register size (4 or 8) */
d1d0c603
JJ
96 HOST_WIDE_INT vars_size; /* variable save area size */
97 int parm_size; /* outgoing parameter size */
98 int save_size; /* save area size */
99 int fixed_size; /* fixed size of stack frame */
100 int gp_size; /* size of saved GP registers */
101 int fp_size; /* size of saved FP registers */
102 int altivec_size; /* size of saved AltiVec registers */
103 int cr_size; /* size to hold CR if not in save_size */
d1d0c603
JJ
104 int vrsave_size; /* size to hold VRSAVE if not in save_size */
105 int altivec_padding_size; /* size of altivec alignment padding if
106 not in save_size */
107 int spe_gp_size; /* size of 64-bit GPR save size for SPE */
108 int spe_padding_size;
d1d0c603
JJ
109 HOST_WIDE_INT total_size; /* total bytes allocated for stack */
110 int spe_64bit_regs_used;
111} rs6000_stack_t;
112
5b667039
JJ
113/* A C structure for machine-specific, per-function data.
114 This is added to the cfun structure. */
115typedef struct machine_function GTY(())
116{
117 /* Flags if __builtin_return_address (n) with n >= 1 was used. */
118 int ra_needs_full_frame;
119 /* Some local-dynamic symbol. */
120 const char *some_ld_name;
121 /* Whether the instruction chain has been scanned already. */
122 int insn_chain_scanned_p;
123 /* Flags if __builtin_return_address (0) was used. */
124 int ra_need_lr;
125 /* Offset from virtual_stack_vars_rtx to the start of the ABI_V4
126 varargs save area. */
127 HOST_WIDE_INT varargs_save_offset;
128} machine_function;
129
5248c961
RK
130/* Target cpu type */
131
132enum processor_type rs6000_cpu;
8e3f41e7
MM
133struct rs6000_cpu_select rs6000_select[3] =
134{
815cdc52
MM
135 /* switch name, tune arch */
136 { (const char *)0, "--with-cpu=", 1, 1 },
137 { (const char *)0, "-mcpu=", 1, 1 },
138 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 139};
5248c961 140
ec507f2d
DE
141/* Always emit branch hint bits. */
142static GTY(()) bool rs6000_always_hint;
143
144/* Schedule instructions for group formation. */
145static GTY(()) bool rs6000_sched_groups;
146
569fa502
DN
147/* Support for -msched-costly-dep option. */
148const char *rs6000_sched_costly_dep_str;
149enum rs6000_dependence_cost rs6000_sched_costly_dep;
150
cbe26ab8
DN
151/* Support for -minsert-sched-nops option. */
152const char *rs6000_sched_insert_nops_str;
153enum rs6000_nop_insertion rs6000_sched_insert_nops;
154
7ccf35ed 155/* Support targetm.vectorize.builtin_mask_for_load. */
13c62176 156static GTY(()) tree altivec_builtin_mask_for_load;
7ccf35ed 157
602ea4d3 158/* Size of long double. */
6fa3f289
ZW
159int rs6000_long_double_type_size;
160
602ea4d3
JJ
161/* IEEE quad extended precision long double. */
162int rs6000_ieeequad;
163
164/* Whether -mabi=altivec has appeared. */
6fa3f289
ZW
165int rs6000_altivec_abi;
166
a3170dc6
AH
167/* Nonzero if we want SPE ABI extensions. */
168int rs6000_spe_abi;
169
5da702b1
AH
170/* Nonzero if floating point operations are done in the GPRs. */
171int rs6000_float_gprs = 0;
172
594a51fe
SS
173/* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
174int rs6000_darwin64_abi;
175
a0ab749a 176/* Set to nonzero once AIX common-mode calls have been defined. */
bbfb86aa 177static GTY(()) int common_mode_defined;
c81bebd7 178
9878760c
RK
179/* Save information from a "cmpxx" operation until the branch or scc is
180 emitted. */
9878760c
RK
181rtx rs6000_compare_op0, rs6000_compare_op1;
182int rs6000_compare_fp_p;
874a0744 183
874a0744
MM
184/* Label number of label created for -mrelocatable, to call to so we can
185 get the address of the GOT section */
186int rs6000_pic_labelno;
c81bebd7 187
b91da81f 188#ifdef USING_ELFOS_H
c81bebd7 189/* Which abi to adhere to */
9739c90c 190const char *rs6000_abi_name;
d9407988
MM
191
192/* Semantics of the small data area */
193enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
194
195/* Which small data model to use */
815cdc52 196const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
197
198/* Counter for labels which are to be placed in .fixup. */
199int fixuplabelno = 0;
874a0744 200#endif
4697a36c 201
c4501e62
JJ
202/* Bit size of immediate TLS offsets and string from which it is decoded. */
203int rs6000_tls_size = 32;
204const char *rs6000_tls_size_string;
205
b6c9286a
MM
206/* ABI enumeration available for subtarget to use. */
207enum rs6000_abi rs6000_current_abi;
208
85b776df
AM
209/* Whether to use variant of AIX ABI for PowerPC64 Linux. */
210int dot_symbols;
211
38c1f2d7 212/* Debug flags */
815cdc52 213const char *rs6000_debug_name;
38c1f2d7
MM
214int rs6000_debug_stack; /* debug stack applications */
215int rs6000_debug_arg; /* debug argument handling */
216
aabcd309 217/* Value is TRUE if register/mode pair is acceptable. */
0d1fbc8c
AH
218bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
219
58646b77
PB
220/* Built in types. */
221
222tree rs6000_builtin_types[RS6000_BTI_MAX];
223tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
8bb418a3 224
57ac7be9
AM
225const char *rs6000_traceback_name;
226static enum {
227 traceback_default = 0,
228 traceback_none,
229 traceback_part,
230 traceback_full
231} rs6000_traceback;
232
38c1f2d7
MM
233/* Flag to say the TOC is initialized */
234int toc_initialized;
9ebbca7d 235char toc_label_name[10];
38c1f2d7 236
d6b5193b
RS
237static GTY(()) section *read_only_data_section;
238static GTY(()) section *private_data_section;
239static GTY(()) section *read_only_private_data_section;
240static GTY(()) section *sdata2_section;
241static GTY(()) section *toc_section;
242
a3c9585f
KH
243/* Control alignment for fields within structures. */
244/* String from -malign-XXXXX. */
025d9908
KH
245int rs6000_alignment_flags;
246
78f5898b
AH
247/* True for any options that were explicitly set. */
248struct {
df01da37 249 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
78f5898b
AH
250 bool alignment; /* True if -malign- was used. */
251 bool abi; /* True if -mabi= was used. */
252 bool spe; /* True if -mspe= was used. */
253 bool float_gprs; /* True if -mfloat-gprs= was used. */
254 bool isel; /* True if -misel was used. */
255 bool long_double; /* True if -mlong-double- was used. */
256} rs6000_explicit_options;
257
a3170dc6
AH
258struct builtin_description
259{
260 /* mask is not const because we're going to alter it below. This
261 nonsense will go away when we rewrite the -march infrastructure
262 to give us more target flag bits. */
263 unsigned int mask;
264 const enum insn_code icode;
265 const char *const name;
266 const enum rs6000_builtins code;
267};
8b897cfa
RS
268\f
269/* Target cpu costs. */
270
271struct processor_costs {
c4ad648e 272 const int mulsi; /* cost of SImode multiplication. */
8b897cfa
RS
273 const int mulsi_const; /* cost of SImode multiplication by constant. */
274 const int mulsi_const9; /* cost of SImode mult by short constant. */
c4ad648e
AM
275 const int muldi; /* cost of DImode multiplication. */
276 const int divsi; /* cost of SImode division. */
277 const int divdi; /* cost of DImode division. */
278 const int fp; /* cost of simple SFmode and DFmode insns. */
279 const int dmul; /* cost of DFmode multiplication (and fmadd). */
280 const int sdiv; /* cost of SFmode division (fdivs). */
281 const int ddiv; /* cost of DFmode division (fdiv). */
8b897cfa
RS
282};
283
284const struct processor_costs *rs6000_cost;
285
286/* Processor costs (relative to an add) */
287
288/* Instruction size costs on 32bit processors. */
289static const
290struct processor_costs size32_cost = {
06a67bdd
RS
291 COSTS_N_INSNS (1), /* mulsi */
292 COSTS_N_INSNS (1), /* mulsi_const */
293 COSTS_N_INSNS (1), /* mulsi_const9 */
294 COSTS_N_INSNS (1), /* muldi */
295 COSTS_N_INSNS (1), /* divsi */
296 COSTS_N_INSNS (1), /* divdi */
297 COSTS_N_INSNS (1), /* fp */
298 COSTS_N_INSNS (1), /* dmul */
299 COSTS_N_INSNS (1), /* sdiv */
300 COSTS_N_INSNS (1), /* ddiv */
8b897cfa
RS
301};
302
303/* Instruction size costs on 64bit processors. */
304static const
305struct processor_costs size64_cost = {
06a67bdd
RS
306 COSTS_N_INSNS (1), /* mulsi */
307 COSTS_N_INSNS (1), /* mulsi_const */
308 COSTS_N_INSNS (1), /* mulsi_const9 */
309 COSTS_N_INSNS (1), /* muldi */
310 COSTS_N_INSNS (1), /* divsi */
311 COSTS_N_INSNS (1), /* divdi */
312 COSTS_N_INSNS (1), /* fp */
313 COSTS_N_INSNS (1), /* dmul */
314 COSTS_N_INSNS (1), /* sdiv */
315 COSTS_N_INSNS (1), /* ddiv */
8b897cfa
RS
316};
317
318/* Instruction costs on RIOS1 processors. */
319static const
320struct processor_costs rios1_cost = {
06a67bdd
RS
321 COSTS_N_INSNS (5), /* mulsi */
322 COSTS_N_INSNS (4), /* mulsi_const */
323 COSTS_N_INSNS (3), /* mulsi_const9 */
324 COSTS_N_INSNS (5), /* muldi */
325 COSTS_N_INSNS (19), /* divsi */
326 COSTS_N_INSNS (19), /* divdi */
327 COSTS_N_INSNS (2), /* fp */
328 COSTS_N_INSNS (2), /* dmul */
329 COSTS_N_INSNS (19), /* sdiv */
330 COSTS_N_INSNS (19), /* ddiv */
8b897cfa
RS
331};
332
333/* Instruction costs on RIOS2 processors. */
334static const
335struct processor_costs rios2_cost = {
06a67bdd
RS
336 COSTS_N_INSNS (2), /* mulsi */
337 COSTS_N_INSNS (2), /* mulsi_const */
338 COSTS_N_INSNS (2), /* mulsi_const9 */
339 COSTS_N_INSNS (2), /* muldi */
340 COSTS_N_INSNS (13), /* divsi */
341 COSTS_N_INSNS (13), /* divdi */
342 COSTS_N_INSNS (2), /* fp */
343 COSTS_N_INSNS (2), /* dmul */
344 COSTS_N_INSNS (17), /* sdiv */
345 COSTS_N_INSNS (17), /* ddiv */
8b897cfa
RS
346};
347
348/* Instruction costs on RS64A processors. */
349static const
350struct processor_costs rs64a_cost = {
06a67bdd
RS
351 COSTS_N_INSNS (20), /* mulsi */
352 COSTS_N_INSNS (12), /* mulsi_const */
353 COSTS_N_INSNS (8), /* mulsi_const9 */
354 COSTS_N_INSNS (34), /* muldi */
355 COSTS_N_INSNS (65), /* divsi */
356 COSTS_N_INSNS (67), /* divdi */
357 COSTS_N_INSNS (4), /* fp */
358 COSTS_N_INSNS (4), /* dmul */
359 COSTS_N_INSNS (31), /* sdiv */
360 COSTS_N_INSNS (31), /* ddiv */
8b897cfa
RS
361};
362
363/* Instruction costs on MPCCORE processors. */
364static const
365struct processor_costs mpccore_cost = {
06a67bdd
RS
366 COSTS_N_INSNS (2), /* mulsi */
367 COSTS_N_INSNS (2), /* mulsi_const */
368 COSTS_N_INSNS (2), /* mulsi_const9 */
369 COSTS_N_INSNS (2), /* muldi */
370 COSTS_N_INSNS (6), /* divsi */
371 COSTS_N_INSNS (6), /* divdi */
372 COSTS_N_INSNS (4), /* fp */
373 COSTS_N_INSNS (5), /* dmul */
374 COSTS_N_INSNS (10), /* sdiv */
375 COSTS_N_INSNS (17), /* ddiv */
8b897cfa
RS
376};
377
378/* Instruction costs on PPC403 processors. */
379static const
380struct processor_costs ppc403_cost = {
06a67bdd
RS
381 COSTS_N_INSNS (4), /* mulsi */
382 COSTS_N_INSNS (4), /* mulsi_const */
383 COSTS_N_INSNS (4), /* mulsi_const9 */
384 COSTS_N_INSNS (4), /* muldi */
385 COSTS_N_INSNS (33), /* divsi */
386 COSTS_N_INSNS (33), /* divdi */
387 COSTS_N_INSNS (11), /* fp */
388 COSTS_N_INSNS (11), /* dmul */
389 COSTS_N_INSNS (11), /* sdiv */
390 COSTS_N_INSNS (11), /* ddiv */
8b897cfa
RS
391};
392
393/* Instruction costs on PPC405 processors. */
394static const
395struct processor_costs ppc405_cost = {
06a67bdd
RS
396 COSTS_N_INSNS (5), /* mulsi */
397 COSTS_N_INSNS (4), /* mulsi_const */
398 COSTS_N_INSNS (3), /* mulsi_const9 */
399 COSTS_N_INSNS (5), /* muldi */
400 COSTS_N_INSNS (35), /* divsi */
401 COSTS_N_INSNS (35), /* divdi */
402 COSTS_N_INSNS (11), /* fp */
403 COSTS_N_INSNS (11), /* dmul */
404 COSTS_N_INSNS (11), /* sdiv */
405 COSTS_N_INSNS (11), /* ddiv */
8b897cfa
RS
406};
407
408/* Instruction costs on PPC440 processors. */
409static const
410struct processor_costs ppc440_cost = {
06a67bdd
RS
411 COSTS_N_INSNS (3), /* mulsi */
412 COSTS_N_INSNS (2), /* mulsi_const */
413 COSTS_N_INSNS (2), /* mulsi_const9 */
414 COSTS_N_INSNS (3), /* muldi */
415 COSTS_N_INSNS (34), /* divsi */
416 COSTS_N_INSNS (34), /* divdi */
417 COSTS_N_INSNS (5), /* fp */
418 COSTS_N_INSNS (5), /* dmul */
419 COSTS_N_INSNS (19), /* sdiv */
420 COSTS_N_INSNS (33), /* ddiv */
8b897cfa
RS
421};
422
423/* Instruction costs on PPC601 processors. */
424static const
425struct processor_costs ppc601_cost = {
06a67bdd
RS
426 COSTS_N_INSNS (5), /* mulsi */
427 COSTS_N_INSNS (5), /* mulsi_const */
428 COSTS_N_INSNS (5), /* mulsi_const9 */
429 COSTS_N_INSNS (5), /* muldi */
430 COSTS_N_INSNS (36), /* divsi */
431 COSTS_N_INSNS (36), /* divdi */
432 COSTS_N_INSNS (4), /* fp */
433 COSTS_N_INSNS (5), /* dmul */
434 COSTS_N_INSNS (17), /* sdiv */
435 COSTS_N_INSNS (31), /* ddiv */
8b897cfa
RS
436};
437
438/* Instruction costs on PPC603 processors. */
439static const
440struct processor_costs ppc603_cost = {
06a67bdd
RS
441 COSTS_N_INSNS (5), /* mulsi */
442 COSTS_N_INSNS (3), /* mulsi_const */
443 COSTS_N_INSNS (2), /* mulsi_const9 */
444 COSTS_N_INSNS (5), /* muldi */
445 COSTS_N_INSNS (37), /* divsi */
446 COSTS_N_INSNS (37), /* divdi */
447 COSTS_N_INSNS (3), /* fp */
448 COSTS_N_INSNS (4), /* dmul */
449 COSTS_N_INSNS (18), /* sdiv */
450 COSTS_N_INSNS (33), /* ddiv */
8b897cfa
RS
451};
452
453/* Instruction costs on PPC604 processors. */
454static const
455struct processor_costs ppc604_cost = {
06a67bdd
RS
456 COSTS_N_INSNS (4), /* mulsi */
457 COSTS_N_INSNS (4), /* mulsi_const */
458 COSTS_N_INSNS (4), /* mulsi_const9 */
459 COSTS_N_INSNS (4), /* muldi */
460 COSTS_N_INSNS (20), /* divsi */
461 COSTS_N_INSNS (20), /* divdi */
462 COSTS_N_INSNS (3), /* fp */
463 COSTS_N_INSNS (3), /* dmul */
464 COSTS_N_INSNS (18), /* sdiv */
465 COSTS_N_INSNS (32), /* ddiv */
8b897cfa
RS
466};
467
468/* Instruction costs on PPC604e processors. */
469static const
470struct processor_costs ppc604e_cost = {
06a67bdd
RS
471 COSTS_N_INSNS (2), /* mulsi */
472 COSTS_N_INSNS (2), /* mulsi_const */
473 COSTS_N_INSNS (2), /* mulsi_const9 */
474 COSTS_N_INSNS (2), /* muldi */
475 COSTS_N_INSNS (20), /* divsi */
476 COSTS_N_INSNS (20), /* divdi */
477 COSTS_N_INSNS (3), /* fp */
478 COSTS_N_INSNS (3), /* dmul */
479 COSTS_N_INSNS (18), /* sdiv */
480 COSTS_N_INSNS (32), /* ddiv */
8b897cfa
RS
481};
482
f0517163 483/* Instruction costs on PPC620 processors. */
8b897cfa
RS
484static const
485struct processor_costs ppc620_cost = {
06a67bdd
RS
486 COSTS_N_INSNS (5), /* mulsi */
487 COSTS_N_INSNS (4), /* mulsi_const */
488 COSTS_N_INSNS (3), /* mulsi_const9 */
489 COSTS_N_INSNS (7), /* muldi */
490 COSTS_N_INSNS (21), /* divsi */
491 COSTS_N_INSNS (37), /* divdi */
492 COSTS_N_INSNS (3), /* fp */
493 COSTS_N_INSNS (3), /* dmul */
494 COSTS_N_INSNS (18), /* sdiv */
495 COSTS_N_INSNS (32), /* ddiv */
f0517163
RS
496};
497
498/* Instruction costs on PPC630 processors. */
499static const
500struct processor_costs ppc630_cost = {
06a67bdd
RS
501 COSTS_N_INSNS (5), /* mulsi */
502 COSTS_N_INSNS (4), /* mulsi_const */
503 COSTS_N_INSNS (3), /* mulsi_const9 */
504 COSTS_N_INSNS (7), /* muldi */
505 COSTS_N_INSNS (21), /* divsi */
506 COSTS_N_INSNS (37), /* divdi */
507 COSTS_N_INSNS (3), /* fp */
508 COSTS_N_INSNS (3), /* dmul */
509 COSTS_N_INSNS (17), /* sdiv */
510 COSTS_N_INSNS (21), /* ddiv */
8b897cfa
RS
511};
512
513/* Instruction costs on PPC750 and PPC7400 processors. */
514static const
515struct processor_costs ppc750_cost = {
06a67bdd
RS
516 COSTS_N_INSNS (5), /* mulsi */
517 COSTS_N_INSNS (3), /* mulsi_const */
518 COSTS_N_INSNS (2), /* mulsi_const9 */
519 COSTS_N_INSNS (5), /* muldi */
520 COSTS_N_INSNS (17), /* divsi */
521 COSTS_N_INSNS (17), /* divdi */
522 COSTS_N_INSNS (3), /* fp */
523 COSTS_N_INSNS (3), /* dmul */
524 COSTS_N_INSNS (17), /* sdiv */
525 COSTS_N_INSNS (31), /* ddiv */
8b897cfa
RS
526};
527
528/* Instruction costs on PPC7450 processors. */
529static const
530struct processor_costs ppc7450_cost = {
06a67bdd
RS
531 COSTS_N_INSNS (4), /* mulsi */
532 COSTS_N_INSNS (3), /* mulsi_const */
533 COSTS_N_INSNS (3), /* mulsi_const9 */
534 COSTS_N_INSNS (4), /* muldi */
535 COSTS_N_INSNS (23), /* divsi */
536 COSTS_N_INSNS (23), /* divdi */
537 COSTS_N_INSNS (5), /* fp */
538 COSTS_N_INSNS (5), /* dmul */
539 COSTS_N_INSNS (21), /* sdiv */
540 COSTS_N_INSNS (35), /* ddiv */
8b897cfa 541};
a3170dc6 542
8b897cfa
RS
543/* Instruction costs on PPC8540 processors. */
544static const
545struct processor_costs ppc8540_cost = {
06a67bdd
RS
546 COSTS_N_INSNS (4), /* mulsi */
547 COSTS_N_INSNS (4), /* mulsi_const */
548 COSTS_N_INSNS (4), /* mulsi_const9 */
549 COSTS_N_INSNS (4), /* muldi */
550 COSTS_N_INSNS (19), /* divsi */
551 COSTS_N_INSNS (19), /* divdi */
552 COSTS_N_INSNS (4), /* fp */
553 COSTS_N_INSNS (4), /* dmul */
554 COSTS_N_INSNS (29), /* sdiv */
555 COSTS_N_INSNS (29), /* ddiv */
8b897cfa
RS
556};
557
558/* Instruction costs on POWER4 and POWER5 processors. */
559static const
560struct processor_costs power4_cost = {
06a67bdd
RS
561 COSTS_N_INSNS (3), /* mulsi */
562 COSTS_N_INSNS (2), /* mulsi_const */
563 COSTS_N_INSNS (2), /* mulsi_const9 */
564 COSTS_N_INSNS (4), /* muldi */
565 COSTS_N_INSNS (18), /* divsi */
566 COSTS_N_INSNS (34), /* divdi */
567 COSTS_N_INSNS (3), /* fp */
568 COSTS_N_INSNS (3), /* dmul */
569 COSTS_N_INSNS (17), /* sdiv */
570 COSTS_N_INSNS (17), /* ddiv */
8b897cfa
RS
571};
572
573\f
a2369ed3 574static bool rs6000_function_ok_for_sibcall (tree, tree);
2ffa9a0c 575static const char *rs6000_invalid_within_doloop (rtx);
a2369ed3
DJ
576static rtx rs6000_generate_compare (enum rtx_code);
577static void rs6000_maybe_dead (rtx);
578static void rs6000_emit_stack_tie (void);
579static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
580static rtx spe_synthesize_frame_save (rtx);
581static bool spe_func_has_64bit_regs_p (void);
b20a9cca 582static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
d1d0c603 583 int, HOST_WIDE_INT);
a2369ed3
DJ
584static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
585static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
586static unsigned rs6000_hash_constant (rtx);
587static unsigned toc_hash_function (const void *);
588static int toc_hash_eq (const void *, const void *);
589static int constant_pool_expr_1 (rtx, int *, int *);
590static bool constant_pool_expr_p (rtx);
a2369ed3 591static bool legitimate_indexed_address_p (rtx, int);
a2369ed3
DJ
592static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
593static struct machine_function * rs6000_init_machine_status (void);
594static bool rs6000_assemble_integer (rtx, unsigned int, int);
6d0a8091 595static bool no_global_regs_above (int);
5add3202 596#ifdef HAVE_GAS_HIDDEN
a2369ed3 597static void rs6000_assemble_visibility (tree, int);
5add3202 598#endif
a2369ed3
DJ
599static int rs6000_ra_ever_killed (void);
600static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
8bb418a3 601static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
76d2b81d 602static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
f18eca82 603static const char *rs6000_mangle_fundamental_type (tree);
b86fe7b4 604extern const struct attribute_spec rs6000_attribute_table[];
a2369ed3
DJ
605static void rs6000_set_default_type_attributes (tree);
606static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
607static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
b20a9cca
AM
608static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
609 tree);
a2369ed3 610static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
c6e8c921 611static bool rs6000_return_in_memory (tree, tree);
a2369ed3 612static void rs6000_file_start (void);
7c262518 613#if TARGET_ELF
a2369ed3
DJ
614static unsigned int rs6000_elf_section_type_flags (tree, const char *, int);
615static void rs6000_elf_asm_out_constructor (rtx, int);
616static void rs6000_elf_asm_out_destructor (rtx, int);
1334b570 617static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
d6b5193b
RS
618static void rs6000_elf_asm_init_sections (void);
619static section *rs6000_elf_select_section (tree, int, unsigned HOST_WIDE_INT);
a2369ed3 620static void rs6000_elf_unique_section (tree, int);
d6b5193b
RS
621static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
622 unsigned HOST_WIDE_INT);
a56d7372 623static void rs6000_elf_encode_section_info (tree, rtx, int)
0e5dbd9b 624 ATTRIBUTE_UNUSED;
7c262518 625#endif
aacd3885 626static bool rs6000_use_blocks_for_constant_p (enum machine_mode, rtx);
cbaaba19 627#if TARGET_XCOFF
0d5817b2 628static void rs6000_xcoff_asm_output_anchor (rtx);
a2369ed3 629static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
d6b5193b 630static void rs6000_xcoff_asm_init_sections (void);
8210e4c4 631static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
d6b5193b 632static section *rs6000_xcoff_select_section (tree, int,
b20a9cca 633 unsigned HOST_WIDE_INT);
d6b5193b
RS
634static void rs6000_xcoff_unique_section (tree, int);
635static section *rs6000_xcoff_select_rtx_section
636 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
a2369ed3
DJ
637static const char * rs6000_xcoff_strip_name_encoding (const char *);
638static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
639static void rs6000_xcoff_file_start (void);
640static void rs6000_xcoff_file_end (void);
f1384257 641#endif
a2369ed3
DJ
642static int rs6000_variable_issue (FILE *, int, rtx, int);
643static bool rs6000_rtx_costs (rtx, int, int, int *);
644static int rs6000_adjust_cost (rtx, rtx, rtx, int);
cbe26ab8 645static bool is_microcoded_insn (rtx);
79ae11c4 646static int is_dispatch_slot_restricted (rtx);
cbe26ab8
DN
647static bool is_cracked_insn (rtx);
648static bool is_branch_slot_insn (rtx);
a2369ed3
DJ
649static int rs6000_adjust_priority (rtx, int);
650static int rs6000_issue_rate (void);
569fa502 651static bool rs6000_is_costly_dependence (rtx, rtx, rtx, int, int);
cbe26ab8
DN
652static rtx get_next_active_insn (rtx, rtx);
653static bool insn_terminates_group_p (rtx , enum group_termination);
654static bool is_costly_group (rtx *, rtx);
655static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
656static int redefine_groups (FILE *, int, rtx, rtx);
657static int pad_groups (FILE *, int, rtx, rtx);
658static void rs6000_sched_finish (FILE *, int);
a2369ed3 659static int rs6000_use_sched_lookahead (void);
7ccf35ed 660static tree rs6000_builtin_mask_for_load (void);
a2369ed3 661
58646b77 662static void def_builtin (int, const char *, tree, int);
a2369ed3
DJ
663static void rs6000_init_builtins (void);
664static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
665static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
666static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
667static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
668static void altivec_init_builtins (void);
669static void rs6000_common_init_builtins (void);
c15c90bb 670static void rs6000_init_libfuncs (void);
a2369ed3 671
b20a9cca
AM
672static void enable_mask_for_builtins (struct builtin_description *, int,
673 enum rs6000_builtins,
674 enum rs6000_builtins);
7c62e993 675static tree build_opaque_vector_type (tree, int);
a2369ed3
DJ
676static void spe_init_builtins (void);
677static rtx spe_expand_builtin (tree, rtx, bool *);
61bea3b0 678static rtx spe_expand_stv_builtin (enum insn_code, tree);
a2369ed3
DJ
679static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
680static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
681static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
d1d0c603
JJ
682static rs6000_stack_t *rs6000_stack_info (void);
683static void debug_stack_info (rs6000_stack_t *);
a2369ed3
DJ
684
685static rtx altivec_expand_builtin (tree, rtx, bool *);
686static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
687static rtx altivec_expand_st_builtin (tree, rtx, bool *);
688static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
689static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
f676971a 690static rtx altivec_expand_predicate_builtin (enum insn_code,
c4ad648e 691 const char *, tree, rtx);
b4a62fa0 692static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
a2369ed3 693static rtx altivec_expand_stv_builtin (enum insn_code, tree);
7a4eca66
DE
694static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
695static rtx altivec_expand_vec_set_builtin (tree);
696static rtx altivec_expand_vec_ext_builtin (tree, rtx);
697static int get_element_number (tree, tree);
78f5898b 698static bool rs6000_handle_option (size_t, const char *, int);
a2369ed3 699static void rs6000_parse_tls_size_option (void);
5da702b1 700static void rs6000_parse_yes_no_option (const char *, const char *, int *);
a2369ed3
DJ
701static int first_altivec_reg_to_save (void);
702static unsigned int compute_vrsave_mask (void);
9390387d 703static void compute_save_world_info (rs6000_stack_t *info_ptr);
a2369ed3
DJ
704static void is_altivec_return_reg (rtx, void *);
705static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
706int easy_vector_constant (rtx, enum machine_mode);
58646b77 707static bool rs6000_is_opaque_type (tree);
a2369ed3
DJ
708static rtx rs6000_dwarf_register_span (rtx);
709static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
fdbe66f2 710static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
a2369ed3
DJ
711static rtx rs6000_tls_get_addr (void);
712static rtx rs6000_got_sym (void);
9390387d 713static int rs6000_tls_symbol_ref_1 (rtx *, void *);
a2369ed3
DJ
714static const char *rs6000_get_some_local_dynamic_name (void);
715static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
ded9bf77 716static rtx rs6000_complex_function_value (enum machine_mode);
b20a9cca 717static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
a2369ed3 718 enum machine_mode, tree);
0b5383eb
DJ
719static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
720 HOST_WIDE_INT);
721static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
722 tree, HOST_WIDE_INT);
723static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
724 HOST_WIDE_INT,
725 rtx[], int *);
726static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
727 tree, HOST_WIDE_INT,
728 rtx[], int *);
729static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, tree, int, bool);
ec6376ab 730static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
b1917422 731static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
c6e8c921
GK
732static void setup_incoming_varargs (CUMULATIVE_ARGS *,
733 enum machine_mode, tree,
734 int *, int);
8cd5a4e0
RH
735static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
736 tree, bool);
78a52f11
RH
737static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
738 tree, bool);
4d3e6fae 739static const char *invalid_arg_for_unprototyped_fn (tree, tree, tree);
efdba735
SH
740#if TARGET_MACHO
741static void macho_branch_islands (void);
742static void add_compiler_branch_island (tree, tree, int);
743static int no_previous_def (tree function_name);
744static tree get_prev_label (tree function_name);
c4e18b1c 745static void rs6000_darwin_file_start (void);
efdba735
SH
746#endif
747
c35d187f 748static tree rs6000_build_builtin_va_list (void);
23a60a04 749static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
fe984136 750static bool rs6000_must_pass_in_stack (enum machine_mode, tree);
00b79d54 751static bool rs6000_scalar_mode_supported_p (enum machine_mode);
f676971a 752static bool rs6000_vector_mode_supported_p (enum machine_mode);
94ff898d 753static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
21213b4c 754 enum machine_mode);
94ff898d 755static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
21213b4c
DP
756 enum machine_mode);
757static int get_vsel_insn (enum machine_mode);
758static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
3aebbe5f 759static tree rs6000_stack_protect_fail (void);
21213b4c
DP
760
761const int INSN_NOT_AVAILABLE = -1;
93f90be6
FJ
762static enum machine_mode rs6000_eh_return_filter_mode (void);
763
17211ab5
GK
764/* Hash table stuff for keeping track of TOC entries. */
765
766struct toc_hash_struct GTY(())
767{
768 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
769 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
770 rtx key;
771 enum machine_mode key_mode;
772 int labelno;
773};
774
775static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
c81bebd7
MM
776\f
777/* Default register names. */
778char rs6000_reg_names[][8] =
779{
802a0058
MM
780 "0", "1", "2", "3", "4", "5", "6", "7",
781 "8", "9", "10", "11", "12", "13", "14", "15",
782 "16", "17", "18", "19", "20", "21", "22", "23",
783 "24", "25", "26", "27", "28", "29", "30", "31",
784 "0", "1", "2", "3", "4", "5", "6", "7",
785 "8", "9", "10", "11", "12", "13", "14", "15",
786 "16", "17", "18", "19", "20", "21", "22", "23",
787 "24", "25", "26", "27", "28", "29", "30", "31",
788 "mq", "lr", "ctr","ap",
789 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
790 "xer",
791 /* AltiVec registers. */
0cd5e3a1
AH
792 "0", "1", "2", "3", "4", "5", "6", "7",
793 "8", "9", "10", "11", "12", "13", "14", "15",
794 "16", "17", "18", "19", "20", "21", "22", "23",
795 "24", "25", "26", "27", "28", "29", "30", "31",
59a4c851
AH
796 "vrsave", "vscr",
797 /* SPE registers. */
7d5175e1
JJ
798 "spe_acc", "spefscr",
799 /* Soft frame pointer. */
800 "sfp"
c81bebd7
MM
801};
802
803#ifdef TARGET_REGNAMES
8b60264b 804static const char alt_reg_names[][8] =
c81bebd7 805{
802a0058
MM
806 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
807 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
808 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
809 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
810 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
811 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
812 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
813 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
814 "mq", "lr", "ctr", "ap",
815 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6 816 "xer",
59a4c851 817 /* AltiVec registers. */
0ac081f6 818 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
59a4c851
AH
819 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
820 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
821 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
822 "vrsave", "vscr",
823 /* SPE registers. */
7d5175e1
JJ
824 "spe_acc", "spefscr",
825 /* Soft frame pointer. */
826 "sfp"
c81bebd7
MM
827};
828#endif
9878760c 829\f
daf11973
MM
830#ifndef MASK_STRICT_ALIGN
831#define MASK_STRICT_ALIGN 0
832#endif
ffcfcb5f
AM
833#ifndef TARGET_PROFILE_KERNEL
834#define TARGET_PROFILE_KERNEL 0
835#endif
3961e8fe
RH
836
837/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
838#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
672a6f42
NB
839\f
840/* Initialize the GCC target structure. */
91d231cb
JM
841#undef TARGET_ATTRIBUTE_TABLE
842#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
843#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
844#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 845
301d03af
RS
846#undef TARGET_ASM_ALIGNED_DI_OP
847#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
848
849/* Default unaligned ops are only provided for ELF. Find the ops needed
850 for non-ELF systems. */
851#ifndef OBJECT_FORMAT_ELF
cbaaba19 852#if TARGET_XCOFF
ae6c1efd 853/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
854 64-bit targets. */
855#undef TARGET_ASM_UNALIGNED_HI_OP
856#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
857#undef TARGET_ASM_UNALIGNED_SI_OP
858#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
859#undef TARGET_ASM_UNALIGNED_DI_OP
860#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
861#else
862/* For Darwin. */
863#undef TARGET_ASM_UNALIGNED_HI_OP
864#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
865#undef TARGET_ASM_UNALIGNED_SI_OP
866#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
49bd1d27
SS
867#undef TARGET_ASM_UNALIGNED_DI_OP
868#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
869#undef TARGET_ASM_ALIGNED_DI_OP
870#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
301d03af
RS
871#endif
872#endif
873
874/* This hook deals with fixups for relocatable code and DI-mode objects
875 in 64-bit code. */
876#undef TARGET_ASM_INTEGER
877#define TARGET_ASM_INTEGER rs6000_assemble_integer
878
93638d7a
AM
879#ifdef HAVE_GAS_HIDDEN
880#undef TARGET_ASM_ASSEMBLE_VISIBILITY
881#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
882#endif
883
c4501e62
JJ
884#undef TARGET_HAVE_TLS
885#define TARGET_HAVE_TLS HAVE_AS_TLS
886
887#undef TARGET_CANNOT_FORCE_CONST_MEM
a7e0b075 888#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
c4501e62 889
08c148a8
NB
890#undef TARGET_ASM_FUNCTION_PROLOGUE
891#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
892#undef TARGET_ASM_FUNCTION_EPILOGUE
893#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
894
b54cf83a
DE
895#undef TARGET_SCHED_VARIABLE_ISSUE
896#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
897
c237e94a
ZW
898#undef TARGET_SCHED_ISSUE_RATE
899#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
900#undef TARGET_SCHED_ADJUST_COST
901#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
902#undef TARGET_SCHED_ADJUST_PRIORITY
903#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
f676971a 904#undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
569fa502 905#define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
cbe26ab8
DN
906#undef TARGET_SCHED_FINISH
907#define TARGET_SCHED_FINISH rs6000_sched_finish
c237e94a 908
be12c2b0
VM
909#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
910#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
911
7ccf35ed
DN
912#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
913#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
914
0ac081f6
AH
915#undef TARGET_INIT_BUILTINS
916#define TARGET_INIT_BUILTINS rs6000_init_builtins
917
918#undef TARGET_EXPAND_BUILTIN
919#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
920
f18eca82
ZL
921#undef TARGET_MANGLE_FUNDAMENTAL_TYPE
922#define TARGET_MANGLE_FUNDAMENTAL_TYPE rs6000_mangle_fundamental_type
923
c15c90bb
ZW
924#undef TARGET_INIT_LIBFUNCS
925#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
926
f1384257 927#if TARGET_MACHO
0e5dbd9b 928#undef TARGET_BINDS_LOCAL_P
31920d83 929#define TARGET_BINDS_LOCAL_P darwin_binds_local_p
f1384257 930#endif
0e5dbd9b 931
3961e8fe
RH
932#undef TARGET_ASM_OUTPUT_MI_THUNK
933#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
934
3961e8fe 935#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5b71a4e7 936#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
00b960c7 937
4977bab6
ZW
938#undef TARGET_FUNCTION_OK_FOR_SIBCALL
939#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
940
2e3f0db6
DJ
941#undef TARGET_INVALID_WITHIN_DOLOOP
942#define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
9419649c 943
3c50106f
RH
944#undef TARGET_RTX_COSTS
945#define TARGET_RTX_COSTS rs6000_rtx_costs
dcefdf67
RH
946#undef TARGET_ADDRESS_COST
947#define TARGET_ADDRESS_COST hook_int_rtx_0
3c50106f 948
c8e4f0e9 949#undef TARGET_VECTOR_OPAQUE_P
58646b77 950#define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
62e1dfcf 951
96714395
AH
952#undef TARGET_DWARF_REGISTER_SPAN
953#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
954
c6e8c921
GK
955/* On rs6000, function arguments are promoted, as are function return
956 values. */
957#undef TARGET_PROMOTE_FUNCTION_ARGS
958#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
959#undef TARGET_PROMOTE_FUNCTION_RETURN
960#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
961
c6e8c921
GK
962#undef TARGET_RETURN_IN_MEMORY
963#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
964
965#undef TARGET_SETUP_INCOMING_VARARGS
966#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
967
968/* Always strict argument naming on rs6000. */
969#undef TARGET_STRICT_ARGUMENT_NAMING
970#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
971#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
972#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
42ba5130
RH
973#undef TARGET_SPLIT_COMPLEX_ARG
974#define TARGET_SPLIT_COMPLEX_ARG hook_bool_tree_true
fe984136
RH
975#undef TARGET_MUST_PASS_IN_STACK
976#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
8cd5a4e0
RH
977#undef TARGET_PASS_BY_REFERENCE
978#define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
78a52f11
RH
979#undef TARGET_ARG_PARTIAL_BYTES
980#define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
c6e8c921 981
c35d187f
RH
982#undef TARGET_BUILD_BUILTIN_VA_LIST
983#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
984
cd3ce9b4
JM
985#undef TARGET_GIMPLIFY_VA_ARG_EXPR
986#define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
987
93f90be6
FJ
988#undef TARGET_EH_RETURN_FILTER_MODE
989#define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
990
00b79d54
BE
991#undef TARGET_SCALAR_MODE_SUPPORTED_P
992#define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
993
f676971a
EC
994#undef TARGET_VECTOR_MODE_SUPPORTED_P
995#define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
996
4d3e6fae
FJ
997#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
998#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
999
78f5898b
AH
1000#undef TARGET_HANDLE_OPTION
1001#define TARGET_HANDLE_OPTION rs6000_handle_option
1002
1003#undef TARGET_DEFAULT_TARGET_FLAGS
1004#define TARGET_DEFAULT_TARGET_FLAGS \
716019c0 1005 (TARGET_DEFAULT)
78f5898b 1006
3aebbe5f
JJ
1007#undef TARGET_STACK_PROTECT_FAIL
1008#define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1009
445cf5eb
JM
1010/* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1011 The PowerPC architecture requires only weak consistency among
1012 processors--that is, memory accesses between processors need not be
1013 sequentially consistent and memory accesses among processors can occur
1014 in any order. The ability to order memory accesses weakly provides
1015 opportunities for more efficient use of the system bus. Unless a
1016 dependency exists, the 604e allows read operations to precede store
1017 operations. */
1018#undef TARGET_RELAXED_ORDERING
1019#define TARGET_RELAXED_ORDERING true
1020
fdbe66f2
EB
1021#ifdef HAVE_AS_TLS
1022#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1023#define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1024#endif
1025
aacd3885
RS
1026/* Use a 32-bit anchor range. This leads to sequences like:
1027
1028 addis tmp,anchor,high
1029 add dest,tmp,low
1030
1031 where tmp itself acts as an anchor, and can be shared between
1032 accesses to the same 64k page. */
1033#undef TARGET_MIN_ANCHOR_OFFSET
1034#define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1035#undef TARGET_MAX_ANCHOR_OFFSET
1036#define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1037#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1038#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1039
f6897b10 1040struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 1041\f
0d1fbc8c
AH
1042
1043/* Value is 1 if hard register REGNO can hold a value of machine-mode
1044 MODE. */
1045static int
1046rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1047{
1048 /* The GPRs can hold any mode, but values bigger than one register
1049 cannot go past R31. */
1050 if (INT_REGNO_P (regno))
1051 return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
1052
a5a97921
BE
1053 /* The float registers can only hold floating modes and DImode.
1054 This also excludes decimal float modes. */
0d1fbc8c
AH
1055 if (FP_REGNO_P (regno))
1056 return
ebb109ad 1057 (SCALAR_FLOAT_MODE_P (mode)
a5a97921 1058 && !DECIMAL_FLOAT_MODE_P (mode)
0d1fbc8c
AH
1059 && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
1060 || (GET_MODE_CLASS (mode) == MODE_INT
1061 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
1062
1063 /* The CR register can only hold CC modes. */
1064 if (CR_REGNO_P (regno))
1065 return GET_MODE_CLASS (mode) == MODE_CC;
1066
1067 if (XER_REGNO_P (regno))
1068 return mode == PSImode;
1069
1070 /* AltiVec only in AldyVec registers. */
1071 if (ALTIVEC_REGNO_P (regno))
1072 return ALTIVEC_VECTOR_MODE (mode);
1073
1074 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1075 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1076 return 1;
1077
1078 /* We cannot put TImode anywhere except general register and it must be
1079 able to fit within the register set. */
1080
1081 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1082}
1083
1084/* Initialize rs6000_hard_regno_mode_ok_p table. */
1085static void
1086rs6000_init_hard_regno_mode_ok (void)
1087{
1088 int r, m;
1089
1090 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1091 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1092 if (rs6000_hard_regno_mode_ok (r, m))
1093 rs6000_hard_regno_mode_ok_p[m][r] = true;
1094}
1095
c1e55850
GK
1096/* If not otherwise specified by a target, make 'long double' equivalent to
1097 'double'. */
1098
1099#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1100#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1101#endif
1102
5248c961
RK
1103/* Override command line options. Mostly we process the processor
1104 type and sometimes adjust other TARGET_ options. */
1105
1106void
d779d0dc 1107rs6000_override_options (const char *default_cpu)
5248c961 1108{
c4d38ccb 1109 size_t i, j;
8e3f41e7 1110 struct rs6000_cpu_select *ptr;
66188a7e 1111 int set_masks;
5248c961 1112
66188a7e 1113 /* Simplifications for entries below. */
85638c0d 1114
66188a7e
GK
1115 enum {
1116 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1117 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1118 };
85638c0d 1119
66188a7e
GK
1120 /* This table occasionally claims that a processor does not support
1121 a particular feature even though it does, but the feature is slower
1122 than the alternative. Thus, it shouldn't be relied on as a
f676971a 1123 complete description of the processor's support.
66188a7e
GK
1124
1125 Please keep this list in order, and don't forget to update the
1126 documentation in invoke.texi when adding a new processor or
1127 flag. */
5248c961
RK
1128 static struct ptt
1129 {
8b60264b
KG
1130 const char *const name; /* Canonical processor name. */
1131 const enum processor_type processor; /* Processor type enum value. */
1132 const int target_enable; /* Target flags to enable. */
8b60264b 1133 } const processor_target_table[]
66188a7e 1134 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
49a0b204 1135 {"403", PROCESSOR_PPC403,
66188a7e 1136 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
131aeb82 1137 {"405", PROCESSOR_PPC405,
716019c0
JM
1138 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1139 {"405fp", PROCESSOR_PPC405,
1140 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
131aeb82 1141 {"440", PROCESSOR_PPC440,
716019c0
JM
1142 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1143 {"440fp", PROCESSOR_PPC440,
1144 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
66188a7e 1145 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
5248c961 1146 {"601", PROCESSOR_PPC601,
66188a7e
GK
1147 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1148 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1149 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1150 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1151 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1152 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
7ddb6568
AM
1153 {"620", PROCESSOR_PPC620,
1154 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1155 {"630", PROCESSOR_PPC630,
1156 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
66188a7e
GK
1157 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1158 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1159 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1160 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1161 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1162 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1163 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1164 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
4d4cbc0e
AH
1165 /* 8548 has a dummy entry for now. */
1166 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
66188a7e 1167 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
7177e720 1168 {"970", PROCESSOR_POWER4,
66188a7e
GK
1169 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1170 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1171 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1172 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1173 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
49ffe578 1174 {"G5", PROCESSOR_POWER4,
66188a7e
GK
1175 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1176 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1177 {"power2", PROCESSOR_POWER,
1178 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
7ddb6568
AM
1179 {"power3", PROCESSOR_PPC630,
1180 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1181 {"power4", PROCESSOR_POWER4,
fc091c8e 1182 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
ec507f2d 1183 {"power5", PROCESSOR_POWER5,
432218ba
DE
1184 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1185 | MASK_MFCRF | MASK_POPCNTB},
9719f3b7
DE
1186 {"power5+", PROCESSOR_POWER5,
1187 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1188 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
66188a7e
GK
1189 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1190 {"powerpc64", PROCESSOR_POWERPC64,
98c41d98 1191 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
66188a7e
GK
1192 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1193 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1194 {"rios2", PROCESSOR_RIOS2,
1195 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1196 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1197 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
98c41d98
DE
1198 {"rs64", PROCESSOR_RS64A,
1199 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
66188a7e 1200 };
5248c961 1201
ca7558fc 1202 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 1203
66188a7e
GK
1204 /* Some OSs don't support saving the high part of 64-bit registers on
1205 context switch. Other OSs don't support saving Altivec registers.
1206 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1207 settings; if the user wants either, the user must explicitly specify
1208 them and we won't interfere with the user's specification. */
1209
1210 enum {
1211 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
f676971a 1212 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT
66188a7e 1213 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
716019c0
JM
1214 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
1215 | MASK_DLMZB)
66188a7e 1216 };
0d1fbc8c
AH
1217
1218 rs6000_init_hard_regno_mode_ok ();
1219
c4ad648e 1220 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
66188a7e
GK
1221#ifdef OS_MISSING_POWERPC64
1222 if (OS_MISSING_POWERPC64)
1223 set_masks &= ~MASK_POWERPC64;
1224#endif
1225#ifdef OS_MISSING_ALTIVEC
1226 if (OS_MISSING_ALTIVEC)
1227 set_masks &= ~MASK_ALTIVEC;
1228#endif
1229
768875a8
AM
1230 /* Don't override by the processor default if given explicitly. */
1231 set_masks &= ~target_flags_explicit;
957211c3 1232
a4f6c312 1233 /* Identify the processor type. */
8e3f41e7 1234 rs6000_select[0].string = default_cpu;
3cb999d8 1235 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 1236
b6a1cbae 1237 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 1238 {
8e3f41e7
MM
1239 ptr = &rs6000_select[i];
1240 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 1241 {
8e3f41e7
MM
1242 for (j = 0; j < ptt_size; j++)
1243 if (! strcmp (ptr->string, processor_target_table[j].name))
1244 {
1245 if (ptr->set_tune_p)
1246 rs6000_cpu = processor_target_table[j].processor;
1247
1248 if (ptr->set_arch_p)
1249 {
66188a7e
GK
1250 target_flags &= ~set_masks;
1251 target_flags |= (processor_target_table[j].target_enable
1252 & set_masks);
8e3f41e7
MM
1253 }
1254 break;
1255 }
1256
4406229e 1257 if (j == ptt_size)
8e3f41e7 1258 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
1259 }
1260 }
8a61d227 1261
993f19a8 1262 if (TARGET_E500)
a3170dc6
AH
1263 rs6000_isel = 1;
1264
dff9f1b6
DE
1265 /* If we are optimizing big endian systems for space, use the load/store
1266 multiple and string instructions. */
ef792183 1267 if (BYTES_BIG_ENDIAN && optimize_size)
957211c3 1268 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
938937d8 1269
a4f6c312
SS
1270 /* Don't allow -mmultiple or -mstring on little endian systems
1271 unless the cpu is a 750, because the hardware doesn't support the
1272 instructions used in little endian mode, and causes an alignment
1273 trap. The 750 does not cause an alignment trap (except when the
1274 target is unaligned). */
bef84347 1275
b21fb038 1276 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
1277 {
1278 if (TARGET_MULTIPLE)
1279 {
1280 target_flags &= ~MASK_MULTIPLE;
b21fb038 1281 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
d4ee4d25 1282 warning (0, "-mmultiple is not supported on little endian systems");
7e69e155
MM
1283 }
1284
1285 if (TARGET_STRING)
1286 {
1287 target_flags &= ~MASK_STRING;
b21fb038 1288 if ((target_flags_explicit & MASK_STRING) != 0)
d4ee4d25 1289 warning (0, "-mstring is not supported on little endian systems");
7e69e155
MM
1290 }
1291 }
3933e0e1 1292
38c1f2d7
MM
1293 /* Set debug flags */
1294 if (rs6000_debug_name)
1295 {
bfc79d3b 1296 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 1297 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 1298 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 1299 rs6000_debug_stack = 1;
bfc79d3b 1300 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
1301 rs6000_debug_arg = 1;
1302 else
c725bd79 1303 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
1304 }
1305
57ac7be9
AM
1306 if (rs6000_traceback_name)
1307 {
1308 if (! strncmp (rs6000_traceback_name, "full", 4))
1309 rs6000_traceback = traceback_full;
1310 else if (! strncmp (rs6000_traceback_name, "part", 4))
1311 rs6000_traceback = traceback_part;
1312 else if (! strncmp (rs6000_traceback_name, "no", 2))
1313 rs6000_traceback = traceback_none;
1314 else
9e637a26 1315 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
57ac7be9
AM
1316 rs6000_traceback_name);
1317 }
1318
78f5898b
AH
1319 if (!rs6000_explicit_options.long_double)
1320 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
6fa3f289 1321
602ea4d3
JJ
1322#ifndef POWERPC_LINUX
1323 if (!rs6000_explicit_options.abi)
1324 rs6000_ieeequad = 1;
1325#endif
1326
6d0ef01e
HP
1327 /* Set Altivec ABI as default for powerpc64 linux. */
1328 if (TARGET_ELF && TARGET_64BIT)
1329 {
1330 rs6000_altivec_abi = 1;
78f5898b 1331 TARGET_ALTIVEC_VRSAVE = 1;
6d0ef01e
HP
1332 }
1333
594a51fe
SS
1334 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1335 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1336 {
1337 rs6000_darwin64_abi = 1;
9c7956fd 1338#if TARGET_MACHO
6ac49599 1339 darwin_one_byte_bool = 1;
9c7956fd 1340#endif
d9168963
SS
1341 /* Default to natural alignment, for better performance. */
1342 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
594a51fe
SS
1343 }
1344
c4501e62
JJ
1345 /* Handle -mtls-size option. */
1346 rs6000_parse_tls_size_option ();
1347
a7ae18e2
AH
1348#ifdef SUBTARGET_OVERRIDE_OPTIONS
1349 SUBTARGET_OVERRIDE_OPTIONS;
1350#endif
1351#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1352 SUBSUBTARGET_OVERRIDE_OPTIONS;
1353#endif
4d4cbc0e
AH
1354#ifdef SUB3TARGET_OVERRIDE_OPTIONS
1355 SUB3TARGET_OVERRIDE_OPTIONS;
1356#endif
a7ae18e2 1357
5da702b1
AH
1358 if (TARGET_E500)
1359 {
e4463bf1
AH
1360 if (TARGET_ALTIVEC)
1361 error ("AltiVec and E500 instructions cannot coexist");
1362
5da702b1
AH
1363 /* The e500 does not have string instructions, and we set
1364 MASK_STRING above when optimizing for size. */
1365 if ((target_flags & MASK_STRING) != 0)
1366 target_flags = target_flags & ~MASK_STRING;
1367 }
1368 else if (rs6000_select[1].string != NULL)
1369 {
1370 /* For the powerpc-eabispe configuration, we set all these by
1371 default, so let's unset them if we manually set another
1372 CPU that is not the E500. */
78f5898b 1373 if (!rs6000_explicit_options.abi)
5da702b1 1374 rs6000_spe_abi = 0;
78f5898b 1375 if (!rs6000_explicit_options.spe)
5da702b1 1376 rs6000_spe = 0;
78f5898b 1377 if (!rs6000_explicit_options.float_gprs)
5da702b1 1378 rs6000_float_gprs = 0;
78f5898b 1379 if (!rs6000_explicit_options.isel)
5da702b1 1380 rs6000_isel = 0;
78f5898b 1381 if (!rs6000_explicit_options.long_double)
c1e55850 1382 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
5da702b1 1383 }
b5044283 1384
ec507f2d
DE
1385 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
1386 && rs6000_cpu != PROCESSOR_POWER5);
1387 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1388 || rs6000_cpu == PROCESSOR_POWER5);
1389
ec507f2d
DE
1390 rs6000_sched_restricted_insns_priority
1391 = (rs6000_sched_groups ? 1 : 0);
79ae11c4 1392
569fa502 1393 /* Handle -msched-costly-dep option. */
ec507f2d
DE
1394 rs6000_sched_costly_dep
1395 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
432218ba 1396
569fa502
DN
1397 if (rs6000_sched_costly_dep_str)
1398 {
f676971a 1399 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
c4ad648e 1400 rs6000_sched_costly_dep = no_dep_costly;
569fa502 1401 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
c4ad648e 1402 rs6000_sched_costly_dep = all_deps_costly;
569fa502 1403 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
c4ad648e 1404 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
569fa502 1405 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
c4ad648e 1406 rs6000_sched_costly_dep = store_to_load_dep_costly;
f676971a 1407 else
c4ad648e 1408 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
cbe26ab8
DN
1409 }
1410
1411 /* Handle -minsert-sched-nops option. */
ec507f2d
DE
1412 rs6000_sched_insert_nops
1413 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
432218ba 1414
cbe26ab8
DN
1415 if (rs6000_sched_insert_nops_str)
1416 {
1417 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
c4ad648e 1418 rs6000_sched_insert_nops = sched_finish_none;
cbe26ab8 1419 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
c4ad648e 1420 rs6000_sched_insert_nops = sched_finish_pad_groups;
cbe26ab8 1421 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
c4ad648e 1422 rs6000_sched_insert_nops = sched_finish_regroup_exact;
cbe26ab8 1423 else
c4ad648e 1424 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
569fa502
DN
1425 }
1426
c81bebd7 1427#ifdef TARGET_REGNAMES
a4f6c312
SS
1428 /* If the user desires alternate register names, copy in the
1429 alternate names now. */
c81bebd7 1430 if (TARGET_REGNAMES)
4e135bdd 1431 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
1432#endif
1433
df01da37 1434 /* Set aix_struct_return last, after the ABI is determined.
6fa3f289
ZW
1435 If -maix-struct-return or -msvr4-struct-return was explicitly
1436 used, don't override with the ABI default. */
df01da37
DE
1437 if (!rs6000_explicit_options.aix_struct_ret)
1438 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
6fa3f289 1439
602ea4d3 1440 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
70a01792 1441 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
fcce224d 1442
f676971a 1443 if (TARGET_TOC)
9ebbca7d 1444 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 1445
301d03af
RS
1446 /* We can only guarantee the availability of DI pseudo-ops when
1447 assembling for 64-bit targets. */
ae6c1efd 1448 if (!TARGET_64BIT)
301d03af
RS
1449 {
1450 targetm.asm_out.aligned_op.di = NULL;
1451 targetm.asm_out.unaligned_op.di = NULL;
1452 }
1453
1494c534
DE
1454 /* Set branch target alignment, if not optimizing for size. */
1455 if (!optimize_size)
1456 {
1457 if (rs6000_sched_groups)
1458 {
1459 if (align_functions <= 0)
1460 align_functions = 16;
1461 if (align_jumps <= 0)
1462 align_jumps = 16;
1463 if (align_loops <= 0)
1464 align_loops = 16;
1465 }
1466 if (align_jumps_max_skip <= 0)
1467 align_jumps_max_skip = 15;
1468 if (align_loops_max_skip <= 0)
1469 align_loops_max_skip = 15;
1470 }
2792d578 1471
71f123ca
FS
1472 /* Arrange to save and restore machine status around nested functions. */
1473 init_machine_status = rs6000_init_machine_status;
42ba5130
RH
1474
1475 /* We should always be splitting complex arguments, but we can't break
1476 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
18f63bfa 1477 if (DEFAULT_ABI != ABI_AIX)
42ba5130 1478 targetm.calls.split_complex_arg = NULL;
8b897cfa
RS
1479
1480 /* Initialize rs6000_cost with the appropriate target costs. */
1481 if (optimize_size)
1482 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1483 else
1484 switch (rs6000_cpu)
1485 {
1486 case PROCESSOR_RIOS1:
1487 rs6000_cost = &rios1_cost;
1488 break;
1489
1490 case PROCESSOR_RIOS2:
1491 rs6000_cost = &rios2_cost;
1492 break;
1493
1494 case PROCESSOR_RS64A:
1495 rs6000_cost = &rs64a_cost;
1496 break;
1497
1498 case PROCESSOR_MPCCORE:
1499 rs6000_cost = &mpccore_cost;
1500 break;
1501
1502 case PROCESSOR_PPC403:
1503 rs6000_cost = &ppc403_cost;
1504 break;
1505
1506 case PROCESSOR_PPC405:
1507 rs6000_cost = &ppc405_cost;
1508 break;
1509
1510 case PROCESSOR_PPC440:
1511 rs6000_cost = &ppc440_cost;
1512 break;
1513
1514 case PROCESSOR_PPC601:
1515 rs6000_cost = &ppc601_cost;
1516 break;
1517
1518 case PROCESSOR_PPC603:
1519 rs6000_cost = &ppc603_cost;
1520 break;
1521
1522 case PROCESSOR_PPC604:
1523 rs6000_cost = &ppc604_cost;
1524 break;
1525
1526 case PROCESSOR_PPC604e:
1527 rs6000_cost = &ppc604e_cost;
1528 break;
1529
1530 case PROCESSOR_PPC620:
8b897cfa
RS
1531 rs6000_cost = &ppc620_cost;
1532 break;
1533
f0517163
RS
1534 case PROCESSOR_PPC630:
1535 rs6000_cost = &ppc630_cost;
1536 break;
1537
8b897cfa
RS
1538 case PROCESSOR_PPC750:
1539 case PROCESSOR_PPC7400:
1540 rs6000_cost = &ppc750_cost;
1541 break;
1542
1543 case PROCESSOR_PPC7450:
1544 rs6000_cost = &ppc7450_cost;
1545 break;
1546
1547 case PROCESSOR_PPC8540:
1548 rs6000_cost = &ppc8540_cost;
1549 break;
1550
1551 case PROCESSOR_POWER4:
1552 case PROCESSOR_POWER5:
1553 rs6000_cost = &power4_cost;
1554 break;
1555
1556 default:
37409796 1557 gcc_unreachable ();
8b897cfa 1558 }
5248c961 1559}
5accd822 1560
7ccf35ed
DN
1561/* Implement targetm.vectorize.builtin_mask_for_load. */
1562static tree
1563rs6000_builtin_mask_for_load (void)
1564{
1565 if (TARGET_ALTIVEC)
1566 return altivec_builtin_mask_for_load;
1567 else
1568 return 0;
1569}
1570
5da702b1
AH
1571/* Handle generic options of the form -mfoo=yes/no.
1572 NAME is the option name.
1573 VALUE is the option value.
1574 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1575 whether the option value is 'yes' or 'no' respectively. */
993f19a8 1576static void
5da702b1 1577rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
993f19a8 1578{
5da702b1 1579 if (value == 0)
993f19a8 1580 return;
5da702b1
AH
1581 else if (!strcmp (value, "yes"))
1582 *flag = 1;
1583 else if (!strcmp (value, "no"))
1584 *flag = 0;
08b57fb3 1585 else
5da702b1 1586 error ("unknown -m%s= option specified: '%s'", name, value);
08b57fb3
AH
1587}
1588
c4501e62
JJ
1589/* Validate and record the size specified with the -mtls-size option. */
1590
1591static void
863d938c 1592rs6000_parse_tls_size_option (void)
c4501e62
JJ
1593{
1594 if (rs6000_tls_size_string == 0)
1595 return;
1596 else if (strcmp (rs6000_tls_size_string, "16") == 0)
1597 rs6000_tls_size = 16;
1598 else if (strcmp (rs6000_tls_size_string, "32") == 0)
1599 rs6000_tls_size = 32;
1600 else if (strcmp (rs6000_tls_size_string, "64") == 0)
1601 rs6000_tls_size = 64;
1602 else
9e637a26 1603 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
c4501e62
JJ
1604}
1605
5accd822 1606void
a2369ed3 1607optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
5accd822 1608{
2e3f0db6
DJ
1609 if (DEFAULT_ABI == ABI_DARWIN)
1610 /* The Darwin libraries never set errno, so we might as well
1611 avoid calling them when that's the only reason we would. */
1612 flag_errno_math = 0;
59d6560b
DE
1613
1614 /* Double growth factor to counter reduced min jump length. */
1615 set_param_value ("max-grow-copy-bb-insns", 16);
5accd822 1616}
78f5898b
AH
1617
1618/* Implement TARGET_HANDLE_OPTION. */
1619
1620static bool
1621rs6000_handle_option (size_t code, const char *arg, int value)
1622{
1623 switch (code)
1624 {
1625 case OPT_mno_power:
1626 target_flags &= ~(MASK_POWER | MASK_POWER2
1627 | MASK_MULTIPLE | MASK_STRING);
c2dba4ab
AH
1628 target_flags_explicit |= (MASK_POWER | MASK_POWER2
1629 | MASK_MULTIPLE | MASK_STRING);
78f5898b
AH
1630 break;
1631 case OPT_mno_powerpc:
1632 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
1633 | MASK_PPC_GFXOPT | MASK_POWERPC64);
c2dba4ab
AH
1634 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
1635 | MASK_PPC_GFXOPT | MASK_POWERPC64);
78f5898b
AH
1636 break;
1637 case OPT_mfull_toc:
d2894ab5
DE
1638 target_flags &= ~MASK_MINIMAL_TOC;
1639 TARGET_NO_FP_IN_TOC = 0;
1640 TARGET_NO_SUM_IN_TOC = 0;
1641 target_flags_explicit |= MASK_MINIMAL_TOC;
78f5898b
AH
1642#ifdef TARGET_USES_SYSV4_OPT
1643 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
1644 just the same as -mminimal-toc. */
1645 target_flags |= MASK_MINIMAL_TOC;
c2dba4ab 1646 target_flags_explicit |= MASK_MINIMAL_TOC;
78f5898b
AH
1647#endif
1648 break;
1649
1650#ifdef TARGET_USES_SYSV4_OPT
1651 case OPT_mtoc:
1652 /* Make -mtoc behave like -mminimal-toc. */
1653 target_flags |= MASK_MINIMAL_TOC;
c2dba4ab 1654 target_flags_explicit |= MASK_MINIMAL_TOC;
78f5898b
AH
1655 break;
1656#endif
1657
1658#ifdef TARGET_USES_AIX64_OPT
1659 case OPT_maix64:
1660#else
1661 case OPT_m64:
1662#endif
2c9c9afd
AM
1663 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
1664 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
1665 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
78f5898b
AH
1666 break;
1667
1668#ifdef TARGET_USES_AIX64_OPT
1669 case OPT_maix32:
1670#else
1671 case OPT_m32:
1672#endif
1673 target_flags &= ~MASK_POWERPC64;
c2dba4ab 1674 target_flags_explicit |= MASK_POWERPC64;
78f5898b
AH
1675 break;
1676
1677 case OPT_minsert_sched_nops_:
1678 rs6000_sched_insert_nops_str = arg;
1679 break;
1680
1681 case OPT_mminimal_toc:
1682 if (value == 1)
1683 {
d2894ab5
DE
1684 TARGET_NO_FP_IN_TOC = 0;
1685 TARGET_NO_SUM_IN_TOC = 0;
78f5898b
AH
1686 }
1687 break;
1688
1689 case OPT_mpower:
1690 if (value == 1)
c2dba4ab
AH
1691 {
1692 target_flags |= (MASK_MULTIPLE | MASK_STRING);
1693 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
1694 }
78f5898b
AH
1695 break;
1696
1697 case OPT_mpower2:
1698 if (value == 1)
c2dba4ab
AH
1699 {
1700 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1701 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
1702 }
78f5898b
AH
1703 break;
1704
1705 case OPT_mpowerpc_gpopt:
1706 case OPT_mpowerpc_gfxopt:
1707 if (value == 1)
c2dba4ab
AH
1708 {
1709 target_flags |= MASK_POWERPC;
1710 target_flags_explicit |= MASK_POWERPC;
1711 }
78f5898b
AH
1712 break;
1713
df01da37
DE
1714 case OPT_maix_struct_return:
1715 case OPT_msvr4_struct_return:
1716 rs6000_explicit_options.aix_struct_ret = true;
1717 break;
1718
78f5898b
AH
1719 case OPT_mvrsave_:
1720 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
1721 break;
78f5898b
AH
1722
1723 case OPT_misel_:
1724 rs6000_explicit_options.isel = true;
1725 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
1726 break;
1727
1728 case OPT_mspe_:
1729 rs6000_explicit_options.spe = true;
1730 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
1731 /* No SPE means 64-bit long doubles, even if an E500. */
1732 if (!rs6000_spe)
1733 rs6000_long_double_type_size = 64;
1734 break;
1735
1736 case OPT_mdebug_:
1737 rs6000_debug_name = arg;
1738 break;
1739
1740#ifdef TARGET_USES_SYSV4_OPT
1741 case OPT_mcall_:
1742 rs6000_abi_name = arg;
1743 break;
1744
1745 case OPT_msdata_:
1746 rs6000_sdata_name = arg;
1747 break;
1748
1749 case OPT_mtls_size_:
1750 rs6000_tls_size_string = arg;
1751 break;
1752
1753 case OPT_mrelocatable:
1754 if (value == 1)
c2dba4ab 1755 {
e0bf274f
AM
1756 target_flags |= MASK_MINIMAL_TOC;
1757 target_flags_explicit |= MASK_MINIMAL_TOC;
1758 TARGET_NO_FP_IN_TOC = 1;
c2dba4ab 1759 }
78f5898b
AH
1760 break;
1761
1762 case OPT_mrelocatable_lib:
1763 if (value == 1)
c2dba4ab 1764 {
e0bf274f
AM
1765 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1766 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
1767 TARGET_NO_FP_IN_TOC = 1;
c2dba4ab 1768 }
78f5898b 1769 else
c2dba4ab
AH
1770 {
1771 target_flags &= ~MASK_RELOCATABLE;
1772 target_flags_explicit |= MASK_RELOCATABLE;
1773 }
78f5898b
AH
1774 break;
1775#endif
1776
1777 case OPT_mabi_:
1778 rs6000_explicit_options.abi = true;
1779 if (!strcmp (arg, "altivec"))
1780 {
1781 rs6000_altivec_abi = 1;
1782 rs6000_spe_abi = 0;
1783 }
1784 else if (! strcmp (arg, "no-altivec"))
1785 rs6000_altivec_abi = 0;
1786 else if (! strcmp (arg, "spe"))
1787 {
1788 rs6000_spe_abi = 1;
1789 rs6000_altivec_abi = 0;
1790 if (!TARGET_SPE_ABI)
1791 error ("not configured for ABI: '%s'", arg);
1792 }
1793 else if (! strcmp (arg, "no-spe"))
1794 rs6000_spe_abi = 0;
1795
1796 /* These are here for testing during development only, do not
1797 document in the manual please. */
1798 else if (! strcmp (arg, "d64"))
1799 {
1800 rs6000_darwin64_abi = 1;
1801 warning (0, "Using darwin64 ABI");
1802 }
1803 else if (! strcmp (arg, "d32"))
1804 {
1805 rs6000_darwin64_abi = 0;
1806 warning (0, "Using old darwin ABI");
1807 }
1808
602ea4d3
JJ
1809 else if (! strcmp (arg, "ibmlongdouble"))
1810 {
1811 rs6000_ieeequad = 0;
1812 warning (0, "Using IBM extended precision long double");
1813 }
1814 else if (! strcmp (arg, "ieeelongdouble"))
1815 {
1816 rs6000_ieeequad = 1;
1817 warning (0, "Using IEEE extended precision long double");
1818 }
1819
78f5898b
AH
1820 else
1821 {
1822 error ("unknown ABI specified: '%s'", arg);
1823 return false;
1824 }
1825 break;
1826
1827 case OPT_mcpu_:
1828 rs6000_select[1].string = arg;
1829 break;
1830
1831 case OPT_mtune_:
1832 rs6000_select[2].string = arg;
1833 break;
1834
1835 case OPT_mtraceback_:
1836 rs6000_traceback_name = arg;
1837 break;
1838
1839 case OPT_mfloat_gprs_:
1840 rs6000_explicit_options.float_gprs = true;
1841 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
1842 rs6000_float_gprs = 1;
1843 else if (! strcmp (arg, "double"))
1844 rs6000_float_gprs = 2;
1845 else if (! strcmp (arg, "no"))
1846 rs6000_float_gprs = 0;
1847 else
1848 {
1849 error ("invalid option for -mfloat-gprs: '%s'", arg);
1850 return false;
1851 }
1852 break;
1853
1854 case OPT_mlong_double_:
1855 rs6000_explicit_options.long_double = true;
1856 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1857 if (value != 64 && value != 128)
1858 {
1859 error ("Unknown switch -mlong-double-%s", arg);
1860 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
1861 return false;
1862 }
1863 else
1864 rs6000_long_double_type_size = value;
1865 break;
1866
1867 case OPT_msched_costly_dep_:
1868 rs6000_sched_costly_dep_str = arg;
1869 break;
1870
1871 case OPT_malign_:
1872 rs6000_explicit_options.alignment = true;
1873 if (! strcmp (arg, "power"))
1874 {
1875 /* On 64-bit Darwin, power alignment is ABI-incompatible with
1876 some C library functions, so warn about it. The flag may be
1877 useful for performance studies from time to time though, so
1878 don't disable it entirely. */
1879 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1880 warning (0, "-malign-power is not supported for 64-bit Darwin;"
1881 " it is incompatible with the installed C and C++ libraries");
1882 rs6000_alignment_flags = MASK_ALIGN_POWER;
1883 }
1884 else if (! strcmp (arg, "natural"))
1885 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
1886 else
1887 {
1888 error ("unknown -malign-XXXXX option specified: '%s'", arg);
1889 return false;
1890 }
1891 break;
1892 }
1893 return true;
1894}
3cfa4909
MM
1895\f
1896/* Do anything needed at the start of the asm file. */
1897
1bc7c5b6 1898static void
863d938c 1899rs6000_file_start (void)
3cfa4909 1900{
c4d38ccb 1901 size_t i;
3cfa4909 1902 char buffer[80];
d330fd93 1903 const char *start = buffer;
3cfa4909 1904 struct rs6000_cpu_select *ptr;
1bc7c5b6
ZW
1905 const char *default_cpu = TARGET_CPU_DEFAULT;
1906 FILE *file = asm_out_file;
1907
1908 default_file_start ();
1909
1910#ifdef TARGET_BI_ARCH
1911 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
1912 default_cpu = 0;
1913#endif
3cfa4909
MM
1914
1915 if (flag_verbose_asm)
1916 {
1917 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
1918 rs6000_select[0].string = default_cpu;
1919
b6a1cbae 1920 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
1921 {
1922 ptr = &rs6000_select[i];
1923 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
1924 {
1925 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
1926 start = "";
1927 }
1928 }
1929
9c6b4ed9 1930 if (PPC405_ERRATUM77)
b0bfee6e 1931 {
9c6b4ed9 1932 fprintf (file, "%s PPC405CR_ERRATUM77", start);
b0bfee6e
DE
1933 start = "";
1934 }
b0bfee6e 1935
b91da81f 1936#ifdef USING_ELFOS_H
3cfa4909
MM
1937 switch (rs6000_sdata)
1938 {
1939 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
1940 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
1941 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
1942 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
1943 }
1944
1945 if (rs6000_sdata && g_switch_value)
1946 {
307b599c
MK
1947 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
1948 g_switch_value);
3cfa4909
MM
1949 start = "";
1950 }
1951#endif
1952
1953 if (*start == '\0')
949ea356 1954 putc ('\n', file);
3cfa4909 1955 }
b723e82f
JJ
1956
1957 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
1958 {
d6b5193b
RS
1959 switch_to_section (toc_section);
1960 switch_to_section (text_section);
b723e82f 1961 }
3cfa4909 1962}
c4e18b1c 1963
5248c961 1964\f
a0ab749a 1965/* Return nonzero if this function is known to have a null epilogue. */
9878760c
RK
1966
1967int
863d938c 1968direct_return (void)
9878760c 1969{
4697a36c
MM
1970 if (reload_completed)
1971 {
1972 rs6000_stack_t *info = rs6000_stack_info ();
1973
1974 if (info->first_gp_reg_save == 32
1975 && info->first_fp_reg_save == 64
00b960c7 1976 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
1977 && ! info->lr_save_p
1978 && ! info->cr_save_p
00b960c7 1979 && info->vrsave_mask == 0
c81fc13e 1980 && ! info->push_p)
4697a36c
MM
1981 return 1;
1982 }
1983
1984 return 0;
9878760c
RK
1985}
1986
4e74d8ec
MM
1987/* Return the number of instructions it takes to form a constant in an
1988 integer register. */
1989
48d72335 1990int
a2369ed3 1991num_insns_constant_wide (HOST_WIDE_INT value)
4e74d8ec
MM
1992{
1993 /* signed constant loadable with {cal|addi} */
5f59ecb7 1994 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1995 return 1;
1996
4e74d8ec 1997 /* constant loadable with {cau|addis} */
5f59ecb7 1998 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1999 return 1;
2000
5f59ecb7 2001#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 2002 else if (TARGET_POWERPC64)
4e74d8ec 2003 {
a65c591c
DE
2004 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
2005 HOST_WIDE_INT high = value >> 31;
4e74d8ec 2006
a65c591c 2007 if (high == 0 || high == -1)
4e74d8ec
MM
2008 return 2;
2009
a65c591c 2010 high >>= 1;
4e74d8ec 2011
a65c591c 2012 if (low == 0)
4e74d8ec 2013 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
2014 else
2015 return (num_insns_constant_wide (high)
e396202a 2016 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
2017 }
2018#endif
2019
2020 else
2021 return 2;
2022}
2023
2024int
a2369ed3 2025num_insns_constant (rtx op, enum machine_mode mode)
4e74d8ec 2026{
37409796 2027 HOST_WIDE_INT low, high;
bb8df8a6 2028
37409796 2029 switch (GET_CODE (op))
0d30d435 2030 {
37409796 2031 case CONST_INT:
0d30d435 2032#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44 2033 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1990cd79 2034 && mask64_operand (op, mode))
c4ad648e 2035 return 2;
0d30d435
DE
2036 else
2037#endif
2038 return num_insns_constant_wide (INTVAL (op));
4e74d8ec 2039
37409796
NS
2040 case CONST_DOUBLE:
2041 if (mode == SFmode)
2042 {
2043 long l;
2044 REAL_VALUE_TYPE rv;
bb8df8a6 2045
37409796
NS
2046 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2047 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
2048 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2049 }
a260abc9 2050
37409796
NS
2051 if (mode == VOIDmode || mode == DImode)
2052 {
2053 high = CONST_DOUBLE_HIGH (op);
2054 low = CONST_DOUBLE_LOW (op);
2055 }
2056 else
2057 {
2058 long l[2];
2059 REAL_VALUE_TYPE rv;
bb8df8a6 2060
37409796
NS
2061 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2062 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
2063 high = l[WORDS_BIG_ENDIAN == 0];
2064 low = l[WORDS_BIG_ENDIAN != 0];
2065 }
47ad8c61 2066
37409796
NS
2067 if (TARGET_32BIT)
2068 return (num_insns_constant_wide (low)
2069 + num_insns_constant_wide (high));
2070 else
2071 {
2072 if ((high == 0 && low >= 0)
2073 || (high == -1 && low < 0))
2074 return num_insns_constant_wide (low);
bb8df8a6 2075
1990cd79 2076 else if (mask64_operand (op, mode))
37409796 2077 return 2;
bb8df8a6 2078
37409796
NS
2079 else if (low == 0)
2080 return num_insns_constant_wide (high) + 1;
bb8df8a6 2081
37409796
NS
2082 else
2083 return (num_insns_constant_wide (high)
2084 + num_insns_constant_wide (low) + 1);
2085 }
bb8df8a6 2086
37409796
NS
2087 default:
2088 gcc_unreachable ();
4e74d8ec 2089 }
4e74d8ec
MM
2090}
2091
452a7d36 2092
66180ff3
PB
2093/* Return true if OP can be synthesized with a particular vspltisb, vspltish
2094 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2095 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2096 all items are set to the same value and contain COPIES replicas of the
2097 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2098 operand and the others are set to the value of the operand's msb. */
2099
2100static bool
2101vspltis_constant (rtx op, unsigned step, unsigned copies)
452a7d36 2102{
66180ff3
PB
2103 enum machine_mode mode = GET_MODE (op);
2104 enum machine_mode inner = GET_MODE_INNER (mode);
2105
2106 unsigned i;
2107 unsigned nunits = GET_MODE_NUNITS (mode);
2108 unsigned bitsize = GET_MODE_BITSIZE (inner);
2109 unsigned mask = GET_MODE_MASK (inner);
2110
2111 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2112 HOST_WIDE_INT val = INTVAL (last);
2113 HOST_WIDE_INT splat_val = val;
2114 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
2115
2116 /* Construct the value to be splatted, if possible. If not, return 0. */
2117 for (i = 2; i <= copies; i *= 2)
452a7d36 2118 {
66180ff3
PB
2119 HOST_WIDE_INT small_val;
2120 bitsize /= 2;
2121 small_val = splat_val >> bitsize;
2122 mask >>= bitsize;
2123 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
2124 return false;
2125 splat_val = small_val;
2126 }
c4ad648e 2127
66180ff3
PB
2128 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2129 if (EASY_VECTOR_15 (splat_val))
2130 ;
2131
2132 /* Also check if we can splat, and then add the result to itself. Do so if
2133 the value is positive, of if the splat instruction is using OP's mode;
2134 for splat_val < 0, the splat and the add should use the same mode. */
2135 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
2136 && (splat_val >= 0 || (step == 1 && copies == 1)))
2137 ;
2138
2139 else
2140 return false;
2141
2142 /* Check if VAL is present in every STEP-th element, and the
2143 other elements are filled with its most significant bit. */
2144 for (i = 0; i < nunits - 1; ++i)
2145 {
2146 HOST_WIDE_INT desired_val;
2147 if (((i + 1) & (step - 1)) == 0)
2148 desired_val = val;
2149 else
2150 desired_val = msb_val;
2151
2152 if (desired_val != INTVAL (CONST_VECTOR_ELT (op, i)))
2153 return false;
452a7d36 2154 }
66180ff3
PB
2155
2156 return true;
452a7d36
HP
2157}
2158
69ef87e2 2159
66180ff3
PB
2160/* Return true if OP is of the given MODE and can be synthesized
2161 with a vspltisb, vspltish or vspltisw. */
2162
2163bool
2164easy_altivec_constant (rtx op, enum machine_mode mode)
d744e06e 2165{
66180ff3 2166 unsigned step, copies;
d744e06e 2167
66180ff3
PB
2168 if (mode == VOIDmode)
2169 mode = GET_MODE (op);
2170 else if (mode != GET_MODE (op))
2171 return false;
d744e06e 2172
66180ff3
PB
2173 /* Start with a vspltisw. */
2174 step = GET_MODE_NUNITS (mode) / 4;
2175 copies = 1;
2176
2177 if (vspltis_constant (op, step, copies))
2178 return true;
2179
2180 /* Then try with a vspltish. */
2181 if (step == 1)
2182 copies <<= 1;
2183 else
2184 step >>= 1;
2185
2186 if (vspltis_constant (op, step, copies))
2187 return true;
2188
2189 /* And finally a vspltisb. */
2190 if (step == 1)
2191 copies <<= 1;
2192 else
2193 step >>= 1;
2194
2195 if (vspltis_constant (op, step, copies))
2196 return true;
2197
2198 return false;
d744e06e
AH
2199}
2200
66180ff3
PB
2201/* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2202 result is OP. Abort if it is not possible. */
d744e06e 2203
f676971a 2204rtx
66180ff3 2205gen_easy_altivec_constant (rtx op)
452a7d36 2206{
66180ff3
PB
2207 enum machine_mode mode = GET_MODE (op);
2208 int nunits = GET_MODE_NUNITS (mode);
2209 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2210 unsigned step = nunits / 4;
2211 unsigned copies = 1;
2212
2213 /* Start with a vspltisw. */
2214 if (vspltis_constant (op, step, copies))
2215 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
2216
2217 /* Then try with a vspltish. */
2218 if (step == 1)
2219 copies <<= 1;
2220 else
2221 step >>= 1;
2222
2223 if (vspltis_constant (op, step, copies))
2224 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
2225
2226 /* And finally a vspltisb. */
2227 if (step == 1)
2228 copies <<= 1;
2229 else
2230 step >>= 1;
2231
2232 if (vspltis_constant (op, step, copies))
2233 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
2234
2235 gcc_unreachable ();
d744e06e
AH
2236}
2237
2238const char *
a2369ed3 2239output_vec_const_move (rtx *operands)
d744e06e
AH
2240{
2241 int cst, cst2;
2242 enum machine_mode mode;
2243 rtx dest, vec;
2244
2245 dest = operands[0];
2246 vec = operands[1];
d744e06e 2247 mode = GET_MODE (dest);
69ef87e2 2248
d744e06e
AH
2249 if (TARGET_ALTIVEC)
2250 {
66180ff3 2251 rtx splat_vec;
d744e06e
AH
2252 if (zero_constant (vec, mode))
2253 return "vxor %0,%0,%0";
37409796 2254
66180ff3
PB
2255 splat_vec = gen_easy_altivec_constant (vec);
2256 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
2257 operands[1] = XEXP (splat_vec, 0);
2258 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
2259 return "#";
bb8df8a6 2260
66180ff3 2261 switch (GET_MODE (splat_vec))
98ef3137 2262 {
37409796 2263 case V4SImode:
66180ff3 2264 return "vspltisw %0,%1";
c4ad648e 2265
37409796 2266 case V8HImode:
66180ff3 2267 return "vspltish %0,%1";
c4ad648e 2268
37409796 2269 case V16QImode:
66180ff3 2270 return "vspltisb %0,%1";
bb8df8a6 2271
37409796
NS
2272 default:
2273 gcc_unreachable ();
98ef3137 2274 }
69ef87e2
AH
2275 }
2276
37409796 2277 gcc_assert (TARGET_SPE);
bb8df8a6 2278
37409796
NS
2279 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2280 pattern of V1DI, V4HI, and V2SF.
2281
2282 FIXME: We should probably return # and add post reload
2283 splitters for these, but this way is so easy ;-). */
e20dcbef
PB
2284 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2285 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2286 operands[1] = CONST_VECTOR_ELT (vec, 0);
2287 operands[2] = CONST_VECTOR_ELT (vec, 1);
37409796
NS
2288 if (cst == cst2)
2289 return "li %0,%1\n\tevmergelo %0,%0,%0";
2290 else
2291 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
69ef87e2
AH
2292}
2293
7a4eca66
DE
2294/* Initialize vector TARGET to VALS. */
2295
2296void
2297rs6000_expand_vector_init (rtx target, rtx vals)
2298{
2299 enum machine_mode mode = GET_MODE (target);
2300 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2301 int n_elts = GET_MODE_NUNITS (mode);
2302 int n_var = 0, one_var = -1;
2303 bool all_same = true, all_const_zero = true;
2304 rtx x, mem;
2305 int i;
2306
2307 for (i = 0; i < n_elts; ++i)
2308 {
2309 x = XVECEXP (vals, 0, i);
2310 if (!CONSTANT_P (x))
2311 ++n_var, one_var = i;
2312 else if (x != CONST0_RTX (inner_mode))
2313 all_const_zero = false;
2314
2315 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2316 all_same = false;
2317 }
2318
2319 if (n_var == 0)
2320 {
2321 if (mode != V4SFmode && all_const_zero)
2322 {
2323 /* Zero register. */
2324 emit_insn (gen_rtx_SET (VOIDmode, target,
2325 gen_rtx_XOR (mode, target, target)));
2326 return;
2327 }
66180ff3 2328 else if (mode != V4SFmode && easy_vector_constant (vals, mode))
7a4eca66
DE
2329 {
2330 /* Splat immediate. */
66180ff3 2331 emit_insn (gen_rtx_SET (VOIDmode, target, vals));
7a4eca66
DE
2332 return;
2333 }
2334 else if (all_same)
2335 ; /* Splat vector element. */
2336 else
2337 {
2338 /* Load from constant pool. */
2339 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2340 return;
2341 }
2342 }
2343
2344 /* Store value to stack temp. Load vector element. Splat. */
2345 if (all_same)
2346 {
2347 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2348 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
2349 XVECEXP (vals, 0, 0));
2350 x = gen_rtx_UNSPEC (VOIDmode,
2351 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2352 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2353 gen_rtvec (2,
2354 gen_rtx_SET (VOIDmode,
2355 target, mem),
2356 x)));
2357 x = gen_rtx_VEC_SELECT (inner_mode, target,
2358 gen_rtx_PARALLEL (VOIDmode,
2359 gen_rtvec (1, const0_rtx)));
2360 emit_insn (gen_rtx_SET (VOIDmode, target,
2361 gen_rtx_VEC_DUPLICATE (mode, x)));
2362 return;
2363 }
2364
2365 /* One field is non-constant. Load constant then overwrite
2366 varying field. */
2367 if (n_var == 1)
2368 {
2369 rtx copy = copy_rtx (vals);
2370
57b51d4d 2371 /* Load constant part of vector, substitute neighboring value for
7a4eca66
DE
2372 varying element. */
2373 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
2374 rs6000_expand_vector_init (target, copy);
2375
2376 /* Insert variable. */
2377 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
2378 return;
2379 }
2380
2381 /* Construct the vector in memory one field at a time
2382 and load the whole vector. */
2383 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2384 for (i = 0; i < n_elts; i++)
2385 emit_move_insn (adjust_address_nv (mem, inner_mode,
2386 i * GET_MODE_SIZE (inner_mode)),
2387 XVECEXP (vals, 0, i));
2388 emit_move_insn (target, mem);
2389}
2390
2391/* Set field ELT of TARGET to VAL. */
2392
2393void
2394rs6000_expand_vector_set (rtx target, rtx val, int elt)
2395{
2396 enum machine_mode mode = GET_MODE (target);
2397 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2398 rtx reg = gen_reg_rtx (mode);
2399 rtx mask, mem, x;
2400 int width = GET_MODE_SIZE (inner_mode);
2401 int i;
2402
2403 /* Load single variable value. */
2404 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2405 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
2406 x = gen_rtx_UNSPEC (VOIDmode,
2407 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2408 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2409 gen_rtvec (2,
2410 gen_rtx_SET (VOIDmode,
2411 reg, mem),
2412 x)));
2413
2414 /* Linear sequence. */
2415 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
2416 for (i = 0; i < 16; ++i)
2417 XVECEXP (mask, 0, i) = GEN_INT (i);
2418
2419 /* Set permute mask to insert element into target. */
2420 for (i = 0; i < width; ++i)
2421 XVECEXP (mask, 0, elt*width + i)
2422 = GEN_INT (i + 0x10);
2423 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
2424 x = gen_rtx_UNSPEC (mode,
2425 gen_rtvec (3, target, reg,
2426 force_reg (V16QImode, x)),
2427 UNSPEC_VPERM);
2428 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2429}
2430
2431/* Extract field ELT from VEC into TARGET. */
2432
2433void
2434rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
2435{
2436 enum machine_mode mode = GET_MODE (vec);
2437 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2438 rtx mem, x;
2439
2440 /* Allocate mode-sized buffer. */
2441 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2442
2443 /* Add offset to field within buffer matching vector element. */
2444 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
2445
2446 /* Store single field into mode-sized buffer. */
2447 x = gen_rtx_UNSPEC (VOIDmode,
2448 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
2449 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2450 gen_rtvec (2,
2451 gen_rtx_SET (VOIDmode,
2452 mem, vec),
2453 x)));
2454 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
2455}
2456
0ba1b2ff
AM
2457/* Generates shifts and masks for a pair of rldicl or rldicr insns to
2458 implement ANDing by the mask IN. */
2459void
a2369ed3 2460build_mask64_2_operands (rtx in, rtx *out)
0ba1b2ff
AM
2461{
2462#if HOST_BITS_PER_WIDE_INT >= 64
2463 unsigned HOST_WIDE_INT c, lsb, m1, m2;
2464 int shift;
2465
37409796 2466 gcc_assert (GET_CODE (in) == CONST_INT);
0ba1b2ff
AM
2467
2468 c = INTVAL (in);
2469 if (c & 1)
2470 {
2471 /* Assume c initially something like 0x00fff000000fffff. The idea
2472 is to rotate the word so that the middle ^^^^^^ group of zeros
2473 is at the MS end and can be cleared with an rldicl mask. We then
2474 rotate back and clear off the MS ^^ group of zeros with a
2475 second rldicl. */
2476 c = ~c; /* c == 0xff000ffffff00000 */
2477 lsb = c & -c; /* lsb == 0x0000000000100000 */
2478 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
2479 c = ~c; /* c == 0x00fff000000fffff */
2480 c &= -lsb; /* c == 0x00fff00000000000 */
2481 lsb = c & -c; /* lsb == 0x0000100000000000 */
2482 c = ~c; /* c == 0xff000fffffffffff */
2483 c &= -lsb; /* c == 0xff00000000000000 */
2484 shift = 0;
2485 while ((lsb >>= 1) != 0)
2486 shift++; /* shift == 44 on exit from loop */
2487 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
2488 m1 = ~m1; /* m1 == 0x000000ffffffffff */
2489 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
2490 }
2491 else
0ba1b2ff
AM
2492 {
2493 /* Assume c initially something like 0xff000f0000000000. The idea
2494 is to rotate the word so that the ^^^ middle group of zeros
2495 is at the LS end and can be cleared with an rldicr mask. We then
2496 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2497 a second rldicr. */
2498 lsb = c & -c; /* lsb == 0x0000010000000000 */
2499 m2 = -lsb; /* m2 == 0xffffff0000000000 */
2500 c = ~c; /* c == 0x00fff0ffffffffff */
2501 c &= -lsb; /* c == 0x00fff00000000000 */
2502 lsb = c & -c; /* lsb == 0x0000100000000000 */
2503 c = ~c; /* c == 0xff000fffffffffff */
2504 c &= -lsb; /* c == 0xff00000000000000 */
2505 shift = 0;
2506 while ((lsb >>= 1) != 0)
2507 shift++; /* shift == 44 on exit from loop */
2508 m1 = ~c; /* m1 == 0x00ffffffffffffff */
2509 m1 >>= shift; /* m1 == 0x0000000000000fff */
2510 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
2511 }
2512
2513 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2514 masks will be all 1's. We are guaranteed more than one transition. */
2515 out[0] = GEN_INT (64 - shift);
2516 out[1] = GEN_INT (m1);
2517 out[2] = GEN_INT (shift);
2518 out[3] = GEN_INT (m2);
2519#else
045572c7
GK
2520 (void)in;
2521 (void)out;
37409796 2522 gcc_unreachable ();
0ba1b2ff 2523#endif
a260abc9
DE
2524}
2525
54b695e7 2526/* Return TRUE if OP is an invalid SUBREG operation on the e500. */
48d72335
DE
2527
2528bool
54b695e7
AH
2529invalid_e500_subreg (rtx op, enum machine_mode mode)
2530{
2531 /* Reject (subreg:SI (reg:DF)). */
2532 if (GET_CODE (op) == SUBREG
2533 && mode == SImode
2534 && REG_P (SUBREG_REG (op))
2535 && GET_MODE (SUBREG_REG (op)) == DFmode)
2536 return true;
2537
2538 /* Reject (subreg:DF (reg:DI)). */
2539 if (GET_CODE (op) == SUBREG
2540 && mode == DFmode
2541 && REG_P (SUBREG_REG (op))
2542 && GET_MODE (SUBREG_REG (op)) == DImode)
2543 return true;
2544
2545 return false;
2546}
2547
95727fb8
AP
2548/* Darwin, AIX increases natural record alignment to doubleword if the first
2549 field is an FP double while the FP fields remain word aligned. */
2550
19d66194 2551unsigned int
fa5b0972
AM
2552rs6000_special_round_type_align (tree type, unsigned int computed,
2553 unsigned int specified)
95727fb8 2554{
fa5b0972 2555 unsigned int align = MAX (computed, specified);
95727fb8 2556 tree field = TYPE_FIELDS (type);
95727fb8 2557
bb8df8a6 2558 /* Skip all non field decls */
85962ac8 2559 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
95727fb8
AP
2560 field = TREE_CHAIN (field);
2561
fa5b0972
AM
2562 if (field != NULL && field != type)
2563 {
2564 type = TREE_TYPE (field);
2565 while (TREE_CODE (type) == ARRAY_TYPE)
2566 type = TREE_TYPE (type);
2567
2568 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
2569 align = MAX (align, 64);
2570 }
95727fb8 2571
fa5b0972 2572 return align;
95727fb8
AP
2573}
2574
a4f6c312 2575/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
2576
2577int
f676971a 2578small_data_operand (rtx op ATTRIBUTE_UNUSED,
a2369ed3 2579 enum machine_mode mode ATTRIBUTE_UNUSED)
7509c759 2580{
38c1f2d7 2581#if TARGET_ELF
5f59ecb7 2582 rtx sym_ref;
7509c759 2583
d9407988 2584 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 2585 return 0;
a54d04b7 2586
f607bc57 2587 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
2588 return 0;
2589
88228c4b
MM
2590 if (GET_CODE (op) == SYMBOL_REF)
2591 sym_ref = op;
2592
2593 else if (GET_CODE (op) != CONST
2594 || GET_CODE (XEXP (op, 0)) != PLUS
2595 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2596 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
2597 return 0;
2598
88228c4b 2599 else
dbf55e53
MM
2600 {
2601 rtx sum = XEXP (op, 0);
2602 HOST_WIDE_INT summand;
2603
2604 /* We have to be careful here, because it is the referenced address
c4ad648e 2605 that must be 32k from _SDA_BASE_, not just the symbol. */
dbf55e53 2606 summand = INTVAL (XEXP (sum, 1));
307b599c 2607 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
9390387d 2608 return 0;
dbf55e53
MM
2609
2610 sym_ref = XEXP (sum, 0);
2611 }
88228c4b 2612
20bfcd69 2613 return SYMBOL_REF_SMALL_P (sym_ref);
d9407988
MM
2614#else
2615 return 0;
2616#endif
7509c759 2617}
46c07df8 2618
3a1f863f 2619/* Return true if either operand is a general purpose register. */
46c07df8 2620
3a1f863f
DE
2621bool
2622gpr_or_gpr_p (rtx op0, rtx op1)
46c07df8 2623{
3a1f863f
DE
2624 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
2625 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
46c07df8
HP
2626}
2627
9ebbca7d 2628\f
4d588c14
RH
2629/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
2630
f676971a
EC
2631static int
2632constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
9ebbca7d 2633{
9390387d 2634 switch (GET_CODE (op))
9ebbca7d
GK
2635 {
2636 case SYMBOL_REF:
c4501e62
JJ
2637 if (RS6000_SYMBOL_REF_TLS_P (op))
2638 return 0;
2639 else if (CONSTANT_POOL_ADDRESS_P (op))
a4f6c312
SS
2640 {
2641 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2642 {
2643 *have_sym = 1;
2644 return 1;
2645 }
2646 else
2647 return 0;
2648 }
2649 else if (! strcmp (XSTR (op, 0), toc_label_name))
2650 {
2651 *have_toc = 1;
2652 return 1;
2653 }
2654 else
2655 return 0;
9ebbca7d
GK
2656 case PLUS:
2657 case MINUS:
c1f11548
DE
2658 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2659 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2660 case CONST:
a4f6c312 2661 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2662 case CONST_INT:
a4f6c312 2663 return 1;
9ebbca7d 2664 default:
a4f6c312 2665 return 0;
9ebbca7d
GK
2666 }
2667}
2668
4d588c14 2669static bool
a2369ed3 2670constant_pool_expr_p (rtx op)
9ebbca7d
GK
2671{
2672 int have_sym = 0;
2673 int have_toc = 0;
2674 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2675}
2676
48d72335 2677bool
a2369ed3 2678toc_relative_expr_p (rtx op)
9ebbca7d 2679{
4d588c14
RH
2680 int have_sym = 0;
2681 int have_toc = 0;
2682 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2683}
2684
4d588c14 2685bool
a2369ed3 2686legitimate_constant_pool_address_p (rtx x)
4d588c14
RH
2687{
2688 return (TARGET_TOC
2689 && GET_CODE (x) == PLUS
2690 && GET_CODE (XEXP (x, 0)) == REG
2691 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
2692 && constant_pool_expr_p (XEXP (x, 1)));
2693}
2694
0c380712
AM
2695bool
2696rs6000_legitimate_small_data_p (enum machine_mode mode, rtx x)
4d588c14
RH
2697{
2698 return (DEFAULT_ABI == ABI_V4
2699 && !flag_pic && !TARGET_TOC
2700 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
2701 && small_data_operand (x, mode));
2702}
2703
60cdabab
DE
2704/* SPE offset addressing is limited to 5-bits worth of double words. */
2705#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
2706
76d2b81d
DJ
2707bool
2708rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4d588c14
RH
2709{
2710 unsigned HOST_WIDE_INT offset, extra;
2711
2712 if (GET_CODE (x) != PLUS)
2713 return false;
2714 if (GET_CODE (XEXP (x, 0)) != REG)
2715 return false;
2716 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2717 return false;
60cdabab
DE
2718 if (legitimate_constant_pool_address_p (x))
2719 return true;
4d588c14
RH
2720 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
2721 return false;
2722
2723 offset = INTVAL (XEXP (x, 1));
2724 extra = 0;
2725 switch (mode)
2726 {
2727 case V16QImode:
2728 case V8HImode:
2729 case V4SFmode:
2730 case V4SImode:
7a4eca66
DE
2731 /* AltiVec vector modes. Only reg+reg addressing is valid and
2732 constant offset zero should not occur due to canonicalization.
2733 Allow any offset when not strict before reload. */
2734 return !strict;
4d588c14
RH
2735
2736 case V4HImode:
2737 case V2SImode:
2738 case V1DImode:
2739 case V2SFmode:
2740 /* SPE vector modes. */
2741 return SPE_CONST_OFFSET_OK (offset);
2742
2743 case DFmode:
4d4cbc0e
AH
2744 if (TARGET_E500_DOUBLE)
2745 return SPE_CONST_OFFSET_OK (offset);
2746
4d588c14 2747 case DImode:
54b695e7
AH
2748 /* On e500v2, we may have:
2749
2750 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
2751
2752 Which gets addressed with evldd instructions. */
2753 if (TARGET_E500_DOUBLE)
2754 return SPE_CONST_OFFSET_OK (offset);
2755
3364872d 2756 if (mode == DFmode || !TARGET_POWERPC64)
4d588c14
RH
2757 extra = 4;
2758 else if (offset & 3)
2759 return false;
2760 break;
2761
2762 case TFmode:
2763 case TImode:
3364872d 2764 if (mode == TFmode || !TARGET_POWERPC64)
4d588c14
RH
2765 extra = 12;
2766 else if (offset & 3)
2767 return false;
2768 else
2769 extra = 8;
2770 break;
2771
2772 default:
2773 break;
2774 }
2775
b1917422
AM
2776 offset += 0x8000;
2777 return (offset < 0x10000) && (offset + extra < 0x10000);
4d588c14
RH
2778}
2779
2780static bool
a2369ed3 2781legitimate_indexed_address_p (rtx x, int strict)
4d588c14
RH
2782{
2783 rtx op0, op1;
2784
2785 if (GET_CODE (x) != PLUS)
2786 return false;
850e8d3d 2787
4d588c14
RH
2788 op0 = XEXP (x, 0);
2789 op1 = XEXP (x, 1);
2790
bf00cc0f 2791 /* Recognize the rtl generated by reload which we know will later be
9024f4b8
AM
2792 replaced with proper base and index regs. */
2793 if (!strict
2794 && reload_in_progress
2795 && (REG_P (op0) || GET_CODE (op0) == PLUS)
2796 && REG_P (op1))
2797 return true;
2798
2799 return (REG_P (op0) && REG_P (op1)
2800 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
2801 && INT_REG_OK_FOR_INDEX_P (op1, strict))
2802 || (INT_REG_OK_FOR_BASE_P (op1, strict)
2803 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
9ebbca7d
GK
2804}
2805
48d72335 2806inline bool
a2369ed3 2807legitimate_indirect_address_p (rtx x, int strict)
4d588c14
RH
2808{
2809 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
2810}
2811
48d72335 2812bool
4c81e946
FJ
2813macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
2814{
c4ad648e 2815 if (!TARGET_MACHO || !flag_pic
9390387d 2816 || mode != SImode || GET_CODE (x) != MEM)
c4ad648e
AM
2817 return false;
2818 x = XEXP (x, 0);
4c81e946
FJ
2819
2820 if (GET_CODE (x) != LO_SUM)
2821 return false;
2822 if (GET_CODE (XEXP (x, 0)) != REG)
2823 return false;
2824 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
2825 return false;
2826 x = XEXP (x, 1);
2827
2828 return CONSTANT_P (x);
2829}
2830
4d588c14 2831static bool
a2369ed3 2832legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4d588c14
RH
2833{
2834 if (GET_CODE (x) != LO_SUM)
2835 return false;
2836 if (GET_CODE (XEXP (x, 0)) != REG)
2837 return false;
2838 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
2839 return false;
54b695e7
AH
2840 /* Restrict addressing for DI because of our SUBREG hackery. */
2841 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
f82f556d 2842 return false;
4d588c14
RH
2843 x = XEXP (x, 1);
2844
8622e235 2845 if (TARGET_ELF || TARGET_MACHO)
4d588c14 2846 {
a29077da 2847 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4d588c14
RH
2848 return false;
2849 if (TARGET_TOC)
2850 return false;
2851 if (GET_MODE_NUNITS (mode) != 1)
2852 return false;
5e5f01b9 2853 if (GET_MODE_BITSIZE (mode) > 64
3c028f65
AM
2854 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
2855 && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
4d588c14
RH
2856 return false;
2857
2858 return CONSTANT_P (x);
2859 }
2860
2861 return false;
2862}
2863
2864
9ebbca7d
GK
2865/* Try machine-dependent ways of modifying an illegitimate address
2866 to be legitimate. If we find one, return the new, valid address.
2867 This is used from only one place: `memory_address' in explow.c.
2868
a4f6c312
SS
2869 OLDX is the address as it was before break_out_memory_refs was
2870 called. In some cases it is useful to look at this to decide what
2871 needs to be done.
9ebbca7d 2872
a4f6c312 2873 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2874
a4f6c312
SS
2875 It is always safe for this function to do nothing. It exists to
2876 recognize opportunities to optimize the output.
9ebbca7d
GK
2877
2878 On RS/6000, first check for the sum of a register with a constant
2879 integer that is out of range. If so, generate code to add the
2880 constant with the low-order 16 bits masked to the register and force
2881 this result into another register (this can be done with `cau').
2882 Then generate an address of REG+(CONST&0xffff), allowing for the
2883 possibility of bit 16 being a one.
2884
2885 Then check for the sum of a register and something not constant, try to
2886 load the other things into a register and return the sum. */
4d588c14 2887
9ebbca7d 2888rtx
a2369ed3
DJ
2889rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
2890 enum machine_mode mode)
0ac081f6 2891{
c4501e62
JJ
2892 if (GET_CODE (x) == SYMBOL_REF)
2893 {
2894 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
2895 if (model != 0)
2896 return rs6000_legitimize_tls_address (x, model);
2897 }
2898
f676971a 2899 if (GET_CODE (x) == PLUS
9ebbca7d
GK
2900 && GET_CODE (XEXP (x, 0)) == REG
2901 && GET_CODE (XEXP (x, 1)) == CONST_INT
2902 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
f676971a 2903 {
9ebbca7d
GK
2904 HOST_WIDE_INT high_int, low_int;
2905 rtx sum;
a65c591c
DE
2906 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2907 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2908 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2909 GEN_INT (high_int)), 0);
2910 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2911 }
f676971a 2912 else if (GET_CODE (x) == PLUS
9ebbca7d
GK
2913 && GET_CODE (XEXP (x, 0)) == REG
2914 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2915 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2916 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2917 || TARGET_POWERPC64
54b695e7
AH
2918 || (((mode != DImode && mode != DFmode) || TARGET_E500_DOUBLE)
2919 && mode != TFmode))
9ebbca7d
GK
2920 && (TARGET_POWERPC64 || mode != DImode)
2921 && mode != TImode)
2922 {
2923 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2924 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2925 }
0ac081f6
AH
2926 else if (ALTIVEC_VECTOR_MODE (mode))
2927 {
2928 rtx reg;
2929
2930 /* Make sure both operands are registers. */
2931 if (GET_CODE (x) == PLUS)
9f85ed45 2932 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2933 force_reg (Pmode, XEXP (x, 1)));
2934
2935 reg = force_reg (Pmode, x);
2936 return reg;
2937 }
4d4cbc0e 2938 else if (SPE_VECTOR_MODE (mode)
54b695e7
AH
2939 || (TARGET_E500_DOUBLE && (mode == DFmode
2940 || mode == DImode)))
a3170dc6 2941 {
54b695e7
AH
2942 if (mode == DImode)
2943 return NULL_RTX;
a3170dc6
AH
2944 /* We accept [reg + reg] and [reg + OFFSET]. */
2945
2946 if (GET_CODE (x) == PLUS)
c4ad648e
AM
2947 {
2948 rtx op1 = XEXP (x, 0);
2949 rtx op2 = XEXP (x, 1);
a3170dc6 2950
c4ad648e 2951 op1 = force_reg (Pmode, op1);
a3170dc6 2952
c4ad648e
AM
2953 if (GET_CODE (op2) != REG
2954 && (GET_CODE (op2) != CONST_INT
2955 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2956 op2 = force_reg (Pmode, op2);
a3170dc6 2957
c4ad648e
AM
2958 return gen_rtx_PLUS (Pmode, op1, op2);
2959 }
a3170dc6
AH
2960
2961 return force_reg (Pmode, x);
2962 }
f1384257
AM
2963 else if (TARGET_ELF
2964 && TARGET_32BIT
2965 && TARGET_NO_TOC
2966 && ! flag_pic
9ebbca7d 2967 && GET_CODE (x) != CONST_INT
f676971a 2968 && GET_CODE (x) != CONST_DOUBLE
9ebbca7d 2969 && CONSTANT_P (x)
6ac7bf2c
GK
2970 && GET_MODE_NUNITS (mode) == 1
2971 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2972 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2973 {
2974 rtx reg = gen_reg_rtx (Pmode);
8a1977f3
GK
2975 emit_insn (gen_elf_high (reg, x));
2976 return gen_rtx_LO_SUM (Pmode, reg, x);
9ebbca7d 2977 }
ee890fe2
SS
2978 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2979 && ! flag_pic
ab82a49f
AP
2980#if TARGET_MACHO
2981 && ! MACHO_DYNAMIC_NO_PIC_P
2982#endif
ee890fe2 2983 && GET_CODE (x) != CONST_INT
f676971a 2984 && GET_CODE (x) != CONST_DOUBLE
ee890fe2 2985 && CONSTANT_P (x)
f82f556d 2986 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
f676971a 2987 && mode != DImode
ee890fe2
SS
2988 && mode != TImode)
2989 {
2990 rtx reg = gen_reg_rtx (Pmode);
8a1977f3
GK
2991 emit_insn (gen_macho_high (reg, x));
2992 return gen_rtx_LO_SUM (Pmode, reg, x);
ee890fe2 2993 }
f676971a 2994 else if (TARGET_TOC
4d588c14 2995 && constant_pool_expr_p (x)
a9098fd0 2996 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2997 {
2998 return create_TOC_reference (x);
2999 }
3000 else
3001 return NULL_RTX;
3002}
258bfae2 3003
fdbe66f2 3004/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
c973d557
JJ
3005 We need to emit DTP-relative relocations. */
3006
fdbe66f2 3007static void
c973d557
JJ
3008rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
3009{
3010 switch (size)
3011 {
3012 case 4:
3013 fputs ("\t.long\t", file);
3014 break;
3015 case 8:
3016 fputs (DOUBLE_INT_ASM_OP, file);
3017 break;
3018 default:
37409796 3019 gcc_unreachable ();
c973d557
JJ
3020 }
3021 output_addr_const (file, x);
3022 fputs ("@dtprel+0x8000", file);
3023}
3024
c4501e62
JJ
3025/* Construct the SYMBOL_REF for the tls_get_addr function. */
3026
3027static GTY(()) rtx rs6000_tls_symbol;
3028static rtx
863d938c 3029rs6000_tls_get_addr (void)
c4501e62
JJ
3030{
3031 if (!rs6000_tls_symbol)
3032 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
3033
3034 return rs6000_tls_symbol;
3035}
3036
3037/* Construct the SYMBOL_REF for TLS GOT references. */
3038
3039static GTY(()) rtx rs6000_got_symbol;
3040static rtx
863d938c 3041rs6000_got_sym (void)
c4501e62
JJ
3042{
3043 if (!rs6000_got_symbol)
3044 {
3045 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3046 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
3047 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
f676971a 3048 }
c4501e62
JJ
3049
3050 return rs6000_got_symbol;
3051}
3052
3053/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3054 this (thread-local) address. */
3055
3056static rtx
a2369ed3 3057rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
c4501e62
JJ
3058{
3059 rtx dest, insn;
3060
3061 dest = gen_reg_rtx (Pmode);
3062 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
3063 {
3064 rtx tlsreg;
3065
3066 if (TARGET_64BIT)
3067 {
3068 tlsreg = gen_rtx_REG (Pmode, 13);
3069 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
3070 }
3071 else
3072 {
3073 tlsreg = gen_rtx_REG (Pmode, 2);
3074 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
3075 }
3076 emit_insn (insn);
3077 }
3078 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
3079 {
3080 rtx tlsreg, tmp;
3081
3082 tmp = gen_reg_rtx (Pmode);
3083 if (TARGET_64BIT)
3084 {
3085 tlsreg = gen_rtx_REG (Pmode, 13);
3086 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
3087 }
3088 else
3089 {
3090 tlsreg = gen_rtx_REG (Pmode, 2);
3091 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
3092 }
3093 emit_insn (insn);
3094 if (TARGET_64BIT)
3095 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
3096 else
3097 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
3098 emit_insn (insn);
3099 }
3100 else
3101 {
3102 rtx r3, got, tga, tmp1, tmp2, eqv;
3103
4fed8f8f
AM
3104 /* We currently use relocations like @got@tlsgd for tls, which
3105 means the linker will handle allocation of tls entries, placing
3106 them in the .got section. So use a pointer to the .got section,
3107 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3108 or to secondary GOT sections used by 32-bit -fPIC. */
c4501e62 3109 if (TARGET_64BIT)
972f427b 3110 got = gen_rtx_REG (Pmode, 2);
c4501e62
JJ
3111 else
3112 {
3113 if (flag_pic == 1)
3114 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3115 else
3116 {
3117 rtx gsym = rs6000_got_sym ();
3118 got = gen_reg_rtx (Pmode);
3119 if (flag_pic == 0)
3120 rs6000_emit_move (got, gsym, Pmode);
3121 else
3122 {
ccbca5e4 3123 rtx tempLR, tmp3, mem;
c4501e62
JJ
3124 rtx first, last;
3125
c4501e62
JJ
3126 tempLR = gen_reg_rtx (Pmode);
3127 tmp1 = gen_reg_rtx (Pmode);
3128 tmp2 = gen_reg_rtx (Pmode);
3129 tmp3 = gen_reg_rtx (Pmode);
542a8afa 3130 mem = gen_const_mem (Pmode, tmp1);
c4501e62 3131
ccbca5e4 3132 first = emit_insn (gen_load_toc_v4_PIC_1b (tempLR, gsym));
c4501e62
JJ
3133 emit_move_insn (tmp1, tempLR);
3134 emit_move_insn (tmp2, mem);
3135 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3136 last = emit_move_insn (got, tmp3);
3137 REG_NOTES (last) = gen_rtx_EXPR_LIST (REG_EQUAL, gsym,
3138 REG_NOTES (last));
3139 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3140 REG_NOTES (first));
3141 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3142 REG_NOTES (last));
3143 }
3144 }
3145 }
3146
3147 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3148 {
3149 r3 = gen_rtx_REG (Pmode, 3);
3150 if (TARGET_64BIT)
3151 insn = gen_tls_gd_64 (r3, got, addr);
3152 else
3153 insn = gen_tls_gd_32 (r3, got, addr);
3154 start_sequence ();
3155 emit_insn (insn);
3156 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3157 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3158 insn = emit_call_insn (insn);
3159 CONST_OR_PURE_CALL_P (insn) = 1;
3160 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3161 insn = get_insns ();
3162 end_sequence ();
3163 emit_libcall_block (insn, dest, r3, addr);
3164 }
3165 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3166 {
3167 r3 = gen_rtx_REG (Pmode, 3);
3168 if (TARGET_64BIT)
3169 insn = gen_tls_ld_64 (r3, got);
3170 else
3171 insn = gen_tls_ld_32 (r3, got);
3172 start_sequence ();
3173 emit_insn (insn);
3174 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3175 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3176 insn = emit_call_insn (insn);
3177 CONST_OR_PURE_CALL_P (insn) = 1;
3178 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3179 insn = get_insns ();
3180 end_sequence ();
3181 tmp1 = gen_reg_rtx (Pmode);
3182 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3183 UNSPEC_TLSLD);
3184 emit_libcall_block (insn, tmp1, r3, eqv);
3185 if (rs6000_tls_size == 16)
3186 {
3187 if (TARGET_64BIT)
3188 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3189 else
3190 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3191 }
3192 else if (rs6000_tls_size == 32)
3193 {
3194 tmp2 = gen_reg_rtx (Pmode);
3195 if (TARGET_64BIT)
3196 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3197 else
3198 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3199 emit_insn (insn);
3200 if (TARGET_64BIT)
3201 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3202 else
3203 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3204 }
3205 else
3206 {
3207 tmp2 = gen_reg_rtx (Pmode);
3208 if (TARGET_64BIT)
3209 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3210 else
3211 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3212 emit_insn (insn);
3213 insn = gen_rtx_SET (Pmode, dest,
3214 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3215 }
3216 emit_insn (insn);
3217 }
3218 else
3219 {
3220 /* IE, or 64 bit offset LE. */
3221 tmp2 = gen_reg_rtx (Pmode);
3222 if (TARGET_64BIT)
3223 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3224 else
3225 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3226 emit_insn (insn);
3227 if (TARGET_64BIT)
3228 insn = gen_tls_tls_64 (dest, tmp2, addr);
3229 else
3230 insn = gen_tls_tls_32 (dest, tmp2, addr);
3231 emit_insn (insn);
3232 }
3233 }
3234
3235 return dest;
3236}
3237
c4501e62
JJ
3238/* Return 1 if X contains a thread-local symbol. */
3239
3240bool
a2369ed3 3241rs6000_tls_referenced_p (rtx x)
c4501e62 3242{
cd413cab
AP
3243 if (! TARGET_HAVE_TLS)
3244 return false;
3245
c4501e62
JJ
3246 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3247}
3248
3249/* Return 1 if *X is a thread-local symbol. This is the same as
3250 rs6000_tls_symbol_ref except for the type of the unused argument. */
3251
9390387d 3252static int
a2369ed3 3253rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
c4501e62
JJ
3254{
3255 return RS6000_SYMBOL_REF_TLS_P (*x);
3256}
3257
24ea750e
DJ
3258/* The convention appears to be to define this wherever it is used.
3259 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3260 is now used here. */
3261#ifndef REG_MODE_OK_FOR_BASE_P
3262#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3263#endif
3264
3265/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3266 replace the input X, or the original X if no replacement is called for.
3267 The output parameter *WIN is 1 if the calling macro should goto WIN,
3268 0 if it should not.
3269
3270 For RS/6000, we wish to handle large displacements off a base
3271 register by splitting the addend across an addiu/addis and the mem insn.
3272 This cuts number of extra insns needed from 3 to 1.
3273
3274 On Darwin, we use this to generate code for floating point constants.
3275 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3276 The Darwin code is inside #if TARGET_MACHO because only then is
3277 machopic_function_base_name() defined. */
3278rtx
f676971a 3279rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
c4ad648e
AM
3280 int opnum, int type,
3281 int ind_levels ATTRIBUTE_UNUSED, int *win)
24ea750e 3282{
f676971a 3283 /* We must recognize output that we have already generated ourselves. */
24ea750e
DJ
3284 if (GET_CODE (x) == PLUS
3285 && GET_CODE (XEXP (x, 0)) == PLUS
3286 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3287 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3288 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3289 {
3290 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
c4ad648e
AM
3291 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3292 opnum, (enum reload_type)type);
24ea750e
DJ
3293 *win = 1;
3294 return x;
3295 }
3deb2758 3296
24ea750e
DJ
3297#if TARGET_MACHO
3298 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
3299 && GET_CODE (x) == LO_SUM
3300 && GET_CODE (XEXP (x, 0)) == PLUS
3301 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
3302 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
3303 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
3304 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
3305 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
3306 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
3307 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
3308 {
3309 /* Result of previous invocation of this function on Darwin
6f317ef3 3310 floating point constant. */
24ea750e 3311 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
c4ad648e
AM
3312 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3313 opnum, (enum reload_type)type);
24ea750e
DJ
3314 *win = 1;
3315 return x;
3316 }
3317#endif
4937d02d
DE
3318
3319 /* Force ld/std non-word aligned offset into base register by wrapping
3320 in offset 0. */
3321 if (GET_CODE (x) == PLUS
3322 && GET_CODE (XEXP (x, 0)) == REG
3323 && REGNO (XEXP (x, 0)) < 32
3324 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3325 && GET_CODE (XEXP (x, 1)) == CONST_INT
3326 && (INTVAL (XEXP (x, 1)) & 3) != 0
78796ad5 3327 && !ALTIVEC_VECTOR_MODE (mode)
4937d02d
DE
3328 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
3329 && TARGET_POWERPC64)
3330 {
3331 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
3332 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3333 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3334 opnum, (enum reload_type) type);
3335 *win = 1;
3336 return x;
3337 }
3338
24ea750e
DJ
3339 if (GET_CODE (x) == PLUS
3340 && GET_CODE (XEXP (x, 0)) == REG
3341 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
3342 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 3343 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 3344 && !SPE_VECTOR_MODE (mode)
54b695e7
AH
3345 && !(TARGET_E500_DOUBLE && (mode == DFmode
3346 || mode == DImode))
78c875e8 3347 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
3348 {
3349 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3350 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
3351 HOST_WIDE_INT high
c4ad648e 3352 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
24ea750e
DJ
3353
3354 /* Check for 32-bit overflow. */
3355 if (high + low != val)
c4ad648e 3356 {
24ea750e
DJ
3357 *win = 0;
3358 return x;
3359 }
3360
3361 /* Reload the high part into a base reg; leave the low part
c4ad648e 3362 in the mem directly. */
24ea750e
DJ
3363
3364 x = gen_rtx_PLUS (GET_MODE (x),
c4ad648e
AM
3365 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
3366 GEN_INT (high)),
3367 GEN_INT (low));
24ea750e
DJ
3368
3369 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
c4ad648e
AM
3370 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3371 opnum, (enum reload_type)type);
24ea750e
DJ
3372 *win = 1;
3373 return x;
3374 }
4937d02d 3375
24ea750e 3376 if (GET_CODE (x) == SYMBOL_REF
69ef87e2 3377 && !ALTIVEC_VECTOR_MODE (mode)
8308679f
DE
3378#if TARGET_MACHO
3379 && DEFAULT_ABI == ABI_DARWIN
a29077da 3380 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
8308679f
DE
3381#else
3382 && DEFAULT_ABI == ABI_V4
3383 && !flag_pic
3384#endif
0d8c1c97
AM
3385 /* Don't do this for TFmode, since the result isn't offsettable.
3386 The same goes for DImode without 64-bit gprs. */
3387 && mode != TFmode
3388 && (mode != DImode || TARGET_POWERPC64))
24ea750e 3389 {
8308679f 3390#if TARGET_MACHO
a29077da
GK
3391 if (flag_pic)
3392 {
3393 rtx offset = gen_rtx_CONST (Pmode,
3394 gen_rtx_MINUS (Pmode, x,
11abc112 3395 machopic_function_base_sym ()));
a29077da
GK
3396 x = gen_rtx_LO_SUM (GET_MODE (x),
3397 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
3398 gen_rtx_HIGH (Pmode, offset)), offset);
3399 }
3400 else
8308679f 3401#endif
a29077da 3402 x = gen_rtx_LO_SUM (GET_MODE (x),
c4ad648e 3403 gen_rtx_HIGH (Pmode, x), x);
a29077da 3404
24ea750e 3405 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
a29077da
GK
3406 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3407 opnum, (enum reload_type)type);
24ea750e
DJ
3408 *win = 1;
3409 return x;
3410 }
4937d02d 3411
dec1f3aa
DE
3412 /* Reload an offset address wrapped by an AND that represents the
3413 masking of the lower bits. Strip the outer AND and let reload
3414 convert the offset address into an indirect address. */
3415 if (TARGET_ALTIVEC
3416 && ALTIVEC_VECTOR_MODE (mode)
3417 && GET_CODE (x) == AND
3418 && GET_CODE (XEXP (x, 0)) == PLUS
3419 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3420 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3421 && GET_CODE (XEXP (x, 1)) == CONST_INT
3422 && INTVAL (XEXP (x, 1)) == -16)
3423 {
3424 x = XEXP (x, 0);
3425 *win = 1;
3426 return x;
3427 }
3428
24ea750e 3429 if (TARGET_TOC
4d588c14 3430 && constant_pool_expr_p (x)
c1f11548 3431 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
3432 {
3433 (x) = create_TOC_reference (x);
3434 *win = 1;
3435 return x;
3436 }
3437 *win = 0;
3438 return x;
f676971a 3439}
24ea750e 3440
258bfae2
FS
3441/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3442 that is a valid memory address for an instruction.
3443 The MODE argument is the machine mode for the MEM expression
3444 that wants to use this address.
3445
3446 On the RS/6000, there are four valid address: a SYMBOL_REF that
3447 refers to a constant pool entry of an address (or the sum of it
3448 plus a constant), a short (16-bit signed) constant plus a register,
3449 the sum of two registers, or a register indirect, possibly with an
5bdc5878 3450 auto-increment. For DFmode and DImode with a constant plus register,
258bfae2
FS
3451 we must ensure that both words are addressable or PowerPC64 with offset
3452 word aligned.
3453
3454 For modes spanning multiple registers (DFmode in 32-bit GPRs,
76d2b81d 3455 32-bit DImode, TImode, TFmode), indexed addressing cannot be used because
258bfae2
FS
3456 adjacent memory cells are accessed by adding word-sized offsets
3457 during assembly output. */
3458int
a2369ed3 3459rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
258bfae2 3460{
850e8d3d
DN
3461 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3462 if (TARGET_ALTIVEC
3463 && ALTIVEC_VECTOR_MODE (mode)
3464 && GET_CODE (x) == AND
3465 && GET_CODE (XEXP (x, 1)) == CONST_INT
3466 && INTVAL (XEXP (x, 1)) == -16)
3467 x = XEXP (x, 0);
3468
c4501e62
JJ
3469 if (RS6000_SYMBOL_REF_TLS_P (x))
3470 return 0;
4d588c14 3471 if (legitimate_indirect_address_p (x, reg_ok_strict))
258bfae2
FS
3472 return 1;
3473 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 3474 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 3475 && !SPE_VECTOR_MODE (mode)
54b695e7
AH
3476 /* Restrict addressing for DI because of our SUBREG hackery. */
3477 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
258bfae2 3478 && TARGET_UPDATE
4d588c14 3479 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
258bfae2 3480 return 1;
0c380712 3481 if (rs6000_legitimate_small_data_p (mode, x))
258bfae2 3482 return 1;
4d588c14 3483 if (legitimate_constant_pool_address_p (x))
258bfae2
FS
3484 return 1;
3485 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3486 if (! reg_ok_strict
3487 && GET_CODE (x) == PLUS
3488 && GET_CODE (XEXP (x, 0)) == REG
708d2456 3489 && (XEXP (x, 0) == virtual_stack_vars_rtx
c4ad648e 3490 || XEXP (x, 0) == arg_pointer_rtx)
258bfae2
FS
3491 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3492 return 1;
76d2b81d 3493 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
258bfae2
FS
3494 return 1;
3495 if (mode != TImode
76d2b81d 3496 && mode != TFmode
a3170dc6
AH
3497 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3498 || TARGET_POWERPC64
4d4cbc0e 3499 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
258bfae2 3500 && (TARGET_POWERPC64 || mode != DImode)
4d588c14 3501 && legitimate_indexed_address_p (x, reg_ok_strict))
258bfae2 3502 return 1;
4d588c14 3503 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
258bfae2
FS
3504 return 1;
3505 return 0;
3506}
4d588c14
RH
3507
3508/* Go to LABEL if ADDR (a legitimate address expression)
3509 has an effect that depends on the machine mode it is used for.
3510
3511 On the RS/6000 this is true of all integral offsets (since AltiVec
3512 modes don't allow them) or is a pre-increment or decrement.
3513
3514 ??? Except that due to conceptual problems in offsettable_address_p
3515 we can't really report the problems of integral offsets. So leave
f676971a 3516 this assuming that the adjustable offset must be valid for the
4d588c14
RH
3517 sub-words of a TFmode operand, which is what we had before. */
3518
3519bool
a2369ed3 3520rs6000_mode_dependent_address (rtx addr)
4d588c14
RH
3521{
3522 switch (GET_CODE (addr))
3523 {
3524 case PLUS:
3525 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
3526 {
3527 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
3528 return val + 12 + 0x8000 >= 0x10000;
3529 }
3530 break;
3531
3532 case LO_SUM:
3533 return true;
3534
3535 case PRE_INC:
3536 case PRE_DEC:
3537 return TARGET_UPDATE;
3538
3539 default:
3540 break;
3541 }
3542
3543 return false;
3544}
d8ecbcdb
AH
3545
3546/* Return number of consecutive hard regs needed starting at reg REGNO
3547 to hold something of mode MODE.
3548 This is ordinarily the length in words of a value of mode MODE
3549 but can be less for certain modes in special long registers.
3550
3551 For the SPE, GPRs are 64 bits but only 32 bits are visible in
3552 scalar instructions. The upper 32 bits are only available to the
3553 SIMD instructions.
3554
3555 POWER and PowerPC GPRs hold 32 bits worth;
3556 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
3557
3558int
3559rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
3560{
3561 if (FP_REGNO_P (regno))
3562 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
3563
4d4cbc0e
AH
3564 if (TARGET_E500_DOUBLE && mode == DFmode)
3565 return 1;
3566
d8ecbcdb
AH
3567 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
3568 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
3569
3570 if (ALTIVEC_REGNO_P (regno))
3571 return
3572 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
3573
3574 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3575}
2aa4498c
AH
3576
3577/* Change register usage conditional on target flags. */
3578void
3579rs6000_conditional_register_usage (void)
3580{
3581 int i;
3582
3583 /* Set MQ register fixed (already call_used) if not POWER
3584 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
3585 be allocated. */
3586 if (! TARGET_POWER)
3587 fixed_regs[64] = 1;
3588
7c9ac5c0 3589 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
2aa4498c
AH
3590 if (TARGET_64BIT)
3591 fixed_regs[13] = call_used_regs[13]
3592 = call_really_used_regs[13] = 1;
3593
3594 /* Conditionally disable FPRs. */
3595 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
3596 for (i = 32; i < 64; i++)
3597 fixed_regs[i] = call_used_regs[i]
c4ad648e 3598 = call_really_used_regs[i] = 1;
2aa4498c 3599
7c9ac5c0
PH
3600 /* The TOC register is not killed across calls in a way that is
3601 visible to the compiler. */
3602 if (DEFAULT_ABI == ABI_AIX)
3603 call_really_used_regs[2] = 0;
3604
2aa4498c
AH
3605 if (DEFAULT_ABI == ABI_V4
3606 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3607 && flag_pic == 2)
3608 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3609
3610 if (DEFAULT_ABI == ABI_V4
3611 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
3612 && flag_pic == 1)
3613 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3614 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3615 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3616
3617 if (DEFAULT_ABI == ABI_DARWIN
3618 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6d0a8091 3619 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
2aa4498c
AH
3620 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3621 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3622
b4db40bf
JJ
3623 if (TARGET_TOC && TARGET_MINIMAL_TOC)
3624 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
3625 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
3626
2aa4498c
AH
3627 if (TARGET_ALTIVEC)
3628 global_regs[VSCR_REGNO] = 1;
3629
3630 if (TARGET_SPE)
3631 {
3632 global_regs[SPEFSCR_REGNO] = 1;
3633 fixed_regs[FIXED_SCRATCH]
c4ad648e 3634 = call_used_regs[FIXED_SCRATCH]
2aa4498c
AH
3635 = call_really_used_regs[FIXED_SCRATCH] = 1;
3636 }
3637
3638 if (! TARGET_ALTIVEC)
3639 {
3640 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
3641 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
3642 call_really_used_regs[VRSAVE_REGNO] = 1;
3643 }
3644
3645 if (TARGET_ALTIVEC_ABI)
3646 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
3647 call_used_regs[i] = call_really_used_regs[i] = 1;
3648}
fb4d4348 3649\f
a4f6c312
SS
3650/* Try to output insns to set TARGET equal to the constant C if it can
3651 be done in less than N insns. Do all computations in MODE.
3652 Returns the place where the output has been placed if it can be
3653 done and the insns have been emitted. If it would take more than N
3654 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
3655
3656rtx
f676971a 3657rs6000_emit_set_const (rtx dest, enum machine_mode mode,
a2369ed3 3658 rtx source, int n ATTRIBUTE_UNUSED)
2bfcf297 3659{
af8cb5c5 3660 rtx result, insn, set;
2bfcf297
DB
3661 HOST_WIDE_INT c0, c1;
3662
37409796 3663 switch (mode)
2bfcf297 3664 {
37409796
NS
3665 case QImode:
3666 case HImode:
2bfcf297 3667 if (dest == NULL)
c4ad648e 3668 dest = gen_reg_rtx (mode);
2bfcf297
DB
3669 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
3670 return dest;
bb8df8a6 3671
37409796 3672 case SImode:
af8cb5c5 3673 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
bb8df8a6 3674
af8cb5c5
DE
3675 emit_insn (gen_rtx_SET (VOIDmode, result,
3676 GEN_INT (INTVAL (source)
3677 & (~ (HOST_WIDE_INT) 0xffff))));
3678 emit_insn (gen_rtx_SET (VOIDmode, dest,
3679 gen_rtx_IOR (SImode, result,
3680 GEN_INT (INTVAL (source) & 0xffff))));
3681 result = dest;
37409796
NS
3682 break;
3683
3684 case DImode:
3685 switch (GET_CODE (source))
af8cb5c5 3686 {
37409796 3687 case CONST_INT:
af8cb5c5
DE
3688 c0 = INTVAL (source);
3689 c1 = -(c0 < 0);
37409796 3690 break;
bb8df8a6 3691
37409796 3692 case CONST_DOUBLE:
2bfcf297 3693#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
3694 c0 = CONST_DOUBLE_LOW (source);
3695 c1 = -(c0 < 0);
2bfcf297 3696#else
af8cb5c5
DE
3697 c0 = CONST_DOUBLE_LOW (source);
3698 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 3699#endif
37409796
NS
3700 break;
3701
3702 default:
3703 gcc_unreachable ();
af8cb5c5 3704 }
af8cb5c5
DE
3705
3706 result = rs6000_emit_set_long_const (dest, c0, c1);
37409796
NS
3707 break;
3708
3709 default:
3710 gcc_unreachable ();
2bfcf297 3711 }
2bfcf297 3712
af8cb5c5
DE
3713 insn = get_last_insn ();
3714 set = single_set (insn);
3715 if (! CONSTANT_P (SET_SRC (set)))
3716 set_unique_reg_note (insn, REG_EQUAL, source);
3717
3718 return result;
2bfcf297
DB
3719}
3720
3721/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
3722 fall back to a straight forward decomposition. We do this to avoid
3723 exponential run times encountered when looking for longer sequences
3724 with rs6000_emit_set_const. */
3725static rtx
a2369ed3 3726rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
2bfcf297
DB
3727{
3728 if (!TARGET_POWERPC64)
3729 {
3730 rtx operand1, operand2;
3731
3732 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
3733 DImode);
3734 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
3735 DImode);
3736 emit_move_insn (operand1, GEN_INT (c1));
3737 emit_move_insn (operand2, GEN_INT (c2));
3738 }
3739 else
3740 {
bc06712d 3741 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 3742
bc06712d 3743 ud1 = c1 & 0xffff;
f921c9c9 3744 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 3745#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 3746 c2 = c1 >> 32;
2bfcf297 3747#endif
bc06712d 3748 ud3 = c2 & 0xffff;
f921c9c9 3749 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 3750
f676971a 3751 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
bc06712d 3752 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 3753 {
bc06712d 3754 if (ud1 & 0x8000)
b78d48dd 3755 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
bc06712d
TR
3756 else
3757 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 3758 }
2bfcf297 3759
f676971a 3760 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
bc06712d 3761 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 3762 {
bc06712d 3763 if (ud2 & 0x8000)
f676971a 3764 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
bc06712d 3765 - 0x80000000));
252b88f7 3766 else
bc06712d
TR
3767 emit_move_insn (dest, GEN_INT (ud2 << 16));
3768 if (ud1 != 0)
3769 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 3770 }
f676971a 3771 else if ((ud4 == 0xffff && (ud3 & 0x8000))
bc06712d
TR
3772 || (ud4 == 0 && ! (ud3 & 0x8000)))
3773 {
3774 if (ud3 & 0x8000)
f676971a 3775 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
bc06712d
TR
3776 - 0x80000000));
3777 else
3778 emit_move_insn (dest, GEN_INT (ud3 << 16));
3779
3780 if (ud2 != 0)
3781 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
3782 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
3783 if (ud1 != 0)
3784 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3785 }
f676971a 3786 else
bc06712d
TR
3787 {
3788 if (ud4 & 0x8000)
f676971a 3789 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
bc06712d
TR
3790 - 0x80000000));
3791 else
3792 emit_move_insn (dest, GEN_INT (ud4 << 16));
3793
3794 if (ud3 != 0)
3795 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 3796
bc06712d
TR
3797 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
3798 if (ud2 != 0)
f676971a
EC
3799 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
3800 GEN_INT (ud2 << 16)));
bc06712d
TR
3801 if (ud1 != 0)
3802 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
3803 }
3804 }
2bfcf297
DB
3805 return dest;
3806}
3807
76d2b81d
DJ
3808/* Helper for the following. Get rid of [r+r] memory refs
3809 in cases where it won't work (TImode, TFmode). */
3810
3811static void
3812rs6000_eliminate_indexed_memrefs (rtx operands[2])
3813{
3814 if (GET_CODE (operands[0]) == MEM
3815 && GET_CODE (XEXP (operands[0], 0)) != REG
55aa0757 3816 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
76d2b81d
DJ
3817 && ! reload_in_progress)
3818 operands[0]
3819 = replace_equiv_address (operands[0],
3820 copy_addr_to_reg (XEXP (operands[0], 0)));
3821
3822 if (GET_CODE (operands[1]) == MEM
3823 && GET_CODE (XEXP (operands[1], 0)) != REG
55aa0757 3824 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
76d2b81d
DJ
3825 && ! reload_in_progress)
3826 operands[1]
3827 = replace_equiv_address (operands[1],
3828 copy_addr_to_reg (XEXP (operands[1], 0)));
3829}
3830
fb4d4348
GK
3831/* Emit a move from SOURCE to DEST in mode MODE. */
3832void
a2369ed3 3833rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
fb4d4348
GK
3834{
3835 rtx operands[2];
3836 operands[0] = dest;
3837 operands[1] = source;
f676971a 3838
fb4d4348
GK
3839 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
3840 if (GET_CODE (operands[1]) == CONST_DOUBLE
3841 && ! FLOAT_MODE_P (mode)
3842 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
3843 {
3844 /* FIXME. This should never happen. */
3845 /* Since it seems that it does, do the safe thing and convert
3846 to a CONST_INT. */
2496c7bd 3847 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348 3848 }
37409796
NS
3849 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
3850 || FLOAT_MODE_P (mode)
3851 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
3852 || CONST_DOUBLE_LOW (operands[1]) < 0)
3853 && (CONST_DOUBLE_HIGH (operands[1]) != -1
3854 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
bb8df8a6 3855
c9e8cb32
DD
3856 /* Check if GCC is setting up a block move that will end up using FP
3857 registers as temporaries. We must make sure this is acceptable. */
3858 if (GET_CODE (operands[0]) == MEM
3859 && GET_CODE (operands[1]) == MEM
3860 && mode == DImode
41543739
GK
3861 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
3862 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
3863 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
3864 ? 32 : MEM_ALIGN (operands[0])))
3865 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
f676971a 3866 ? 32
41543739
GK
3867 : MEM_ALIGN (operands[1]))))
3868 && ! MEM_VOLATILE_P (operands [0])
3869 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 3870 {
41543739
GK
3871 emit_move_insn (adjust_address (operands[0], SImode, 0),
3872 adjust_address (operands[1], SImode, 0));
3873 emit_move_insn (adjust_address (operands[0], SImode, 4),
3874 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
3875 return;
3876 }
630d42a0 3877
55aa0757 3878 if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
c9dbf840 3879 && !gpc_reg_operand (operands[1], mode))
f6219a5e 3880 operands[1] = force_reg (mode, operands[1]);
a9098fd0 3881
a3170dc6
AH
3882 if (mode == SFmode && ! TARGET_POWERPC
3883 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 3884 && GET_CODE (operands[0]) == MEM)
fb4d4348 3885 {
ffc14f31
GK
3886 int regnum;
3887
3888 if (reload_in_progress || reload_completed)
3889 regnum = true_regnum (operands[1]);
3890 else if (GET_CODE (operands[1]) == REG)
3891 regnum = REGNO (operands[1]);
3892 else
3893 regnum = -1;
f676971a 3894
fb4d4348
GK
3895 /* If operands[1] is a register, on POWER it may have
3896 double-precision data in it, so truncate it to single
3897 precision. */
3898 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
3899 {
3900 rtx newreg;
3901 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
3902 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
3903 operands[1] = newreg;
3904 }
3905 }
3906
c4501e62
JJ
3907 /* Recognize the case where operand[1] is a reference to thread-local
3908 data and load its address to a register. */
84f52ebd 3909 if (rs6000_tls_referenced_p (operands[1]))
c4501e62 3910 {
84f52ebd
RH
3911 enum tls_model model;
3912 rtx tmp = operands[1];
3913 rtx addend = NULL;
3914
3915 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
3916 {
3917 addend = XEXP (XEXP (tmp, 0), 1);
3918 tmp = XEXP (XEXP (tmp, 0), 0);
3919 }
3920
3921 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
3922 model = SYMBOL_REF_TLS_MODEL (tmp);
3923 gcc_assert (model != 0);
3924
3925 tmp = rs6000_legitimize_tls_address (tmp, model);
3926 if (addend)
3927 {
3928 tmp = gen_rtx_PLUS (mode, tmp, addend);
3929 tmp = force_operand (tmp, operands[0]);
3930 }
3931 operands[1] = tmp;
c4501e62
JJ
3932 }
3933
8f4e6caf
RH
3934 /* Handle the case where reload calls us with an invalid address. */
3935 if (reload_in_progress && mode == Pmode
69ef87e2 3936 && (! general_operand (operands[1], mode)
8f4e6caf
RH
3937 || ! nonimmediate_operand (operands[0], mode)))
3938 goto emit_set;
3939
a9baceb1
GK
3940 /* 128-bit constant floating-point values on Darwin should really be
3941 loaded as two parts. */
602ea4d3 3942 if (!TARGET_IEEEQUAD
a9baceb1
GK
3943 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128
3944 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
3945 {
3946 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
3947 know how to get a DFmode SUBREG of a TFmode. */
3948 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode, 0),
3949 simplify_gen_subreg (DImode, operands[1], mode, 0),
3950 DImode);
3951 rs6000_emit_move (simplify_gen_subreg (DImode, operands[0], mode,
3952 GET_MODE_SIZE (DImode)),
3953 simplify_gen_subreg (DImode, operands[1], mode,
3954 GET_MODE_SIZE (DImode)),
3955 DImode);
3956 return;
3957 }
3958
fb4d4348
GK
3959 /* FIXME: In the long term, this switch statement should go away
3960 and be replaced by a sequence of tests based on things like
3961 mode == Pmode. */
3962 switch (mode)
3963 {
3964 case HImode:
3965 case QImode:
3966 if (CONSTANT_P (operands[1])
3967 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 3968 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
3969 break;
3970
06f4e019 3971 case TFmode:
76d2b81d
DJ
3972 rs6000_eliminate_indexed_memrefs (operands);
3973 /* fall through */
3974
fb4d4348
GK
3975 case DFmode:
3976 case SFmode:
f676971a 3977 if (CONSTANT_P (operands[1])
fb4d4348 3978 && ! easy_fp_constant (operands[1], mode))
a9098fd0 3979 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348 3980 break;
f676971a 3981
0ac081f6
AH
3982 case V16QImode:
3983 case V8HImode:
3984 case V4SFmode:
3985 case V4SImode:
a3170dc6
AH
3986 case V4HImode:
3987 case V2SFmode:
3988 case V2SImode:
00a892b8 3989 case V1DImode:
69ef87e2 3990 if (CONSTANT_P (operands[1])
d744e06e 3991 && !easy_vector_constant (operands[1], mode))
0ac081f6
AH
3992 operands[1] = force_const_mem (mode, operands[1]);
3993 break;
f676971a 3994
fb4d4348 3995 case SImode:
a9098fd0 3996 case DImode:
fb4d4348
GK
3997 /* Use default pattern for address of ELF small data */
3998 if (TARGET_ELF
a9098fd0 3999 && mode == Pmode
f607bc57 4000 && DEFAULT_ABI == ABI_V4
f676971a 4001 && (GET_CODE (operands[1]) == SYMBOL_REF
a9098fd0
GK
4002 || GET_CODE (operands[1]) == CONST)
4003 && small_data_operand (operands[1], mode))
fb4d4348
GK
4004 {
4005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4006 return;
4007 }
4008
f607bc57 4009 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
4010 && mode == Pmode && mode == SImode
4011 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
4012 {
4013 emit_insn (gen_movsi_got (operands[0], operands[1]));
4014 return;
4015 }
4016
ee890fe2 4017 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
f1384257
AM
4018 && TARGET_NO_TOC
4019 && ! flag_pic
a9098fd0 4020 && mode == Pmode
fb4d4348
GK
4021 && CONSTANT_P (operands[1])
4022 && GET_CODE (operands[1]) != HIGH
4023 && GET_CODE (operands[1]) != CONST_INT)
4024 {
a9098fd0 4025 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
4026
4027 /* If this is a function address on -mcall-aixdesc,
4028 convert it to the address of the descriptor. */
4029 if (DEFAULT_ABI == ABI_AIX
4030 && GET_CODE (operands[1]) == SYMBOL_REF
4031 && XSTR (operands[1], 0)[0] == '.')
4032 {
4033 const char *name = XSTR (operands[1], 0);
4034 rtx new_ref;
4035 while (*name == '.')
4036 name++;
4037 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4038 CONSTANT_POOL_ADDRESS_P (new_ref)
4039 = CONSTANT_POOL_ADDRESS_P (operands[1]);
d1908feb 4040 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
fb4d4348 4041 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
c185c797 4042 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
fb4d4348
GK
4043 operands[1] = new_ref;
4044 }
7509c759 4045
ee890fe2
SS
4046 if (DEFAULT_ABI == ABI_DARWIN)
4047 {
ab82a49f
AP
4048#if TARGET_MACHO
4049 if (MACHO_DYNAMIC_NO_PIC_P)
4050 {
4051 /* Take care of any required data indirection. */
4052 operands[1] = rs6000_machopic_legitimize_pic_address (
4053 operands[1], mode, operands[0]);
4054 if (operands[0] != operands[1])
4055 emit_insn (gen_rtx_SET (VOIDmode,
c4ad648e 4056 operands[0], operands[1]));
ab82a49f
AP
4057 return;
4058 }
4059#endif
b8a55285
AP
4060 emit_insn (gen_macho_high (target, operands[1]));
4061 emit_insn (gen_macho_low (operands[0], target, operands[1]));
ee890fe2
SS
4062 return;
4063 }
4064
fb4d4348
GK
4065 emit_insn (gen_elf_high (target, operands[1]));
4066 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4067 return;
4068 }
4069
a9098fd0
GK
4070 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4071 and we have put it in the TOC, we just need to make a TOC-relative
4072 reference to it. */
4073 if (TARGET_TOC
4074 && GET_CODE (operands[1]) == SYMBOL_REF
4d588c14 4075 && constant_pool_expr_p (operands[1])
a9098fd0
GK
4076 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4077 get_pool_mode (operands[1])))
fb4d4348 4078 {
a9098fd0 4079 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 4080 }
a9098fd0
GK
4081 else if (mode == Pmode
4082 && CONSTANT_P (operands[1])
38886f37
AO
4083 && ((GET_CODE (operands[1]) != CONST_INT
4084 && ! easy_fp_constant (operands[1], mode))
4085 || (GET_CODE (operands[1]) == CONST_INT
4086 && num_insns_constant (operands[1], mode) > 2)
4087 || (GET_CODE (operands[0]) == REG
4088 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0 4089 && GET_CODE (operands[1]) != HIGH
4d588c14
RH
4090 && ! legitimate_constant_pool_address_p (operands[1])
4091 && ! toc_relative_expr_p (operands[1]))
fb4d4348
GK
4092 {
4093 /* Emit a USE operation so that the constant isn't deleted if
4094 expensive optimizations are turned on because nobody
4095 references it. This should only be done for operands that
4096 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4097 This should not be done for operands that contain LABEL_REFs.
4098 For now, we just handle the obvious case. */
4099 if (GET_CODE (operands[1]) != LABEL_REF)
4100 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
4101
c859cda6 4102#if TARGET_MACHO
ee890fe2 4103 /* Darwin uses a special PIC legitimizer. */
ab82a49f 4104 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
ee890fe2 4105 {
ee890fe2
SS
4106 operands[1] =
4107 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
4108 operands[0]);
4109 if (operands[0] != operands[1])
4110 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
4111 return;
4112 }
c859cda6 4113#endif
ee890fe2 4114
fb4d4348
GK
4115 /* If we are to limit the number of things we put in the TOC and
4116 this is a symbol plus a constant we can add in one insn,
4117 just put the symbol in the TOC and add the constant. Don't do
4118 this if reload is in progress. */
4119 if (GET_CODE (operands[1]) == CONST
4120 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4121 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 4122 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
4123 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4124 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4125 && ! side_effects_p (operands[0]))
4126 {
a4f6c312
SS
4127 rtx sym =
4128 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
4129 rtx other = XEXP (XEXP (operands[1], 0), 1);
4130
a9098fd0
GK
4131 sym = force_reg (mode, sym);
4132 if (mode == SImode)
4133 emit_insn (gen_addsi3 (operands[0], sym, other));
4134 else
4135 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
4136 return;
4137 }
4138
a9098fd0 4139 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348 4140
f676971a 4141 if (TARGET_TOC
4d588c14 4142 && constant_pool_expr_p (XEXP (operands[1], 0))
d34c5b80
DE
4143 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4144 get_pool_constant (XEXP (operands[1], 0)),
4145 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 4146 {
ba4828e0 4147 operands[1]
542a8afa 4148 = gen_const_mem (mode,
c4ad648e 4149 create_TOC_reference (XEXP (operands[1], 0)));
ba4828e0 4150 set_mem_alias_set (operands[1], get_TOC_alias_set ());
a9098fd0 4151 }
fb4d4348
GK
4152 }
4153 break;
a9098fd0 4154
fb4d4348 4155 case TImode:
76d2b81d
DJ
4156 rs6000_eliminate_indexed_memrefs (operands);
4157
27dc0551
DE
4158 if (TARGET_POWER)
4159 {
4160 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4161 gen_rtvec (2,
4162 gen_rtx_SET (VOIDmode,
4163 operands[0], operands[1]),
4164 gen_rtx_CLOBBER (VOIDmode,
4165 gen_rtx_SCRATCH (SImode)))));
4166 return;
4167 }
fb4d4348
GK
4168 break;
4169
4170 default:
37409796 4171 gcc_unreachable ();
fb4d4348
GK
4172 }
4173
a9098fd0
GK
4174 /* Above, we may have called force_const_mem which may have returned
4175 an invalid address. If we can, fix this up; otherwise, reload will
4176 have to deal with it. */
8f4e6caf
RH
4177 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
4178 operands[1] = validize_mem (operands[1]);
a9098fd0 4179
8f4e6caf 4180 emit_set:
fb4d4348
GK
4181 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4182}
4697a36c 4183\f
2858f73a
GK
4184/* Nonzero if we can use a floating-point register to pass this arg. */
4185#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
ebb109ad 4186 (SCALAR_FLOAT_MODE_P (MODE) \
00b79d54 4187 && !DECIMAL_FLOAT_MODE_P (MODE) \
2858f73a
GK
4188 && (CUM)->fregno <= FP_ARG_MAX_REG \
4189 && TARGET_HARD_FLOAT && TARGET_FPRS)
4190
4191/* Nonzero if we can use an AltiVec register to pass this arg. */
4192#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4193 (ALTIVEC_VECTOR_MODE (MODE) \
4194 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4195 && TARGET_ALTIVEC_ABI \
83953138 4196 && (NAMED))
2858f73a 4197
c6e8c921
GK
4198/* Return a nonzero value to say to return the function value in
4199 memory, just as large structures are always returned. TYPE will be
4200 the data type of the value, and FNTYPE will be the type of the
4201 function doing the returning, or @code{NULL} for libcalls.
4202
4203 The AIX ABI for the RS/6000 specifies that all structures are
4204 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4205 specifies that structures <= 8 bytes are returned in r3/r4, but a
4206 draft put them in memory, and GCC used to implement the draft
df01da37 4207 instead of the final standard. Therefore, aix_struct_return
c6e8c921
GK
4208 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4209 compatibility can change DRAFT_V4_STRUCT_RET to override the
4210 default, and -m switches get the final word. See
4211 rs6000_override_options for more details.
4212
4213 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4214 long double support is enabled. These values are returned in memory.
4215
4216 int_size_in_bytes returns -1 for variable size objects, which go in
4217 memory always. The cast to unsigned makes -1 > 8. */
4218
4219static bool
4220rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
4221{
594a51fe
SS
4222 /* In the darwin64 abi, try to use registers for larger structs
4223 if possible. */
0b5383eb 4224 if (rs6000_darwin64_abi
594a51fe 4225 && TREE_CODE (type) == RECORD_TYPE
0b5383eb
DJ
4226 && int_size_in_bytes (type) > 0)
4227 {
4228 CUMULATIVE_ARGS valcum;
4229 rtx valret;
4230
4231 valcum.words = 0;
4232 valcum.fregno = FP_ARG_MIN_REG;
4233 valcum.vregno = ALTIVEC_ARG_MIN_REG;
4234 /* Do a trial code generation as if this were going to be passed
4235 as an argument; if any part goes in memory, we return NULL. */
4236 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
4237 if (valret)
4238 return false;
4239 /* Otherwise fall through to more conventional ABI rules. */
4240 }
594a51fe 4241
c6e8c921 4242 if (AGGREGATE_TYPE_P (type)
df01da37 4243 && (aix_struct_return
c6e8c921
GK
4244 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
4245 return true;
b693336b 4246
bada2eb8
DE
4247 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4248 modes only exist for GCC vector types if -maltivec. */
4249 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
4250 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
4251 return false;
4252
b693336b
PB
4253 /* Return synthetic vectors in memory. */
4254 if (TREE_CODE (type) == VECTOR_TYPE
ad630bef 4255 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
b693336b
PB
4256 {
4257 static bool warned_for_return_big_vectors = false;
4258 if (!warned_for_return_big_vectors)
4259 {
d4ee4d25 4260 warning (0, "GCC vector returned by reference: "
b693336b
PB
4261 "non-standard ABI extension with no compatibility guarantee");
4262 warned_for_return_big_vectors = true;
4263 }
4264 return true;
4265 }
4266
602ea4d3 4267 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
c6e8c921 4268 return true;
ad630bef 4269
c6e8c921
GK
4270 return false;
4271}
4272
4697a36c
MM
4273/* Initialize a variable CUM of type CUMULATIVE_ARGS
4274 for a call to a function whose data type is FNTYPE.
4275 For a library call, FNTYPE is 0.
4276
4277 For incoming args we set the number of arguments in the prototype large
1c20ae99 4278 so we never return a PARALLEL. */
4697a36c
MM
4279
4280void
f676971a 4281init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
0f6937fe
AM
4282 rtx libname ATTRIBUTE_UNUSED, int incoming,
4283 int libcall, int n_named_args)
4697a36c
MM
4284{
4285 static CUMULATIVE_ARGS zero_cumulative;
4286
4287 *cum = zero_cumulative;
4288 cum->words = 0;
4289 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 4290 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 4291 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
ddcc8263
DE
4292 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
4293 ? CALL_LIBCALL : CALL_NORMAL);
4cc833b7 4294 cum->sysv_gregno = GP_ARG_MIN_REG;
a6c9bed4
AH
4295 cum->stdarg = fntype
4296 && (TYPE_ARG_TYPES (fntype) != 0
4297 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4298 != void_type_node));
4697a36c 4299
0f6937fe
AM
4300 cum->nargs_prototype = 0;
4301 if (incoming || cum->prototype)
4302 cum->nargs_prototype = n_named_args;
4697a36c 4303
a5c76ee6 4304 /* Check for a longcall attribute. */
3eb4e360
AM
4305 if ((!fntype && rs6000_default_long_calls)
4306 || (fntype
4307 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
4308 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
4309 cum->call_cookie |= CALL_LONG;
6a4cee5f 4310
4697a36c
MM
4311 if (TARGET_DEBUG_ARG)
4312 {
4313 fprintf (stderr, "\ninit_cumulative_args:");
4314 if (fntype)
4315 {
4316 tree ret_type = TREE_TYPE (fntype);
4317 fprintf (stderr, " ret code = %s,",
4318 tree_code_name[ (int)TREE_CODE (ret_type) ]);
4319 }
4320
6a4cee5f
MM
4321 if (cum->call_cookie & CALL_LONG)
4322 fprintf (stderr, " longcall,");
4323
4697a36c
MM
4324 fprintf (stderr, " proto = %d, nargs = %d\n",
4325 cum->prototype, cum->nargs_prototype);
4326 }
f676971a 4327
c4ad648e
AM
4328 if (fntype
4329 && !TARGET_ALTIVEC
4330 && TARGET_ALTIVEC_ABI
4331 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
4332 {
c85ce869 4333 error ("cannot return value in vector register because"
c4ad648e 4334 " altivec instructions are disabled, use -maltivec"
c85ce869 4335 " to enable them");
c4ad648e 4336 }
4697a36c
MM
4337}
4338\f
fe984136
RH
4339/* Return true if TYPE must be passed on the stack and not in registers. */
4340
4341static bool
4342rs6000_must_pass_in_stack (enum machine_mode mode, tree type)
4343{
4344 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
4345 return must_pass_in_stack_var_size (mode, type);
4346 else
4347 return must_pass_in_stack_var_size_or_pad (mode, type);
4348}
4349
c229cba9
DE
4350/* If defined, a C expression which determines whether, and in which
4351 direction, to pad out an argument with extra space. The value
4352 should be of type `enum direction': either `upward' to pad above
4353 the argument, `downward' to pad below, or `none' to inhibit
4354 padding.
4355
4356 For the AIX ABI structs are always stored left shifted in their
4357 argument slot. */
4358
9ebbca7d 4359enum direction
a2369ed3 4360function_arg_padding (enum machine_mode mode, tree type)
c229cba9 4361{
6e985040
AM
4362#ifndef AGGREGATE_PADDING_FIXED
4363#define AGGREGATE_PADDING_FIXED 0
4364#endif
4365#ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4366#define AGGREGATES_PAD_UPWARD_ALWAYS 0
4367#endif
4368
4369 if (!AGGREGATE_PADDING_FIXED)
4370 {
4371 /* GCC used to pass structures of the same size as integer types as
4372 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
19525b57 4373 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6e985040
AM
4374 passed padded downward, except that -mstrict-align further
4375 muddied the water in that multi-component structures of 2 and 4
4376 bytes in size were passed padded upward.
4377
4378 The following arranges for best compatibility with previous
4379 versions of gcc, but removes the -mstrict-align dependency. */
4380 if (BYTES_BIG_ENDIAN)
4381 {
4382 HOST_WIDE_INT size = 0;
4383
4384 if (mode == BLKmode)
4385 {
4386 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4387 size = int_size_in_bytes (type);
4388 }
4389 else
4390 size = GET_MODE_SIZE (mode);
4391
4392 if (size == 1 || size == 2 || size == 4)
4393 return downward;
4394 }
4395 return upward;
4396 }
4397
4398 if (AGGREGATES_PAD_UPWARD_ALWAYS)
4399 {
4400 if (type != 0 && AGGREGATE_TYPE_P (type))
4401 return upward;
4402 }
c229cba9 4403
d3704c46
KH
4404 /* Fall back to the default. */
4405 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
c229cba9
DE
4406}
4407
b6c9286a 4408/* If defined, a C expression that gives the alignment boundary, in bits,
f676971a 4409 of an argument with the specified mode and type. If it is not defined,
b6c9286a 4410 PARM_BOUNDARY is used for all arguments.
f676971a 4411
b693336b
PB
4412 V.4 wants long longs to be double word aligned.
4413 Doubleword align SPE vectors.
4414 Quadword align Altivec vectors.
4415 Quadword align large synthetic vector types. */
b6c9286a
MM
4416
4417int
b693336b 4418function_arg_boundary (enum machine_mode mode, tree type)
b6c9286a 4419{
4ed78545
AM
4420 if (DEFAULT_ABI == ABI_V4 && GET_MODE_SIZE (mode) == 8)
4421 return 64;
ad630bef
DE
4422 else if (SPE_VECTOR_MODE (mode)
4423 || (type && TREE_CODE (type) == VECTOR_TYPE
4424 && int_size_in_bytes (type) >= 8
4425 && int_size_in_bytes (type) < 16))
e1f83b4d 4426 return 64;
ad630bef
DE
4427 else if (ALTIVEC_VECTOR_MODE (mode)
4428 || (type && TREE_CODE (type) == VECTOR_TYPE
4429 && int_size_in_bytes (type) >= 16))
0ac081f6 4430 return 128;
0b5383eb
DJ
4431 else if (rs6000_darwin64_abi && mode == BLKmode
4432 && type && TYPE_ALIGN (type) > 64)
4433 return 128;
9ebbca7d 4434 else
b6c9286a 4435 return PARM_BOUNDARY;
b6c9286a 4436}
c53bdcf5 4437
294bd182
AM
4438/* For a function parm of MODE and TYPE, return the starting word in
4439 the parameter area. NWORDS of the parameter area are already used. */
4440
4441static unsigned int
4442rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
4443{
4444 unsigned int align;
4445 unsigned int parm_offset;
4446
4447 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
4448 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
4449 return nwords + (-(parm_offset + nwords) & align);
4450}
4451
c53bdcf5
AM
4452/* Compute the size (in words) of a function argument. */
4453
4454static unsigned long
4455rs6000_arg_size (enum machine_mode mode, tree type)
4456{
4457 unsigned long size;
4458
4459 if (mode != BLKmode)
4460 size = GET_MODE_SIZE (mode);
4461 else
4462 size = int_size_in_bytes (type);
4463
4464 if (TARGET_32BIT)
4465 return (size + 3) >> 2;
4466 else
4467 return (size + 7) >> 3;
4468}
b6c9286a 4469\f
0b5383eb 4470/* Use this to flush pending int fields. */
594a51fe
SS
4471
4472static void
0b5383eb
DJ
4473rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
4474 HOST_WIDE_INT bitpos)
594a51fe 4475{
0b5383eb
DJ
4476 unsigned int startbit, endbit;
4477 int intregs, intoffset;
4478 enum machine_mode mode;
594a51fe 4479
0b5383eb
DJ
4480 if (cum->intoffset == -1)
4481 return;
594a51fe 4482
0b5383eb
DJ
4483 intoffset = cum->intoffset;
4484 cum->intoffset = -1;
4485
4486 if (intoffset % BITS_PER_WORD != 0)
4487 {
4488 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4489 MODE_INT, 0);
4490 if (mode == BLKmode)
594a51fe 4491 {
0b5383eb
DJ
4492 /* We couldn't find an appropriate mode, which happens,
4493 e.g., in packed structs when there are 3 bytes to load.
4494 Back intoffset back to the beginning of the word in this
4495 case. */
4496 intoffset = intoffset & -BITS_PER_WORD;
594a51fe 4497 }
594a51fe 4498 }
0b5383eb
DJ
4499
4500 startbit = intoffset & -BITS_PER_WORD;
4501 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4502 intregs = (endbit - startbit) / BITS_PER_WORD;
4503 cum->words += intregs;
4504}
4505
4506/* The darwin64 ABI calls for us to recurse down through structs,
4507 looking for elements passed in registers. Unfortunately, we have
4508 to track int register count here also because of misalignments
4509 in powerpc alignment mode. */
4510
4511static void
4512rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
4513 tree type,
4514 HOST_WIDE_INT startbitpos)
4515{
4516 tree f;
4517
4518 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4519 if (TREE_CODE (f) == FIELD_DECL)
4520 {
4521 HOST_WIDE_INT bitpos = startbitpos;
4522 tree ftype = TREE_TYPE (f);
4523 enum machine_mode mode = TYPE_MODE (ftype);
4524
4525 if (DECL_SIZE (f) != 0
4526 && host_integerp (bit_position (f), 1))
4527 bitpos += int_bit_position (f);
4528
4529 /* ??? FIXME: else assume zero offset. */
4530
4531 if (TREE_CODE (ftype) == RECORD_TYPE)
4532 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
4533 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
4534 {
4535 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4536 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4537 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
4538 }
4539 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
4540 {
4541 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
4542 cum->vregno++;
4543 cum->words += 2;
4544 }
4545 else if (cum->intoffset == -1)
4546 cum->intoffset = bitpos;
4547 }
594a51fe
SS
4548}
4549
4697a36c
MM
4550/* Update the data in CUM to advance over an argument
4551 of mode MODE and data type TYPE.
b2d04ecf
AM
4552 (TYPE is null for libcalls where that information may not be available.)
4553
4554 Note that for args passed by reference, function_arg will be called
4555 with MODE and TYPE set to that of the pointer to the arg, not the arg
4556 itself. */
4697a36c
MM
4557
4558void
f676971a 4559function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
594a51fe 4560 tree type, int named, int depth)
4697a36c 4561{
0b5383eb
DJ
4562 int size;
4563
594a51fe
SS
4564 /* Only tick off an argument if we're not recursing. */
4565 if (depth == 0)
4566 cum->nargs_prototype--;
4697a36c 4567
ad630bef
DE
4568 if (TARGET_ALTIVEC_ABI
4569 && (ALTIVEC_VECTOR_MODE (mode)
4570 || (type && TREE_CODE (type) == VECTOR_TYPE
4571 && int_size_in_bytes (type) == 16)))
0ac081f6 4572 {
4ed78545
AM
4573 bool stack = false;
4574
2858f73a 4575 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
c4ad648e 4576 {
6d0ef01e
HP
4577 cum->vregno++;
4578 if (!TARGET_ALTIVEC)
c85ce869 4579 error ("cannot pass argument in vector register because"
6d0ef01e 4580 " altivec instructions are disabled, use -maltivec"
c85ce869 4581 " to enable them");
4ed78545
AM
4582
4583 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
f676971a 4584 even if it is going to be passed in a vector register.
4ed78545
AM
4585 Darwin does the same for variable-argument functions. */
4586 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
4587 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
4588 stack = true;
6d0ef01e 4589 }
4ed78545
AM
4590 else
4591 stack = true;
4592
4593 if (stack)
c4ad648e 4594 {
a594a19c 4595 int align;
f676971a 4596
2858f73a
GK
4597 /* Vector parameters must be 16-byte aligned. This places
4598 them at 2 mod 4 in terms of words in 32-bit mode, since
4599 the parameter save area starts at offset 24 from the
4600 stack. In 64-bit mode, they just have to start on an
4601 even word, since the parameter save area is 16-byte
4602 aligned. Space for GPRs is reserved even if the argument
4603 will be passed in memory. */
4604 if (TARGET_32BIT)
4ed78545 4605 align = (2 - cum->words) & 3;
2858f73a
GK
4606 else
4607 align = cum->words & 1;
c53bdcf5 4608 cum->words += align + rs6000_arg_size (mode, type);
f676971a 4609
a594a19c
GK
4610 if (TARGET_DEBUG_ARG)
4611 {
f676971a 4612 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
a594a19c
GK
4613 cum->words, align);
4614 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
f676971a 4615 cum->nargs_prototype, cum->prototype,
2858f73a 4616 GET_MODE_NAME (mode));
a594a19c
GK
4617 }
4618 }
0ac081f6 4619 }
a4b0320c 4620 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
a6c9bed4
AH
4621 && !cum->stdarg
4622 && cum->sysv_gregno <= GP_ARG_MAX_REG)
a4b0320c 4623 cum->sysv_gregno++;
594a51fe
SS
4624
4625 else if (rs6000_darwin64_abi
4626 && mode == BLKmode
0b5383eb
DJ
4627 && TREE_CODE (type) == RECORD_TYPE
4628 && (size = int_size_in_bytes (type)) > 0)
4629 {
4630 /* Variable sized types have size == -1 and are
4631 treated as if consisting entirely of ints.
4632 Pad to 16 byte boundary if needed. */
4633 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4634 && (cum->words % 2) != 0)
4635 cum->words++;
4636 /* For varargs, we can just go up by the size of the struct. */
4637 if (!named)
4638 cum->words += (size + 7) / 8;
4639 else
4640 {
4641 /* It is tempting to say int register count just goes up by
4642 sizeof(type)/8, but this is wrong in a case such as
4643 { int; double; int; } [powerpc alignment]. We have to
4644 grovel through the fields for these too. */
4645 cum->intoffset = 0;
4646 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
bb8df8a6 4647 rs6000_darwin64_record_arg_advance_flush (cum,
0b5383eb
DJ
4648 size * BITS_PER_UNIT);
4649 }
4650 }
f607bc57 4651 else if (DEFAULT_ABI == ABI_V4)
4697a36c 4652 {
a3170dc6 4653 if (TARGET_HARD_FLOAT && TARGET_FPRS
602ea4d3
JJ
4654 && (mode == SFmode || mode == DFmode
4655 || (mode == TFmode && !TARGET_IEEEQUAD)))
4697a36c 4656 {
602ea4d3
JJ
4657 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
4658 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4cc833b7
RH
4659 else
4660 {
602ea4d3
JJ
4661 cum->fregno = FP_ARG_V4_MAX_REG + 1;
4662 if (mode == DFmode || mode == TFmode)
c4ad648e 4663 cum->words += cum->words & 1;
c53bdcf5 4664 cum->words += rs6000_arg_size (mode, type);
4cc833b7 4665 }
4697a36c 4666 }
4cc833b7
RH
4667 else
4668 {
b2d04ecf 4669 int n_words = rs6000_arg_size (mode, type);
4cc833b7
RH
4670 int gregno = cum->sysv_gregno;
4671
4ed78545
AM
4672 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
4673 (r7,r8) or (r9,r10). As does any other 2 word item such
4674 as complex int due to a historical mistake. */
4675 if (n_words == 2)
4676 gregno += (1 - gregno) & 1;
4cc833b7 4677
4ed78545 4678 /* Multi-reg args are not split between registers and stack. */
4cc833b7
RH
4679 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
4680 {
4ed78545
AM
4681 /* Long long and SPE vectors are aligned on the stack.
4682 So are other 2 word items such as complex int due to
4683 a historical mistake. */
4cc833b7
RH
4684 if (n_words == 2)
4685 cum->words += cum->words & 1;
4686 cum->words += n_words;
4687 }
4697a36c 4688
4cc833b7
RH
4689 /* Note: continuing to accumulate gregno past when we've started
4690 spilling to the stack indicates the fact that we've started
4691 spilling to the stack to expand_builtin_saveregs. */
4692 cum->sysv_gregno = gregno + n_words;
4693 }
4697a36c 4694
4cc833b7
RH
4695 if (TARGET_DEBUG_ARG)
4696 {
4697 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4698 cum->words, cum->fregno);
4699 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
4700 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
4701 fprintf (stderr, "mode = %4s, named = %d\n",
4702 GET_MODE_NAME (mode), named);
4703 }
4697a36c
MM
4704 }
4705 else
4cc833b7 4706 {
b2d04ecf 4707 int n_words = rs6000_arg_size (mode, type);
294bd182
AM
4708 int start_words = cum->words;
4709 int align_words = rs6000_parm_start (mode, type, start_words);
a4f6c312 4710
294bd182 4711 cum->words = align_words + n_words;
4697a36c 4712
ebb109ad 4713 if (SCALAR_FLOAT_MODE_P (mode)
00b79d54 4714 && !DECIMAL_FLOAT_MODE_P (mode)
a3170dc6 4715 && TARGET_HARD_FLOAT && TARGET_FPRS)
c53bdcf5 4716 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4cc833b7
RH
4717
4718 if (TARGET_DEBUG_ARG)
4719 {
4720 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
4721 cum->words, cum->fregno);
4722 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
4723 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
594a51fe 4724 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
294bd182 4725 named, align_words - start_words, depth);
4cc833b7
RH
4726 }
4727 }
4697a36c 4728}
a6c9bed4 4729
f82f556d
AH
4730static rtx
4731spe_build_register_parallel (enum machine_mode mode, int gregno)
4732{
54b695e7 4733 rtx r1, r3;
f82f556d 4734
37409796 4735 switch (mode)
f82f556d 4736 {
37409796 4737 case DFmode:
54b695e7
AH
4738 r1 = gen_rtx_REG (DImode, gregno);
4739 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
4740 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
37409796
NS
4741
4742 case DCmode:
54b695e7
AH
4743 r1 = gen_rtx_REG (DImode, gregno);
4744 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
4745 r3 = gen_rtx_REG (DImode, gregno + 2);
4746 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
4747 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
37409796
NS
4748
4749 default:
4750 gcc_unreachable ();
f82f556d 4751 }
f82f556d 4752}
b78d48dd 4753
f82f556d 4754/* Determine where to put a SIMD argument on the SPE. */
a6c9bed4 4755static rtx
f676971a 4756rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
a2369ed3 4757 tree type)
a6c9bed4 4758{
f82f556d
AH
4759 int gregno = cum->sysv_gregno;
4760
4761 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
600e1f95 4762 are passed and returned in a pair of GPRs for ABI compatibility. */
18f63bfa 4763 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode))
f82f556d 4764 {
b5870bee
AH
4765 int n_words = rs6000_arg_size (mode, type);
4766
f82f556d 4767 /* Doubles go in an odd/even register pair (r5/r6, etc). */
b5870bee
AH
4768 if (mode == DFmode)
4769 gregno += (1 - gregno) & 1;
f82f556d 4770
b5870bee
AH
4771 /* Multi-reg args are not split between registers and stack. */
4772 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
f82f556d
AH
4773 return NULL_RTX;
4774
4775 return spe_build_register_parallel (mode, gregno);
4776 }
a6c9bed4
AH
4777 if (cum->stdarg)
4778 {
c53bdcf5 4779 int n_words = rs6000_arg_size (mode, type);
a6c9bed4
AH
4780
4781 /* SPE vectors are put in odd registers. */
4782 if (n_words == 2 && (gregno & 1) == 0)
4783 gregno += 1;
4784
4785 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
4786 {
4787 rtx r1, r2;
4788 enum machine_mode m = SImode;
4789
4790 r1 = gen_rtx_REG (m, gregno);
4791 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
4792 r2 = gen_rtx_REG (m, gregno + 1);
4793 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
4794 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
4795 }
4796 else
b78d48dd 4797 return NULL_RTX;
a6c9bed4
AH
4798 }
4799 else
4800 {
f82f556d
AH
4801 if (gregno <= GP_ARG_MAX_REG)
4802 return gen_rtx_REG (mode, gregno);
a6c9bed4 4803 else
b78d48dd 4804 return NULL_RTX;
a6c9bed4
AH
4805 }
4806}
4807
0b5383eb
DJ
4808/* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
4809 structure between cum->intoffset and bitpos to integer registers. */
594a51fe 4810
0b5383eb 4811static void
bb8df8a6 4812rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
0b5383eb 4813 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
594a51fe 4814{
0b5383eb
DJ
4815 enum machine_mode mode;
4816 unsigned int regno;
4817 unsigned int startbit, endbit;
4818 int this_regno, intregs, intoffset;
4819 rtx reg;
594a51fe 4820
0b5383eb
DJ
4821 if (cum->intoffset == -1)
4822 return;
4823
4824 intoffset = cum->intoffset;
4825 cum->intoffset = -1;
4826
4827 /* If this is the trailing part of a word, try to only load that
4828 much into the register. Otherwise load the whole register. Note
4829 that in the latter case we may pick up unwanted bits. It's not a
4830 problem at the moment but may wish to revisit. */
4831
4832 if (intoffset % BITS_PER_WORD != 0)
594a51fe 4833 {
0b5383eb
DJ
4834 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
4835 MODE_INT, 0);
4836 if (mode == BLKmode)
4837 {
4838 /* We couldn't find an appropriate mode, which happens,
4839 e.g., in packed structs when there are 3 bytes to load.
4840 Back intoffset back to the beginning of the word in this
4841 case. */
4842 intoffset = intoffset & -BITS_PER_WORD;
4843 mode = word_mode;
4844 }
4845 }
4846 else
4847 mode = word_mode;
4848
4849 startbit = intoffset & -BITS_PER_WORD;
4850 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
4851 intregs = (endbit - startbit) / BITS_PER_WORD;
4852 this_regno = cum->words + intoffset / BITS_PER_WORD;
4853
4854 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
4855 cum->use_stack = 1;
bb8df8a6 4856
0b5383eb
DJ
4857 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
4858 if (intregs <= 0)
4859 return;
4860
4861 intoffset /= BITS_PER_UNIT;
4862 do
4863 {
4864 regno = GP_ARG_MIN_REG + this_regno;
4865 reg = gen_rtx_REG (mode, regno);
4866 rvec[(*k)++] =
4867 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
4868
4869 this_regno += 1;
4870 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
4871 mode = word_mode;
4872 intregs -= 1;
4873 }
4874 while (intregs > 0);
4875}
4876
4877/* Recursive workhorse for the following. */
4878
4879static void
bb8df8a6 4880rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, tree type,
0b5383eb
DJ
4881 HOST_WIDE_INT startbitpos, rtx rvec[],
4882 int *k)
4883{
4884 tree f;
4885
4886 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
4887 if (TREE_CODE (f) == FIELD_DECL)
4888 {
4889 HOST_WIDE_INT bitpos = startbitpos;
4890 tree ftype = TREE_TYPE (f);
4891 enum machine_mode mode = TYPE_MODE (ftype);
4892
4893 if (DECL_SIZE (f) != 0
4894 && host_integerp (bit_position (f), 1))
4895 bitpos += int_bit_position (f);
4896
4897 /* ??? FIXME: else assume zero offset. */
4898
4899 if (TREE_CODE (ftype) == RECORD_TYPE)
4900 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
4901 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
594a51fe 4902 {
0b5383eb
DJ
4903#if 0
4904 switch (mode)
594a51fe 4905 {
0b5383eb
DJ
4906 case SCmode: mode = SFmode; break;
4907 case DCmode: mode = DFmode; break;
4908 case TCmode: mode = TFmode; break;
4909 default: break;
594a51fe 4910 }
0b5383eb
DJ
4911#endif
4912 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
4913 rvec[(*k)++]
bb8df8a6 4914 = gen_rtx_EXPR_LIST (VOIDmode,
0b5383eb
DJ
4915 gen_rtx_REG (mode, cum->fregno++),
4916 GEN_INT (bitpos / BITS_PER_UNIT));
4917 if (mode == TFmode)
4918 cum->fregno++;
594a51fe 4919 }
0b5383eb
DJ
4920 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
4921 {
4922 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
4923 rvec[(*k)++]
bb8df8a6
EC
4924 = gen_rtx_EXPR_LIST (VOIDmode,
4925 gen_rtx_REG (mode, cum->vregno++),
0b5383eb
DJ
4926 GEN_INT (bitpos / BITS_PER_UNIT));
4927 }
4928 else if (cum->intoffset == -1)
4929 cum->intoffset = bitpos;
4930 }
4931}
594a51fe 4932
0b5383eb
DJ
4933/* For the darwin64 ABI, we want to construct a PARALLEL consisting of
4934 the register(s) to be used for each field and subfield of a struct
4935 being passed by value, along with the offset of where the
4936 register's value may be found in the block. FP fields go in FP
4937 register, vector fields go in vector registers, and everything
bb8df8a6 4938 else goes in int registers, packed as in memory.
8ff40a74 4939
0b5383eb
DJ
4940 This code is also used for function return values. RETVAL indicates
4941 whether this is the case.
8ff40a74 4942
a4d05547 4943 Much of this is taken from the SPARC V9 port, which has a similar
0b5383eb 4944 calling convention. */
594a51fe 4945
0b5383eb
DJ
4946static rtx
4947rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, tree type,
4948 int named, bool retval)
4949{
4950 rtx rvec[FIRST_PSEUDO_REGISTER];
4951 int k = 1, kbase = 1;
4952 HOST_WIDE_INT typesize = int_size_in_bytes (type);
4953 /* This is a copy; modifications are not visible to our caller. */
4954 CUMULATIVE_ARGS copy_cum = *orig_cum;
4955 CUMULATIVE_ARGS *cum = &copy_cum;
4956
4957 /* Pad to 16 byte boundary if needed. */
4958 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
4959 && (cum->words % 2) != 0)
4960 cum->words++;
4961
4962 cum->intoffset = 0;
4963 cum->use_stack = 0;
4964 cum->named = named;
4965
4966 /* Put entries into rvec[] for individual FP and vector fields, and
4967 for the chunks of memory that go in int regs. Note we start at
4968 element 1; 0 is reserved for an indication of using memory, and
4969 may or may not be filled in below. */
4970 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
4971 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
4972
4973 /* If any part of the struct went on the stack put all of it there.
4974 This hack is because the generic code for
4975 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
4976 parts of the struct are not at the beginning. */
4977 if (cum->use_stack)
4978 {
4979 if (retval)
4980 return NULL_RTX; /* doesn't go in registers at all */
4981 kbase = 0;
4982 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
4983 }
4984 if (k > 1 || cum->use_stack)
4985 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
594a51fe
SS
4986 else
4987 return NULL_RTX;
4988}
4989
b78d48dd
FJ
4990/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
4991
4992static rtx
ec6376ab 4993rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
b78d48dd 4994{
ec6376ab
AM
4995 int n_units;
4996 int i, k;
4997 rtx rvec[GP_ARG_NUM_REG + 1];
4998
4999 if (align_words >= GP_ARG_NUM_REG)
5000 return NULL_RTX;
5001
5002 n_units = rs6000_arg_size (mode, type);
5003
5004 /* Optimize the simple case where the arg fits in one gpr, except in
5005 the case of BLKmode due to assign_parms assuming that registers are
5006 BITS_PER_WORD wide. */
5007 if (n_units == 0
5008 || (n_units == 1 && mode != BLKmode))
5009 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5010
5011 k = 0;
5012 if (align_words + n_units > GP_ARG_NUM_REG)
5013 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5014 using a magic NULL_RTX component.
5015 FIXME: This is not strictly correct. Only some of the arg
5016 belongs in memory, not all of it. However, there isn't any way
5017 to do this currently, apart from building rtx descriptions for
5018 the pieces of memory we want stored. Due to bugs in the generic
5019 code we can't use the normal function_arg_partial_nregs scheme
5020 with the PARALLEL arg description we emit here.
5021 In any case, the code to store the whole arg to memory is often
5022 more efficient than code to store pieces, and we know that space
5023 is available in the right place for the whole arg. */
78a52f11
RH
5024 /* FIXME: This should be fixed since the conversion to
5025 TARGET_ARG_PARTIAL_BYTES. */
ec6376ab
AM
5026 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5027
5028 i = 0;
5029 do
36a454e1 5030 {
ec6376ab
AM
5031 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5032 rtx off = GEN_INT (i++ * 4);
5033 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
36a454e1 5034 }
ec6376ab
AM
5035 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5036
5037 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
b78d48dd
FJ
5038}
5039
4697a36c
MM
5040/* Determine where to put an argument to a function.
5041 Value is zero to push the argument on the stack,
5042 or a hard register in which to store the argument.
5043
5044 MODE is the argument's machine mode.
5045 TYPE is the data type of the argument (as a tree).
5046 This is null for libcalls where that information may
5047 not be available.
5048 CUM is a variable of type CUMULATIVE_ARGS which gives info about
0b5383eb
DJ
5049 the preceding args and about the function being called. It is
5050 not modified in this routine.
4697a36c
MM
5051 NAMED is nonzero if this argument is a named parameter
5052 (otherwise it is an extra parameter matching an ellipsis).
5053
5054 On RS/6000 the first eight words of non-FP are normally in registers
5055 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5056 Under V.4, the first 8 FP args are in registers.
5057
5058 If this is floating-point and no prototype is specified, we use
5059 both an FP and integer register (or possibly FP reg and stack). Library
b9599e46 5060 functions (when CALL_LIBCALL is set) always have the proper types for args,
4697a36c 5061 so we can pass the FP value just in one register. emit_library_function
b2d04ecf
AM
5062 doesn't support PARALLEL anyway.
5063
5064 Note that for args passed by reference, function_arg will be called
5065 with MODE and TYPE set to that of the pointer to the arg, not the arg
5066 itself. */
4697a36c 5067
9390387d 5068rtx
f676971a 5069function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
a2369ed3 5070 tree type, int named)
4697a36c 5071{
4cc833b7 5072 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 5073
a4f6c312
SS
5074 /* Return a marker to indicate whether CR1 needs to set or clear the
5075 bit that V.4 uses to say fp args were passed in registers.
5076 Assume that we don't need the marker for software floating point,
5077 or compiler generated library calls. */
4697a36c
MM
5078 if (mode == VOIDmode)
5079 {
f607bc57 5080 if (abi == ABI_V4
b9599e46 5081 && (cum->call_cookie & CALL_LIBCALL) == 0
c1fa753e
AM
5082 && (cum->stdarg
5083 || (cum->nargs_prototype < 0
5084 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7509c759 5085 {
a3170dc6
AH
5086 /* For the SPE, we need to crxor CR6 always. */
5087 if (TARGET_SPE_ABI)
5088 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
5089 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
5090 return GEN_INT (cum->call_cookie
5091 | ((cum->fregno == FP_ARG_MIN_REG)
5092 ? CALL_V4_SET_FP_ARGS
5093 : CALL_V4_CLEAR_FP_ARGS));
7509c759 5094 }
4697a36c 5095
7509c759 5096 return GEN_INT (cum->call_cookie);
4697a36c
MM
5097 }
5098
0b5383eb
DJ
5099 if (rs6000_darwin64_abi && mode == BLKmode
5100 && TREE_CODE (type) == RECORD_TYPE)
8ff40a74 5101 {
0b5383eb 5102 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8ff40a74
SS
5103 if (rslt != NULL_RTX)
5104 return rslt;
5105 /* Else fall through to usual handling. */
5106 }
5107
2858f73a 5108 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
c72d6c26
HP
5109 if (TARGET_64BIT && ! cum->prototype)
5110 {
c4ad648e
AM
5111 /* Vector parameters get passed in vector register
5112 and also in GPRs or memory, in absence of prototype. */
5113 int align_words;
5114 rtx slot;
5115 align_words = (cum->words + 1) & ~1;
5116
5117 if (align_words >= GP_ARG_NUM_REG)
5118 {
5119 slot = NULL_RTX;
5120 }
5121 else
5122 {
5123 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5124 }
5125 return gen_rtx_PARALLEL (mode,
5126 gen_rtvec (2,
5127 gen_rtx_EXPR_LIST (VOIDmode,
5128 slot, const0_rtx),
5129 gen_rtx_EXPR_LIST (VOIDmode,
5130 gen_rtx_REG (mode, cum->vregno),
5131 const0_rtx)));
c72d6c26
HP
5132 }
5133 else
5134 return gen_rtx_REG (mode, cum->vregno);
ad630bef
DE
5135 else if (TARGET_ALTIVEC_ABI
5136 && (ALTIVEC_VECTOR_MODE (mode)
5137 || (type && TREE_CODE (type) == VECTOR_TYPE
5138 && int_size_in_bytes (type) == 16)))
0ac081f6 5139 {
2858f73a 5140 if (named || abi == ABI_V4)
a594a19c 5141 return NULL_RTX;
0ac081f6 5142 else
a594a19c
GK
5143 {
5144 /* Vector parameters to varargs functions under AIX or Darwin
5145 get passed in memory and possibly also in GPRs. */
ec6376ab
AM
5146 int align, align_words, n_words;
5147 enum machine_mode part_mode;
a594a19c
GK
5148
5149 /* Vector parameters must be 16-byte aligned. This places them at
2858f73a
GK
5150 2 mod 4 in terms of words in 32-bit mode, since the parameter
5151 save area starts at offset 24 from the stack. In 64-bit mode,
5152 they just have to start on an even word, since the parameter
5153 save area is 16-byte aligned. */
5154 if (TARGET_32BIT)
4ed78545 5155 align = (2 - cum->words) & 3;
2858f73a
GK
5156 else
5157 align = cum->words & 1;
a594a19c
GK
5158 align_words = cum->words + align;
5159
5160 /* Out of registers? Memory, then. */
5161 if (align_words >= GP_ARG_NUM_REG)
5162 return NULL_RTX;
ec6376ab
AM
5163
5164 if (TARGET_32BIT && TARGET_POWERPC64)
5165 return rs6000_mixed_function_arg (mode, type, align_words);
5166
2858f73a
GK
5167 /* The vector value goes in GPRs. Only the part of the
5168 value in GPRs is reported here. */
ec6376ab
AM
5169 part_mode = mode;
5170 n_words = rs6000_arg_size (mode, type);
5171 if (align_words + n_words > GP_ARG_NUM_REG)
839a4992 5172 /* Fortunately, there are only two possibilities, the value
2858f73a
GK
5173 is either wholly in GPRs or half in GPRs and half not. */
5174 part_mode = DImode;
ec6376ab
AM
5175
5176 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
a594a19c 5177 }
0ac081f6 5178 }
f82f556d
AH
5179 else if (TARGET_SPE_ABI && TARGET_SPE
5180 && (SPE_VECTOR_MODE (mode)
18f63bfa
AH
5181 || (TARGET_E500_DOUBLE && (mode == DFmode
5182 || mode == DCmode))))
a6c9bed4 5183 return rs6000_spe_function_arg (cum, mode, type);
594a51fe 5184
f607bc57 5185 else if (abi == ABI_V4)
4697a36c 5186 {
a3170dc6 5187 if (TARGET_HARD_FLOAT && TARGET_FPRS
602ea4d3
JJ
5188 && (mode == SFmode || mode == DFmode
5189 || (mode == TFmode && !TARGET_IEEEQUAD)))
4cc833b7 5190 {
602ea4d3 5191 if (cum->fregno + (mode == TFmode ? 1 : 0) <= FP_ARG_V4_MAX_REG)
4cc833b7
RH
5192 return gen_rtx_REG (mode, cum->fregno);
5193 else
b78d48dd 5194 return NULL_RTX;
4cc833b7
RH
5195 }
5196 else
5197 {
b2d04ecf 5198 int n_words = rs6000_arg_size (mode, type);
4cc833b7
RH
5199 int gregno = cum->sysv_gregno;
5200
4ed78545
AM
5201 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5202 (r7,r8) or (r9,r10). As does any other 2 word item such
5203 as complex int due to a historical mistake. */
5204 if (n_words == 2)
5205 gregno += (1 - gregno) & 1;
4cc833b7 5206
4ed78545 5207 /* Multi-reg args are not split between registers and stack. */
ec6376ab 5208 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
b78d48dd 5209 return NULL_RTX;
ec6376ab
AM
5210
5211 if (TARGET_32BIT && TARGET_POWERPC64)
5212 return rs6000_mixed_function_arg (mode, type,
5213 gregno - GP_ARG_MIN_REG);
5214 return gen_rtx_REG (mode, gregno);
4cc833b7 5215 }
4697a36c 5216 }
4cc833b7
RH
5217 else
5218 {
294bd182 5219 int align_words = rs6000_parm_start (mode, type, cum->words);
b78d48dd 5220
2858f73a 5221 if (USE_FP_FOR_ARG_P (cum, mode, type))
4cc833b7 5222 {
ec6376ab
AM
5223 rtx rvec[GP_ARG_NUM_REG + 1];
5224 rtx r;
5225 int k;
c53bdcf5
AM
5226 bool needs_psave;
5227 enum machine_mode fmode = mode;
c53bdcf5
AM
5228 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
5229
5230 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
5231 {
c53bdcf5
AM
5232 /* Currently, we only ever need one reg here because complex
5233 doubles are split. */
37409796 5234 gcc_assert (cum->fregno == FP_ARG_MAX_REG && fmode == TFmode);
ec6376ab
AM
5235
5236 /* Long double split over regs and memory. */
5237 fmode = DFmode;
c53bdcf5 5238 }
c53bdcf5
AM
5239
5240 /* Do we also need to pass this arg in the parameter save
5241 area? */
5242 needs_psave = (type
5243 && (cum->nargs_prototype <= 0
5244 || (DEFAULT_ABI == ABI_AIX
de17c25f 5245 && TARGET_XL_COMPAT
c53bdcf5
AM
5246 && align_words >= GP_ARG_NUM_REG)));
5247
5248 if (!needs_psave && mode == fmode)
ec6376ab 5249 return gen_rtx_REG (fmode, cum->fregno);
c53bdcf5 5250
ec6376ab 5251 k = 0;
c53bdcf5
AM
5252 if (needs_psave)
5253 {
ec6376ab 5254 /* Describe the part that goes in gprs or the stack.
c53bdcf5 5255 This piece must come first, before the fprs. */
c53bdcf5
AM
5256 if (align_words < GP_ARG_NUM_REG)
5257 {
5258 unsigned long n_words = rs6000_arg_size (mode, type);
ec6376ab
AM
5259
5260 if (align_words + n_words > GP_ARG_NUM_REG
5261 || (TARGET_32BIT && TARGET_POWERPC64))
5262 {
5263 /* If this is partially on the stack, then we only
5264 include the portion actually in registers here. */
5265 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
5266 rtx off;
2e6c9641 5267 int i=0;
c4ad648e
AM
5268 if (align_words + n_words > GP_ARG_NUM_REG
5269 && (TARGET_32BIT && TARGET_POWERPC64))
5270 /* Not all of the arg fits in gprs. Say that it
5271 goes in memory too, using a magic NULL_RTX
5272 component. Also see comment in
5273 rs6000_mixed_function_arg for why the normal
5274 function_arg_partial_nregs scheme doesn't work
5275 in this case. */
5276 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
5277 const0_rtx);
ec6376ab
AM
5278 do
5279 {
5280 r = gen_rtx_REG (rmode,
5281 GP_ARG_MIN_REG + align_words);
2e6c9641 5282 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
ec6376ab
AM
5283 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5284 }
5285 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
5286 }
5287 else
5288 {
5289 /* The whole arg fits in gprs. */
5290 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5291 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5292 }
c53bdcf5 5293 }
ec6376ab
AM
5294 else
5295 /* It's entirely in memory. */
5296 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
c53bdcf5
AM
5297 }
5298
ec6376ab
AM
5299 /* Describe where this piece goes in the fprs. */
5300 r = gen_rtx_REG (fmode, cum->fregno);
5301 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5302
5303 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
4cc833b7
RH
5304 }
5305 else if (align_words < GP_ARG_NUM_REG)
b2d04ecf 5306 {
ec6376ab
AM
5307 if (TARGET_32BIT && TARGET_POWERPC64)
5308 return rs6000_mixed_function_arg (mode, type, align_words);
b2d04ecf 5309
4eeca74f
AM
5310 if (mode == BLKmode)
5311 mode = Pmode;
5312
b2d04ecf
AM
5313 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5314 }
4cc833b7
RH
5315 else
5316 return NULL_RTX;
4697a36c 5317 }
4697a36c
MM
5318}
5319\f
ec6376ab 5320/* For an arg passed partly in registers and partly in memory, this is
fb63c729
AM
5321 the number of bytes passed in registers. For args passed entirely in
5322 registers or entirely in memory, zero. When an arg is described by a
5323 PARALLEL, perhaps using more than one register type, this function
5324 returns the number of bytes used by the first element of the PARALLEL. */
4697a36c 5325
78a52f11
RH
5326static int
5327rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5328 tree type, bool named)
4697a36c 5329{
c53bdcf5 5330 int ret = 0;
ec6376ab 5331 int align_words;
c53bdcf5 5332
f607bc57 5333 if (DEFAULT_ABI == ABI_V4)
4697a36c 5334 return 0;
4697a36c 5335
c53bdcf5
AM
5336 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
5337 && cum->nargs_prototype >= 0)
5338 return 0;
5339
0b5383eb
DJ
5340 /* In this complicated case we just disable the partial_nregs code. */
5341 if (rs6000_darwin64_abi && mode == BLKmode
5342 && TREE_CODE (type) == RECORD_TYPE
5343 && int_size_in_bytes (type) > 0)
5344 return 0;
5345
294bd182 5346 align_words = rs6000_parm_start (mode, type, cum->words);
ec6376ab
AM
5347
5348 if (USE_FP_FOR_ARG_P (cum, mode, type)
fb63c729
AM
5349 /* If we are passing this arg in the fixed parameter save area
5350 (gprs or memory) as well as fprs, then this function should
5351 return the number of bytes passed in the parameter save area
bb8df8a6 5352 rather than bytes passed in fprs. */
ec6376ab
AM
5353 && !(type
5354 && (cum->nargs_prototype <= 0
5355 || (DEFAULT_ABI == ABI_AIX
de17c25f 5356 && TARGET_XL_COMPAT
ec6376ab 5357 && align_words >= GP_ARG_NUM_REG))))
4697a36c 5358 {
c53bdcf5 5359 if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3) > FP_ARG_MAX_REG + 1)
ac7e839c 5360 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
c53bdcf5 5361 else if (cum->nargs_prototype >= 0)
4697a36c
MM
5362 return 0;
5363 }
5364
ec6376ab
AM
5365 if (align_words < GP_ARG_NUM_REG
5366 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
ac7e839c 5367 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
78a52f11 5368
c53bdcf5 5369 if (ret != 0 && TARGET_DEBUG_ARG)
78a52f11 5370 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
4697a36c 5371
c53bdcf5 5372 return ret;
4697a36c
MM
5373}
5374\f
5375/* A C expression that indicates when an argument must be passed by
5376 reference. If nonzero for an argument, a copy of that argument is
5377 made in memory and a pointer to the argument is passed instead of
5378 the argument itself. The pointer is passed in whatever way is
5379 appropriate for passing a pointer to that type.
5380
b2d04ecf
AM
5381 Under V.4, aggregates and long double are passed by reference.
5382
5383 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
5384 reference unless the AltiVec vector extension ABI is in force.
c8c99a68
DE
5385
5386 As an extension to all ABIs, variable sized types are passed by
5387 reference. */
4697a36c 5388
8cd5a4e0 5389static bool
f676971a 5390rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
bada2eb8
DE
5391 enum machine_mode mode, tree type,
5392 bool named ATTRIBUTE_UNUSED)
4697a36c 5393{
602ea4d3 5394 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
4697a36c
MM
5395 {
5396 if (TARGET_DEBUG_ARG)
bada2eb8
DE
5397 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
5398 return 1;
5399 }
5400
5401 if (!type)
5402 return 0;
4697a36c 5403
bada2eb8
DE
5404 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
5405 {
5406 if (TARGET_DEBUG_ARG)
5407 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
5408 return 1;
5409 }
5410
5411 if (int_size_in_bytes (type) < 0)
5412 {
5413 if (TARGET_DEBUG_ARG)
5414 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
5415 return 1;
5416 }
5417
5418 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
5419 modes only exist for GCC vector types if -maltivec. */
5420 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
5421 {
5422 if (TARGET_DEBUG_ARG)
5423 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
4697a36c
MM
5424 return 1;
5425 }
b693336b
PB
5426
5427 /* Pass synthetic vectors in memory. */
bada2eb8 5428 if (TREE_CODE (type) == VECTOR_TYPE
ad630bef 5429 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
b693336b
PB
5430 {
5431 static bool warned_for_pass_big_vectors = false;
5432 if (TARGET_DEBUG_ARG)
5433 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
5434 if (!warned_for_pass_big_vectors)
5435 {
d4ee4d25 5436 warning (0, "GCC vector passed by reference: "
b693336b
PB
5437 "non-standard ABI extension with no compatibility guarantee");
5438 warned_for_pass_big_vectors = true;
5439 }
5440 return 1;
5441 }
5442
b2d04ecf 5443 return 0;
4697a36c 5444}
5985c7a6
FJ
5445
5446static void
2d9db8eb 5447rs6000_move_block_from_reg (int regno, rtx x, int nregs)
5985c7a6
FJ
5448{
5449 int i;
5450 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
5451
5452 if (nregs == 0)
5453 return;
5454
c4ad648e 5455 for (i = 0; i < nregs; i++)
5985c7a6 5456 {
9390387d 5457 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
5985c7a6 5458 if (reload_completed)
c4ad648e
AM
5459 {
5460 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
5461 tem = NULL_RTX;
5462 else
5463 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9390387d 5464 i * GET_MODE_SIZE (reg_mode));
c4ad648e 5465 }
5985c7a6
FJ
5466 else
5467 tem = replace_equiv_address (tem, XEXP (tem, 0));
5468
37409796 5469 gcc_assert (tem);
5985c7a6
FJ
5470
5471 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
5472 }
5473}
4697a36c
MM
5474\f
5475/* Perform any needed actions needed for a function that is receiving a
f676971a 5476 variable number of arguments.
4697a36c
MM
5477
5478 CUM is as above.
5479
5480 MODE and TYPE are the mode and type of the current parameter.
5481
5482 PRETEND_SIZE is a variable that should be set to the amount of stack
5483 that must be pushed by the prolog to pretend that our caller pushed
5484 it.
5485
5486 Normally, this macro will push all remaining incoming registers on the
5487 stack and set PRETEND_SIZE to the length of the registers pushed. */
5488
c6e8c921 5489static void
f676971a 5490setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
c4ad648e
AM
5491 tree type, int *pretend_size ATTRIBUTE_UNUSED,
5492 int no_rtl)
4697a36c 5493{
4cc833b7
RH
5494 CUMULATIVE_ARGS next_cum;
5495 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 5496 rtx save_area = NULL_RTX, mem;
dfafc897 5497 int first_reg_offset, set;
4697a36c 5498
f31bf321 5499 /* Skip the last named argument. */
d34c5b80 5500 next_cum = *cum;
594a51fe 5501 function_arg_advance (&next_cum, mode, type, 1, 0);
4cc833b7 5502
f607bc57 5503 if (DEFAULT_ABI == ABI_V4)
d34c5b80 5504 {
5b667039
JJ
5505 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
5506
60e2d0ca 5507 if (! no_rtl)
5b667039
JJ
5508 {
5509 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
5510 HOST_WIDE_INT offset = 0;
5511
5512 /* Try to optimize the size of the varargs save area.
5513 The ABI requires that ap.reg_save_area is doubleword
5514 aligned, but we don't need to allocate space for all
5515 the bytes, only those to which we actually will save
5516 anything. */
5517 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
5518 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
5519 if (TARGET_HARD_FLOAT && TARGET_FPRS
5520 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5521 && cfun->va_list_fpr_size)
5522 {
5523 if (gpr_reg_num)
5524 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
5525 * UNITS_PER_FP_WORD;
5526 if (cfun->va_list_fpr_size
5527 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5528 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
5529 else
5530 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
5531 * UNITS_PER_FP_WORD;
5532 }
5533 if (gpr_reg_num)
5534 {
5535 offset = -((first_reg_offset * reg_size) & ~7);
5536 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
5537 {
5538 gpr_reg_num = cfun->va_list_gpr_size;
5539 if (reg_size == 4 && (first_reg_offset & 1))
5540 gpr_reg_num++;
5541 }
5542 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
5543 }
5544 else if (fpr_size)
5545 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
5546 * UNITS_PER_FP_WORD
5547 - (int) (GP_ARG_NUM_REG * reg_size);
4cc833b7 5548
5b667039
JJ
5549 if (gpr_size + fpr_size)
5550 {
5551 rtx reg_save_area
5552 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
5553 gcc_assert (GET_CODE (reg_save_area) == MEM);
5554 reg_save_area = XEXP (reg_save_area, 0);
5555 if (GET_CODE (reg_save_area) == PLUS)
5556 {
5557 gcc_assert (XEXP (reg_save_area, 0)
5558 == virtual_stack_vars_rtx);
5559 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
5560 offset += INTVAL (XEXP (reg_save_area, 1));
5561 }
5562 else
5563 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
5564 }
5565
5566 cfun->machine->varargs_save_offset = offset;
5567 save_area = plus_constant (virtual_stack_vars_rtx, offset);
5568 }
4697a36c 5569 }
60e2d0ca 5570 else
4697a36c 5571 {
d34c5b80 5572 first_reg_offset = next_cum.words;
4cc833b7 5573 save_area = virtual_incoming_args_rtx;
4697a36c 5574
fe984136 5575 if (targetm.calls.must_pass_in_stack (mode, type))
c53bdcf5 5576 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
4cc833b7 5577 }
4697a36c 5578
dfafc897 5579 set = get_varargs_alias_set ();
9d30f3c1
JJ
5580 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
5581 && cfun->va_list_gpr_size)
4cc833b7 5582 {
9d30f3c1
JJ
5583 int nregs = GP_ARG_NUM_REG - first_reg_offset;
5584
5585 if (va_list_gpr_counter_field)
5586 {
5587 /* V4 va_list_gpr_size counts number of registers needed. */
5588 if (nregs > cfun->va_list_gpr_size)
5589 nregs = cfun->va_list_gpr_size;
5590 }
5591 else
5592 {
5593 /* char * va_list instead counts number of bytes needed. */
5594 if (nregs > cfun->va_list_gpr_size / reg_size)
5595 nregs = cfun->va_list_gpr_size / reg_size;
5596 }
5597
dfafc897 5598 mem = gen_rtx_MEM (BLKmode,
c4ad648e 5599 plus_constant (save_area,
13e2e16e
DE
5600 first_reg_offset * reg_size));
5601 MEM_NOTRAP_P (mem) = 1;
ba4828e0 5602 set_mem_alias_set (mem, set);
8ac61af7 5603 set_mem_align (mem, BITS_PER_WORD);
dfafc897 5604
f676971a 5605 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9d30f3c1 5606 nregs);
4697a36c
MM
5607 }
5608
4697a36c 5609 /* Save FP registers if needed. */
f607bc57 5610 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
5611 && TARGET_HARD_FLOAT && TARGET_FPRS
5612 && ! no_rtl
9d30f3c1
JJ
5613 && next_cum.fregno <= FP_ARG_V4_MAX_REG
5614 && cfun->va_list_fpr_size)
4697a36c 5615 {
9d30f3c1 5616 int fregno = next_cum.fregno, nregs;
9ebbca7d 5617 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7 5618 rtx lab = gen_label_rtx ();
5b667039
JJ
5619 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
5620 * UNITS_PER_FP_WORD);
4697a36c 5621
c4ad648e
AM
5622 emit_jump_insn
5623 (gen_rtx_SET (VOIDmode,
5624 pc_rtx,
5625 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7 5626 gen_rtx_NE (VOIDmode, cr1,
c4ad648e 5627 const0_rtx),
39403d82 5628 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
5629 pc_rtx)));
5630
9d30f3c1
JJ
5631 for (nregs = 0;
5632 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
5b667039 5633 fregno++, off += UNITS_PER_FP_WORD, nregs++)
4cc833b7 5634 {
5496b36f 5635 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
13e2e16e 5636 MEM_NOTRAP_P (mem) = 1;
c4ad648e 5637 set_mem_alias_set (mem, set);
94ff898d 5638 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
dfafc897 5639 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4697a36c 5640 }
4cc833b7
RH
5641
5642 emit_label (lab);
4697a36c 5643 }
4697a36c 5644}
4697a36c 5645
dfafc897 5646/* Create the va_list data type. */
2c4974b7 5647
c35d187f
RH
5648static tree
5649rs6000_build_builtin_va_list (void)
dfafc897 5650{
64c2816f 5651 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
4697a36c 5652
9ebbca7d
GK
5653 /* For AIX, prefer 'char *' because that's what the system
5654 header files like. */
f607bc57 5655 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 5656 return build_pointer_type (char_type_node);
dfafc897 5657
f1e639b1 5658 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 5659 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 5660
f676971a 5661 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
9ebbca7d 5662 unsigned_char_type_node);
f676971a 5663 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
9ebbca7d 5664 unsigned_char_type_node);
64c2816f
DT
5665 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
5666 every user file. */
5667 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
5668 short_unsigned_type_node);
dfafc897
FS
5669 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
5670 ptr_type_node);
5671 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
5672 ptr_type_node);
5673
9d30f3c1
JJ
5674 va_list_gpr_counter_field = f_gpr;
5675 va_list_fpr_counter_field = f_fpr;
5676
dfafc897
FS
5677 DECL_FIELD_CONTEXT (f_gpr) = record;
5678 DECL_FIELD_CONTEXT (f_fpr) = record;
64c2816f 5679 DECL_FIELD_CONTEXT (f_res) = record;
dfafc897
FS
5680 DECL_FIELD_CONTEXT (f_ovf) = record;
5681 DECL_FIELD_CONTEXT (f_sav) = record;
5682
bab45a51
FS
5683 TREE_CHAIN (record) = type_decl;
5684 TYPE_NAME (record) = type_decl;
dfafc897
FS
5685 TYPE_FIELDS (record) = f_gpr;
5686 TREE_CHAIN (f_gpr) = f_fpr;
64c2816f
DT
5687 TREE_CHAIN (f_fpr) = f_res;
5688 TREE_CHAIN (f_res) = f_ovf;
dfafc897
FS
5689 TREE_CHAIN (f_ovf) = f_sav;
5690
5691 layout_type (record);
5692
5693 /* The correct type is an array type of one element. */
5694 return build_array_type (record, build_index_type (size_zero_node));
5695}
5696
5697/* Implement va_start. */
5698
5699void
a2369ed3 5700rs6000_va_start (tree valist, rtx nextarg)
4697a36c 5701{
dfafc897 5702 HOST_WIDE_INT words, n_gpr, n_fpr;
c566f9bd 5703 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
dfafc897 5704 tree gpr, fpr, ovf, sav, t;
2c4974b7 5705
dfafc897 5706 /* Only SVR4 needs something special. */
f607bc57 5707 if (DEFAULT_ABI != ABI_V4)
dfafc897 5708 {
e5faf155 5709 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
5710 return;
5711 }
5712
973a648b 5713 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897 5714 f_fpr = TREE_CHAIN (f_gpr);
c566f9bd
DT
5715 f_res = TREE_CHAIN (f_fpr);
5716 f_ovf = TREE_CHAIN (f_res);
dfafc897
FS
5717 f_sav = TREE_CHAIN (f_ovf);
5718
872a65b5 5719 valist = build_va_arg_indirect_ref (valist);
47a25a46
RG
5720 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
5721 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
5722 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
5723 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
dfafc897
FS
5724
5725 /* Count number of gp and fp argument registers used. */
4cc833b7 5726 words = current_function_args_info.words;
987732e0
DE
5727 n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
5728 GP_ARG_NUM_REG);
5729 n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
5730 FP_ARG_NUM_REG);
dfafc897
FS
5731
5732 if (TARGET_DEBUG_ARG)
4a0a75dd
KG
5733 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
5734 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
5735 words, n_gpr, n_fpr);
dfafc897 5736
9d30f3c1
JJ
5737 if (cfun->va_list_gpr_size)
5738 {
47a25a46
RG
5739 t = build2 (MODIFY_EXPR, TREE_TYPE (gpr), gpr,
5740 build_int_cst (NULL_TREE, n_gpr));
9d30f3c1
JJ
5741 TREE_SIDE_EFFECTS (t) = 1;
5742 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5743 }
58c8adc1 5744
9d30f3c1
JJ
5745 if (cfun->va_list_fpr_size)
5746 {
47a25a46
RG
5747 t = build2 (MODIFY_EXPR, TREE_TYPE (fpr), fpr,
5748 build_int_cst (NULL_TREE, n_fpr));
9d30f3c1
JJ
5749 TREE_SIDE_EFFECTS (t) = 1;
5750 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5751 }
dfafc897
FS
5752
5753 /* Find the overflow area. */
5754 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
5755 if (words != 0)
47a25a46
RG
5756 t = build2 (PLUS_EXPR, TREE_TYPE (ovf), t,
5757 build_int_cst (NULL_TREE, words * UNITS_PER_WORD));
5758 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
dfafc897
FS
5759 TREE_SIDE_EFFECTS (t) = 1;
5760 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5761
9d30f3c1
JJ
5762 /* If there were no va_arg invocations, don't set up the register
5763 save area. */
5764 if (!cfun->va_list_gpr_size
5765 && !cfun->va_list_fpr_size
5766 && n_gpr < GP_ARG_NUM_REG
5767 && n_fpr < FP_ARG_V4_MAX_REG)
5768 return;
5769
dfafc897
FS
5770 /* Find the register save area. */
5771 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
5b667039 5772 if (cfun->machine->varargs_save_offset)
47a25a46
RG
5773 t = build2 (PLUS_EXPR, TREE_TYPE (sav), t,
5774 build_int_cst (NULL_TREE, cfun->machine->varargs_save_offset));
5775 t = build2 (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
dfafc897
FS
5776 TREE_SIDE_EFFECTS (t) = 1;
5777 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
5778}
5779
5780/* Implement va_arg. */
5781
23a60a04
JM
5782tree
5783rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
cd3ce9b4 5784{
cd3ce9b4
JM
5785 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
5786 tree gpr, fpr, ovf, sav, reg, t, u;
08b0dc1b 5787 int size, rsize, n_reg, sav_ofs, sav_scale;
cd3ce9b4
JM
5788 tree lab_false, lab_over, addr;
5789 int align;
5790 tree ptrtype = build_pointer_type (type);
5791
08b0dc1b
RH
5792 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
5793 {
5794 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
872a65b5 5795 return build_va_arg_indirect_ref (t);
08b0dc1b
RH
5796 }
5797
cd3ce9b4
JM
5798 if (DEFAULT_ABI != ABI_V4)
5799 {
08b0dc1b 5800 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
cd3ce9b4
JM
5801 {
5802 tree elem_type = TREE_TYPE (type);
5803 enum machine_mode elem_mode = TYPE_MODE (elem_type);
5804 int elem_size = GET_MODE_SIZE (elem_mode);
5805
5806 if (elem_size < UNITS_PER_WORD)
5807 {
23a60a04 5808 tree real_part, imag_part;
cd3ce9b4
JM
5809 tree post = NULL_TREE;
5810
23a60a04
JM
5811 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
5812 &post);
5813 /* Copy the value into a temporary, lest the formal temporary
5814 be reused out from under us. */
5815 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
cd3ce9b4
JM
5816 append_to_statement_list (post, pre_p);
5817
23a60a04
JM
5818 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
5819 post_p);
cd3ce9b4 5820
47a25a46 5821 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
cd3ce9b4
JM
5822 }
5823 }
5824
23a60a04 5825 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
cd3ce9b4
JM
5826 }
5827
5828 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
5829 f_fpr = TREE_CHAIN (f_gpr);
5830 f_res = TREE_CHAIN (f_fpr);
5831 f_ovf = TREE_CHAIN (f_res);
5832 f_sav = TREE_CHAIN (f_ovf);
5833
872a65b5 5834 valist = build_va_arg_indirect_ref (valist);
47a25a46
RG
5835 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
5836 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
5837 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
5838 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
cd3ce9b4
JM
5839
5840 size = int_size_in_bytes (type);
5841 rsize = (size + 3) / 4;
5842 align = 1;
5843
08b0dc1b 5844 if (TARGET_HARD_FLOAT && TARGET_FPRS
602ea4d3
JJ
5845 && (TYPE_MODE (type) == SFmode
5846 || TYPE_MODE (type) == DFmode
5847 || TYPE_MODE (type) == TFmode))
cd3ce9b4
JM
5848 {
5849 /* FP args go in FP registers, if present. */
cd3ce9b4 5850 reg = fpr;
602ea4d3 5851 n_reg = (size + 7) / 8;
cd3ce9b4
JM
5852 sav_ofs = 8*4;
5853 sav_scale = 8;
602ea4d3 5854 if (TYPE_MODE (type) != SFmode)
cd3ce9b4
JM
5855 align = 8;
5856 }
5857 else
5858 {
5859 /* Otherwise into GP registers. */
cd3ce9b4
JM
5860 reg = gpr;
5861 n_reg = rsize;
5862 sav_ofs = 0;
5863 sav_scale = 4;
5864 if (n_reg == 2)
5865 align = 8;
5866 }
5867
5868 /* Pull the value out of the saved registers.... */
5869
5870 lab_over = NULL;
5871 addr = create_tmp_var (ptr_type_node, "addr");
5872 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
5873
5874 /* AltiVec vectors never go in registers when -mabi=altivec. */
5875 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
5876 align = 16;
5877 else
5878 {
5879 lab_false = create_artificial_label ();
5880 lab_over = create_artificial_label ();
5881
5882 /* Long long and SPE vectors are aligned in the registers.
5883 As are any other 2 gpr item such as complex int due to a
5884 historical mistake. */
5885 u = reg;
602ea4d3 5886 if (n_reg == 2 && reg == gpr)
cd3ce9b4
JM
5887 {
5888 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
95674810 5889 size_int (n_reg - 1));
cd3ce9b4
JM
5890 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
5891 }
5892
95674810 5893 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
cd3ce9b4
JM
5894 t = build2 (GE_EXPR, boolean_type_node, u, t);
5895 u = build1 (GOTO_EXPR, void_type_node, lab_false);
5896 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
5897 gimplify_and_add (t, pre_p);
5898
5899 t = sav;
5900 if (sav_ofs)
95674810 5901 t = build2 (PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
cd3ce9b4 5902
95674810 5903 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, size_int (n_reg));
cd3ce9b4 5904 u = build1 (CONVERT_EXPR, integer_type_node, u);
95674810 5905 u = build2 (MULT_EXPR, integer_type_node, u, size_int (sav_scale));
cd3ce9b4
JM
5906 t = build2 (PLUS_EXPR, ptr_type_node, t, u);
5907
5908 t = build2 (MODIFY_EXPR, void_type_node, addr, t);
5909 gimplify_and_add (t, pre_p);
5910
5911 t = build1 (GOTO_EXPR, void_type_node, lab_over);
5912 gimplify_and_add (t, pre_p);
5913
5914 t = build1 (LABEL_EXPR, void_type_node, lab_false);
5915 append_to_statement_list (t, pre_p);
5916
5917 if (n_reg > 2)
5918 {
5919 /* Ensure that we don't find any more args in regs.
5920 Alignment has taken care of the n_reg == 2 case. */
47a25a46 5921 t = build2 (MODIFY_EXPR, TREE_TYPE (reg), reg, size_int (8));
cd3ce9b4
JM
5922 gimplify_and_add (t, pre_p);
5923 }
5924 }
5925
5926 /* ... otherwise out of the overflow area. */
5927
5928 /* Care for on-stack alignment if needed. */
5929 t = ovf;
5930 if (align != 1)
5931 {
95674810 5932 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
4a90aeeb 5933 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
7d60be94 5934 build_int_cst (NULL_TREE, -align));
cd3ce9b4
JM
5935 }
5936 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
5937
5938 u = build2 (MODIFY_EXPR, void_type_node, addr, t);
5939 gimplify_and_add (u, pre_p);
5940
95674810 5941 t = build2 (PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
cd3ce9b4
JM
5942 t = build2 (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
5943 gimplify_and_add (t, pre_p);
5944
5945 if (lab_over)
5946 {
5947 t = build1 (LABEL_EXPR, void_type_node, lab_over);
5948 append_to_statement_list (t, pre_p);
5949 }
5950
08b0dc1b 5951 addr = fold_convert (ptrtype, addr);
872a65b5 5952 return build_va_arg_indirect_ref (addr);
cd3ce9b4
JM
5953}
5954
0ac081f6
AH
5955/* Builtins. */
5956
58646b77
PB
5957static void
5958def_builtin (int mask, const char *name, tree type, int code)
5959{
5960 if (mask & target_flags)
5961 {
5962 if (rs6000_builtin_decls[code])
5963 abort ();
5964
5965 rs6000_builtin_decls[code] =
5966 lang_hooks.builtin_function (name, type, code, BUILT_IN_MD,
5967 NULL, NULL_TREE);
5968 }
5969}
0ac081f6 5970
24408032
AH
5971/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
5972
2212663f 5973static const struct builtin_description bdesc_3arg[] =
24408032
AH
5974{
5975 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
5976 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
5977 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
5978 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
5979 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
5980 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
5981 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
5982 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
5983 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
5984 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
f676971a 5985 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
aba5fb01
NS
5986 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
5987 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
5988 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
5989 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
5990 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
5991 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
5992 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
5993 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
5994 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
5995 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
5996 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
5997 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
58646b77
PB
5998
5999 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
6000 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
6001 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
6002 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
6003 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
6004 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
6005 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
6006 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
6007 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
6008 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
6009 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
6010 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
6011 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
6012 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
6013 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
24408032 6014};
2212663f 6015
95385cbb
AH
6016/* DST operations: void foo (void *, const int, const char). */
6017
6018static const struct builtin_description bdesc_dst[] =
6019{
6020 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
6021 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
6022 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
58646b77
PB
6023 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
6024
6025 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
6026 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
6027 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
6028 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
95385cbb
AH
6029};
6030
2212663f 6031/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 6032
a3170dc6 6033static struct builtin_description bdesc_2arg[] =
0ac081f6 6034{
f18c054f
DB
6035 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
6036 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
6037 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
6038 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
6039 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
6040 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
6041 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
6042 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
6043 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
6044 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
6045 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 6046 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
aba5fb01 6047 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
0ac081f6
AH
6048 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
6049 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
6050 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
6051 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
6052 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
6053 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
6054 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
6055 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
6056 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
6057 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
6058 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
6059 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
6060 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
6061 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
6062 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
6063 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
6064 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
6065 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
6066 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
6067 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
6068 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
6069 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
6070 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
6071 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
6072 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
6073 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
6074 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
6075 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
6076 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
6077 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
6078 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
6079 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
6080 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
6081 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
6082 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
6083 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
6084 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
6085 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
6086 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
6087 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
6088 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
6089 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
6090 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
6091 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
6092 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
6093 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
6094 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
6095 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
6096 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
6097 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
6098 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
f96bc213 6099 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 6100 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
6101 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
6102 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
6103 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
0ac081f6 6104 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
0ac081f6
AH
6105 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
6106 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
6107 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
6108 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
6109 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
6110 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
6111 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
6112 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
6113 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
6114 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
6115 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
6116 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
6117 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
6118 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
6119 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
6120 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
3e0de9d1
DP
6121 { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
6122 { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
6123 { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
6124 { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
6125 { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
6126 { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
0ac081f6
AH
6127 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
6128 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
6129 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
6130 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
6131 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
6132 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
6133 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
6134 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
6135 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
6136 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
6137 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
6138 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
6139 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
6140 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
6141 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
6142 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
6143 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
6144 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 6145 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6 6146
58646b77
PB
6147 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
6148 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
6149 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
6150 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
6151 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
6152 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
6153 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
6154 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
6155 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
6156 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
6157 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
6158 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
6159 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
6160 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
6161 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
6162 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
6163 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
6164 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
6165 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
6166 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
6167 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
6168 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
6169 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
6170 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
6171 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
6172 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
6173 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
6174 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
6175 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
6176 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
6177 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
6178 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
6179 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
6180 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
6181 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
6182 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
6183 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
6184 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
6185 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
6186 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
6187 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
6188 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
6189 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
6190 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
6191 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
6192 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
6193 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
6194 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
6195 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
6196 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
6197 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
6198 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
6199 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
6200 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
6201 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
6202 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
6203 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
6204 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
6205 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
6206 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
6207 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
6208 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
6209 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
6210 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
6211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
6212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
6213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
6214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
6215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
6216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
6217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
6218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
6219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
6220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
6221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
6222 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
6223 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
6224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
6225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
6226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
6227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
6228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
6229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
6230 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
6231 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
6232 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
6233 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
6234 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
6235 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
6236 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
6237 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
6238 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
6239 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
6240 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
6241 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
6242 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
6243 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
6244 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
6245 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
6246 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
6247 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
6248 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
6249 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
6250 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
6251 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
6252 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
6253 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
6254 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
6255 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
6256 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
6257 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
6258 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
6259 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
6260 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
6261 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
6262 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
6263 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
6264 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
6265 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
6266 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
6267 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
6268 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
6269 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
6270 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
6271 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
6272 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
6273 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
6274
a3170dc6
AH
6275 /* Place holder, leave as first spe builtin. */
6276 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
6277 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
6278 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
6279 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
6280 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
6281 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
6282 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
6283 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
6284 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
6285 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
6286 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
6287 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
6288 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
6289 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
6290 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
6291 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
6292 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
6293 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
6294 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
6295 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
6296 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
6297 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
6298 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
6299 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
6300 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
6301 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
6302 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
6303 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
6304 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
6305 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
6306 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
6307 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
6308 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
6309 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
6310 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
6311 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
6312 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
6313 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
6314 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
6315 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
6316 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
6317 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
6318 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
6319 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
6320 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
6321 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
6322 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
6323 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
6324 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
6325 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
6326 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
6327 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
6328 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
6329 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
6330 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
6331 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
6332 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
6333 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
6334 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
6335 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
6336 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
6337 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
6338 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
6339 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
6340 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
6341 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
6342 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
6343 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
6344 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
6345 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
6346 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
6347 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
6348 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
6349 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
a3170dc6
AH
6350 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
6351 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
a3170dc6
AH
6352 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
6353 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
6354 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
6355 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
6356 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
6357 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
6358 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
6359 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
6360 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
6361 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
6362 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
6363 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
6364 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
6365 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
6366 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
6367 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
6368 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
6369 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
6370 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
6371 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
6372 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
6373 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
6374 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
6375 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
6376 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
6377 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
6378 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
6379 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
6380 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
6381 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
6382 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
6383 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
6384 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
6385
6386 /* SPE binary operations expecting a 5-bit unsigned literal. */
6387 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
6388
6389 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
6390 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
6391 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
6392 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
6393 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
6394 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
6395 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
6396 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
6397 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
6398 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
6399 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
6400 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
6401 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
6402 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
6403 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
6404 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
6405 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
6406 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
6407 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
6408 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
6409 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
6410 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
6411 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
6412 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
6413 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
6414 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
6415
6416 /* Place-holder. Leave as last binary SPE builtin. */
58646b77 6417 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
ae4b4a02
AH
6418};
6419
6420/* AltiVec predicates. */
6421
6422struct builtin_description_predicates
6423{
6424 const unsigned int mask;
6425 const enum insn_code icode;
6426 const char *opcode;
6427 const char *const name;
6428 const enum rs6000_builtins code;
6429};
6430
6431static const struct builtin_description_predicates bdesc_altivec_preds[] =
6432{
6433 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
6434 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
6435 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
6436 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
6437 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
6438 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
6439 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
6440 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
6441 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
6442 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
6443 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
6444 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
58646b77
PB
6445 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
6446
6447 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
6448 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
6449 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
0ac081f6 6450};
24408032 6451
a3170dc6
AH
6452/* SPE predicates. */
6453static struct builtin_description bdesc_spe_predicates[] =
6454{
6455 /* Place-holder. Leave as first. */
6456 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
6457 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
6458 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
6459 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
6460 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
6461 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
6462 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
6463 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
6464 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
6465 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
6466 /* Place-holder. Leave as last. */
6467 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
6468};
6469
6470/* SPE evsel predicates. */
6471static struct builtin_description bdesc_spe_evsel[] =
6472{
6473 /* Place-holder. Leave as first. */
6474 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
6475 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
6476 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
6477 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
6478 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
6479 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
6480 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
6481 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
6482 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
6483 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
6484 /* Place-holder. Leave as last. */
6485 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
6486};
6487
b6d08ca1 6488/* ABS* operations. */
100c4561
AH
6489
6490static const struct builtin_description bdesc_abs[] =
6491{
6492 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
6493 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
6494 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
6495 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
6496 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
6497 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
6498 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
6499};
6500
617e0e1d
DB
6501/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
6502 foo (VECa). */
24408032 6503
a3170dc6 6504static struct builtin_description bdesc_1arg[] =
2212663f 6505{
617e0e1d
DB
6506 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
6507 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
6508 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
6509 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
6510 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
6511 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
6512 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
6513 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
6514 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
6515 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
6516 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
6517 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
6518 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
6519 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
6520 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
6521 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
6522 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6 6523
58646b77
PB
6524 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
6525 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
6526 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
6527 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
6528 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
6529 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
6530 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
6531 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
6532 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
6533 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
6534 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
6535 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
6536 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
6537 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
6538 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
6539 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
6540 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
6541 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
6542 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
6543
a3170dc6
AH
6544 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
6545 end with SPE_BUILTIN_EVSUBFUSIAAW. */
6546 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
6547 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
6548 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
6549 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
6550 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
6551 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
6552 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
6553 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
6554 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
6555 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
6556 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
6557 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
6558 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
6559 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
6560 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
6561 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
6562 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
6563 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
6564 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
6565 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
6566 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
6567 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
6568 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
6a599451 6569 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
a3170dc6
AH
6570 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
6571 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
6572 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
6573 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
a3170dc6
AH
6574
6575 /* Place-holder. Leave as last unary SPE builtin. */
58646b77 6576 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW }
2212663f
DB
6577};
6578
6579static rtx
a2369ed3 6580rs6000_expand_unop_builtin (enum insn_code icode, tree arglist, rtx target)
2212663f
DB
6581{
6582 rtx pat;
6583 tree arg0 = TREE_VALUE (arglist);
84217346 6584 rtx op0 = expand_normal (arg0);
2212663f
DB
6585 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6586 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6587
0559cc77
DE
6588 if (icode == CODE_FOR_nothing)
6589 /* Builtin not supported on this processor. */
6590 return 0;
6591
20e26713
AH
6592 /* If we got invalid arguments bail out before generating bad rtl. */
6593 if (arg0 == error_mark_node)
9a171fcd 6594 return const0_rtx;
20e26713 6595
0559cc77
DE
6596 if (icode == CODE_FOR_altivec_vspltisb
6597 || icode == CODE_FOR_altivec_vspltish
6598 || icode == CODE_FOR_altivec_vspltisw
6599 || icode == CODE_FOR_spe_evsplatfi
6600 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
6601 {
6602 /* Only allow 5-bit *signed* literals. */
b44140e7 6603 if (GET_CODE (op0) != CONST_INT
afca671b
DP
6604 || INTVAL (op0) > 15
6605 || INTVAL (op0) < -16)
b44140e7
AH
6606 {
6607 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 6608 return const0_rtx;
b44140e7 6609 }
b44140e7
AH
6610 }
6611
c62f2db5 6612 if (target == 0
2212663f
DB
6613 || GET_MODE (target) != tmode
6614 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6615 target = gen_reg_rtx (tmode);
6616
6617 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6618 op0 = copy_to_mode_reg (mode0, op0);
6619
6620 pat = GEN_FCN (icode) (target, op0);
6621 if (! pat)
6622 return 0;
6623 emit_insn (pat);
0ac081f6 6624
2212663f
DB
6625 return target;
6626}
ae4b4a02 6627
100c4561 6628static rtx
a2369ed3 6629altivec_expand_abs_builtin (enum insn_code icode, tree arglist, rtx target)
100c4561
AH
6630{
6631 rtx pat, scratch1, scratch2;
6632 tree arg0 = TREE_VALUE (arglist);
84217346 6633 rtx op0 = expand_normal (arg0);
100c4561
AH
6634 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6635 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6636
6637 /* If we have invalid arguments, bail out before generating bad rtl. */
6638 if (arg0 == error_mark_node)
9a171fcd 6639 return const0_rtx;
100c4561
AH
6640
6641 if (target == 0
6642 || GET_MODE (target) != tmode
6643 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6644 target = gen_reg_rtx (tmode);
6645
6646 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6647 op0 = copy_to_mode_reg (mode0, op0);
6648
6649 scratch1 = gen_reg_rtx (mode0);
6650 scratch2 = gen_reg_rtx (mode0);
6651
6652 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
6653 if (! pat)
6654 return 0;
6655 emit_insn (pat);
6656
6657 return target;
6658}
6659
0ac081f6 6660static rtx
a2369ed3 6661rs6000_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
0ac081f6
AH
6662{
6663 rtx pat;
6664 tree arg0 = TREE_VALUE (arglist);
6665 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
84217346
MD
6666 rtx op0 = expand_normal (arg0);
6667 rtx op1 = expand_normal (arg1);
0ac081f6
AH
6668 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6669 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6670 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6671
0559cc77
DE
6672 if (icode == CODE_FOR_nothing)
6673 /* Builtin not supported on this processor. */
6674 return 0;
6675
20e26713
AH
6676 /* If we got invalid arguments bail out before generating bad rtl. */
6677 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 6678 return const0_rtx;
20e26713 6679
0559cc77
DE
6680 if (icode == CODE_FOR_altivec_vcfux
6681 || icode == CODE_FOR_altivec_vcfsx
6682 || icode == CODE_FOR_altivec_vctsxs
6683 || icode == CODE_FOR_altivec_vctuxs
6684 || icode == CODE_FOR_altivec_vspltb
6685 || icode == CODE_FOR_altivec_vsplth
6686 || icode == CODE_FOR_altivec_vspltw
6687 || icode == CODE_FOR_spe_evaddiw
6688 || icode == CODE_FOR_spe_evldd
6689 || icode == CODE_FOR_spe_evldh
6690 || icode == CODE_FOR_spe_evldw
6691 || icode == CODE_FOR_spe_evlhhesplat
6692 || icode == CODE_FOR_spe_evlhhossplat
6693 || icode == CODE_FOR_spe_evlhhousplat
6694 || icode == CODE_FOR_spe_evlwhe
6695 || icode == CODE_FOR_spe_evlwhos
6696 || icode == CODE_FOR_spe_evlwhou
6697 || icode == CODE_FOR_spe_evlwhsplat
6698 || icode == CODE_FOR_spe_evlwwsplat
6699 || icode == CODE_FOR_spe_evrlwi
6700 || icode == CODE_FOR_spe_evslwi
6701 || icode == CODE_FOR_spe_evsrwis
f5119d10 6702 || icode == CODE_FOR_spe_evsubifw
0559cc77 6703 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
6704 {
6705 /* Only allow 5-bit unsigned literals. */
8bb418a3 6706 STRIP_NOPS (arg1);
b44140e7
AH
6707 if (TREE_CODE (arg1) != INTEGER_CST
6708 || TREE_INT_CST_LOW (arg1) & ~0x1f)
6709 {
6710 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 6711 return const0_rtx;
b44140e7 6712 }
b44140e7
AH
6713 }
6714
c62f2db5 6715 if (target == 0
0ac081f6
AH
6716 || GET_MODE (target) != tmode
6717 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6718 target = gen_reg_rtx (tmode);
6719
6720 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6721 op0 = copy_to_mode_reg (mode0, op0);
6722 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6723 op1 = copy_to_mode_reg (mode1, op1);
6724
6725 pat = GEN_FCN (icode) (target, op0, op1);
6726 if (! pat)
6727 return 0;
6728 emit_insn (pat);
6729
6730 return target;
6731}
6525c0e7 6732
ae4b4a02 6733static rtx
f676971a 6734altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
a2369ed3 6735 tree arglist, rtx target)
ae4b4a02
AH
6736{
6737 rtx pat, scratch;
6738 tree cr6_form = TREE_VALUE (arglist);
6739 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
6740 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
84217346
MD
6741 rtx op0 = expand_normal (arg0);
6742 rtx op1 = expand_normal (arg1);
ae4b4a02
AH
6743 enum machine_mode tmode = SImode;
6744 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6745 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6746 int cr6_form_int;
6747
6748 if (TREE_CODE (cr6_form) != INTEGER_CST)
6749 {
6750 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 6751 return const0_rtx;
ae4b4a02
AH
6752 }
6753 else
6754 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
6755
37409796 6756 gcc_assert (mode0 == mode1);
ae4b4a02
AH
6757
6758 /* If we have invalid arguments, bail out before generating bad rtl. */
6759 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 6760 return const0_rtx;
ae4b4a02
AH
6761
6762 if (target == 0
6763 || GET_MODE (target) != tmode
6764 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6765 target = gen_reg_rtx (tmode);
6766
6767 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6768 op0 = copy_to_mode_reg (mode0, op0);
6769 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6770 op1 = copy_to_mode_reg (mode1, op1);
6771
6772 scratch = gen_reg_rtx (mode0);
6773
6774 pat = GEN_FCN (icode) (scratch, op0, op1,
f1c25d3b 6775 gen_rtx_SYMBOL_REF (Pmode, opcode));
ae4b4a02
AH
6776 if (! pat)
6777 return 0;
6778 emit_insn (pat);
6779
6780 /* The vec_any* and vec_all* predicates use the same opcodes for two
6781 different operations, but the bits in CR6 will be different
6782 depending on what information we want. So we have to play tricks
6783 with CR6 to get the right bits out.
6784
6785 If you think this is disgusting, look at the specs for the
6786 AltiVec predicates. */
6787
c4ad648e
AM
6788 switch (cr6_form_int)
6789 {
6790 case 0:
6791 emit_insn (gen_cr6_test_for_zero (target));
6792 break;
6793 case 1:
6794 emit_insn (gen_cr6_test_for_zero_reverse (target));
6795 break;
6796 case 2:
6797 emit_insn (gen_cr6_test_for_lt (target));
6798 break;
6799 case 3:
6800 emit_insn (gen_cr6_test_for_lt_reverse (target));
6801 break;
6802 default:
6803 error ("argument 1 of __builtin_altivec_predicate is out of range");
6804 break;
6805 }
ae4b4a02
AH
6806
6807 return target;
6808}
6809
b4a62fa0 6810static rtx
38f391a5 6811altivec_expand_lv_builtin (enum insn_code icode, tree arglist, rtx target)
b4a62fa0
SB
6812{
6813 rtx pat, addr;
6814 tree arg0 = TREE_VALUE (arglist);
6815 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6816 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6817 enum machine_mode mode0 = Pmode;
6818 enum machine_mode mode1 = Pmode;
84217346
MD
6819 rtx op0 = expand_normal (arg0);
6820 rtx op1 = expand_normal (arg1);
b4a62fa0
SB
6821
6822 if (icode == CODE_FOR_nothing)
6823 /* Builtin not supported on this processor. */
6824 return 0;
6825
6826 /* If we got invalid arguments bail out before generating bad rtl. */
6827 if (arg0 == error_mark_node || arg1 == error_mark_node)
6828 return const0_rtx;
6829
6830 if (target == 0
6831 || GET_MODE (target) != tmode
6832 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6833 target = gen_reg_rtx (tmode);
6834
f676971a 6835 op1 = copy_to_mode_reg (mode1, op1);
b4a62fa0
SB
6836
6837 if (op0 == const0_rtx)
6838 {
6839 addr = gen_rtx_MEM (tmode, op1);
6840 }
6841 else
6842 {
6843 op0 = copy_to_mode_reg (mode0, op0);
6844 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
6845 }
6846
6847 pat = GEN_FCN (icode) (target, addr);
6848
6849 if (! pat)
6850 return 0;
6851 emit_insn (pat);
6852
6853 return target;
6854}
6855
61bea3b0
AH
6856static rtx
6857spe_expand_stv_builtin (enum insn_code icode, tree arglist)
6858{
6859 tree arg0 = TREE_VALUE (arglist);
6860 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6861 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
84217346
MD
6862 rtx op0 = expand_normal (arg0);
6863 rtx op1 = expand_normal (arg1);
6864 rtx op2 = expand_normal (arg2);
61bea3b0
AH
6865 rtx pat;
6866 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
6867 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
6868 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
6869
6870 /* Invalid arguments. Bail before doing anything stoopid! */
6871 if (arg0 == error_mark_node
6872 || arg1 == error_mark_node
6873 || arg2 == error_mark_node)
6874 return const0_rtx;
6875
6876 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
6877 op0 = copy_to_mode_reg (mode2, op0);
6878 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
6879 op1 = copy_to_mode_reg (mode0, op1);
6880 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
6881 op2 = copy_to_mode_reg (mode1, op2);
6882
6883 pat = GEN_FCN (icode) (op1, op2, op0);
6884 if (pat)
6885 emit_insn (pat);
6886 return NULL_RTX;
6887}
6888
6525c0e7 6889static rtx
a2369ed3 6890altivec_expand_stv_builtin (enum insn_code icode, tree arglist)
6525c0e7
AH
6891{
6892 tree arg0 = TREE_VALUE (arglist);
6893 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6894 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
84217346
MD
6895 rtx op0 = expand_normal (arg0);
6896 rtx op1 = expand_normal (arg1);
6897 rtx op2 = expand_normal (arg2);
b4a62fa0
SB
6898 rtx pat, addr;
6899 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6900 enum machine_mode mode1 = Pmode;
6901 enum machine_mode mode2 = Pmode;
6525c0e7
AH
6902
6903 /* Invalid arguments. Bail before doing anything stoopid! */
6904 if (arg0 == error_mark_node
6905 || arg1 == error_mark_node
6906 || arg2 == error_mark_node)
9a171fcd 6907 return const0_rtx;
6525c0e7 6908
b4a62fa0
SB
6909 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
6910 op0 = copy_to_mode_reg (tmode, op0);
6911
f676971a 6912 op2 = copy_to_mode_reg (mode2, op2);
b4a62fa0
SB
6913
6914 if (op1 == const0_rtx)
6915 {
6916 addr = gen_rtx_MEM (tmode, op2);
6917 }
6918 else
6919 {
6920 op1 = copy_to_mode_reg (mode1, op1);
6921 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
6922 }
6525c0e7 6923
b4a62fa0 6924 pat = GEN_FCN (icode) (addr, op0);
6525c0e7
AH
6925 if (pat)
6926 emit_insn (pat);
6927 return NULL_RTX;
6928}
6929
2212663f 6930static rtx
a2369ed3 6931rs6000_expand_ternop_builtin (enum insn_code icode, tree arglist, rtx target)
2212663f
DB
6932{
6933 rtx pat;
6934 tree arg0 = TREE_VALUE (arglist);
6935 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
6936 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
84217346
MD
6937 rtx op0 = expand_normal (arg0);
6938 rtx op1 = expand_normal (arg1);
6939 rtx op2 = expand_normal (arg2);
2212663f
DB
6940 enum machine_mode tmode = insn_data[icode].operand[0].mode;
6941 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
6942 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
6943 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 6944
774b5662
DE
6945 if (icode == CODE_FOR_nothing)
6946 /* Builtin not supported on this processor. */
6947 return 0;
6948
20e26713
AH
6949 /* If we got invalid arguments bail out before generating bad rtl. */
6950 if (arg0 == error_mark_node
6951 || arg1 == error_mark_node
6952 || arg2 == error_mark_node)
9a171fcd 6953 return const0_rtx;
20e26713 6954
aba5fb01
NS
6955 if (icode == CODE_FOR_altivec_vsldoi_v4sf
6956 || icode == CODE_FOR_altivec_vsldoi_v4si
6957 || icode == CODE_FOR_altivec_vsldoi_v8hi
6958 || icode == CODE_FOR_altivec_vsldoi_v16qi)
b44140e7
AH
6959 {
6960 /* Only allow 4-bit unsigned literals. */
8bb418a3 6961 STRIP_NOPS (arg2);
b44140e7
AH
6962 if (TREE_CODE (arg2) != INTEGER_CST
6963 || TREE_INT_CST_LOW (arg2) & ~0xf)
6964 {
6965 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 6966 return const0_rtx;
b44140e7 6967 }
b44140e7
AH
6968 }
6969
c62f2db5 6970 if (target == 0
2212663f
DB
6971 || GET_MODE (target) != tmode
6972 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
6973 target = gen_reg_rtx (tmode);
6974
6975 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
6976 op0 = copy_to_mode_reg (mode0, op0);
6977 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
6978 op1 = copy_to_mode_reg (mode1, op1);
6979 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
6980 op2 = copy_to_mode_reg (mode2, op2);
6981
6982 pat = GEN_FCN (icode) (target, op0, op1, op2);
6983 if (! pat)
6984 return 0;
6985 emit_insn (pat);
6986
6987 return target;
6988}
92898235 6989
3a9b8c7e 6990/* Expand the lvx builtins. */
0ac081f6 6991static rtx
a2369ed3 6992altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
0ac081f6 6993{
0ac081f6
AH
6994 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6995 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 6996 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
6997 tree arg0;
6998 enum machine_mode tmode, mode0;
7c3abc73 6999 rtx pat, op0;
3a9b8c7e 7000 enum insn_code icode;
92898235 7001
0ac081f6
AH
7002 switch (fcode)
7003 {
f18c054f 7004 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
81466555 7005 icode = CODE_FOR_altivec_lvx_v16qi;
3a9b8c7e 7006 break;
f18c054f 7007 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
81466555 7008 icode = CODE_FOR_altivec_lvx_v8hi;
3a9b8c7e
AH
7009 break;
7010 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
81466555 7011 icode = CODE_FOR_altivec_lvx_v4si;
3a9b8c7e
AH
7012 break;
7013 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
81466555 7014 icode = CODE_FOR_altivec_lvx_v4sf;
3a9b8c7e
AH
7015 break;
7016 default:
7017 *expandedp = false;
7018 return NULL_RTX;
7019 }
0ac081f6 7020
3a9b8c7e 7021 *expandedp = true;
f18c054f 7022
3a9b8c7e 7023 arg0 = TREE_VALUE (arglist);
84217346 7024 op0 = expand_normal (arg0);
3a9b8c7e
AH
7025 tmode = insn_data[icode].operand[0].mode;
7026 mode0 = insn_data[icode].operand[1].mode;
f18c054f 7027
3a9b8c7e
AH
7028 if (target == 0
7029 || GET_MODE (target) != tmode
7030 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7031 target = gen_reg_rtx (tmode);
24408032 7032
3a9b8c7e
AH
7033 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7034 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 7035
3a9b8c7e
AH
7036 pat = GEN_FCN (icode) (target, op0);
7037 if (! pat)
7038 return 0;
7039 emit_insn (pat);
7040 return target;
7041}
f18c054f 7042
3a9b8c7e
AH
7043/* Expand the stvx builtins. */
7044static rtx
f676971a 7045altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
a2369ed3 7046 bool *expandedp)
3a9b8c7e
AH
7047{
7048 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7049 tree arglist = TREE_OPERAND (exp, 1);
7050 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7051 tree arg0, arg1;
7052 enum machine_mode mode0, mode1;
7c3abc73 7053 rtx pat, op0, op1;
3a9b8c7e 7054 enum insn_code icode;
f18c054f 7055
3a9b8c7e
AH
7056 switch (fcode)
7057 {
7058 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
81466555 7059 icode = CODE_FOR_altivec_stvx_v16qi;
3a9b8c7e
AH
7060 break;
7061 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
81466555 7062 icode = CODE_FOR_altivec_stvx_v8hi;
3a9b8c7e
AH
7063 break;
7064 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
81466555 7065 icode = CODE_FOR_altivec_stvx_v4si;
3a9b8c7e
AH
7066 break;
7067 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
81466555 7068 icode = CODE_FOR_altivec_stvx_v4sf;
3a9b8c7e
AH
7069 break;
7070 default:
7071 *expandedp = false;
7072 return NULL_RTX;
7073 }
24408032 7074
3a9b8c7e
AH
7075 arg0 = TREE_VALUE (arglist);
7076 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
84217346
MD
7077 op0 = expand_normal (arg0);
7078 op1 = expand_normal (arg1);
3a9b8c7e
AH
7079 mode0 = insn_data[icode].operand[0].mode;
7080 mode1 = insn_data[icode].operand[1].mode;
f18c054f 7081
3a9b8c7e
AH
7082 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7083 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7084 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7085 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 7086
3a9b8c7e
AH
7087 pat = GEN_FCN (icode) (op0, op1);
7088 if (pat)
7089 emit_insn (pat);
f18c054f 7090
3a9b8c7e
AH
7091 *expandedp = true;
7092 return NULL_RTX;
7093}
f18c054f 7094
3a9b8c7e
AH
7095/* Expand the dst builtins. */
7096static rtx
f676971a 7097altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
a2369ed3 7098 bool *expandedp)
3a9b8c7e
AH
7099{
7100 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7101 tree arglist = TREE_OPERAND (exp, 1);
7102 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7103 tree arg0, arg1, arg2;
7104 enum machine_mode mode0, mode1, mode2;
7c3abc73 7105 rtx pat, op0, op1, op2;
3a9b8c7e 7106 struct builtin_description *d;
a3170dc6 7107 size_t i;
f18c054f 7108
3a9b8c7e 7109 *expandedp = false;
f18c054f 7110
3a9b8c7e
AH
7111 /* Handle DST variants. */
7112 d = (struct builtin_description *) bdesc_dst;
7113 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
7114 if (d->code == fcode)
7115 {
7116 arg0 = TREE_VALUE (arglist);
7117 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7118 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
84217346
MD
7119 op0 = expand_normal (arg0);
7120 op1 = expand_normal (arg1);
7121 op2 = expand_normal (arg2);
3a9b8c7e
AH
7122 mode0 = insn_data[d->icode].operand[0].mode;
7123 mode1 = insn_data[d->icode].operand[1].mode;
7124 mode2 = insn_data[d->icode].operand[2].mode;
24408032 7125
3a9b8c7e
AH
7126 /* Invalid arguments, bail out before generating bad rtl. */
7127 if (arg0 == error_mark_node
7128 || arg1 == error_mark_node
7129 || arg2 == error_mark_node)
7130 return const0_rtx;
f18c054f 7131
86e7df90 7132 *expandedp = true;
8bb418a3 7133 STRIP_NOPS (arg2);
3a9b8c7e
AH
7134 if (TREE_CODE (arg2) != INTEGER_CST
7135 || TREE_INT_CST_LOW (arg2) & ~0x3)
7136 {
9e637a26 7137 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
3a9b8c7e
AH
7138 return const0_rtx;
7139 }
f18c054f 7140
3a9b8c7e 7141 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
666158b9 7142 op0 = copy_to_mode_reg (Pmode, op0);
3a9b8c7e
AH
7143 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
7144 op1 = copy_to_mode_reg (mode1, op1);
24408032 7145
3a9b8c7e
AH
7146 pat = GEN_FCN (d->icode) (op0, op1, op2);
7147 if (pat != 0)
7148 emit_insn (pat);
f18c054f 7149
3a9b8c7e
AH
7150 return NULL_RTX;
7151 }
f18c054f 7152
3a9b8c7e
AH
7153 return NULL_RTX;
7154}
24408032 7155
7a4eca66
DE
7156/* Expand vec_init builtin. */
7157static rtx
7158altivec_expand_vec_init_builtin (tree type, tree arglist, rtx target)
7159{
7160 enum machine_mode tmode = TYPE_MODE (type);
7161 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
7162 int i, n_elt = GET_MODE_NUNITS (tmode);
7163 rtvec v = rtvec_alloc (n_elt);
7164
7165 gcc_assert (VECTOR_MODE_P (tmode));
7166
7167 for (i = 0; i < n_elt; ++i, arglist = TREE_CHAIN (arglist))
7168 {
84217346 7169 rtx x = expand_normal (TREE_VALUE (arglist));
7a4eca66
DE
7170 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
7171 }
7172
7173 gcc_assert (arglist == NULL);
7174
7175 if (!target || !register_operand (target, tmode))
7176 target = gen_reg_rtx (tmode);
7177
7178 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
7179 return target;
7180}
7181
7182/* Return the integer constant in ARG. Constrain it to be in the range
7183 of the subparts of VEC_TYPE; issue an error if not. */
7184
7185static int
7186get_element_number (tree vec_type, tree arg)
7187{
7188 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
7189
7190 if (!host_integerp (arg, 1)
7191 || (elt = tree_low_cst (arg, 1), elt > max))
7192 {
7193 error ("selector must be an integer constant in the range 0..%wi", max);
7194 return 0;
7195 }
7196
7197 return elt;
7198}
7199
7200/* Expand vec_set builtin. */
7201static rtx
7202altivec_expand_vec_set_builtin (tree arglist)
7203{
7204 enum machine_mode tmode, mode1;
7205 tree arg0, arg1, arg2;
7206 int elt;
7207 rtx op0, op1;
7208
7209 arg0 = TREE_VALUE (arglist);
7210 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7211 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7212
7213 tmode = TYPE_MODE (TREE_TYPE (arg0));
7214 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7215 gcc_assert (VECTOR_MODE_P (tmode));
7216
7217 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
7218 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
7219 elt = get_element_number (TREE_TYPE (arg0), arg2);
7220
7221 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
7222 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
7223
7224 op0 = force_reg (tmode, op0);
7225 op1 = force_reg (mode1, op1);
7226
7227 rs6000_expand_vector_set (op0, op1, elt);
7228
7229 return op0;
7230}
7231
7232/* Expand vec_ext builtin. */
7233static rtx
7234altivec_expand_vec_ext_builtin (tree arglist, rtx target)
7235{
7236 enum machine_mode tmode, mode0;
7237 tree arg0, arg1;
7238 int elt;
7239 rtx op0;
7240
7241 arg0 = TREE_VALUE (arglist);
7242 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7243
84217346 7244 op0 = expand_normal (arg0);
7a4eca66
DE
7245 elt = get_element_number (TREE_TYPE (arg0), arg1);
7246
7247 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7248 mode0 = TYPE_MODE (TREE_TYPE (arg0));
7249 gcc_assert (VECTOR_MODE_P (mode0));
7250
7251 op0 = force_reg (mode0, op0);
7252
7253 if (optimize || !target || !register_operand (target, tmode))
7254 target = gen_reg_rtx (tmode);
7255
7256 rs6000_expand_vector_extract (target, op0, elt);
7257
7258 return target;
7259}
7260
3a9b8c7e
AH
7261/* Expand the builtin in EXP and store the result in TARGET. Store
7262 true in *EXPANDEDP if we found a builtin to expand. */
7263static rtx
a2369ed3 7264altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
3a9b8c7e
AH
7265{
7266 struct builtin_description *d;
7267 struct builtin_description_predicates *dp;
7268 size_t i;
7269 enum insn_code icode;
7270 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7271 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
7272 tree arg0;
7273 rtx op0, pat;
7274 enum machine_mode tmode, mode0;
3a9b8c7e 7275 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 7276
58646b77
PB
7277 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
7278 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
7279 {
7280 *expandedp = true;
ea40ba9c 7281 error ("unresolved overload for Altivec builtin %qF", fndecl);
58646b77
PB
7282 return const0_rtx;
7283 }
7284
3a9b8c7e
AH
7285 target = altivec_expand_ld_builtin (exp, target, expandedp);
7286 if (*expandedp)
7287 return target;
0ac081f6 7288
3a9b8c7e
AH
7289 target = altivec_expand_st_builtin (exp, target, expandedp);
7290 if (*expandedp)
7291 return target;
7292
7293 target = altivec_expand_dst_builtin (exp, target, expandedp);
7294 if (*expandedp)
7295 return target;
7296
7297 *expandedp = true;
95385cbb 7298
3a9b8c7e
AH
7299 switch (fcode)
7300 {
6525c0e7
AH
7301 case ALTIVEC_BUILTIN_STVX:
7302 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
7303 case ALTIVEC_BUILTIN_STVEBX:
7304 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
7305 case ALTIVEC_BUILTIN_STVEHX:
7306 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
7307 case ALTIVEC_BUILTIN_STVEWX:
7308 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
7309 case ALTIVEC_BUILTIN_STVXL:
7310 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 7311
95385cbb
AH
7312 case ALTIVEC_BUILTIN_MFVSCR:
7313 icode = CODE_FOR_altivec_mfvscr;
7314 tmode = insn_data[icode].operand[0].mode;
7315
7316 if (target == 0
7317 || GET_MODE (target) != tmode
7318 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7319 target = gen_reg_rtx (tmode);
f676971a 7320
95385cbb 7321 pat = GEN_FCN (icode) (target);
0ac081f6
AH
7322 if (! pat)
7323 return 0;
7324 emit_insn (pat);
95385cbb
AH
7325 return target;
7326
7327 case ALTIVEC_BUILTIN_MTVSCR:
7328 icode = CODE_FOR_altivec_mtvscr;
7329 arg0 = TREE_VALUE (arglist);
84217346 7330 op0 = expand_normal (arg0);
95385cbb
AH
7331 mode0 = insn_data[icode].operand[0].mode;
7332
7333 /* If we got invalid arguments bail out before generating bad rtl. */
7334 if (arg0 == error_mark_node)
9a171fcd 7335 return const0_rtx;
95385cbb
AH
7336
7337 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7338 op0 = copy_to_mode_reg (mode0, op0);
7339
7340 pat = GEN_FCN (icode) (op0);
7341 if (pat)
7342 emit_insn (pat);
7343 return NULL_RTX;
3a9b8c7e 7344
95385cbb
AH
7345 case ALTIVEC_BUILTIN_DSSALL:
7346 emit_insn (gen_altivec_dssall ());
7347 return NULL_RTX;
7348
7349 case ALTIVEC_BUILTIN_DSS:
7350 icode = CODE_FOR_altivec_dss;
7351 arg0 = TREE_VALUE (arglist);
8bb418a3 7352 STRIP_NOPS (arg0);
84217346 7353 op0 = expand_normal (arg0);
95385cbb
AH
7354 mode0 = insn_data[icode].operand[0].mode;
7355
7356 /* If we got invalid arguments bail out before generating bad rtl. */
7357 if (arg0 == error_mark_node)
9a171fcd 7358 return const0_rtx;
95385cbb 7359
b44140e7
AH
7360 if (TREE_CODE (arg0) != INTEGER_CST
7361 || TREE_INT_CST_LOW (arg0) & ~0x3)
7362 {
7363 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 7364 return const0_rtx;
b44140e7
AH
7365 }
7366
95385cbb
AH
7367 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7368 op0 = copy_to_mode_reg (mode0, op0);
7369
7370 emit_insn (gen_altivec_dss (op0));
0ac081f6 7371 return NULL_RTX;
7a4eca66
DE
7372
7373 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
7374 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
7375 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
7376 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
7377 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), arglist, target);
7378
7379 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
7380 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
7381 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
7382 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
7383 return altivec_expand_vec_set_builtin (arglist);
7384
7385 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
7386 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
7387 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
7388 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
7389 return altivec_expand_vec_ext_builtin (arglist, target);
7390
7391 default:
7392 break;
7393 /* Fall through. */
0ac081f6 7394 }
24408032 7395
100c4561
AH
7396 /* Expand abs* operations. */
7397 d = (struct builtin_description *) bdesc_abs;
ca7558fc 7398 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
7399 if (d->code == fcode)
7400 return altivec_expand_abs_builtin (d->icode, arglist, target);
7401
ae4b4a02
AH
7402 /* Expand the AltiVec predicates. */
7403 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 7404 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02 7405 if (dp->code == fcode)
c4ad648e
AM
7406 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
7407 arglist, target);
ae4b4a02 7408
6525c0e7
AH
7409 /* LV* are funky. We initialized them differently. */
7410 switch (fcode)
7411 {
7412 case ALTIVEC_BUILTIN_LVSL:
b4a62fa0 7413 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
c4ad648e 7414 arglist, target);
6525c0e7 7415 case ALTIVEC_BUILTIN_LVSR:
b4a62fa0 7416 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
c4ad648e 7417 arglist, target);
6525c0e7 7418 case ALTIVEC_BUILTIN_LVEBX:
b4a62fa0 7419 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
c4ad648e 7420 arglist, target);
6525c0e7 7421 case ALTIVEC_BUILTIN_LVEHX:
b4a62fa0 7422 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
c4ad648e 7423 arglist, target);
6525c0e7 7424 case ALTIVEC_BUILTIN_LVEWX:
b4a62fa0 7425 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
c4ad648e 7426 arglist, target);
6525c0e7 7427 case ALTIVEC_BUILTIN_LVXL:
b4a62fa0 7428 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
c4ad648e 7429 arglist, target);
6525c0e7 7430 case ALTIVEC_BUILTIN_LVX:
b4a62fa0 7431 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
c4ad648e 7432 arglist, target);
6525c0e7
AH
7433 default:
7434 break;
7435 /* Fall through. */
7436 }
95385cbb 7437
92898235 7438 *expandedp = false;
0ac081f6
AH
7439 return NULL_RTX;
7440}
7441
a3170dc6
AH
7442/* Binops that need to be initialized manually, but can be expanded
7443 automagically by rs6000_expand_binop_builtin. */
7444static struct builtin_description bdesc_2arg_spe[] =
7445{
7446 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
7447 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
7448 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
7449 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
7450 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
7451 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
7452 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
7453 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
7454 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
7455 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
7456 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
7457 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
7458 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
7459 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
7460 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
7461 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
7462 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
7463 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
7464 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
7465 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
7466 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
7467 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
7468};
7469
7470/* Expand the builtin in EXP and store the result in TARGET. Store
7471 true in *EXPANDEDP if we found a builtin to expand.
7472
7473 This expands the SPE builtins that are not simple unary and binary
7474 operations. */
7475static rtx
a2369ed3 7476spe_expand_builtin (tree exp, rtx target, bool *expandedp)
a3170dc6
AH
7477{
7478 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7479 tree arglist = TREE_OPERAND (exp, 1);
7480 tree arg1, arg0;
7481 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7482 enum insn_code icode;
7483 enum machine_mode tmode, mode0;
7484 rtx pat, op0;
7485 struct builtin_description *d;
7486 size_t i;
7487
7488 *expandedp = true;
7489
7490 /* Syntax check for a 5-bit unsigned immediate. */
7491 switch (fcode)
7492 {
7493 case SPE_BUILTIN_EVSTDD:
7494 case SPE_BUILTIN_EVSTDH:
7495 case SPE_BUILTIN_EVSTDW:
7496 case SPE_BUILTIN_EVSTWHE:
7497 case SPE_BUILTIN_EVSTWHO:
7498 case SPE_BUILTIN_EVSTWWE:
7499 case SPE_BUILTIN_EVSTWWO:
7500 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7501 if (TREE_CODE (arg1) != INTEGER_CST
7502 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7503 {
7504 error ("argument 2 must be a 5-bit unsigned literal");
7505 return const0_rtx;
7506 }
7507 break;
7508 default:
7509 break;
7510 }
7511
00332c9f
AH
7512 /* The evsplat*i instructions are not quite generic. */
7513 switch (fcode)
7514 {
7515 case SPE_BUILTIN_EVSPLATFI:
7516 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
7517 arglist, target);
7518 case SPE_BUILTIN_EVSPLATI:
7519 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
7520 arglist, target);
7521 default:
7522 break;
7523 }
7524
a3170dc6
AH
7525 d = (struct builtin_description *) bdesc_2arg_spe;
7526 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
7527 if (d->code == fcode)
7528 return rs6000_expand_binop_builtin (d->icode, arglist, target);
7529
7530 d = (struct builtin_description *) bdesc_spe_predicates;
7531 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
7532 if (d->code == fcode)
7533 return spe_expand_predicate_builtin (d->icode, arglist, target);
7534
7535 d = (struct builtin_description *) bdesc_spe_evsel;
7536 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
7537 if (d->code == fcode)
7538 return spe_expand_evsel_builtin (d->icode, arglist, target);
7539
7540 switch (fcode)
7541 {
7542 case SPE_BUILTIN_EVSTDDX:
61bea3b0 7543 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
a3170dc6 7544 case SPE_BUILTIN_EVSTDHX:
61bea3b0 7545 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
a3170dc6 7546 case SPE_BUILTIN_EVSTDWX:
61bea3b0 7547 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
a3170dc6 7548 case SPE_BUILTIN_EVSTWHEX:
61bea3b0 7549 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
a3170dc6 7550 case SPE_BUILTIN_EVSTWHOX:
61bea3b0 7551 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
a3170dc6 7552 case SPE_BUILTIN_EVSTWWEX:
61bea3b0 7553 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
a3170dc6 7554 case SPE_BUILTIN_EVSTWWOX:
61bea3b0 7555 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
a3170dc6 7556 case SPE_BUILTIN_EVSTDD:
61bea3b0 7557 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
a3170dc6 7558 case SPE_BUILTIN_EVSTDH:
61bea3b0 7559 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
a3170dc6 7560 case SPE_BUILTIN_EVSTDW:
61bea3b0 7561 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
a3170dc6 7562 case SPE_BUILTIN_EVSTWHE:
61bea3b0 7563 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
a3170dc6 7564 case SPE_BUILTIN_EVSTWHO:
61bea3b0 7565 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
a3170dc6 7566 case SPE_BUILTIN_EVSTWWE:
61bea3b0 7567 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
a3170dc6 7568 case SPE_BUILTIN_EVSTWWO:
61bea3b0 7569 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
a3170dc6
AH
7570 case SPE_BUILTIN_MFSPEFSCR:
7571 icode = CODE_FOR_spe_mfspefscr;
7572 tmode = insn_data[icode].operand[0].mode;
7573
7574 if (target == 0
7575 || GET_MODE (target) != tmode
7576 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7577 target = gen_reg_rtx (tmode);
f676971a 7578
a3170dc6
AH
7579 pat = GEN_FCN (icode) (target);
7580 if (! pat)
7581 return 0;
7582 emit_insn (pat);
7583 return target;
7584 case SPE_BUILTIN_MTSPEFSCR:
7585 icode = CODE_FOR_spe_mtspefscr;
7586 arg0 = TREE_VALUE (arglist);
84217346 7587 op0 = expand_normal (arg0);
a3170dc6
AH
7588 mode0 = insn_data[icode].operand[0].mode;
7589
7590 if (arg0 == error_mark_node)
7591 return const0_rtx;
7592
7593 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7594 op0 = copy_to_mode_reg (mode0, op0);
7595
7596 pat = GEN_FCN (icode) (op0);
7597 if (pat)
7598 emit_insn (pat);
7599 return NULL_RTX;
7600 default:
7601 break;
7602 }
7603
7604 *expandedp = false;
7605 return NULL_RTX;
7606}
7607
7608static rtx
a2369ed3 7609spe_expand_predicate_builtin (enum insn_code icode, tree arglist, rtx target)
a3170dc6
AH
7610{
7611 rtx pat, scratch, tmp;
7612 tree form = TREE_VALUE (arglist);
7613 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
7614 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
84217346
MD
7615 rtx op0 = expand_normal (arg0);
7616 rtx op1 = expand_normal (arg1);
a3170dc6
AH
7617 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7618 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7619 int form_int;
7620 enum rtx_code code;
7621
7622 if (TREE_CODE (form) != INTEGER_CST)
7623 {
7624 error ("argument 1 of __builtin_spe_predicate must be a constant");
7625 return const0_rtx;
7626 }
7627 else
7628 form_int = TREE_INT_CST_LOW (form);
7629
37409796 7630 gcc_assert (mode0 == mode1);
a3170dc6
AH
7631
7632 if (arg0 == error_mark_node || arg1 == error_mark_node)
7633 return const0_rtx;
7634
7635 if (target == 0
7636 || GET_MODE (target) != SImode
7637 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
7638 target = gen_reg_rtx (SImode);
7639
7640 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7641 op0 = copy_to_mode_reg (mode0, op0);
7642 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7643 op1 = copy_to_mode_reg (mode1, op1);
7644
7645 scratch = gen_reg_rtx (CCmode);
7646
7647 pat = GEN_FCN (icode) (scratch, op0, op1);
7648 if (! pat)
7649 return const0_rtx;
7650 emit_insn (pat);
7651
7652 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
7653 _lower_. We use one compare, but look in different bits of the
7654 CR for each variant.
7655
7656 There are 2 elements in each SPE simd type (upper/lower). The CR
7657 bits are set as follows:
7658
7659 BIT0 | BIT 1 | BIT 2 | BIT 3
7660 U | L | (U | L) | (U & L)
7661
7662 So, for an "all" relationship, BIT 3 would be set.
7663 For an "any" relationship, BIT 2 would be set. Etc.
7664
7665 Following traditional nomenclature, these bits map to:
7666
7667 BIT0 | BIT 1 | BIT 2 | BIT 3
7668 LT | GT | EQ | OV
7669
7670 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
7671 */
7672
7673 switch (form_int)
7674 {
7675 /* All variant. OV bit. */
7676 case 0:
7677 /* We need to get to the OV bit, which is the ORDERED bit. We
7678 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
992d08b1 7679 that's ugly and will make validate_condition_mode die.
a3170dc6
AH
7680 So let's just use another pattern. */
7681 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
7682 return target;
7683 /* Any variant. EQ bit. */
7684 case 1:
7685 code = EQ;
7686 break;
7687 /* Upper variant. LT bit. */
7688 case 2:
7689 code = LT;
7690 break;
7691 /* Lower variant. GT bit. */
7692 case 3:
7693 code = GT;
7694 break;
7695 default:
7696 error ("argument 1 of __builtin_spe_predicate is out of range");
7697 return const0_rtx;
7698 }
7699
7700 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
7701 emit_move_insn (target, tmp);
7702
7703 return target;
7704}
7705
7706/* The evsel builtins look like this:
7707
7708 e = __builtin_spe_evsel_OP (a, b, c, d);
7709
7710 and work like this:
7711
7712 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
7713 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
7714*/
7715
7716static rtx
a2369ed3 7717spe_expand_evsel_builtin (enum insn_code icode, tree arglist, rtx target)
a3170dc6
AH
7718{
7719 rtx pat, scratch;
7720 tree arg0 = TREE_VALUE (arglist);
7721 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
7722 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
7723 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
84217346
MD
7724 rtx op0 = expand_normal (arg0);
7725 rtx op1 = expand_normal (arg1);
7726 rtx op2 = expand_normal (arg2);
7727 rtx op3 = expand_normal (arg3);
a3170dc6
AH
7728 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7729 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7730
37409796 7731 gcc_assert (mode0 == mode1);
a3170dc6
AH
7732
7733 if (arg0 == error_mark_node || arg1 == error_mark_node
7734 || arg2 == error_mark_node || arg3 == error_mark_node)
7735 return const0_rtx;
7736
7737 if (target == 0
7738 || GET_MODE (target) != mode0
7739 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
7740 target = gen_reg_rtx (mode0);
7741
7742 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7743 op0 = copy_to_mode_reg (mode0, op0);
7744 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7745 op1 = copy_to_mode_reg (mode0, op1);
7746 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7747 op2 = copy_to_mode_reg (mode0, op2);
7748 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
7749 op3 = copy_to_mode_reg (mode0, op3);
7750
7751 /* Generate the compare. */
7752 scratch = gen_reg_rtx (CCmode);
7753 pat = GEN_FCN (icode) (scratch, op0, op1);
7754 if (! pat)
7755 return const0_rtx;
7756 emit_insn (pat);
7757
7758 if (mode0 == V2SImode)
7759 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
7760 else
7761 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
7762
7763 return target;
7764}
7765
0ac081f6
AH
7766/* Expand an expression EXP that calls a built-in function,
7767 with result going to TARGET if that's convenient
7768 (and in mode MODE if that's convenient).
7769 SUBTARGET may be used as the target for computing one of EXP's operands.
7770 IGNORE is nonzero if the value is to be ignored. */
7771
7772static rtx
a2369ed3 7773rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
c4ad648e
AM
7774 enum machine_mode mode ATTRIBUTE_UNUSED,
7775 int ignore ATTRIBUTE_UNUSED)
0ac081f6 7776{
92898235
AH
7777 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
7778 tree arglist = TREE_OPERAND (exp, 1);
7779 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7780 struct builtin_description *d;
7781 size_t i;
7782 rtx ret;
7783 bool success;
f676971a 7784
7ccf35ed
DN
7785 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
7786 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
7787 {
7788 int icode = (int) CODE_FOR_altivec_lvsr;
7789 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7790 enum machine_mode mode = insn_data[icode].operand[1].mode;
7791 tree arg;
7792 rtx op, addr, pat;
7793
37409796 7794 gcc_assert (TARGET_ALTIVEC);
7ccf35ed
DN
7795
7796 arg = TREE_VALUE (arglist);
37409796 7797 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
7ccf35ed
DN
7798 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
7799 addr = memory_address (mode, op);
7800 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
7801 op = addr;
7802 else
7803 {
7804 /* For the load case need to negate the address. */
7805 op = gen_reg_rtx (GET_MODE (addr));
7806 emit_insn (gen_rtx_SET (VOIDmode, op,
7807 gen_rtx_NEG (GET_MODE (addr), addr)));
c4ad648e 7808 }
7ccf35ed
DN
7809 op = gen_rtx_MEM (mode, op);
7810
7811 if (target == 0
7812 || GET_MODE (target) != tmode
7813 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7814 target = gen_reg_rtx (tmode);
7815
7816 /*pat = gen_altivec_lvsr (target, op);*/
7817 pat = GEN_FCN (icode) (target, op);
7818 if (!pat)
7819 return 0;
7820 emit_insn (pat);
7821
7822 return target;
7823 }
7824
0ac081f6 7825 if (TARGET_ALTIVEC)
92898235
AH
7826 {
7827 ret = altivec_expand_builtin (exp, target, &success);
7828
a3170dc6
AH
7829 if (success)
7830 return ret;
7831 }
7832 if (TARGET_SPE)
7833 {
7834 ret = spe_expand_builtin (exp, target, &success);
7835
92898235
AH
7836 if (success)
7837 return ret;
7838 }
7839
37409796 7840 gcc_assert (TARGET_ALTIVEC || TARGET_SPE);
bb8df8a6 7841
37409796
NS
7842 /* Handle simple unary operations. */
7843 d = (struct builtin_description *) bdesc_1arg;
7844 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
7845 if (d->code == fcode)
7846 return rs6000_expand_unop_builtin (d->icode, arglist, target);
bb8df8a6 7847
37409796
NS
7848 /* Handle simple binary operations. */
7849 d = (struct builtin_description *) bdesc_2arg;
7850 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
7851 if (d->code == fcode)
7852 return rs6000_expand_binop_builtin (d->icode, arglist, target);
0ac081f6 7853
37409796
NS
7854 /* Handle simple ternary operations. */
7855 d = (struct builtin_description *) bdesc_3arg;
7856 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
7857 if (d->code == fcode)
7858 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
bb8df8a6 7859
37409796 7860 gcc_unreachable ();
0ac081f6
AH
7861}
7862
7c62e993
PB
7863static tree
7864build_opaque_vector_type (tree node, int nunits)
7865{
7866 node = copy_node (node);
7867 TYPE_MAIN_VARIANT (node) = node;
7868 return build_vector_type (node, nunits);
7869}
7870
0ac081f6 7871static void
863d938c 7872rs6000_init_builtins (void)
0ac081f6 7873{
4a5eab38
PB
7874 V2SI_type_node = build_vector_type (intSI_type_node, 2);
7875 V2SF_type_node = build_vector_type (float_type_node, 2);
7876 V4HI_type_node = build_vector_type (intHI_type_node, 4);
7877 V4SI_type_node = build_vector_type (intSI_type_node, 4);
7878 V4SF_type_node = build_vector_type (float_type_node, 4);
7e463bda 7879 V8HI_type_node = build_vector_type (intHI_type_node, 8);
4a5eab38
PB
7880 V16QI_type_node = build_vector_type (intQI_type_node, 16);
7881
7882 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
7883 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
7884 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
7885
7c62e993
PB
7886 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
7887 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
6035d635 7888 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
58646b77 7889 opaque_V4SI_type_node = copy_node (V4SI_type_node);
3fdaa45a 7890
8bb418a3
ZL
7891 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
7892 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
7893 'vector unsigned short'. */
7894
8dd16ecc
NS
7895 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
7896 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
7897 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
7898 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8bb418a3 7899
58646b77
PB
7900 long_integer_type_internal_node = long_integer_type_node;
7901 long_unsigned_type_internal_node = long_unsigned_type_node;
7902 intQI_type_internal_node = intQI_type_node;
7903 uintQI_type_internal_node = unsigned_intQI_type_node;
7904 intHI_type_internal_node = intHI_type_node;
7905 uintHI_type_internal_node = unsigned_intHI_type_node;
7906 intSI_type_internal_node = intSI_type_node;
7907 uintSI_type_internal_node = unsigned_intSI_type_node;
7908 float_type_internal_node = float_type_node;
7909 void_type_internal_node = void_type_node;
7910
8bb418a3
ZL
7911 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7912 get_identifier ("__bool char"),
7913 bool_char_type_node));
7914 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7915 get_identifier ("__bool short"),
7916 bool_short_type_node));
7917 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7918 get_identifier ("__bool int"),
7919 bool_int_type_node));
7920 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7921 get_identifier ("__pixel"),
7922 pixel_type_node));
7923
4a5eab38
PB
7924 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
7925 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
7926 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
7927 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
8bb418a3
ZL
7928
7929 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7930 get_identifier ("__vector unsigned char"),
7931 unsigned_V16QI_type_node));
7932 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7933 get_identifier ("__vector signed char"),
7934 V16QI_type_node));
7935 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7936 get_identifier ("__vector __bool char"),
7937 bool_V16QI_type_node));
7938
7939 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7940 get_identifier ("__vector unsigned short"),
7941 unsigned_V8HI_type_node));
7942 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7943 get_identifier ("__vector signed short"),
7944 V8HI_type_node));
7945 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7946 get_identifier ("__vector __bool short"),
7947 bool_V8HI_type_node));
7948
7949 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7950 get_identifier ("__vector unsigned int"),
7951 unsigned_V4SI_type_node));
7952 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7953 get_identifier ("__vector signed int"),
7954 V4SI_type_node));
7955 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7956 get_identifier ("__vector __bool int"),
7957 bool_V4SI_type_node));
7958
7959 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7960 get_identifier ("__vector float"),
7961 V4SF_type_node));
7962 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
7963 get_identifier ("__vector __pixel"),
7964 pixel_V8HI_type_node));
7965
a3170dc6 7966 if (TARGET_SPE)
3fdaa45a 7967 spe_init_builtins ();
0ac081f6
AH
7968 if (TARGET_ALTIVEC)
7969 altivec_init_builtins ();
0559cc77
DE
7970 if (TARGET_ALTIVEC || TARGET_SPE)
7971 rs6000_common_init_builtins ();
69ca3549
DE
7972
7973#if TARGET_XCOFF
7974 /* AIX libm provides clog as __clog. */
7975 if (built_in_decls [BUILT_IN_CLOG])
7976 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
7977#endif
0ac081f6
AH
7978}
7979
a3170dc6
AH
7980/* Search through a set of builtins and enable the mask bits.
7981 DESC is an array of builtins.
b6d08ca1 7982 SIZE is the total number of builtins.
a3170dc6
AH
7983 START is the builtin enum at which to start.
7984 END is the builtin enum at which to end. */
0ac081f6 7985static void
a2369ed3 7986enable_mask_for_builtins (struct builtin_description *desc, int size,
f676971a 7987 enum rs6000_builtins start,
a2369ed3 7988 enum rs6000_builtins end)
a3170dc6
AH
7989{
7990 int i;
7991
7992 for (i = 0; i < size; ++i)
7993 if (desc[i].code == start)
7994 break;
7995
7996 if (i == size)
7997 return;
7998
7999 for (; i < size; ++i)
8000 {
8001 /* Flip all the bits on. */
8002 desc[i].mask = target_flags;
8003 if (desc[i].code == end)
8004 break;
8005 }
8006}
8007
8008static void
863d938c 8009spe_init_builtins (void)
0ac081f6 8010{
a3170dc6
AH
8011 tree endlink = void_list_node;
8012 tree puint_type_node = build_pointer_type (unsigned_type_node);
8013 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
ae4b4a02 8014 struct builtin_description *d;
0ac081f6
AH
8015 size_t i;
8016
a3170dc6
AH
8017 tree v2si_ftype_4_v2si
8018 = build_function_type
3fdaa45a
AH
8019 (opaque_V2SI_type_node,
8020 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8021 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8022 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8023 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8024 endlink)))));
8025
8026 tree v2sf_ftype_4_v2sf
8027 = build_function_type
3fdaa45a
AH
8028 (opaque_V2SF_type_node,
8029 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8030 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8031 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8032 tree_cons (NULL_TREE, opaque_V2SF_type_node,
a3170dc6
AH
8033 endlink)))));
8034
8035 tree int_ftype_int_v2si_v2si
8036 = build_function_type
8037 (integer_type_node,
8038 tree_cons (NULL_TREE, integer_type_node,
3fdaa45a
AH
8039 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8040 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8041 endlink))));
8042
8043 tree int_ftype_int_v2sf_v2sf
8044 = build_function_type
8045 (integer_type_node,
8046 tree_cons (NULL_TREE, integer_type_node,
3fdaa45a
AH
8047 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8048 tree_cons (NULL_TREE, opaque_V2SF_type_node,
a3170dc6
AH
8049 endlink))));
8050
8051 tree void_ftype_v2si_puint_int
8052 = build_function_type (void_type_node,
3fdaa45a 8053 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8054 tree_cons (NULL_TREE, puint_type_node,
8055 tree_cons (NULL_TREE,
8056 integer_type_node,
8057 endlink))));
8058
8059 tree void_ftype_v2si_puint_char
8060 = build_function_type (void_type_node,
3fdaa45a 8061 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8062 tree_cons (NULL_TREE, puint_type_node,
8063 tree_cons (NULL_TREE,
8064 char_type_node,
8065 endlink))));
8066
8067 tree void_ftype_v2si_pv2si_int
8068 = build_function_type (void_type_node,
3fdaa45a 8069 tree_cons (NULL_TREE, opaque_V2SI_type_node,
6035d635 8070 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
a3170dc6
AH
8071 tree_cons (NULL_TREE,
8072 integer_type_node,
8073 endlink))));
8074
8075 tree void_ftype_v2si_pv2si_char
8076 = build_function_type (void_type_node,
3fdaa45a 8077 tree_cons (NULL_TREE, opaque_V2SI_type_node,
6035d635 8078 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
a3170dc6
AH
8079 tree_cons (NULL_TREE,
8080 char_type_node,
8081 endlink))));
8082
8083 tree void_ftype_int
8084 = build_function_type (void_type_node,
8085 tree_cons (NULL_TREE, integer_type_node, endlink));
8086
8087 tree int_ftype_void
36e8d515 8088 = build_function_type (integer_type_node, endlink);
a3170dc6
AH
8089
8090 tree v2si_ftype_pv2si_int
3fdaa45a 8091 = build_function_type (opaque_V2SI_type_node,
6035d635 8092 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
a3170dc6
AH
8093 tree_cons (NULL_TREE, integer_type_node,
8094 endlink)));
8095
8096 tree v2si_ftype_puint_int
3fdaa45a 8097 = build_function_type (opaque_V2SI_type_node,
a3170dc6
AH
8098 tree_cons (NULL_TREE, puint_type_node,
8099 tree_cons (NULL_TREE, integer_type_node,
8100 endlink)));
8101
8102 tree v2si_ftype_pushort_int
3fdaa45a 8103 = build_function_type (opaque_V2SI_type_node,
a3170dc6
AH
8104 tree_cons (NULL_TREE, pushort_type_node,
8105 tree_cons (NULL_TREE, integer_type_node,
8106 endlink)));
8107
00332c9f
AH
8108 tree v2si_ftype_signed_char
8109 = build_function_type (opaque_V2SI_type_node,
8110 tree_cons (NULL_TREE, signed_char_type_node,
8111 endlink));
8112
a3170dc6
AH
8113 /* The initialization of the simple binary and unary builtins is
8114 done in rs6000_common_init_builtins, but we have to enable the
8115 mask bits here manually because we have run out of `target_flags'
8116 bits. We really need to redesign this mask business. */
8117
8118 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
8119 ARRAY_SIZE (bdesc_2arg),
8120 SPE_BUILTIN_EVADDW,
8121 SPE_BUILTIN_EVXOR);
8122 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
8123 ARRAY_SIZE (bdesc_1arg),
8124 SPE_BUILTIN_EVABS,
8125 SPE_BUILTIN_EVSUBFUSIAAW);
8126 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
8127 ARRAY_SIZE (bdesc_spe_predicates),
8128 SPE_BUILTIN_EVCMPEQ,
8129 SPE_BUILTIN_EVFSTSTLT);
8130 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
8131 ARRAY_SIZE (bdesc_spe_evsel),
8132 SPE_BUILTIN_EVSEL_CMPGTS,
8133 SPE_BUILTIN_EVSEL_FSTSTEQ);
8134
36252949
AH
8135 (*lang_hooks.decls.pushdecl)
8136 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
8137 opaque_V2SI_type_node));
8138
a3170dc6 8139 /* Initialize irregular SPE builtins. */
f676971a 8140
a3170dc6
AH
8141 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
8142 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
8143 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
8144 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
8145 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
8146 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
8147 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
8148 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
8149 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
8150 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
8151 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
8152 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
8153 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
8154 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
8155 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
8156 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
00332c9f
AH
8157 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
8158 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
a3170dc6
AH
8159
8160 /* Loads. */
8161 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
8162 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
8163 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
8164 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
8165 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
8166 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
8167 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
8168 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
8169 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
8170 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
8171 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
8172 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
8173 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
8174 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
8175 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
8176 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
8177 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
8178 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
8179 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
8180 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
8181 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
8182 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
8183
8184 /* Predicates. */
8185 d = (struct builtin_description *) bdesc_spe_predicates;
8186 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
8187 {
8188 tree type;
8189
8190 switch (insn_data[d->icode].operand[1].mode)
8191 {
8192 case V2SImode:
8193 type = int_ftype_int_v2si_v2si;
8194 break;
8195 case V2SFmode:
8196 type = int_ftype_int_v2sf_v2sf;
8197 break;
8198 default:
37409796 8199 gcc_unreachable ();
a3170dc6
AH
8200 }
8201
8202 def_builtin (d->mask, d->name, type, d->code);
8203 }
8204
8205 /* Evsel predicates. */
8206 d = (struct builtin_description *) bdesc_spe_evsel;
8207 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
8208 {
8209 tree type;
8210
8211 switch (insn_data[d->icode].operand[1].mode)
8212 {
8213 case V2SImode:
8214 type = v2si_ftype_4_v2si;
8215 break;
8216 case V2SFmode:
8217 type = v2sf_ftype_4_v2sf;
8218 break;
8219 default:
37409796 8220 gcc_unreachable ();
a3170dc6
AH
8221 }
8222
8223 def_builtin (d->mask, d->name, type, d->code);
8224 }
8225}
8226
8227static void
863d938c 8228altivec_init_builtins (void)
a3170dc6
AH
8229{
8230 struct builtin_description *d;
8231 struct builtin_description_predicates *dp;
8232 size_t i;
7a4eca66
DE
8233 tree ftype;
8234
a3170dc6
AH
8235 tree pfloat_type_node = build_pointer_type (float_type_node);
8236 tree pint_type_node = build_pointer_type (integer_type_node);
8237 tree pshort_type_node = build_pointer_type (short_integer_type_node);
8238 tree pchar_type_node = build_pointer_type (char_type_node);
8239
8240 tree pvoid_type_node = build_pointer_type (void_type_node);
8241
0dbc3651
ZW
8242 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
8243 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
8244 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
8245 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
8246
8247 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
8248
58646b77
PB
8249 tree int_ftype_opaque
8250 = build_function_type_list (integer_type_node,
8251 opaque_V4SI_type_node, NULL_TREE);
8252
8253 tree opaque_ftype_opaque_int
8254 = build_function_type_list (opaque_V4SI_type_node,
8255 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
8256 tree opaque_ftype_opaque_opaque_int
8257 = build_function_type_list (opaque_V4SI_type_node,
8258 opaque_V4SI_type_node, opaque_V4SI_type_node,
8259 integer_type_node, NULL_TREE);
8260 tree int_ftype_int_opaque_opaque
8261 = build_function_type_list (integer_type_node,
8262 integer_type_node, opaque_V4SI_type_node,
8263 opaque_V4SI_type_node, NULL_TREE);
a3170dc6
AH
8264 tree int_ftype_int_v4si_v4si
8265 = build_function_type_list (integer_type_node,
8266 integer_type_node, V4SI_type_node,
8267 V4SI_type_node, NULL_TREE);
0dbc3651
ZW
8268 tree v4sf_ftype_pcfloat
8269 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
a3170dc6 8270 tree void_ftype_pfloat_v4sf
b4de2f7d 8271 = build_function_type_list (void_type_node,
a3170dc6 8272 pfloat_type_node, V4SF_type_node, NULL_TREE);
0dbc3651
ZW
8273 tree v4si_ftype_pcint
8274 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
8275 tree void_ftype_pint_v4si
b4de2f7d
AH
8276 = build_function_type_list (void_type_node,
8277 pint_type_node, V4SI_type_node, NULL_TREE);
0dbc3651
ZW
8278 tree v8hi_ftype_pcshort
8279 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
f18c054f 8280 tree void_ftype_pshort_v8hi
b4de2f7d
AH
8281 = build_function_type_list (void_type_node,
8282 pshort_type_node, V8HI_type_node, NULL_TREE);
0dbc3651
ZW
8283 tree v16qi_ftype_pcchar
8284 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
f18c054f 8285 tree void_ftype_pchar_v16qi
b4de2f7d
AH
8286 = build_function_type_list (void_type_node,
8287 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 8288 tree void_ftype_v4si
b4de2f7d 8289 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
8290 tree v8hi_ftype_void
8291 = build_function_type (V8HI_type_node, void_list_node);
8292 tree void_ftype_void
8293 = build_function_type (void_type_node, void_list_node);
e34b6648
JJ
8294 tree void_ftype_int
8295 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
0dbc3651 8296
58646b77
PB
8297 tree opaque_ftype_long_pcvoid
8298 = build_function_type_list (opaque_V4SI_type_node,
8299 long_integer_type_node, pcvoid_type_node, NULL_TREE);
b4a62fa0 8300 tree v16qi_ftype_long_pcvoid
a3170dc6 8301 = build_function_type_list (V16QI_type_node,
b4a62fa0
SB
8302 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8303 tree v8hi_ftype_long_pcvoid
a3170dc6 8304 = build_function_type_list (V8HI_type_node,
b4a62fa0
SB
8305 long_integer_type_node, pcvoid_type_node, NULL_TREE);
8306 tree v4si_ftype_long_pcvoid
a3170dc6 8307 = build_function_type_list (V4SI_type_node,
b4a62fa0 8308 long_integer_type_node, pcvoid_type_node, NULL_TREE);
0dbc3651 8309
58646b77
PB
8310 tree void_ftype_opaque_long_pvoid
8311 = build_function_type_list (void_type_node,
8312 opaque_V4SI_type_node, long_integer_type_node,
8313 pvoid_type_node, NULL_TREE);
b4a62fa0 8314 tree void_ftype_v4si_long_pvoid
b4de2f7d 8315 = build_function_type_list (void_type_node,
b4a62fa0 8316 V4SI_type_node, long_integer_type_node,
b4de2f7d 8317 pvoid_type_node, NULL_TREE);
b4a62fa0 8318 tree void_ftype_v16qi_long_pvoid
b4de2f7d 8319 = build_function_type_list (void_type_node,
b4a62fa0 8320 V16QI_type_node, long_integer_type_node,
b4de2f7d 8321 pvoid_type_node, NULL_TREE);
b4a62fa0 8322 tree void_ftype_v8hi_long_pvoid
b4de2f7d 8323 = build_function_type_list (void_type_node,
b4a62fa0 8324 V8HI_type_node, long_integer_type_node,
b4de2f7d 8325 pvoid_type_node, NULL_TREE);
a3170dc6
AH
8326 tree int_ftype_int_v8hi_v8hi
8327 = build_function_type_list (integer_type_node,
8328 integer_type_node, V8HI_type_node,
8329 V8HI_type_node, NULL_TREE);
8330 tree int_ftype_int_v16qi_v16qi
8331 = build_function_type_list (integer_type_node,
8332 integer_type_node, V16QI_type_node,
8333 V16QI_type_node, NULL_TREE);
8334 tree int_ftype_int_v4sf_v4sf
8335 = build_function_type_list (integer_type_node,
8336 integer_type_node, V4SF_type_node,
8337 V4SF_type_node, NULL_TREE);
8338 tree v4si_ftype_v4si
8339 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
8340 tree v8hi_ftype_v8hi
8341 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
8342 tree v16qi_ftype_v16qi
8343 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
8344 tree v4sf_ftype_v4sf
8345 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8bb418a3 8346 tree void_ftype_pcvoid_int_int
a3170dc6 8347 = build_function_type_list (void_type_node,
0dbc3651 8348 pcvoid_type_node, integer_type_node,
8bb418a3 8349 integer_type_node, NULL_TREE);
8bb418a3 8350
0dbc3651
ZW
8351 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
8352 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
8353 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
8354 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
8355 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
8356 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
8357 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
8358 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
8359 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
8360 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
8361 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
8362 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
8363 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
8364 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
8365 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
8366 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
a3170dc6
AH
8367 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
8368 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
8369 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
e34b6648 8370 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
b4a62fa0
SB
8371 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
8372 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
8373 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
8374 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
8375 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
8376 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
8377 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
8378 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
8379 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
8380 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
8381 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
8382 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
58646b77
PB
8383 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
8384 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
8385 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
8386 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
8387 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
8388 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
8389 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
8390 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
8391 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
8392 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
8393 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
8394 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
8395 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
8396 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
8397
8398 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
8399
8400 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
8401 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
8402 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
8403 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
8404 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
8405 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
8406 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
8407 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
8408 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
8409 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
8bb418a3 8410
a3170dc6
AH
8411 /* Add the DST variants. */
8412 d = (struct builtin_description *) bdesc_dst;
8413 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8bb418a3 8414 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
a3170dc6
AH
8415
8416 /* Initialize the predicates. */
8417 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
8418 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
8419 {
8420 enum machine_mode mode1;
8421 tree type;
58646b77
PB
8422 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8423 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
a3170dc6 8424
58646b77
PB
8425 if (is_overloaded)
8426 mode1 = VOIDmode;
8427 else
8428 mode1 = insn_data[dp->icode].operand[1].mode;
a3170dc6
AH
8429
8430 switch (mode1)
8431 {
58646b77
PB
8432 case VOIDmode:
8433 type = int_ftype_int_opaque_opaque;
8434 break;
a3170dc6
AH
8435 case V4SImode:
8436 type = int_ftype_int_v4si_v4si;
8437 break;
8438 case V8HImode:
8439 type = int_ftype_int_v8hi_v8hi;
8440 break;
8441 case V16QImode:
8442 type = int_ftype_int_v16qi_v16qi;
8443 break;
8444 case V4SFmode:
8445 type = int_ftype_int_v4sf_v4sf;
8446 break;
8447 default:
37409796 8448 gcc_unreachable ();
a3170dc6 8449 }
f676971a 8450
a3170dc6
AH
8451 def_builtin (dp->mask, dp->name, type, dp->code);
8452 }
8453
8454 /* Initialize the abs* operators. */
8455 d = (struct builtin_description *) bdesc_abs;
8456 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
8457 {
8458 enum machine_mode mode0;
8459 tree type;
8460
8461 mode0 = insn_data[d->icode].operand[0].mode;
8462
8463 switch (mode0)
8464 {
8465 case V4SImode:
8466 type = v4si_ftype_v4si;
8467 break;
8468 case V8HImode:
8469 type = v8hi_ftype_v8hi;
8470 break;
8471 case V16QImode:
8472 type = v16qi_ftype_v16qi;
8473 break;
8474 case V4SFmode:
8475 type = v4sf_ftype_v4sf;
8476 break;
8477 default:
37409796 8478 gcc_unreachable ();
a3170dc6 8479 }
f676971a 8480
a3170dc6
AH
8481 def_builtin (d->mask, d->name, type, d->code);
8482 }
7ccf35ed 8483
13c62176
DN
8484 if (TARGET_ALTIVEC)
8485 {
8486 tree decl;
8487
8488 /* Initialize target builtin that implements
8489 targetm.vectorize.builtin_mask_for_load. */
8490
8491 decl = lang_hooks.builtin_function ("__builtin_altivec_mask_for_load",
8bb46326
DN
8492 v16qi_ftype_long_pcvoid,
8493 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
8494 BUILT_IN_MD, NULL,
8495 tree_cons (get_identifier ("const"),
8496 NULL_TREE, NULL_TREE));
13c62176
DN
8497 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
8498 altivec_builtin_mask_for_load = decl;
13c62176 8499 }
7a4eca66
DE
8500
8501 /* Access to the vec_init patterns. */
8502 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
8503 integer_type_node, integer_type_node,
8504 integer_type_node, NULL_TREE);
8505 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
8506 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
8507
8508 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
8509 short_integer_type_node,
8510 short_integer_type_node,
8511 short_integer_type_node,
8512 short_integer_type_node,
8513 short_integer_type_node,
8514 short_integer_type_node,
8515 short_integer_type_node, NULL_TREE);
8516 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
8517 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
8518
8519 ftype = build_function_type_list (V16QI_type_node, char_type_node,
8520 char_type_node, char_type_node,
8521 char_type_node, char_type_node,
8522 char_type_node, char_type_node,
8523 char_type_node, char_type_node,
8524 char_type_node, char_type_node,
8525 char_type_node, char_type_node,
8526 char_type_node, char_type_node,
8527 char_type_node, NULL_TREE);
8528 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
8529 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
8530
8531 ftype = build_function_type_list (V4SF_type_node, float_type_node,
8532 float_type_node, float_type_node,
8533 float_type_node, NULL_TREE);
8534 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
8535 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
8536
8537 /* Access to the vec_set patterns. */
8538 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
8539 intSI_type_node,
8540 integer_type_node, NULL_TREE);
8541 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
8542 ALTIVEC_BUILTIN_VEC_SET_V4SI);
8543
8544 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
8545 intHI_type_node,
8546 integer_type_node, NULL_TREE);
8547 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
8548 ALTIVEC_BUILTIN_VEC_SET_V8HI);
8549
8550 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
8551 intQI_type_node,
8552 integer_type_node, NULL_TREE);
8553 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
8554 ALTIVEC_BUILTIN_VEC_SET_V16QI);
8555
8556 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
8557 float_type_node,
8558 integer_type_node, NULL_TREE);
8559 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
8560 ALTIVEC_BUILTIN_VEC_SET_V4SF);
8561
8562 /* Access to the vec_extract patterns. */
8563 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
8564 integer_type_node, NULL_TREE);
8565 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
8566 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
8567
8568 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
8569 integer_type_node, NULL_TREE);
8570 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
8571 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
8572
8573 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
8574 integer_type_node, NULL_TREE);
8575 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
8576 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
8577
8578 ftype = build_function_type_list (float_type_node, V4SF_type_node,
8579 integer_type_node, NULL_TREE);
8580 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
8581 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
a3170dc6
AH
8582}
8583
8584static void
863d938c 8585rs6000_common_init_builtins (void)
a3170dc6
AH
8586{
8587 struct builtin_description *d;
8588 size_t i;
8589
8590 tree v4sf_ftype_v4sf_v4sf_v16qi
8591 = build_function_type_list (V4SF_type_node,
8592 V4SF_type_node, V4SF_type_node,
8593 V16QI_type_node, NULL_TREE);
8594 tree v4si_ftype_v4si_v4si_v16qi
8595 = build_function_type_list (V4SI_type_node,
8596 V4SI_type_node, V4SI_type_node,
8597 V16QI_type_node, NULL_TREE);
8598 tree v8hi_ftype_v8hi_v8hi_v16qi
8599 = build_function_type_list (V8HI_type_node,
8600 V8HI_type_node, V8HI_type_node,
8601 V16QI_type_node, NULL_TREE);
8602 tree v16qi_ftype_v16qi_v16qi_v16qi
8603 = build_function_type_list (V16QI_type_node,
8604 V16QI_type_node, V16QI_type_node,
8605 V16QI_type_node, NULL_TREE);
b9e4e5d1
ZL
8606 tree v4si_ftype_int
8607 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
8608 tree v8hi_ftype_int
8609 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
8610 tree v16qi_ftype_int
8611 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
a3170dc6
AH
8612 tree v8hi_ftype_v16qi
8613 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
8614 tree v4sf_ftype_v4sf
8615 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8616
8617 tree v2si_ftype_v2si_v2si
2abe3e28
AH
8618 = build_function_type_list (opaque_V2SI_type_node,
8619 opaque_V2SI_type_node,
8620 opaque_V2SI_type_node, NULL_TREE);
a3170dc6
AH
8621
8622 tree v2sf_ftype_v2sf_v2sf
2abe3e28
AH
8623 = build_function_type_list (opaque_V2SF_type_node,
8624 opaque_V2SF_type_node,
8625 opaque_V2SF_type_node, NULL_TREE);
a3170dc6
AH
8626
8627 tree v2si_ftype_int_int
2abe3e28 8628 = build_function_type_list (opaque_V2SI_type_node,
a3170dc6
AH
8629 integer_type_node, integer_type_node,
8630 NULL_TREE);
8631
58646b77
PB
8632 tree opaque_ftype_opaque
8633 = build_function_type_list (opaque_V4SI_type_node,
8634 opaque_V4SI_type_node, NULL_TREE);
8635
a3170dc6 8636 tree v2si_ftype_v2si
2abe3e28
AH
8637 = build_function_type_list (opaque_V2SI_type_node,
8638 opaque_V2SI_type_node, NULL_TREE);
a3170dc6
AH
8639
8640 tree v2sf_ftype_v2sf
2abe3e28
AH
8641 = build_function_type_list (opaque_V2SF_type_node,
8642 opaque_V2SF_type_node, NULL_TREE);
f676971a 8643
a3170dc6 8644 tree v2sf_ftype_v2si
2abe3e28
AH
8645 = build_function_type_list (opaque_V2SF_type_node,
8646 opaque_V2SI_type_node, NULL_TREE);
a3170dc6
AH
8647
8648 tree v2si_ftype_v2sf
2abe3e28
AH
8649 = build_function_type_list (opaque_V2SI_type_node,
8650 opaque_V2SF_type_node, NULL_TREE);
a3170dc6
AH
8651
8652 tree v2si_ftype_v2si_char
2abe3e28
AH
8653 = build_function_type_list (opaque_V2SI_type_node,
8654 opaque_V2SI_type_node,
8655 char_type_node, NULL_TREE);
a3170dc6
AH
8656
8657 tree v2si_ftype_int_char
2abe3e28 8658 = build_function_type_list (opaque_V2SI_type_node,
a3170dc6
AH
8659 integer_type_node, char_type_node, NULL_TREE);
8660
8661 tree v2si_ftype_char
2abe3e28
AH
8662 = build_function_type_list (opaque_V2SI_type_node,
8663 char_type_node, NULL_TREE);
a3170dc6
AH
8664
8665 tree int_ftype_int_int
8666 = build_function_type_list (integer_type_node,
8667 integer_type_node, integer_type_node,
8668 NULL_TREE);
95385cbb 8669
58646b77
PB
8670 tree opaque_ftype_opaque_opaque
8671 = build_function_type_list (opaque_V4SI_type_node,
8672 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
0ac081f6 8673 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
8674 = build_function_type_list (V4SI_type_node,
8675 V4SI_type_node, V4SI_type_node, NULL_TREE);
b9e4e5d1 8676 tree v4sf_ftype_v4si_int
b4de2f7d 8677 = build_function_type_list (V4SF_type_node,
b9e4e5d1
ZL
8678 V4SI_type_node, integer_type_node, NULL_TREE);
8679 tree v4si_ftype_v4sf_int
b4de2f7d 8680 = build_function_type_list (V4SI_type_node,
b9e4e5d1
ZL
8681 V4SF_type_node, integer_type_node, NULL_TREE);
8682 tree v4si_ftype_v4si_int
b4de2f7d 8683 = build_function_type_list (V4SI_type_node,
b9e4e5d1
ZL
8684 V4SI_type_node, integer_type_node, NULL_TREE);
8685 tree v8hi_ftype_v8hi_int
b4de2f7d 8686 = build_function_type_list (V8HI_type_node,
b9e4e5d1
ZL
8687 V8HI_type_node, integer_type_node, NULL_TREE);
8688 tree v16qi_ftype_v16qi_int
b4de2f7d 8689 = build_function_type_list (V16QI_type_node,
b9e4e5d1
ZL
8690 V16QI_type_node, integer_type_node, NULL_TREE);
8691 tree v16qi_ftype_v16qi_v16qi_int
b4de2f7d
AH
8692 = build_function_type_list (V16QI_type_node,
8693 V16QI_type_node, V16QI_type_node,
b9e4e5d1
ZL
8694 integer_type_node, NULL_TREE);
8695 tree v8hi_ftype_v8hi_v8hi_int
b4de2f7d
AH
8696 = build_function_type_list (V8HI_type_node,
8697 V8HI_type_node, V8HI_type_node,
b9e4e5d1
ZL
8698 integer_type_node, NULL_TREE);
8699 tree v4si_ftype_v4si_v4si_int
b4de2f7d
AH
8700 = build_function_type_list (V4SI_type_node,
8701 V4SI_type_node, V4SI_type_node,
b9e4e5d1
ZL
8702 integer_type_node, NULL_TREE);
8703 tree v4sf_ftype_v4sf_v4sf_int
b4de2f7d
AH
8704 = build_function_type_list (V4SF_type_node,
8705 V4SF_type_node, V4SF_type_node,
b9e4e5d1 8706 integer_type_node, NULL_TREE);
0ac081f6 8707 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
8708 = build_function_type_list (V4SF_type_node,
8709 V4SF_type_node, V4SF_type_node, NULL_TREE);
58646b77
PB
8710 tree opaque_ftype_opaque_opaque_opaque
8711 = build_function_type_list (opaque_V4SI_type_node,
8712 opaque_V4SI_type_node, opaque_V4SI_type_node,
8713 opaque_V4SI_type_node, NULL_TREE);
617e0e1d 8714 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
8715 = build_function_type_list (V4SF_type_node,
8716 V4SF_type_node, V4SF_type_node,
8717 V4SI_type_node, NULL_TREE);
2212663f 8718 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
8719 = build_function_type_list (V4SF_type_node,
8720 V4SF_type_node, V4SF_type_node,
8721 V4SF_type_node, NULL_TREE);
f676971a 8722 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
8723 = build_function_type_list (V4SI_type_node,
8724 V4SI_type_node, V4SI_type_node,
8725 V4SI_type_node, NULL_TREE);
0ac081f6 8726 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
8727 = build_function_type_list (V8HI_type_node,
8728 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 8729 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
8730 = build_function_type_list (V8HI_type_node,
8731 V8HI_type_node, V8HI_type_node,
8732 V8HI_type_node, NULL_TREE);
c4ad648e 8733 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
8734 = build_function_type_list (V4SI_type_node,
8735 V8HI_type_node, V8HI_type_node,
8736 V4SI_type_node, NULL_TREE);
c4ad648e 8737 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
8738 = build_function_type_list (V4SI_type_node,
8739 V16QI_type_node, V16QI_type_node,
8740 V4SI_type_node, NULL_TREE);
0ac081f6 8741 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
8742 = build_function_type_list (V16QI_type_node,
8743 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 8744 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
8745 = build_function_type_list (V4SI_type_node,
8746 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 8747 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
8748 = build_function_type_list (V8HI_type_node,
8749 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 8750 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
8751 = build_function_type_list (V4SI_type_node,
8752 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 8753 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
8754 = build_function_type_list (V8HI_type_node,
8755 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 8756 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
8757 = build_function_type_list (V16QI_type_node,
8758 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 8759 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
8760 = build_function_type_list (V4SI_type_node,
8761 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 8762 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
8763 = build_function_type_list (V4SI_type_node,
8764 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 8765 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
8766 = build_function_type_list (V4SI_type_node,
8767 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
8768 tree v4si_ftype_v8hi
8769 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
8770 tree int_ftype_v4si_v4si
8771 = build_function_type_list (integer_type_node,
8772 V4SI_type_node, V4SI_type_node, NULL_TREE);
8773 tree int_ftype_v4sf_v4sf
8774 = build_function_type_list (integer_type_node,
8775 V4SF_type_node, V4SF_type_node, NULL_TREE);
8776 tree int_ftype_v16qi_v16qi
8777 = build_function_type_list (integer_type_node,
8778 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 8779 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
8780 = build_function_type_list (integer_type_node,
8781 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 8782
6f317ef3 8783 /* Add the simple ternary operators. */
2212663f 8784 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 8785 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f 8786 {
2212663f
DB
8787 enum machine_mode mode0, mode1, mode2, mode3;
8788 tree type;
58646b77
PB
8789 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8790 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
2212663f 8791
58646b77
PB
8792 if (is_overloaded)
8793 {
8794 mode0 = VOIDmode;
8795 mode1 = VOIDmode;
8796 mode2 = VOIDmode;
8797 mode3 = VOIDmode;
8798 }
8799 else
8800 {
8801 if (d->name == 0 || d->icode == CODE_FOR_nothing)
8802 continue;
f676971a 8803
58646b77
PB
8804 mode0 = insn_data[d->icode].operand[0].mode;
8805 mode1 = insn_data[d->icode].operand[1].mode;
8806 mode2 = insn_data[d->icode].operand[2].mode;
8807 mode3 = insn_data[d->icode].operand[3].mode;
8808 }
bb8df8a6 8809
2212663f
DB
8810 /* When all four are of the same mode. */
8811 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
8812 {
8813 switch (mode0)
8814 {
58646b77
PB
8815 case VOIDmode:
8816 type = opaque_ftype_opaque_opaque_opaque;
8817 break;
617e0e1d
DB
8818 case V4SImode:
8819 type = v4si_ftype_v4si_v4si_v4si;
8820 break;
2212663f
DB
8821 case V4SFmode:
8822 type = v4sf_ftype_v4sf_v4sf_v4sf;
8823 break;
8824 case V8HImode:
8825 type = v8hi_ftype_v8hi_v8hi_v8hi;
f676971a 8826 break;
2212663f
DB
8827 case V16QImode:
8828 type = v16qi_ftype_v16qi_v16qi_v16qi;
f676971a 8829 break;
2212663f 8830 default:
37409796 8831 gcc_unreachable ();
2212663f
DB
8832 }
8833 }
8834 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
c4ad648e 8835 {
2212663f
DB
8836 switch (mode0)
8837 {
8838 case V4SImode:
8839 type = v4si_ftype_v4si_v4si_v16qi;
8840 break;
8841 case V4SFmode:
8842 type = v4sf_ftype_v4sf_v4sf_v16qi;
8843 break;
8844 case V8HImode:
8845 type = v8hi_ftype_v8hi_v8hi_v16qi;
f676971a 8846 break;
2212663f
DB
8847 case V16QImode:
8848 type = v16qi_ftype_v16qi_v16qi_v16qi;
f676971a 8849 break;
2212663f 8850 default:
37409796 8851 gcc_unreachable ();
2212663f
DB
8852 }
8853 }
f676971a 8854 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
2212663f 8855 && mode3 == V4SImode)
24408032 8856 type = v4si_ftype_v16qi_v16qi_v4si;
f676971a 8857 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
2212663f 8858 && mode3 == V4SImode)
24408032 8859 type = v4si_ftype_v8hi_v8hi_v4si;
f676971a 8860 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
617e0e1d 8861 && mode3 == V4SImode)
24408032
AH
8862 type = v4sf_ftype_v4sf_v4sf_v4si;
8863
8864 /* vchar, vchar, vchar, 4 bit literal. */
8865 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
8866 && mode3 == QImode)
b9e4e5d1 8867 type = v16qi_ftype_v16qi_v16qi_int;
24408032
AH
8868
8869 /* vshort, vshort, vshort, 4 bit literal. */
8870 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
8871 && mode3 == QImode)
b9e4e5d1 8872 type = v8hi_ftype_v8hi_v8hi_int;
24408032
AH
8873
8874 /* vint, vint, vint, 4 bit literal. */
8875 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
8876 && mode3 == QImode)
b9e4e5d1 8877 type = v4si_ftype_v4si_v4si_int;
24408032
AH
8878
8879 /* vfloat, vfloat, vfloat, 4 bit literal. */
8880 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
8881 && mode3 == QImode)
b9e4e5d1 8882 type = v4sf_ftype_v4sf_v4sf_int;
24408032 8883
2212663f 8884 else
37409796 8885 gcc_unreachable ();
2212663f
DB
8886
8887 def_builtin (d->mask, d->name, type, d->code);
8888 }
8889
0ac081f6 8890 /* Add the simple binary operators. */
00b960c7 8891 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 8892 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
8893 {
8894 enum machine_mode mode0, mode1, mode2;
8895 tree type;
58646b77
PB
8896 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8897 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
0ac081f6 8898
58646b77
PB
8899 if (is_overloaded)
8900 {
8901 mode0 = VOIDmode;
8902 mode1 = VOIDmode;
8903 mode2 = VOIDmode;
8904 }
8905 else
bb8df8a6 8906 {
58646b77
PB
8907 if (d->name == 0 || d->icode == CODE_FOR_nothing)
8908 continue;
f676971a 8909
58646b77
PB
8910 mode0 = insn_data[d->icode].operand[0].mode;
8911 mode1 = insn_data[d->icode].operand[1].mode;
8912 mode2 = insn_data[d->icode].operand[2].mode;
8913 }
0ac081f6
AH
8914
8915 /* When all three operands are of the same mode. */
8916 if (mode0 == mode1 && mode1 == mode2)
8917 {
8918 switch (mode0)
8919 {
58646b77
PB
8920 case VOIDmode:
8921 type = opaque_ftype_opaque_opaque;
8922 break;
0ac081f6
AH
8923 case V4SFmode:
8924 type = v4sf_ftype_v4sf_v4sf;
8925 break;
8926 case V4SImode:
8927 type = v4si_ftype_v4si_v4si;
8928 break;
8929 case V16QImode:
8930 type = v16qi_ftype_v16qi_v16qi;
8931 break;
8932 case V8HImode:
8933 type = v8hi_ftype_v8hi_v8hi;
8934 break;
a3170dc6
AH
8935 case V2SImode:
8936 type = v2si_ftype_v2si_v2si;
8937 break;
8938 case V2SFmode:
8939 type = v2sf_ftype_v2sf_v2sf;
8940 break;
8941 case SImode:
8942 type = int_ftype_int_int;
8943 break;
0ac081f6 8944 default:
37409796 8945 gcc_unreachable ();
0ac081f6
AH
8946 }
8947 }
8948
8949 /* A few other combos we really don't want to do manually. */
8950
8951 /* vint, vfloat, vfloat. */
8952 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
8953 type = v4si_ftype_v4sf_v4sf;
8954
8955 /* vshort, vchar, vchar. */
8956 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
8957 type = v8hi_ftype_v16qi_v16qi;
8958
8959 /* vint, vshort, vshort. */
8960 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
8961 type = v4si_ftype_v8hi_v8hi;
8962
8963 /* vshort, vint, vint. */
8964 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
8965 type = v8hi_ftype_v4si_v4si;
8966
8967 /* vchar, vshort, vshort. */
8968 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
8969 type = v16qi_ftype_v8hi_v8hi;
8970
8971 /* vint, vchar, vint. */
8972 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
8973 type = v4si_ftype_v16qi_v4si;
8974
fa066a23
AH
8975 /* vint, vchar, vchar. */
8976 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
8977 type = v4si_ftype_v16qi_v16qi;
8978
0ac081f6
AH
8979 /* vint, vshort, vint. */
8980 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
8981 type = v4si_ftype_v8hi_v4si;
f676971a 8982
2212663f
DB
8983 /* vint, vint, 5 bit literal. */
8984 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
b9e4e5d1 8985 type = v4si_ftype_v4si_int;
f676971a 8986
2212663f
DB
8987 /* vshort, vshort, 5 bit literal. */
8988 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
b9e4e5d1 8989 type = v8hi_ftype_v8hi_int;
f676971a 8990
2212663f
DB
8991 /* vchar, vchar, 5 bit literal. */
8992 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
b9e4e5d1 8993 type = v16qi_ftype_v16qi_int;
0ac081f6 8994
617e0e1d
DB
8995 /* vfloat, vint, 5 bit literal. */
8996 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
b9e4e5d1 8997 type = v4sf_ftype_v4si_int;
f676971a 8998
617e0e1d
DB
8999 /* vint, vfloat, 5 bit literal. */
9000 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
b9e4e5d1 9001 type = v4si_ftype_v4sf_int;
617e0e1d 9002
a3170dc6
AH
9003 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
9004 type = v2si_ftype_int_int;
9005
9006 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
9007 type = v2si_ftype_v2si_char;
9008
9009 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
9010 type = v2si_ftype_int_char;
9011
37409796 9012 else
0ac081f6 9013 {
37409796
NS
9014 /* int, x, x. */
9015 gcc_assert (mode0 == SImode);
0ac081f6
AH
9016 switch (mode1)
9017 {
9018 case V4SImode:
9019 type = int_ftype_v4si_v4si;
9020 break;
9021 case V4SFmode:
9022 type = int_ftype_v4sf_v4sf;
9023 break;
9024 case V16QImode:
9025 type = int_ftype_v16qi_v16qi;
9026 break;
9027 case V8HImode:
9028 type = int_ftype_v8hi_v8hi;
9029 break;
9030 default:
37409796 9031 gcc_unreachable ();
0ac081f6
AH
9032 }
9033 }
9034
2212663f
DB
9035 def_builtin (d->mask, d->name, type, d->code);
9036 }
24408032 9037
2212663f
DB
9038 /* Add the simple unary operators. */
9039 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 9040 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
9041 {
9042 enum machine_mode mode0, mode1;
9043 tree type;
58646b77
PB
9044 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9045 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
9046
9047 if (is_overloaded)
9048 {
9049 mode0 = VOIDmode;
9050 mode1 = VOIDmode;
9051 }
9052 else
9053 {
9054 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9055 continue;
bb8df8a6 9056
58646b77
PB
9057 mode0 = insn_data[d->icode].operand[0].mode;
9058 mode1 = insn_data[d->icode].operand[1].mode;
9059 }
2212663f
DB
9060
9061 if (mode0 == V4SImode && mode1 == QImode)
c4ad648e 9062 type = v4si_ftype_int;
2212663f 9063 else if (mode0 == V8HImode && mode1 == QImode)
c4ad648e 9064 type = v8hi_ftype_int;
2212663f 9065 else if (mode0 == V16QImode && mode1 == QImode)
c4ad648e 9066 type = v16qi_ftype_int;
58646b77
PB
9067 else if (mode0 == VOIDmode && mode1 == VOIDmode)
9068 type = opaque_ftype_opaque;
617e0e1d
DB
9069 else if (mode0 == V4SFmode && mode1 == V4SFmode)
9070 type = v4sf_ftype_v4sf;
20e26713
AH
9071 else if (mode0 == V8HImode && mode1 == V16QImode)
9072 type = v8hi_ftype_v16qi;
9073 else if (mode0 == V4SImode && mode1 == V8HImode)
9074 type = v4si_ftype_v8hi;
a3170dc6
AH
9075 else if (mode0 == V2SImode && mode1 == V2SImode)
9076 type = v2si_ftype_v2si;
9077 else if (mode0 == V2SFmode && mode1 == V2SFmode)
9078 type = v2sf_ftype_v2sf;
9079 else if (mode0 == V2SFmode && mode1 == V2SImode)
9080 type = v2sf_ftype_v2si;
9081 else if (mode0 == V2SImode && mode1 == V2SFmode)
9082 type = v2si_ftype_v2sf;
9083 else if (mode0 == V2SImode && mode1 == QImode)
9084 type = v2si_ftype_char;
2212663f 9085 else
37409796 9086 gcc_unreachable ();
2212663f 9087
0ac081f6
AH
9088 def_builtin (d->mask, d->name, type, d->code);
9089 }
9090}
9091
c15c90bb
ZW
9092static void
9093rs6000_init_libfuncs (void)
9094{
9095 if (!TARGET_HARD_FLOAT)
9096 return;
9097
602ea4d3
JJ
9098 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
9099 && !TARGET_POWER2 && !TARGET_POWERPC)
c15c90bb 9100 {
602ea4d3
JJ
9101 /* AIX library routines for float->int conversion. */
9102 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
9103 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
9104 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
9105 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
9106 }
c15c90bb 9107
602ea4d3 9108 if (!TARGET_IEEEQUAD)
98c41d98 9109 /* AIX/Darwin/64-bit Linux quad floating point routines. */
602ea4d3
JJ
9110 if (!TARGET_XL_COMPAT)
9111 {
9112 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
9113 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
9114 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
9115 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
9116 }
9117 else
9118 {
9119 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
9120 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
9121 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
9122 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
9123 }
c9034561 9124 else
c15c90bb 9125 {
c9034561 9126 /* 32-bit SVR4 quad floating point routines. */
c15c90bb
ZW
9127
9128 set_optab_libfunc (add_optab, TFmode, "_q_add");
9129 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
9130 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
9131 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
9132 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
9133 if (TARGET_PPC_GPOPT || TARGET_POWER2)
9134 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
9135
c9034561
ZW
9136 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
9137 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
9138 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
9139 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
9140 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
9141 set_optab_libfunc (le_optab, TFmode, "_q_fle");
9142
85363ca0
ZW
9143 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
9144 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
9145 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
9146 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
9147 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
9148 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
9149 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
57904aa7 9150 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
c15c90bb
ZW
9151 }
9152}
fba73eb1
DE
9153
9154\f
9155/* Expand a block clear operation, and return 1 if successful. Return 0
9156 if we should let the compiler generate normal code.
9157
9158 operands[0] is the destination
9159 operands[1] is the length
57e84f18 9160 operands[3] is the alignment */
fba73eb1
DE
9161
9162int
9163expand_block_clear (rtx operands[])
9164{
9165 rtx orig_dest = operands[0];
9166 rtx bytes_rtx = operands[1];
57e84f18 9167 rtx align_rtx = operands[3];
5514620a
GK
9168 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
9169 HOST_WIDE_INT align;
9170 HOST_WIDE_INT bytes;
fba73eb1
DE
9171 int offset;
9172 int clear_bytes;
5514620a 9173 int clear_step;
fba73eb1
DE
9174
9175 /* If this is not a fixed size move, just call memcpy */
9176 if (! constp)
9177 return 0;
9178
37409796
NS
9179 /* This must be a fixed size alignment */
9180 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
fba73eb1
DE
9181 align = INTVAL (align_rtx) * BITS_PER_UNIT;
9182
9183 /* Anything to clear? */
9184 bytes = INTVAL (bytes_rtx);
9185 if (bytes <= 0)
9186 return 1;
9187
5514620a
GK
9188 /* Use the builtin memset after a point, to avoid huge code bloat.
9189 When optimize_size, avoid any significant code bloat; calling
9190 memset is about 4 instructions, so allow for one instruction to
9191 load zero and three to do clearing. */
9192 if (TARGET_ALTIVEC && align >= 128)
9193 clear_step = 16;
9194 else if (TARGET_POWERPC64 && align >= 32)
9195 clear_step = 8;
9196 else
9197 clear_step = 4;
fba73eb1 9198
5514620a
GK
9199 if (optimize_size && bytes > 3 * clear_step)
9200 return 0;
9201 if (! optimize_size && bytes > 8 * clear_step)
fba73eb1
DE
9202 return 0;
9203
9204 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
9205 {
fba73eb1
DE
9206 enum machine_mode mode = BLKmode;
9207 rtx dest;
f676971a 9208
5514620a
GK
9209 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
9210 {
9211 clear_bytes = 16;
9212 mode = V4SImode;
9213 }
9214 else if (bytes >= 8 && TARGET_POWERPC64
9215 /* 64-bit loads and stores require word-aligned
9216 displacements. */
9217 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
fba73eb1
DE
9218 {
9219 clear_bytes = 8;
9220 mode = DImode;
fba73eb1 9221 }
5514620a 9222 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
fba73eb1
DE
9223 { /* move 4 bytes */
9224 clear_bytes = 4;
9225 mode = SImode;
fba73eb1 9226 }
ec53fc93 9227 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
fba73eb1
DE
9228 { /* move 2 bytes */
9229 clear_bytes = 2;
9230 mode = HImode;
fba73eb1
DE
9231 }
9232 else /* move 1 byte at a time */
9233 {
9234 clear_bytes = 1;
9235 mode = QImode;
fba73eb1 9236 }
f676971a 9237
fba73eb1 9238 dest = adjust_address (orig_dest, mode, offset);
f676971a 9239
5514620a 9240 emit_move_insn (dest, CONST0_RTX (mode));
fba73eb1
DE
9241 }
9242
9243 return 1;
9244}
9245
35aff10b 9246\f
7e69e155
MM
9247/* Expand a block move operation, and return 1 if successful. Return 0
9248 if we should let the compiler generate normal code.
9249
9250 operands[0] is the destination
9251 operands[1] is the source
9252 operands[2] is the length
9253 operands[3] is the alignment */
9254
3933e0e1
MM
9255#define MAX_MOVE_REG 4
9256
7e69e155 9257int
a2369ed3 9258expand_block_move (rtx operands[])
7e69e155 9259{
b6c9286a
MM
9260 rtx orig_dest = operands[0];
9261 rtx orig_src = operands[1];
7e69e155 9262 rtx bytes_rtx = operands[2];
7e69e155 9263 rtx align_rtx = operands[3];
3933e0e1 9264 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 9265 int align;
3933e0e1
MM
9266 int bytes;
9267 int offset;
7e69e155 9268 int move_bytes;
cabfd258
GK
9269 rtx stores[MAX_MOVE_REG];
9270 int num_reg = 0;
7e69e155 9271
3933e0e1 9272 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 9273 if (! constp)
3933e0e1
MM
9274 return 0;
9275
37409796
NS
9276 /* This must be a fixed size alignment */
9277 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
fba73eb1 9278 align = INTVAL (align_rtx) * BITS_PER_UNIT;
5ee95df6 9279
7e69e155 9280 /* Anything to move? */
3933e0e1
MM
9281 bytes = INTVAL (bytes_rtx);
9282 if (bytes <= 0)
7e69e155
MM
9283 return 1;
9284
ea9982a8 9285 /* store_one_arg depends on expand_block_move to handle at least the size of
f676971a 9286 reg_parm_stack_space. */
ea9982a8 9287 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
9288 return 0;
9289
cabfd258 9290 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 9291 {
cabfd258 9292 union {
70128ad9 9293 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
a2369ed3 9294 rtx (*mov) (rtx, rtx);
cabfd258
GK
9295 } gen_func;
9296 enum machine_mode mode = BLKmode;
9297 rtx src, dest;
f676971a 9298
5514620a
GK
9299 /* Altivec first, since it will be faster than a string move
9300 when it applies, and usually not significantly larger. */
9301 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
9302 {
9303 move_bytes = 16;
9304 mode = V4SImode;
9305 gen_func.mov = gen_movv4si;
9306 }
9307 else if (TARGET_STRING
cabfd258
GK
9308 && bytes > 24 /* move up to 32 bytes at a time */
9309 && ! fixed_regs[5]
9310 && ! fixed_regs[6]
9311 && ! fixed_regs[7]
9312 && ! fixed_regs[8]
9313 && ! fixed_regs[9]
9314 && ! fixed_regs[10]
9315 && ! fixed_regs[11]
9316 && ! fixed_regs[12])
7e69e155 9317 {
cabfd258 9318 move_bytes = (bytes > 32) ? 32 : bytes;
70128ad9 9319 gen_func.movmemsi = gen_movmemsi_8reg;
cabfd258
GK
9320 }
9321 else if (TARGET_STRING
9322 && bytes > 16 /* move up to 24 bytes at a time */
9323 && ! fixed_regs[5]
9324 && ! fixed_regs[6]
9325 && ! fixed_regs[7]
9326 && ! fixed_regs[8]
9327 && ! fixed_regs[9]
9328 && ! fixed_regs[10])
9329 {
9330 move_bytes = (bytes > 24) ? 24 : bytes;
70128ad9 9331 gen_func.movmemsi = gen_movmemsi_6reg;
cabfd258
GK
9332 }
9333 else if (TARGET_STRING
9334 && bytes > 8 /* move up to 16 bytes at a time */
9335 && ! fixed_regs[5]
9336 && ! fixed_regs[6]
9337 && ! fixed_regs[7]
9338 && ! fixed_regs[8])
9339 {
9340 move_bytes = (bytes > 16) ? 16 : bytes;
70128ad9 9341 gen_func.movmemsi = gen_movmemsi_4reg;
cabfd258
GK
9342 }
9343 else if (bytes >= 8 && TARGET_POWERPC64
9344 /* 64-bit loads and stores require word-aligned
9345 displacements. */
fba73eb1 9346 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
cabfd258
GK
9347 {
9348 move_bytes = 8;
9349 mode = DImode;
9350 gen_func.mov = gen_movdi;
9351 }
9352 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
9353 { /* move up to 8 bytes at a time */
9354 move_bytes = (bytes > 8) ? 8 : bytes;
70128ad9 9355 gen_func.movmemsi = gen_movmemsi_2reg;
cabfd258 9356 }
cd7d9ca4 9357 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
cabfd258
GK
9358 { /* move 4 bytes */
9359 move_bytes = 4;
9360 mode = SImode;
9361 gen_func.mov = gen_movsi;
9362 }
ec53fc93 9363 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
cabfd258
GK
9364 { /* move 2 bytes */
9365 move_bytes = 2;
9366 mode = HImode;
9367 gen_func.mov = gen_movhi;
9368 }
9369 else if (TARGET_STRING && bytes > 1)
9370 { /* move up to 4 bytes at a time */
9371 move_bytes = (bytes > 4) ? 4 : bytes;
70128ad9 9372 gen_func.movmemsi = gen_movmemsi_1reg;
cabfd258
GK
9373 }
9374 else /* move 1 byte at a time */
9375 {
9376 move_bytes = 1;
9377 mode = QImode;
9378 gen_func.mov = gen_movqi;
9379 }
f676971a 9380
cabfd258
GK
9381 src = adjust_address (orig_src, mode, offset);
9382 dest = adjust_address (orig_dest, mode, offset);
f676971a
EC
9383
9384 if (mode != BLKmode)
cabfd258
GK
9385 {
9386 rtx tmp_reg = gen_reg_rtx (mode);
f676971a 9387
cabfd258
GK
9388 emit_insn ((*gen_func.mov) (tmp_reg, src));
9389 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
4c64a852 9390 }
3933e0e1 9391
cabfd258
GK
9392 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
9393 {
9394 int i;
9395 for (i = 0; i < num_reg; i++)
9396 emit_insn (stores[i]);
9397 num_reg = 0;
9398 }
35aff10b 9399
cabfd258 9400 if (mode == BLKmode)
7e69e155 9401 {
70128ad9 9402 /* Move the address into scratch registers. The movmemsi
cabfd258
GK
9403 patterns require zero offset. */
9404 if (!REG_P (XEXP (src, 0)))
b6c9286a 9405 {
cabfd258
GK
9406 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
9407 src = replace_equiv_address (src, src_reg);
b6c9286a 9408 }
cabfd258 9409 set_mem_size (src, GEN_INT (move_bytes));
f676971a 9410
cabfd258 9411 if (!REG_P (XEXP (dest, 0)))
3933e0e1 9412 {
cabfd258
GK
9413 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
9414 dest = replace_equiv_address (dest, dest_reg);
7e69e155 9415 }
cabfd258 9416 set_mem_size (dest, GEN_INT (move_bytes));
f676971a 9417
70128ad9 9418 emit_insn ((*gen_func.movmemsi) (dest, src,
cabfd258
GK
9419 GEN_INT (move_bytes & 31),
9420 align_rtx));
7e69e155 9421 }
7e69e155
MM
9422 }
9423
9424 return 1;
9425}
9426
d62294f5 9427\f
9caa3eb2
DE
9428/* Return a string to perform a load_multiple operation.
9429 operands[0] is the vector.
9430 operands[1] is the source address.
9431 operands[2] is the first destination register. */
9432
9433const char *
a2369ed3 9434rs6000_output_load_multiple (rtx operands[3])
9caa3eb2
DE
9435{
9436 /* We have to handle the case where the pseudo used to contain the address
9437 is assigned to one of the output registers. */
9438 int i, j;
9439 int words = XVECLEN (operands[0], 0);
9440 rtx xop[10];
9441
9442 if (XVECLEN (operands[0], 0) == 1)
9443 return "{l|lwz} %2,0(%1)";
9444
9445 for (i = 0; i < words; i++)
9446 if (refers_to_regno_p (REGNO (operands[2]) + i,
9447 REGNO (operands[2]) + i + 1, operands[1], 0))
9448 {
9449 if (i == words-1)
9450 {
9451 xop[0] = GEN_INT (4 * (words-1));
9452 xop[1] = operands[1];
9453 xop[2] = operands[2];
9454 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
9455 return "";
9456 }
9457 else if (i == 0)
9458 {
9459 xop[0] = GEN_INT (4 * (words-1));
9460 xop[1] = operands[1];
9461 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
9462 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);
9463 return "";
9464 }
9465 else
9466 {
9467 for (j = 0; j < words; j++)
9468 if (j != i)
9469 {
9470 xop[0] = GEN_INT (j * 4);
9471 xop[1] = operands[1];
9472 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
9473 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
9474 }
9475 xop[0] = GEN_INT (i * 4);
9476 xop[1] = operands[1];
9477 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
9478 return "";
9479 }
9480 }
9481
9482 return "{lsi|lswi} %2,%1,%N0";
9483}
9484
9878760c 9485\f
a4f6c312
SS
9486/* A validation routine: say whether CODE, a condition code, and MODE
9487 match. The other alternatives either don't make sense or should
9488 never be generated. */
39a10a29 9489
48d72335 9490void
a2369ed3 9491validate_condition_mode (enum rtx_code code, enum machine_mode mode)
39a10a29 9492{
37409796
NS
9493 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
9494 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
9495 && GET_MODE_CLASS (mode) == MODE_CC);
39a10a29
GK
9496
9497 /* These don't make sense. */
37409796
NS
9498 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
9499 || mode != CCUNSmode);
39a10a29 9500
37409796
NS
9501 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
9502 || mode == CCUNSmode);
39a10a29 9503
37409796
NS
9504 gcc_assert (mode == CCFPmode
9505 || (code != ORDERED && code != UNORDERED
9506 && code != UNEQ && code != LTGT
9507 && code != UNGT && code != UNLT
9508 && code != UNGE && code != UNLE));
f676971a
EC
9509
9510 /* These should never be generated except for
bc9ec0e0 9511 flag_finite_math_only. */
37409796
NS
9512 gcc_assert (mode != CCFPmode
9513 || flag_finite_math_only
9514 || (code != LE && code != GE
9515 && code != UNEQ && code != LTGT
9516 && code != UNGT && code != UNLT));
39a10a29
GK
9517
9518 /* These are invalid; the information is not there. */
37409796 9519 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
39a10a29
GK
9520}
9521
9878760c
RK
9522\f
9523/* Return 1 if ANDOP is a mask that has no bits on that are not in the
9524 mask required to convert the result of a rotate insn into a shift
b1765bde 9525 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
9526
9527int
a2369ed3 9528includes_lshift_p (rtx shiftop, rtx andop)
9878760c 9529{
e2c953b6
DE
9530 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9531
9532 shift_mask <<= INTVAL (shiftop);
9878760c 9533
b1765bde 9534 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
9535}
9536
9537/* Similar, but for right shift. */
9538
9539int
a2369ed3 9540includes_rshift_p (rtx shiftop, rtx andop)
9878760c 9541{
a7653a2c 9542 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
9543
9544 shift_mask >>= INTVAL (shiftop);
9545
b1765bde 9546 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
9547}
9548
c5059423
AM
9549/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
9550 to perform a left shift. It must have exactly SHIFTOP least
b6d08ca1 9551 significant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
9552
9553int
a2369ed3 9554includes_rldic_lshift_p (rtx shiftop, rtx andop)
e2c953b6 9555{
c5059423
AM
9556 if (GET_CODE (andop) == CONST_INT)
9557 {
02071907 9558 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 9559
c5059423 9560 c = INTVAL (andop);
02071907 9561 if (c == 0 || c == ~0)
c5059423 9562 return 0;
e2c953b6 9563
02071907 9564 shift_mask = ~0;
c5059423
AM
9565 shift_mask <<= INTVAL (shiftop);
9566
b6d08ca1 9567 /* Find the least significant one bit. */
c5059423
AM
9568 lsb = c & -c;
9569
9570 /* It must coincide with the LSB of the shift mask. */
9571 if (-lsb != shift_mask)
9572 return 0;
e2c953b6 9573
c5059423
AM
9574 /* Invert to look for the next transition (if any). */
9575 c = ~c;
9576
9577 /* Remove the low group of ones (originally low group of zeros). */
9578 c &= -lsb;
9579
9580 /* Again find the lsb, and check we have all 1's above. */
9581 lsb = c & -c;
9582 return c == -lsb;
9583 }
9584 else if (GET_CODE (andop) == CONST_DOUBLE
9585 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9586 {
02071907
AM
9587 HOST_WIDE_INT low, high, lsb;
9588 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
9589
9590 low = CONST_DOUBLE_LOW (andop);
9591 if (HOST_BITS_PER_WIDE_INT < 64)
9592 high = CONST_DOUBLE_HIGH (andop);
9593
9594 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 9595 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
9596 return 0;
9597
9598 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9599 {
02071907 9600 shift_mask_high = ~0;
c5059423
AM
9601 if (INTVAL (shiftop) > 32)
9602 shift_mask_high <<= INTVAL (shiftop) - 32;
9603
9604 lsb = high & -high;
9605
9606 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
9607 return 0;
9608
9609 high = ~high;
9610 high &= -lsb;
9611
9612 lsb = high & -high;
9613 return high == -lsb;
9614 }
9615
02071907 9616 shift_mask_low = ~0;
c5059423
AM
9617 shift_mask_low <<= INTVAL (shiftop);
9618
9619 lsb = low & -low;
9620
9621 if (-lsb != shift_mask_low)
9622 return 0;
9623
9624 if (HOST_BITS_PER_WIDE_INT < 64)
9625 high = ~high;
9626 low = ~low;
9627 low &= -lsb;
9628
9629 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
9630 {
9631 lsb = high & -high;
9632 return high == -lsb;
9633 }
9634
9635 lsb = low & -low;
9636 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
9637 }
9638 else
9639 return 0;
9640}
e2c953b6 9641
c5059423
AM
9642/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
9643 to perform a left shift. It must have SHIFTOP or more least
c1207243 9644 significant 0's, with the remainder of the word 1's. */
e2c953b6 9645
c5059423 9646int
a2369ed3 9647includes_rldicr_lshift_p (rtx shiftop, rtx andop)
c5059423 9648{
e2c953b6 9649 if (GET_CODE (andop) == CONST_INT)
c5059423 9650 {
02071907 9651 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 9652
02071907 9653 shift_mask = ~0;
c5059423
AM
9654 shift_mask <<= INTVAL (shiftop);
9655 c = INTVAL (andop);
9656
c1207243 9657 /* Find the least significant one bit. */
c5059423
AM
9658 lsb = c & -c;
9659
9660 /* It must be covered by the shift mask.
a4f6c312 9661 This test also rejects c == 0. */
c5059423
AM
9662 if ((lsb & shift_mask) == 0)
9663 return 0;
9664
9665 /* Check we have all 1's above the transition, and reject all 1's. */
9666 return c == -lsb && lsb != 1;
9667 }
9668 else if (GET_CODE (andop) == CONST_DOUBLE
9669 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
9670 {
02071907 9671 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
9672
9673 low = CONST_DOUBLE_LOW (andop);
9674
9675 if (HOST_BITS_PER_WIDE_INT < 64)
9676 {
02071907 9677 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
9678
9679 high = CONST_DOUBLE_HIGH (andop);
9680
9681 if (low == 0)
9682 {
02071907 9683 shift_mask_high = ~0;
c5059423
AM
9684 if (INTVAL (shiftop) > 32)
9685 shift_mask_high <<= INTVAL (shiftop) - 32;
9686
9687 lsb = high & -high;
9688
9689 if ((lsb & shift_mask_high) == 0)
9690 return 0;
9691
9692 return high == -lsb;
9693 }
9694 if (high != ~0)
9695 return 0;
9696 }
9697
02071907 9698 shift_mask_low = ~0;
c5059423
AM
9699 shift_mask_low <<= INTVAL (shiftop);
9700
9701 lsb = low & -low;
9702
9703 if ((lsb & shift_mask_low) == 0)
9704 return 0;
9705
9706 return low == -lsb && lsb != 1;
9707 }
e2c953b6 9708 else
c5059423 9709 return 0;
9878760c 9710}
35068b43 9711
11ac38b2
DE
9712/* Return 1 if operands will generate a valid arguments to rlwimi
9713instruction for insert with right shift in 64-bit mode. The mask may
9714not start on the first bit or stop on the last bit because wrap-around
9715effects of instruction do not correspond to semantics of RTL insn. */
9716
9717int
9718insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
9719{
9720 if (INTVAL (startop) < 64
9721 && INTVAL (startop) > 32
9722 && (INTVAL (sizeop) + INTVAL (startop) < 64)
9723 && (INTVAL (sizeop) + INTVAL (startop) > 33)
9724 && (INTVAL (sizeop) + INTVAL (startop) + INTVAL (shiftop) < 96)
9725 && (INTVAL (sizeop) + INTVAL (startop) + INTVAL (shiftop) >= 64)
9726 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
9727 return 1;
9728
9729 return 0;
9730}
9731
35068b43 9732/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
90f81f99 9733 for lfq and stfq insns iff the registers are hard registers. */
35068b43
RK
9734
9735int
a2369ed3 9736registers_ok_for_quad_peep (rtx reg1, rtx reg2)
35068b43
RK
9737{
9738 /* We might have been passed a SUBREG. */
f676971a 9739 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
35068b43 9740 return 0;
f676971a 9741
90f81f99
AP
9742 /* We might have been passed non floating point registers. */
9743 if (!FP_REGNO_P (REGNO (reg1))
9744 || !FP_REGNO_P (REGNO (reg2)))
9745 return 0;
35068b43
RK
9746
9747 return (REGNO (reg1) == REGNO (reg2) - 1);
9748}
9749
a4f6c312
SS
9750/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
9751 addr1 and addr2 must be in consecutive memory locations
9752 (addr2 == addr1 + 8). */
35068b43
RK
9753
9754int
90f81f99 9755mems_ok_for_quad_peep (rtx mem1, rtx mem2)
35068b43 9756{
90f81f99 9757 rtx addr1, addr2;
bb8df8a6
EC
9758 unsigned int reg1, reg2;
9759 int offset1, offset2;
35068b43 9760
90f81f99
AP
9761 /* The mems cannot be volatile. */
9762 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
9763 return 0;
f676971a 9764
90f81f99
AP
9765 addr1 = XEXP (mem1, 0);
9766 addr2 = XEXP (mem2, 0);
9767
35068b43
RK
9768 /* Extract an offset (if used) from the first addr. */
9769 if (GET_CODE (addr1) == PLUS)
9770 {
9771 /* If not a REG, return zero. */
9772 if (GET_CODE (XEXP (addr1, 0)) != REG)
9773 return 0;
9774 else
9775 {
c4ad648e 9776 reg1 = REGNO (XEXP (addr1, 0));
35068b43
RK
9777 /* The offset must be constant! */
9778 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
c4ad648e
AM
9779 return 0;
9780 offset1 = INTVAL (XEXP (addr1, 1));
35068b43
RK
9781 }
9782 }
9783 else if (GET_CODE (addr1) != REG)
9784 return 0;
9785 else
9786 {
9787 reg1 = REGNO (addr1);
9788 /* This was a simple (mem (reg)) expression. Offset is 0. */
9789 offset1 = 0;
9790 }
9791
bb8df8a6
EC
9792 /* And now for the second addr. */
9793 if (GET_CODE (addr2) == PLUS)
9794 {
9795 /* If not a REG, return zero. */
9796 if (GET_CODE (XEXP (addr2, 0)) != REG)
9797 return 0;
9798 else
9799 {
9800 reg2 = REGNO (XEXP (addr2, 0));
9801 /* The offset must be constant. */
9802 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
9803 return 0;
9804 offset2 = INTVAL (XEXP (addr2, 1));
9805 }
9806 }
9807 else if (GET_CODE (addr2) != REG)
35068b43 9808 return 0;
bb8df8a6
EC
9809 else
9810 {
9811 reg2 = REGNO (addr2);
9812 /* This was a simple (mem (reg)) expression. Offset is 0. */
9813 offset2 = 0;
9814 }
35068b43 9815
bb8df8a6
EC
9816 /* Both of these must have the same base register. */
9817 if (reg1 != reg2)
35068b43
RK
9818 return 0;
9819
9820 /* The offset for the second addr must be 8 more than the first addr. */
bb8df8a6 9821 if (offset2 != offset1 + 8)
35068b43
RK
9822 return 0;
9823
9824 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
9825 instructions. */
9826 return 1;
9827}
9878760c
RK
9828\f
9829/* Return the register class of a scratch register needed to copy IN into
9830 or out of a register in CLASS in MODE. If it can be done directly,
9831 NO_REGS is returned. */
9832
9833enum reg_class
3c4774e0
R
9834rs6000_secondary_reload_class (enum reg_class class,
9835 enum machine_mode mode ATTRIBUTE_UNUSED,
9836 rtx in)
9878760c 9837{
5accd822 9838 int regno;
9878760c 9839
ab82a49f
AP
9840 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
9841#if TARGET_MACHO
c4ad648e 9842 && MACHOPIC_INDIRECT
ab82a49f 9843#endif
c4ad648e 9844 ))
46fad5b7
DJ
9845 {
9846 /* We cannot copy a symbolic operand directly into anything
c4ad648e
AM
9847 other than BASE_REGS for TARGET_ELF. So indicate that a
9848 register from BASE_REGS is needed as an intermediate
9849 register.
f676971a 9850
46fad5b7
DJ
9851 On Darwin, pic addresses require a load from memory, which
9852 needs a base register. */
9853 if (class != BASE_REGS
c4ad648e
AM
9854 && (GET_CODE (in) == SYMBOL_REF
9855 || GET_CODE (in) == HIGH
9856 || GET_CODE (in) == LABEL_REF
9857 || GET_CODE (in) == CONST))
9858 return BASE_REGS;
46fad5b7 9859 }
e7b7998a 9860
5accd822
DE
9861 if (GET_CODE (in) == REG)
9862 {
9863 regno = REGNO (in);
9864 if (regno >= FIRST_PSEUDO_REGISTER)
9865 {
9866 regno = true_regnum (in);
9867 if (regno >= FIRST_PSEUDO_REGISTER)
9868 regno = -1;
9869 }
9870 }
9871 else if (GET_CODE (in) == SUBREG)
9872 {
9873 regno = true_regnum (in);
9874 if (regno >= FIRST_PSEUDO_REGISTER)
9875 regno = -1;
9876 }
9877 else
9878 regno = -1;
9879
9878760c
RK
9880 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
9881 into anything. */
9882 if (class == GENERAL_REGS || class == BASE_REGS
9883 || (regno >= 0 && INT_REGNO_P (regno)))
9884 return NO_REGS;
9885
9886 /* Constants, memory, and FP registers can go into FP registers. */
9887 if ((regno == -1 || FP_REGNO_P (regno))
9888 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
9889 return NO_REGS;
9890
0ac081f6
AH
9891 /* Memory, and AltiVec registers can go into AltiVec registers. */
9892 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
9893 && class == ALTIVEC_REGS)
9894 return NO_REGS;
9895
9878760c
RK
9896 /* We can copy among the CR registers. */
9897 if ((class == CR_REGS || class == CR0_REGS)
9898 && regno >= 0 && CR_REGNO_P (regno))
9899 return NO_REGS;
9900
9901 /* Otherwise, we need GENERAL_REGS. */
9902 return GENERAL_REGS;
9903}
9904\f
9905/* Given a comparison operation, return the bit number in CCR to test. We
f676971a 9906 know this is a valid comparison.
9878760c
RK
9907
9908 SCC_P is 1 if this is for an scc. That means that %D will have been
9909 used instead of %C, so the bits will be in different places.
9910
b4ac57ab 9911 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
9912
9913int
a2369ed3 9914ccr_bit (rtx op, int scc_p)
9878760c
RK
9915{
9916 enum rtx_code code = GET_CODE (op);
9917 enum machine_mode cc_mode;
9918 int cc_regnum;
9919 int base_bit;
9ebbca7d 9920 rtx reg;
9878760c 9921
ec8e098d 9922 if (!COMPARISON_P (op))
9878760c
RK
9923 return -1;
9924
9ebbca7d
GK
9925 reg = XEXP (op, 0);
9926
37409796 9927 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
9ebbca7d
GK
9928
9929 cc_mode = GET_MODE (reg);
9930 cc_regnum = REGNO (reg);
9931 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 9932
39a10a29 9933 validate_condition_mode (code, cc_mode);
c5defebb 9934
b7053a3f
GK
9935 /* When generating a sCOND operation, only positive conditions are
9936 allowed. */
37409796
NS
9937 gcc_assert (!scc_p
9938 || code == EQ || code == GT || code == LT || code == UNORDERED
9939 || code == GTU || code == LTU);
f676971a 9940
9878760c
RK
9941 switch (code)
9942 {
9943 case NE:
9944 return scc_p ? base_bit + 3 : base_bit + 2;
9945 case EQ:
9946 return base_bit + 2;
1c882ea4 9947 case GT: case GTU: case UNLE:
9878760c 9948 return base_bit + 1;
1c882ea4 9949 case LT: case LTU: case UNGE:
9878760c 9950 return base_bit;
1c882ea4
GK
9951 case ORDERED: case UNORDERED:
9952 return base_bit + 3;
9878760c
RK
9953
9954 case GE: case GEU:
39a10a29 9955 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
9956 unordered position. So test that bit. For integer, this is ! LT
9957 unless this is an scc insn. */
39a10a29 9958 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
9959
9960 case LE: case LEU:
39a10a29 9961 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 9962
9878760c 9963 default:
37409796 9964 gcc_unreachable ();
9878760c
RK
9965 }
9966}
1ff7789b 9967\f
8d30c4ee 9968/* Return the GOT register. */
1ff7789b 9969
9390387d 9970rtx
a2369ed3 9971rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
1ff7789b 9972{
a4f6c312
SS
9973 /* The second flow pass currently (June 1999) can't update
9974 regs_ever_live without disturbing other parts of the compiler, so
9975 update it here to make the prolog/epilogue code happy. */
1db02437
FS
9976 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
9977 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 9978
8d30c4ee 9979 current_function_uses_pic_offset_table = 1;
3cb999d8 9980
1ff7789b
MM
9981 return pic_offset_table_rtx;
9982}
a7df97e6 9983\f
e2500fed
GK
9984/* Function to init struct machine_function.
9985 This will be called, via a pointer variable,
9986 from push_function_context. */
a7df97e6 9987
e2500fed 9988static struct machine_function *
863d938c 9989rs6000_init_machine_status (void)
a7df97e6 9990{
e2500fed 9991 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 9992}
9878760c 9993\f
0ba1b2ff
AM
9994/* These macros test for integers and extract the low-order bits. */
9995#define INT_P(X) \
9996((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
9997 && GET_MODE (X) == VOIDmode)
9998
9999#define INT_LOWPART(X) \
10000 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
10001
10002int
a2369ed3 10003extract_MB (rtx op)
0ba1b2ff
AM
10004{
10005 int i;
10006 unsigned long val = INT_LOWPART (op);
10007
10008 /* If the high bit is zero, the value is the first 1 bit we find
10009 from the left. */
10010 if ((val & 0x80000000) == 0)
10011 {
37409796 10012 gcc_assert (val & 0xffffffff);
0ba1b2ff
AM
10013
10014 i = 1;
10015 while (((val <<= 1) & 0x80000000) == 0)
10016 ++i;
10017 return i;
10018 }
10019
10020 /* If the high bit is set and the low bit is not, or the mask is all
10021 1's, the value is zero. */
10022 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
10023 return 0;
10024
10025 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10026 from the right. */
10027 i = 31;
10028 while (((val >>= 1) & 1) != 0)
10029 --i;
10030
10031 return i;
10032}
10033
10034int
a2369ed3 10035extract_ME (rtx op)
0ba1b2ff
AM
10036{
10037 int i;
10038 unsigned long val = INT_LOWPART (op);
10039
10040 /* If the low bit is zero, the value is the first 1 bit we find from
10041 the right. */
10042 if ((val & 1) == 0)
10043 {
37409796 10044 gcc_assert (val & 0xffffffff);
0ba1b2ff
AM
10045
10046 i = 30;
10047 while (((val >>= 1) & 1) == 0)
10048 --i;
10049
10050 return i;
10051 }
10052
10053 /* If the low bit is set and the high bit is not, or the mask is all
10054 1's, the value is 31. */
10055 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
10056 return 31;
10057
10058 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
10059 from the left. */
10060 i = 0;
10061 while (((val <<= 1) & 0x80000000) != 0)
10062 ++i;
10063
10064 return i;
10065}
10066
c4501e62
JJ
10067/* Locate some local-dynamic symbol still in use by this function
10068 so that we can print its name in some tls_ld pattern. */
10069
10070static const char *
863d938c 10071rs6000_get_some_local_dynamic_name (void)
c4501e62
JJ
10072{
10073 rtx insn;
10074
10075 if (cfun->machine->some_ld_name)
10076 return cfun->machine->some_ld_name;
10077
10078 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
10079 if (INSN_P (insn)
10080 && for_each_rtx (&PATTERN (insn),
10081 rs6000_get_some_local_dynamic_name_1, 0))
10082 return cfun->machine->some_ld_name;
10083
37409796 10084 gcc_unreachable ();
c4501e62
JJ
10085}
10086
10087/* Helper function for rs6000_get_some_local_dynamic_name. */
10088
10089static int
a2369ed3 10090rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
c4501e62
JJ
10091{
10092 rtx x = *px;
10093
10094 if (GET_CODE (x) == SYMBOL_REF)
10095 {
10096 const char *str = XSTR (x, 0);
10097 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
10098 {
10099 cfun->machine->some_ld_name = str;
10100 return 1;
10101 }
10102 }
10103
10104 return 0;
10105}
10106
85b776df
AM
10107/* Write out a function code label. */
10108
10109void
10110rs6000_output_function_entry (FILE *file, const char *fname)
10111{
10112 if (fname[0] != '.')
10113 {
10114 switch (DEFAULT_ABI)
10115 {
10116 default:
37409796 10117 gcc_unreachable ();
85b776df
AM
10118
10119 case ABI_AIX:
10120 if (DOT_SYMBOLS)
10121 putc ('.', file);
10122 else
10123 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
10124 break;
10125
10126 case ABI_V4:
10127 case ABI_DARWIN:
10128 break;
10129 }
10130 }
10131 if (TARGET_AIX)
10132 RS6000_OUTPUT_BASENAME (file, fname);
10133 else
10134 assemble_name (file, fname);
10135}
10136
9878760c
RK
10137/* Print an operand. Recognize special options, documented below. */
10138
38c1f2d7 10139#if TARGET_ELF
d9407988 10140#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 10141#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
10142#else
10143#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 10144#define SMALL_DATA_REG 0
ba5e43aa
MM
10145#endif
10146
9878760c 10147void
a2369ed3 10148print_operand (FILE *file, rtx x, int code)
9878760c
RK
10149{
10150 int i;
a260abc9 10151 HOST_WIDE_INT val;
0ba1b2ff 10152 unsigned HOST_WIDE_INT uval;
9878760c
RK
10153
10154 switch (code)
10155 {
a8b3aeda 10156 case '.':
a85d226b
RK
10157 /* Write out an instruction after the call which may be replaced
10158 with glue code by the loader. This depends on the AIX version. */
10159 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
10160 return;
10161
81eace42
GK
10162 /* %a is output_address. */
10163
9854d9ed
RK
10164 case 'A':
10165 /* If X is a constant integer whose low-order 5 bits are zero,
10166 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 10167 in the AIX assembler where "sri" with a zero shift count
20e26713 10168 writes a trash instruction. */
9854d9ed 10169 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 10170 putc ('l', file);
9854d9ed 10171 else
76229ac8 10172 putc ('r', file);
9854d9ed
RK
10173 return;
10174
10175 case 'b':
e2c953b6
DE
10176 /* If constant, low-order 16 bits of constant, unsigned.
10177 Otherwise, write normally. */
10178 if (INT_P (x))
10179 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
10180 else
10181 print_operand (file, x, 0);
cad12a8d
RK
10182 return;
10183
a260abc9
DE
10184 case 'B':
10185 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
10186 for 64-bit mask direction. */
9390387d 10187 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 10188 return;
a260abc9 10189
81eace42
GK
10190 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
10191 output_operand. */
10192
423c1189
AH
10193 case 'c':
10194 /* X is a CR register. Print the number of the GT bit of the CR. */
10195 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10196 output_operand_lossage ("invalid %%E value");
10197 else
10198 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
10199 return;
10200
10201 case 'D':
6b1fedc3 10202 /* Like 'J' but get to the EQ bit. */
37409796 10203 gcc_assert (GET_CODE (x) == REG);
423c1189 10204
6b1fedc3
AH
10205 /* Bit 1 is EQ bit. */
10206 i = 4 * (REGNO (x) - CR0_REGNO) + 2;
423c1189 10207
64022b5d 10208 fprintf (file, "%d", i);
423c1189
AH
10209 return;
10210
9854d9ed 10211 case 'E':
39a10a29 10212 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
10213 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10214 output_operand_lossage ("invalid %%E value");
78fbdbf7 10215 else
39a10a29 10216 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 10217 return;
9854d9ed
RK
10218
10219 case 'f':
10220 /* X is a CR register. Print the shift count needed to move it
10221 to the high-order four bits. */
10222 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10223 output_operand_lossage ("invalid %%f value");
10224 else
9ebbca7d 10225 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
10226 return;
10227
10228 case 'F':
10229 /* Similar, but print the count for the rotate in the opposite
10230 direction. */
10231 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10232 output_operand_lossage ("invalid %%F value");
10233 else
9ebbca7d 10234 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
10235 return;
10236
10237 case 'G':
10238 /* X is a constant integer. If it is negative, print "m",
43aa4e05 10239 otherwise print "z". This is to make an aze or ame insn. */
9854d9ed
RK
10240 if (GET_CODE (x) != CONST_INT)
10241 output_operand_lossage ("invalid %%G value");
10242 else if (INTVAL (x) >= 0)
76229ac8 10243 putc ('z', file);
9854d9ed 10244 else
76229ac8 10245 putc ('m', file);
9854d9ed 10246 return;
e2c953b6 10247
9878760c 10248 case 'h':
a4f6c312
SS
10249 /* If constant, output low-order five bits. Otherwise, write
10250 normally. */
9878760c 10251 if (INT_P (x))
5f59ecb7 10252 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
10253 else
10254 print_operand (file, x, 0);
10255 return;
10256
64305719 10257 case 'H':
a4f6c312
SS
10258 /* If constant, output low-order six bits. Otherwise, write
10259 normally. */
64305719 10260 if (INT_P (x))
5f59ecb7 10261 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
10262 else
10263 print_operand (file, x, 0);
10264 return;
10265
9854d9ed
RK
10266 case 'I':
10267 /* Print `i' if this is a constant, else nothing. */
9878760c 10268 if (INT_P (x))
76229ac8 10269 putc ('i', file);
9878760c
RK
10270 return;
10271
9854d9ed
RK
10272 case 'j':
10273 /* Write the bit number in CCR for jump. */
10274 i = ccr_bit (x, 0);
10275 if (i == -1)
10276 output_operand_lossage ("invalid %%j code");
9878760c 10277 else
9854d9ed 10278 fprintf (file, "%d", i);
9878760c
RK
10279 return;
10280
9854d9ed
RK
10281 case 'J':
10282 /* Similar, but add one for shift count in rlinm for scc and pass
10283 scc flag to `ccr_bit'. */
10284 i = ccr_bit (x, 1);
10285 if (i == -1)
10286 output_operand_lossage ("invalid %%J code");
10287 else
a0466a68
RK
10288 /* If we want bit 31, write a shift count of zero, not 32. */
10289 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
10290 return;
10291
9854d9ed
RK
10292 case 'k':
10293 /* X must be a constant. Write the 1's complement of the
10294 constant. */
9878760c 10295 if (! INT_P (x))
9854d9ed 10296 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
10297 else
10298 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
10299 return;
10300
81eace42 10301 case 'K':
9ebbca7d
GK
10302 /* X must be a symbolic constant on ELF. Write an
10303 expression suitable for an 'addi' that adds in the low 16
10304 bits of the MEM. */
10305 if (GET_CODE (x) != CONST)
10306 {
10307 print_operand_address (file, x);
10308 fputs ("@l", file);
10309 }
10310 else
10311 {
10312 if (GET_CODE (XEXP (x, 0)) != PLUS
10313 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
10314 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
10315 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 10316 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
10317 print_operand_address (file, XEXP (XEXP (x, 0), 0));
10318 fputs ("@l", file);
ed8d2920
MM
10319 /* For GNU as, there must be a non-alphanumeric character
10320 between 'l' and the number. The '-' is added by
10321 print_operand() already. */
10322 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
10323 fputs ("+", file);
9ebbca7d
GK
10324 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
10325 }
81eace42
GK
10326 return;
10327
10328 /* %l is output_asm_label. */
9ebbca7d 10329
9854d9ed
RK
10330 case 'L':
10331 /* Write second word of DImode or DFmode reference. Works on register
10332 or non-indexed memory only. */
10333 if (GET_CODE (x) == REG)
fb5c67a7 10334 fputs (reg_names[REGNO (x) + 1], file);
9854d9ed
RK
10335 else if (GET_CODE (x) == MEM)
10336 {
10337 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 10338 we have already done it, we can just use an offset of word. */
9854d9ed
RK
10339 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10340 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
10341 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
10342 UNITS_PER_WORD));
9854d9ed 10343 else
d7624dc0
RK
10344 output_address (XEXP (adjust_address_nv (x, SImode,
10345 UNITS_PER_WORD),
10346 0));
ed8908e7 10347
ba5e43aa 10348 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
10349 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10350 reg_names[SMALL_DATA_REG]);
9854d9ed 10351 }
9878760c 10352 return;
f676971a 10353
9878760c
RK
10354 case 'm':
10355 /* MB value for a mask operand. */
b1765bde 10356 if (! mask_operand (x, SImode))
9878760c
RK
10357 output_operand_lossage ("invalid %%m value");
10358
0ba1b2ff 10359 fprintf (file, "%d", extract_MB (x));
9878760c
RK
10360 return;
10361
10362 case 'M':
10363 /* ME value for a mask operand. */
b1765bde 10364 if (! mask_operand (x, SImode))
a260abc9 10365 output_operand_lossage ("invalid %%M value");
9878760c 10366
0ba1b2ff 10367 fprintf (file, "%d", extract_ME (x));
9878760c
RK
10368 return;
10369
81eace42
GK
10370 /* %n outputs the negative of its operand. */
10371
9878760c
RK
10372 case 'N':
10373 /* Write the number of elements in the vector times 4. */
10374 if (GET_CODE (x) != PARALLEL)
10375 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
10376 else
10377 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
10378 return;
10379
10380 case 'O':
10381 /* Similar, but subtract 1 first. */
10382 if (GET_CODE (x) != PARALLEL)
1427100a 10383 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
10384 else
10385 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
10386 return;
10387
9854d9ed
RK
10388 case 'p':
10389 /* X is a CONST_INT that is a power of two. Output the logarithm. */
10390 if (! INT_P (x)
2bfcf297 10391 || INT_LOWPART (x) < 0
9854d9ed
RK
10392 || (i = exact_log2 (INT_LOWPART (x))) < 0)
10393 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
10394 else
10395 fprintf (file, "%d", i);
9854d9ed
RK
10396 return;
10397
9878760c
RK
10398 case 'P':
10399 /* The operand must be an indirect memory reference. The result
8bb418a3 10400 is the register name. */
9878760c
RK
10401 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
10402 || REGNO (XEXP (x, 0)) >= 32)
10403 output_operand_lossage ("invalid %%P value");
e2c953b6 10404 else
fb5c67a7 10405 fputs (reg_names[REGNO (XEXP (x, 0))], file);
9878760c
RK
10406 return;
10407
dfbdccdb
GK
10408 case 'q':
10409 /* This outputs the logical code corresponding to a boolean
10410 expression. The expression may have one or both operands
39a10a29 10411 negated (if one, only the first one). For condition register
c4ad648e
AM
10412 logical operations, it will also treat the negated
10413 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 10414 {
63bc1d05 10415 const char *const *t = 0;
dfbdccdb
GK
10416 const char *s;
10417 enum rtx_code code = GET_CODE (x);
10418 static const char * const tbl[3][3] = {
10419 { "and", "andc", "nor" },
10420 { "or", "orc", "nand" },
10421 { "xor", "eqv", "xor" } };
10422
10423 if (code == AND)
10424 t = tbl[0];
10425 else if (code == IOR)
10426 t = tbl[1];
10427 else if (code == XOR)
10428 t = tbl[2];
10429 else
10430 output_operand_lossage ("invalid %%q value");
10431
10432 if (GET_CODE (XEXP (x, 0)) != NOT)
10433 s = t[0];
10434 else
10435 {
10436 if (GET_CODE (XEXP (x, 1)) == NOT)
10437 s = t[2];
10438 else
10439 s = t[1];
10440 }
f676971a 10441
dfbdccdb
GK
10442 fputs (s, file);
10443 }
10444 return;
10445
2c4a9cff
DE
10446 case 'Q':
10447 if (TARGET_MFCRF)
3b6ce0af 10448 fputc (',', file);
5efb1046 10449 /* FALLTHRU */
2c4a9cff
DE
10450 else
10451 return;
10452
9854d9ed
RK
10453 case 'R':
10454 /* X is a CR register. Print the mask for `mtcrf'. */
10455 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
10456 output_operand_lossage ("invalid %%R value");
10457 else
9ebbca7d 10458 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 10459 return;
9854d9ed
RK
10460
10461 case 's':
10462 /* Low 5 bits of 32 - value */
10463 if (! INT_P (x))
10464 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
10465 else
10466 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 10467 return;
9854d9ed 10468
a260abc9 10469 case 'S':
0ba1b2ff 10470 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
10471 CONST_INT 32-bit mask is considered sign-extended so any
10472 transition must occur within the CONST_INT, not on the boundary. */
1990cd79 10473 if (! mask64_operand (x, DImode))
a260abc9
DE
10474 output_operand_lossage ("invalid %%S value");
10475
0ba1b2ff 10476 uval = INT_LOWPART (x);
a260abc9 10477
0ba1b2ff 10478 if (uval & 1) /* Clear Left */
a260abc9 10479 {
f099d360
GK
10480#if HOST_BITS_PER_WIDE_INT > 64
10481 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10482#endif
0ba1b2ff 10483 i = 64;
a260abc9 10484 }
0ba1b2ff 10485 else /* Clear Right */
a260abc9 10486 {
0ba1b2ff 10487 uval = ~uval;
f099d360
GK
10488#if HOST_BITS_PER_WIDE_INT > 64
10489 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
10490#endif
0ba1b2ff 10491 i = 63;
a260abc9 10492 }
0ba1b2ff
AM
10493 while (uval != 0)
10494 --i, uval >>= 1;
37409796 10495 gcc_assert (i >= 0);
0ba1b2ff
AM
10496 fprintf (file, "%d", i);
10497 return;
a260abc9 10498
a3170dc6
AH
10499 case 't':
10500 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
37409796 10501 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
a3170dc6
AH
10502
10503 /* Bit 3 is OV bit. */
10504 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
10505
10506 /* If we want bit 31, write a shift count of zero, not 32. */
10507 fprintf (file, "%d", i == 31 ? 0 : i + 1);
10508 return;
10509
cccf3bdc
DE
10510 case 'T':
10511 /* Print the symbolic name of a branch target register. */
10512 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
10513 && REGNO (x) != COUNT_REGISTER_REGNUM))
10514 output_operand_lossage ("invalid %%T value");
e2c953b6 10515 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
10516 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
10517 else
10518 fputs ("ctr", file);
10519 return;
10520
9854d9ed 10521 case 'u':
802a0058 10522 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
10523 if (! INT_P (x))
10524 output_operand_lossage ("invalid %%u value");
e2c953b6 10525 else
f676971a 10526 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
e2c953b6 10527 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
10528 return;
10529
802a0058
MM
10530 case 'v':
10531 /* High-order 16 bits of constant for use in signed operand. */
10532 if (! INT_P (x))
10533 output_operand_lossage ("invalid %%v value");
e2c953b6 10534 else
134c32f6
DE
10535 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
10536 (INT_LOWPART (x) >> 16) & 0xffff);
10537 return;
802a0058 10538
9854d9ed
RK
10539 case 'U':
10540 /* Print `u' if this has an auto-increment or auto-decrement. */
10541 if (GET_CODE (x) == MEM
10542 && (GET_CODE (XEXP (x, 0)) == PRE_INC
10543 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 10544 putc ('u', file);
9854d9ed 10545 return;
9878760c 10546
e0cd0770
JC
10547 case 'V':
10548 /* Print the trap code for this operand. */
10549 switch (GET_CODE (x))
10550 {
10551 case EQ:
10552 fputs ("eq", file); /* 4 */
10553 break;
10554 case NE:
10555 fputs ("ne", file); /* 24 */
10556 break;
10557 case LT:
10558 fputs ("lt", file); /* 16 */
10559 break;
10560 case LE:
10561 fputs ("le", file); /* 20 */
10562 break;
10563 case GT:
10564 fputs ("gt", file); /* 8 */
10565 break;
10566 case GE:
10567 fputs ("ge", file); /* 12 */
10568 break;
10569 case LTU:
10570 fputs ("llt", file); /* 2 */
10571 break;
10572 case LEU:
10573 fputs ("lle", file); /* 6 */
10574 break;
10575 case GTU:
10576 fputs ("lgt", file); /* 1 */
10577 break;
10578 case GEU:
10579 fputs ("lge", file); /* 5 */
10580 break;
10581 default:
37409796 10582 gcc_unreachable ();
e0cd0770
JC
10583 }
10584 break;
10585
9854d9ed
RK
10586 case 'w':
10587 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
10588 normally. */
10589 if (INT_P (x))
f676971a 10590 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5f59ecb7 10591 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
10592 else
10593 print_operand (file, x, 0);
9878760c
RK
10594 return;
10595
9854d9ed 10596 case 'W':
e2c953b6 10597 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
10598 val = (GET_CODE (x) == CONST_INT
10599 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
10600
10601 if (val < 0)
10602 i = -1;
9854d9ed 10603 else
e2c953b6
DE
10604 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
10605 if ((val <<= 1) < 0)
10606 break;
10607
10608#if HOST_BITS_PER_WIDE_INT == 32
10609 if (GET_CODE (x) == CONST_INT && i >= 0)
10610 i += 32; /* zero-extend high-part was all 0's */
10611 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
10612 {
10613 val = CONST_DOUBLE_LOW (x);
10614
37409796
NS
10615 gcc_assert (val);
10616 if (val < 0)
e2c953b6
DE
10617 --i;
10618 else
10619 for ( ; i < 64; i++)
10620 if ((val <<= 1) < 0)
10621 break;
10622 }
10623#endif
10624
10625 fprintf (file, "%d", i + 1);
9854d9ed 10626 return;
9878760c 10627
9854d9ed
RK
10628 case 'X':
10629 if (GET_CODE (x) == MEM
4d588c14 10630 && legitimate_indexed_address_p (XEXP (x, 0), 0))
76229ac8 10631 putc ('x', file);
9854d9ed 10632 return;
9878760c 10633
9854d9ed
RK
10634 case 'Y':
10635 /* Like 'L', for third word of TImode */
10636 if (GET_CODE (x) == REG)
fb5c67a7 10637 fputs (reg_names[REGNO (x) + 2], file);
9854d9ed 10638 else if (GET_CODE (x) == MEM)
9878760c 10639 {
9854d9ed
RK
10640 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10641 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 10642 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 10643 else
d7624dc0 10644 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 10645 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
10646 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10647 reg_names[SMALL_DATA_REG]);
9878760c
RK
10648 }
10649 return;
f676971a 10650
9878760c 10651 case 'z':
b4ac57ab
RS
10652 /* X is a SYMBOL_REF. Write out the name preceded by a
10653 period and without any trailing data in brackets. Used for function
4d30c363
MM
10654 names. If we are configured for System V (or the embedded ABI) on
10655 the PowerPC, do not emit the period, since those systems do not use
10656 TOCs and the like. */
37409796 10657 gcc_assert (GET_CODE (x) == SYMBOL_REF);
9878760c 10658
c4ad648e
AM
10659 /* Mark the decl as referenced so that cgraph will output the
10660 function. */
9bf6462a 10661 if (SYMBOL_REF_DECL (x))
c4ad648e 10662 mark_decl_referenced (SYMBOL_REF_DECL (x));
9bf6462a 10663
85b776df 10664 /* For macho, check to see if we need a stub. */
f9da97f0
AP
10665 if (TARGET_MACHO)
10666 {
10667 const char *name = XSTR (x, 0);
a031e781 10668#if TARGET_MACHO
3b48085e 10669 if (MACHOPIC_INDIRECT
11abc112
MM
10670 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
10671 name = machopic_indirection_name (x, /*stub_p=*/true);
f9da97f0
AP
10672#endif
10673 assemble_name (file, name);
10674 }
85b776df 10675 else if (!DOT_SYMBOLS)
9739c90c 10676 assemble_name (file, XSTR (x, 0));
85b776df
AM
10677 else
10678 rs6000_output_function_entry (file, XSTR (x, 0));
9878760c
RK
10679 return;
10680
9854d9ed
RK
10681 case 'Z':
10682 /* Like 'L', for last word of TImode. */
10683 if (GET_CODE (x) == REG)
fb5c67a7 10684 fputs (reg_names[REGNO (x) + 3], file);
9854d9ed
RK
10685 else if (GET_CODE (x) == MEM)
10686 {
10687 if (GET_CODE (XEXP (x, 0)) == PRE_INC
10688 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 10689 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 10690 else
d7624dc0 10691 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 10692 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
10693 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10694 reg_names[SMALL_DATA_REG]);
9854d9ed 10695 }
5c23c401 10696 return;
0ac081f6 10697
a3170dc6 10698 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
10699 case 'y':
10700 {
10701 rtx tmp;
10702
37409796 10703 gcc_assert (GET_CODE (x) == MEM);
0ac081f6
AH
10704
10705 tmp = XEXP (x, 0);
10706
993f19a8 10707 if (TARGET_E500)
a3170dc6
AH
10708 {
10709 /* Handle [reg]. */
10710 if (GET_CODE (tmp) == REG)
10711 {
10712 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
10713 break;
10714 }
10715 /* Handle [reg+UIMM]. */
10716 else if (GET_CODE (tmp) == PLUS &&
10717 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
10718 {
10719 int x;
10720
37409796 10721 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
a3170dc6
AH
10722
10723 x = INTVAL (XEXP (tmp, 1));
10724 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
10725 break;
10726 }
10727
10728 /* Fall through. Must be [reg+reg]. */
10729 }
850e8d3d
DN
10730 if (TARGET_ALTIVEC
10731 && GET_CODE (tmp) == AND
10732 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
10733 && INTVAL (XEXP (tmp, 1)) == -16)
10734 tmp = XEXP (tmp, 0);
0ac081f6 10735 if (GET_CODE (tmp) == REG)
c62f2db5 10736 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
37409796 10737 else
0ac081f6 10738 {
37409796 10739 gcc_assert (GET_CODE (tmp) == PLUS
9024f4b8
AM
10740 && REG_P (XEXP (tmp, 0))
10741 && REG_P (XEXP (tmp, 1)));
bb8df8a6 10742
0ac081f6
AH
10743 if (REGNO (XEXP (tmp, 0)) == 0)
10744 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
10745 reg_names[ REGNO (XEXP (tmp, 0)) ]);
10746 else
10747 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
10748 reg_names[ REGNO (XEXP (tmp, 1)) ]);
10749 }
0ac081f6
AH
10750 break;
10751 }
f676971a 10752
9878760c
RK
10753 case 0:
10754 if (GET_CODE (x) == REG)
10755 fprintf (file, "%s", reg_names[REGNO (x)]);
10756 else if (GET_CODE (x) == MEM)
10757 {
10758 /* We need to handle PRE_INC and PRE_DEC here, since we need to
10759 know the width from the mode. */
10760 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
10761 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
10762 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 10763 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
10764 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
10765 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 10766 else
a54d04b7 10767 output_address (XEXP (x, 0));
9878760c
RK
10768 }
10769 else
a54d04b7 10770 output_addr_const (file, x);
a85d226b 10771 return;
9878760c 10772
c4501e62
JJ
10773 case '&':
10774 assemble_name (file, rs6000_get_some_local_dynamic_name ());
10775 return;
10776
9878760c
RK
10777 default:
10778 output_operand_lossage ("invalid %%xn code");
10779 }
10780}
10781\f
10782/* Print the address of an operand. */
10783
10784void
a2369ed3 10785print_operand_address (FILE *file, rtx x)
9878760c
RK
10786{
10787 if (GET_CODE (x) == REG)
4697a36c 10788 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
10789 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
10790 || GET_CODE (x) == LABEL_REF)
9878760c
RK
10791 {
10792 output_addr_const (file, x);
ba5e43aa 10793 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
10794 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
10795 reg_names[SMALL_DATA_REG]);
37409796
NS
10796 else
10797 gcc_assert (!TARGET_TOC);
9878760c
RK
10798 }
10799 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
10800 {
9024f4b8 10801 gcc_assert (REG_P (XEXP (x, 0)));
9878760c 10802 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
10803 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
10804 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 10805 else
4697a36c
MM
10806 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
10807 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
10808 }
10809 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
4a0a75dd
KG
10810 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
10811 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
3cb999d8
DE
10812#if TARGET_ELF
10813 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
c4ad648e 10814 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
10815 {
10816 output_addr_const (file, XEXP (x, 1));
10817 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
10818 }
c859cda6
DJ
10819#endif
10820#if TARGET_MACHO
10821 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
c4ad648e 10822 && CONSTANT_P (XEXP (x, 1)))
c859cda6
DJ
10823 {
10824 fprintf (file, "lo16(");
10825 output_addr_const (file, XEXP (x, 1));
10826 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
10827 }
3cb999d8 10828#endif
4d588c14 10829 else if (legitimate_constant_pool_address_p (x))
9ebbca7d 10830 {
2bfcf297 10831 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 10832 {
2bfcf297
DB
10833 rtx contains_minus = XEXP (x, 1);
10834 rtx minus, symref;
10835 const char *name;
f676971a 10836
9ebbca7d 10837 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 10838 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
10839 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
10840 contains_minus = XEXP (contains_minus, 0);
10841
2bfcf297
DB
10842 minus = XEXP (contains_minus, 0);
10843 symref = XEXP (minus, 0);
10844 XEXP (contains_minus, 0) = symref;
10845 if (TARGET_ELF)
10846 {
10847 char *newname;
10848
10849 name = XSTR (symref, 0);
10850 newname = alloca (strlen (name) + sizeof ("@toc"));
10851 strcpy (newname, name);
10852 strcat (newname, "@toc");
10853 XSTR (symref, 0) = newname;
10854 }
10855 output_addr_const (file, XEXP (x, 1));
10856 if (TARGET_ELF)
10857 XSTR (symref, 0) = name;
9ebbca7d
GK
10858 XEXP (contains_minus, 0) = minus;
10859 }
10860 else
10861 output_addr_const (file, XEXP (x, 1));
10862
10863 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
10864 }
9878760c 10865 else
37409796 10866 gcc_unreachable ();
9878760c
RK
10867}
10868\f
88cad84b 10869/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
10870 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
10871 is defined. It also needs to handle DI-mode objects on 64-bit
10872 targets. */
10873
10874static bool
a2369ed3 10875rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
301d03af 10876{
f4f4921e 10877#ifdef RELOCATABLE_NEEDS_FIXUP
301d03af 10878 /* Special handling for SI values. */
84dcde01 10879 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
301d03af 10880 {
301d03af 10881 static int recurse = 0;
f676971a 10882
301d03af
RS
10883 /* For -mrelocatable, we mark all addresses that need to be fixed up
10884 in the .fixup section. */
10885 if (TARGET_RELOCATABLE
d6b5193b
RS
10886 && in_section != toc_section
10887 && in_section != text_section
4325ca90 10888 && !unlikely_text_section_p (in_section)
301d03af
RS
10889 && !recurse
10890 && GET_CODE (x) != CONST_INT
10891 && GET_CODE (x) != CONST_DOUBLE
10892 && CONSTANT_P (x))
10893 {
10894 char buf[256];
10895
10896 recurse = 1;
10897 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
10898 fixuplabelno++;
10899 ASM_OUTPUT_LABEL (asm_out_file, buf);
10900 fprintf (asm_out_file, "\t.long\t(");
10901 output_addr_const (asm_out_file, x);
10902 fprintf (asm_out_file, ")@fixup\n");
10903 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
10904 ASM_OUTPUT_ALIGN (asm_out_file, 2);
10905 fprintf (asm_out_file, "\t.long\t");
10906 assemble_name (asm_out_file, buf);
10907 fprintf (asm_out_file, "\n\t.previous\n");
10908 recurse = 0;
10909 return true;
10910 }
10911 /* Remove initial .'s to turn a -mcall-aixdesc function
10912 address into the address of the descriptor, not the function
10913 itself. */
10914 else if (GET_CODE (x) == SYMBOL_REF
10915 && XSTR (x, 0)[0] == '.'
10916 && DEFAULT_ABI == ABI_AIX)
10917 {
10918 const char *name = XSTR (x, 0);
10919 while (*name == '.')
10920 name++;
10921
10922 fprintf (asm_out_file, "\t.long\t%s\n", name);
10923 return true;
10924 }
10925 }
f4f4921e 10926#endif /* RELOCATABLE_NEEDS_FIXUP */
301d03af
RS
10927 return default_assemble_integer (x, size, aligned_p);
10928}
93638d7a
AM
10929
10930#ifdef HAVE_GAS_HIDDEN
10931/* Emit an assembler directive to set symbol visibility for DECL to
10932 VISIBILITY_TYPE. */
10933
5add3202 10934static void
a2369ed3 10935rs6000_assemble_visibility (tree decl, int vis)
93638d7a 10936{
93638d7a
AM
10937 /* Functions need to have their entry point symbol visibility set as
10938 well as their descriptor symbol visibility. */
85b776df
AM
10939 if (DEFAULT_ABI == ABI_AIX
10940 && DOT_SYMBOLS
10941 && TREE_CODE (decl) == FUNCTION_DECL)
93638d7a 10942 {
25fdb4dc 10943 static const char * const visibility_types[] = {
c4ad648e 10944 NULL, "internal", "hidden", "protected"
25fdb4dc
RH
10945 };
10946
10947 const char *name, *type;
93638d7a
AM
10948
10949 name = ((* targetm.strip_name_encoding)
10950 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
25fdb4dc 10951 type = visibility_types[vis];
93638d7a 10952
25fdb4dc
RH
10953 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
10954 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
93638d7a 10955 }
25fdb4dc
RH
10956 else
10957 default_assemble_visibility (decl, vis);
93638d7a
AM
10958}
10959#endif
301d03af 10960\f
39a10a29 10961enum rtx_code
a2369ed3 10962rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
39a10a29
GK
10963{
10964 /* Reversal of FP compares takes care -- an ordered compare
10965 becomes an unordered compare and vice versa. */
f676971a 10966 if (mode == CCFPmode
bc9ec0e0
GK
10967 && (!flag_finite_math_only
10968 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
10969 || code == UNEQ || code == LTGT))
bab6226b 10970 return reverse_condition_maybe_unordered (code);
39a10a29 10971 else
bab6226b 10972 return reverse_condition (code);
39a10a29
GK
10973}
10974
39a10a29
GK
10975/* Generate a compare for CODE. Return a brand-new rtx that
10976 represents the result of the compare. */
a4f6c312 10977
39a10a29 10978static rtx
a2369ed3 10979rs6000_generate_compare (enum rtx_code code)
39a10a29
GK
10980{
10981 enum machine_mode comp_mode;
10982 rtx compare_result;
10983
10984 if (rs6000_compare_fp_p)
10985 comp_mode = CCFPmode;
10986 else if (code == GTU || code == LTU
c4ad648e 10987 || code == GEU || code == LEU)
39a10a29 10988 comp_mode = CCUNSmode;
60934f9c
NS
10989 else if ((code == EQ || code == NE)
10990 && GET_CODE (rs6000_compare_op0) == SUBREG
10991 && GET_CODE (rs6000_compare_op1) == SUBREG
10992 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
10993 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
10994 /* These are unsigned values, perhaps there will be a later
10995 ordering compare that can be shared with this one.
10996 Unfortunately we cannot detect the signedness of the operands
10997 for non-subregs. */
10998 comp_mode = CCUNSmode;
39a10a29
GK
10999 else
11000 comp_mode = CCmode;
11001
11002 /* First, the compare. */
11003 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
11004
11005 /* SPE FP compare instructions on the GPRs. Yuck! */
993f19a8
AH
11006 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11007 && rs6000_compare_fp_p)
a3170dc6 11008 {
64022b5d 11009 rtx cmp, or_result, compare_result2;
4d4cbc0e
AH
11010 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
11011
11012 if (op_mode == VOIDmode)
11013 op_mode = GET_MODE (rs6000_compare_op1);
a3170dc6 11014
423c1189
AH
11015 /* Note: The E500 comparison instructions set the GT bit (x +
11016 1), on success. This explains the mess. */
11017
a3170dc6
AH
11018 switch (code)
11019 {
423c1189 11020 case EQ: case UNEQ: case NE: case LTGT:
37409796
NS
11021 switch (op_mode)
11022 {
11023 case SFmode:
11024 cmp = flag_unsafe_math_optimizations
11025 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
11026 rs6000_compare_op1)
11027 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
11028 rs6000_compare_op1);
11029 break;
11030
11031 case DFmode:
11032 cmp = flag_unsafe_math_optimizations
11033 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
11034 rs6000_compare_op1)
11035 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
11036 rs6000_compare_op1);
11037 break;
11038
11039 default:
11040 gcc_unreachable ();
11041 }
a3170dc6 11042 break;
bb8df8a6 11043
423c1189 11044 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
37409796
NS
11045 switch (op_mode)
11046 {
11047 case SFmode:
11048 cmp = flag_unsafe_math_optimizations
11049 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
11050 rs6000_compare_op1)
11051 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
11052 rs6000_compare_op1);
11053 break;
bb8df8a6 11054
37409796
NS
11055 case DFmode:
11056 cmp = flag_unsafe_math_optimizations
11057 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
11058 rs6000_compare_op1)
11059 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
11060 rs6000_compare_op1);
11061 break;
11062
11063 default:
11064 gcc_unreachable ();
11065 }
a3170dc6 11066 break;
bb8df8a6 11067
423c1189 11068 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
37409796
NS
11069 switch (op_mode)
11070 {
11071 case SFmode:
11072 cmp = flag_unsafe_math_optimizations
11073 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
11074 rs6000_compare_op1)
11075 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
11076 rs6000_compare_op1);
11077 break;
bb8df8a6 11078
37409796
NS
11079 case DFmode:
11080 cmp = flag_unsafe_math_optimizations
11081 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
11082 rs6000_compare_op1)
11083 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
11084 rs6000_compare_op1);
11085 break;
11086
11087 default:
11088 gcc_unreachable ();
11089 }
a3170dc6 11090 break;
4d4cbc0e 11091 default:
37409796 11092 gcc_unreachable ();
a3170dc6
AH
11093 }
11094
11095 /* Synthesize LE and GE from LT/GT || EQ. */
11096 if (code == LE || code == GE || code == LEU || code == GEU)
11097 {
a3170dc6
AH
11098 emit_insn (cmp);
11099
11100 switch (code)
11101 {
11102 case LE: code = LT; break;
11103 case GE: code = GT; break;
11104 case LEU: code = LT; break;
11105 case GEU: code = GT; break;
37409796 11106 default: gcc_unreachable ();
a3170dc6
AH
11107 }
11108
a3170dc6
AH
11109 compare_result2 = gen_reg_rtx (CCFPmode);
11110
11111 /* Do the EQ. */
37409796
NS
11112 switch (op_mode)
11113 {
11114 case SFmode:
11115 cmp = flag_unsafe_math_optimizations
11116 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
11117 rs6000_compare_op1)
11118 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
11119 rs6000_compare_op1);
11120 break;
11121
11122 case DFmode:
11123 cmp = flag_unsafe_math_optimizations
11124 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
11125 rs6000_compare_op1)
11126 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
11127 rs6000_compare_op1);
11128 break;
11129
11130 default:
11131 gcc_unreachable ();
11132 }
a3170dc6
AH
11133 emit_insn (cmp);
11134
a3170dc6 11135 /* OR them together. */
64022b5d
AH
11136 or_result = gen_reg_rtx (CCFPmode);
11137 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
11138 compare_result2);
a3170dc6
AH
11139 compare_result = or_result;
11140 code = EQ;
11141 }
11142 else
11143 {
a3170dc6 11144 if (code == NE || code == LTGT)
a3170dc6 11145 code = NE;
423c1189
AH
11146 else
11147 code = EQ;
a3170dc6
AH
11148 }
11149
11150 emit_insn (cmp);
11151 }
11152 else
de17c25f
DE
11153 {
11154 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
11155 CLOBBERs to match cmptf_internal2 pattern. */
11156 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
11157 && GET_MODE (rs6000_compare_op0) == TFmode
602ea4d3 11158 && !TARGET_IEEEQUAD
de17c25f
DE
11159 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
11160 emit_insn (gen_rtx_PARALLEL (VOIDmode,
11161 gen_rtvec (9,
11162 gen_rtx_SET (VOIDmode,
11163 compare_result,
11164 gen_rtx_COMPARE (comp_mode,
11165 rs6000_compare_op0,
11166 rs6000_compare_op1)),
11167 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11168 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11169 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11170 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11171 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11172 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11173 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
11174 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
3aebbe5f
JJ
11175 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
11176 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
11177 {
11178 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
11179 comp_mode = CCEQmode;
11180 compare_result = gen_reg_rtx (CCEQmode);
11181 if (TARGET_64BIT)
11182 emit_insn (gen_stack_protect_testdi (compare_result,
11183 rs6000_compare_op0, op1));
11184 else
11185 emit_insn (gen_stack_protect_testsi (compare_result,
11186 rs6000_compare_op0, op1));
11187 }
de17c25f
DE
11188 else
11189 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
11190 gen_rtx_COMPARE (comp_mode,
11191 rs6000_compare_op0,
11192 rs6000_compare_op1)));
11193 }
f676971a 11194
ca5adc63 11195 /* Some kinds of FP comparisons need an OR operation;
e7108df9 11196 under flag_finite_math_only we don't bother. */
39a10a29 11197 if (rs6000_compare_fp_p
e7108df9
DE
11198 && !flag_finite_math_only
11199 && !(TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)
39a10a29
GK
11200 && (code == LE || code == GE
11201 || code == UNEQ || code == LTGT
11202 || code == UNGT || code == UNLT))
11203 {
11204 enum rtx_code or1, or2;
11205 rtx or1_rtx, or2_rtx, compare2_rtx;
11206 rtx or_result = gen_reg_rtx (CCEQmode);
f676971a 11207
39a10a29
GK
11208 switch (code)
11209 {
11210 case LE: or1 = LT; or2 = EQ; break;
11211 case GE: or1 = GT; or2 = EQ; break;
11212 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
11213 case LTGT: or1 = LT; or2 = GT; break;
11214 case UNGT: or1 = UNORDERED; or2 = GT; break;
11215 case UNLT: or1 = UNORDERED; or2 = LT; break;
37409796 11216 default: gcc_unreachable ();
39a10a29
GK
11217 }
11218 validate_condition_mode (or1, comp_mode);
11219 validate_condition_mode (or2, comp_mode);
1c563bed
KH
11220 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
11221 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
39a10a29
GK
11222 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
11223 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
11224 const_true_rtx);
11225 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
11226
11227 compare_result = or_result;
11228 code = EQ;
11229 }
11230
11231 validate_condition_mode (code, GET_MODE (compare_result));
f676971a 11232
1c563bed 11233 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
39a10a29
GK
11234}
11235
11236
11237/* Emit the RTL for an sCOND pattern. */
11238
11239void
a2369ed3 11240rs6000_emit_sCOND (enum rtx_code code, rtx result)
39a10a29
GK
11241{
11242 rtx condition_rtx;
11243 enum machine_mode op_mode;
b7053a3f 11244 enum rtx_code cond_code;
39a10a29
GK
11245
11246 condition_rtx = rs6000_generate_compare (code);
b7053a3f
GK
11247 cond_code = GET_CODE (condition_rtx);
11248
423c1189
AH
11249 if (TARGET_E500 && rs6000_compare_fp_p
11250 && !TARGET_FPRS && TARGET_HARD_FLOAT)
11251 {
11252 rtx t;
11253
11254 PUT_MODE (condition_rtx, SImode);
11255 t = XEXP (condition_rtx, 0);
11256
37409796 11257 gcc_assert (cond_code == NE || cond_code == EQ);
423c1189
AH
11258
11259 if (cond_code == NE)
64022b5d 11260 emit_insn (gen_e500_flip_gt_bit (t, t));
423c1189 11261
64022b5d 11262 emit_insn (gen_move_from_CR_gt_bit (result, t));
423c1189
AH
11263 return;
11264 }
11265
b7053a3f
GK
11266 if (cond_code == NE
11267 || cond_code == GE || cond_code == LE
11268 || cond_code == GEU || cond_code == LEU
11269 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
11270 {
11271 rtx not_result = gen_reg_rtx (CCEQmode);
11272 rtx not_op, rev_cond_rtx;
11273 enum machine_mode cc_mode;
f676971a 11274
b7053a3f
GK
11275 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
11276
1c563bed 11277 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
0f4c242b 11278 SImode, XEXP (condition_rtx, 0), const0_rtx);
b7053a3f
GK
11279 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
11280 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
11281 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
11282 }
39a10a29
GK
11283
11284 op_mode = GET_MODE (rs6000_compare_op0);
11285 if (op_mode == VOIDmode)
11286 op_mode = GET_MODE (rs6000_compare_op1);
11287
11288 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
11289 {
11290 PUT_MODE (condition_rtx, DImode);
11291 convert_move (result, condition_rtx, 0);
11292 }
11293 else
11294 {
11295 PUT_MODE (condition_rtx, SImode);
11296 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
11297 }
11298}
11299
39a10a29
GK
11300/* Emit a branch of kind CODE to location LOC. */
11301
11302void
a2369ed3 11303rs6000_emit_cbranch (enum rtx_code code, rtx loc)
39a10a29
GK
11304{
11305 rtx condition_rtx, loc_ref;
11306
11307 condition_rtx = rs6000_generate_compare (code);
11308 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
11309 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
11310 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
11311 loc_ref, pc_rtx)));
11312}
11313
12a4e8c5
GK
11314/* Return the string to output a conditional branch to LABEL, which is
11315 the operand number of the label, or -1 if the branch is really a
f676971a 11316 conditional return.
12a4e8c5
GK
11317
11318 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
11319 condition code register and its mode specifies what kind of
11320 comparison we made.
11321
a0ab749a 11322 REVERSED is nonzero if we should reverse the sense of the comparison.
12a4e8c5
GK
11323
11324 INSN is the insn. */
11325
11326char *
a2369ed3 11327output_cbranch (rtx op, const char *label, int reversed, rtx insn)
12a4e8c5
GK
11328{
11329 static char string[64];
11330 enum rtx_code code = GET_CODE (op);
11331 rtx cc_reg = XEXP (op, 0);
11332 enum machine_mode mode = GET_MODE (cc_reg);
11333 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 11334 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
11335 int really_reversed = reversed ^ need_longbranch;
11336 char *s = string;
11337 const char *ccode;
11338 const char *pred;
11339 rtx note;
11340
39a10a29
GK
11341 validate_condition_mode (code, mode);
11342
11343 /* Work out which way this really branches. We could use
11344 reverse_condition_maybe_unordered here always but this
11345 makes the resulting assembler clearer. */
12a4e8c5 11346 if (really_reversed)
de40e1df
DJ
11347 {
11348 /* Reversal of FP compares takes care -- an ordered compare
11349 becomes an unordered compare and vice versa. */
11350 if (mode == CCFPmode)
11351 code = reverse_condition_maybe_unordered (code);
11352 else
11353 code = reverse_condition (code);
11354 }
12a4e8c5 11355
993f19a8 11356 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
a3170dc6
AH
11357 {
11358 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
11359 to the GT bit. */
37409796
NS
11360 switch (code)
11361 {
11362 case EQ:
11363 /* Opposite of GT. */
11364 code = GT;
11365 break;
11366
11367 case NE:
11368 code = UNLE;
11369 break;
11370
11371 default:
11372 gcc_unreachable ();
11373 }
a3170dc6
AH
11374 }
11375
39a10a29 11376 switch (code)
12a4e8c5
GK
11377 {
11378 /* Not all of these are actually distinct opcodes, but
11379 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
11380 case NE: case LTGT:
11381 ccode = "ne"; break;
11382 case EQ: case UNEQ:
11383 ccode = "eq"; break;
f676971a 11384 case GE: case GEU:
50a0b056 11385 ccode = "ge"; break;
f676971a 11386 case GT: case GTU: case UNGT:
50a0b056 11387 ccode = "gt"; break;
f676971a 11388 case LE: case LEU:
50a0b056 11389 ccode = "le"; break;
f676971a 11390 case LT: case LTU: case UNLT:
50a0b056 11391 ccode = "lt"; break;
12a4e8c5
GK
11392 case UNORDERED: ccode = "un"; break;
11393 case ORDERED: ccode = "nu"; break;
11394 case UNGE: ccode = "nl"; break;
11395 case UNLE: ccode = "ng"; break;
11396 default:
37409796 11397 gcc_unreachable ();
12a4e8c5 11398 }
f676971a
EC
11399
11400 /* Maybe we have a guess as to how likely the branch is.
94a54f47 11401 The old mnemonics don't have a way to specify this information. */
f4857b9b 11402 pred = "";
12a4e8c5
GK
11403 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
11404 if (note != NULL_RTX)
11405 {
11406 /* PROB is the difference from 50%. */
11407 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
11408
11409 /* Only hint for highly probable/improbable branches on newer
11410 cpus as static prediction overrides processor dynamic
11411 prediction. For older cpus we may as well always hint, but
11412 assume not taken for branches that are very close to 50% as a
11413 mispredicted taken branch is more expensive than a
f676971a 11414 mispredicted not-taken branch. */
ec507f2d 11415 if (rs6000_always_hint
f4857b9b
AM
11416 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
11417 {
11418 if (abs (prob) > REG_BR_PROB_BASE / 20
11419 && ((prob > 0) ^ need_longbranch))
c4ad648e 11420 pred = "+";
f4857b9b
AM
11421 else
11422 pred = "-";
11423 }
12a4e8c5 11424 }
12a4e8c5
GK
11425
11426 if (label == NULL)
94a54f47 11427 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 11428 else
94a54f47 11429 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 11430
37c67319 11431 /* We need to escape any '%' characters in the reg_names string.
a3c9585f 11432 Assume they'd only be the first character.... */
37c67319
GK
11433 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
11434 *s++ = '%';
94a54f47 11435 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
11436
11437 if (label != NULL)
11438 {
11439 /* If the branch distance was too far, we may have to use an
11440 unconditional branch to go the distance. */
11441 if (need_longbranch)
44518ddd 11442 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
11443 else
11444 s += sprintf (s, ",%s", label);
11445 }
11446
11447 return string;
11448}
50a0b056 11449
64022b5d 11450/* Return the string to flip the GT bit on a CR. */
423c1189 11451char *
64022b5d 11452output_e500_flip_gt_bit (rtx dst, rtx src)
423c1189
AH
11453{
11454 static char string[64];
11455 int a, b;
11456
37409796
NS
11457 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
11458 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
423c1189 11459
64022b5d
AH
11460 /* GT bit. */
11461 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
11462 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
423c1189
AH
11463
11464 sprintf (string, "crnot %d,%d", a, b);
11465 return string;
11466}
11467
21213b4c
DP
11468/* Return insn index for the vector compare instruction for given CODE,
11469 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
11470 not available. */
11471
11472static int
94ff898d 11473get_vec_cmp_insn (enum rtx_code code,
21213b4c
DP
11474 enum machine_mode dest_mode,
11475 enum machine_mode op_mode)
11476{
11477 if (!TARGET_ALTIVEC)
11478 return INSN_NOT_AVAILABLE;
11479
11480 switch (code)
11481 {
11482 case EQ:
11483 if (dest_mode == V16QImode && op_mode == V16QImode)
11484 return UNSPEC_VCMPEQUB;
11485 if (dest_mode == V8HImode && op_mode == V8HImode)
11486 return UNSPEC_VCMPEQUH;
11487 if (dest_mode == V4SImode && op_mode == V4SImode)
11488 return UNSPEC_VCMPEQUW;
11489 if (dest_mode == V4SImode && op_mode == V4SFmode)
11490 return UNSPEC_VCMPEQFP;
11491 break;
11492 case GE:
11493 if (dest_mode == V4SImode && op_mode == V4SFmode)
11494 return UNSPEC_VCMPGEFP;
11495 case GT:
11496 if (dest_mode == V16QImode && op_mode == V16QImode)
11497 return UNSPEC_VCMPGTSB;
11498 if (dest_mode == V8HImode && op_mode == V8HImode)
11499 return UNSPEC_VCMPGTSH;
11500 if (dest_mode == V4SImode && op_mode == V4SImode)
11501 return UNSPEC_VCMPGTSW;
11502 if (dest_mode == V4SImode && op_mode == V4SFmode)
11503 return UNSPEC_VCMPGTFP;
11504 break;
11505 case GTU:
11506 if (dest_mode == V16QImode && op_mode == V16QImode)
11507 return UNSPEC_VCMPGTUB;
11508 if (dest_mode == V8HImode && op_mode == V8HImode)
11509 return UNSPEC_VCMPGTUH;
11510 if (dest_mode == V4SImode && op_mode == V4SImode)
11511 return UNSPEC_VCMPGTUW;
11512 break;
11513 default:
11514 break;
11515 }
11516 return INSN_NOT_AVAILABLE;
11517}
11518
11519/* Emit vector compare for operands OP0 and OP1 using code RCODE.
11520 DMODE is expected destination mode. This is a recursive function. */
11521
11522static rtx
11523rs6000_emit_vector_compare (enum rtx_code rcode,
11524 rtx op0, rtx op1,
11525 enum machine_mode dmode)
11526{
11527 int vec_cmp_insn;
11528 rtx mask;
11529 enum machine_mode dest_mode;
11530 enum machine_mode op_mode = GET_MODE (op1);
11531
37409796
NS
11532 gcc_assert (TARGET_ALTIVEC);
11533 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
21213b4c
DP
11534
11535 /* Floating point vector compare instructions uses destination V4SImode.
11536 Move destination to appropriate mode later. */
11537 if (dmode == V4SFmode)
11538 dest_mode = V4SImode;
11539 else
11540 dest_mode = dmode;
11541
11542 mask = gen_reg_rtx (dest_mode);
11543 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
11544
11545 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
11546 {
11547 bool swap_operands = false;
11548 bool try_again = false;
11549 switch (rcode)
11550 {
11551 case LT:
11552 rcode = GT;
11553 swap_operands = true;
11554 try_again = true;
11555 break;
11556 case LTU:
11557 rcode = GTU;
11558 swap_operands = true;
11559 try_again = true;
11560 break;
11561 case NE:
11562 /* Treat A != B as ~(A==B). */
11563 {
11564 enum insn_code nor_code;
11565 rtx eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11566 dest_mode);
94ff898d 11567
21213b4c 11568 nor_code = one_cmpl_optab->handlers[(int)dest_mode].insn_code;
37409796 11569 gcc_assert (nor_code != CODE_FOR_nothing);
21213b4c
DP
11570 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
11571
11572 if (dmode != dest_mode)
11573 {
11574 rtx temp = gen_reg_rtx (dest_mode);
11575 convert_move (temp, mask, 0);
11576 return temp;
11577 }
11578 return mask;
11579 }
11580 break;
11581 case GE:
11582 case GEU:
11583 case LE:
11584 case LEU:
11585 /* Try GT/GTU/LT/LTU OR EQ */
11586 {
11587 rtx c_rtx, eq_rtx;
11588 enum insn_code ior_code;
11589 enum rtx_code new_code;
11590
37409796
NS
11591 switch (rcode)
11592 {
11593 case GE:
11594 new_code = GT;
11595 break;
11596
11597 case GEU:
11598 new_code = GTU;
11599 break;
11600
11601 case LE:
11602 new_code = LT;
11603 break;
11604
11605 case LEU:
11606 new_code = LTU;
11607 break;
11608
11609 default:
11610 gcc_unreachable ();
11611 }
21213b4c
DP
11612
11613 c_rtx = rs6000_emit_vector_compare (new_code,
11614 op0, op1, dest_mode);
11615 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
11616 dest_mode);
11617
11618 ior_code = ior_optab->handlers[(int)dest_mode].insn_code;
37409796 11619 gcc_assert (ior_code != CODE_FOR_nothing);
21213b4c
DP
11620 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
11621 if (dmode != dest_mode)
11622 {
11623 rtx temp = gen_reg_rtx (dest_mode);
11624 convert_move (temp, mask, 0);
11625 return temp;
11626 }
11627 return mask;
11628 }
11629 break;
11630 default:
37409796 11631 gcc_unreachable ();
21213b4c
DP
11632 }
11633
11634 if (try_again)
11635 {
11636 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
37409796
NS
11637 /* You only get two chances. */
11638 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
21213b4c
DP
11639 }
11640
11641 if (swap_operands)
11642 {
11643 rtx tmp;
11644 tmp = op0;
11645 op0 = op1;
11646 op1 = tmp;
11647 }
11648 }
11649
915167f5
GK
11650 emit_insn (gen_rtx_SET (VOIDmode, mask,
11651 gen_rtx_UNSPEC (dest_mode,
11652 gen_rtvec (2, op0, op1),
11653 vec_cmp_insn)));
21213b4c
DP
11654 if (dmode != dest_mode)
11655 {
11656 rtx temp = gen_reg_rtx (dest_mode);
11657 convert_move (temp, mask, 0);
11658 return temp;
11659 }
11660 return mask;
11661}
11662
11663/* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
11664 valid insn doesn exist for given mode. */
11665
11666static int
11667get_vsel_insn (enum machine_mode mode)
11668{
11669 switch (mode)
11670 {
11671 case V4SImode:
11672 return UNSPEC_VSEL4SI;
11673 break;
11674 case V4SFmode:
11675 return UNSPEC_VSEL4SF;
11676 break;
11677 case V8HImode:
11678 return UNSPEC_VSEL8HI;
11679 break;
11680 case V16QImode:
11681 return UNSPEC_VSEL16QI;
11682 break;
11683 default:
11684 return INSN_NOT_AVAILABLE;
11685 break;
11686 }
11687 return INSN_NOT_AVAILABLE;
11688}
11689
11690/* Emit vector select insn where DEST is destination using
11691 operands OP1, OP2 and MASK. */
11692
11693static void
11694rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
11695{
11696 rtx t, temp;
11697 enum machine_mode dest_mode = GET_MODE (dest);
11698 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
11699
11700 temp = gen_reg_rtx (dest_mode);
94ff898d 11701
bb8df8a6 11702 /* For each vector element, select op1 when mask is 1 otherwise
19f1ebc7 11703 select op2. */
915167f5
GK
11704 t = gen_rtx_SET (VOIDmode, temp,
11705 gen_rtx_UNSPEC (dest_mode,
11706 gen_rtvec (3, op2, op1, mask),
11707 vsel_insn_index));
21213b4c
DP
11708 emit_insn (t);
11709 emit_move_insn (dest, temp);
11710 return;
11711}
11712
94ff898d 11713/* Emit vector conditional expression.
21213b4c
DP
11714 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
11715 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
11716
11717int
11718rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
11719 rtx cond, rtx cc_op0, rtx cc_op1)
11720{
11721 enum machine_mode dest_mode = GET_MODE (dest);
11722 enum rtx_code rcode = GET_CODE (cond);
11723 rtx mask;
11724
11725 if (!TARGET_ALTIVEC)
11726 return 0;
11727
11728 /* Get the vector mask for the given relational operations. */
11729 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
11730
11731 rs6000_emit_vector_select (dest, op1, op2, mask);
11732
11733 return 1;
11734}
11735
50a0b056
GK
11736/* Emit a conditional move: move TRUE_COND to DEST if OP of the
11737 operands of the last comparison is nonzero/true, FALSE_COND if it
11738 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 11739
50a0b056 11740int
a2369ed3 11741rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
50a0b056
GK
11742{
11743 enum rtx_code code = GET_CODE (op);
11744 rtx op0 = rs6000_compare_op0;
11745 rtx op1 = rs6000_compare_op1;
11746 REAL_VALUE_TYPE c1;
3148ad6d
DJ
11747 enum machine_mode compare_mode = GET_MODE (op0);
11748 enum machine_mode result_mode = GET_MODE (dest);
50a0b056 11749 rtx temp;
add2402e 11750 bool is_against_zero;
50a0b056 11751
a3c9585f 11752 /* These modes should always match. */
a3170dc6
AH
11753 if (GET_MODE (op1) != compare_mode
11754 /* In the isel case however, we can use a compare immediate, so
11755 op1 may be a small constant. */
11756 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 11757 return 0;
178c3eff 11758 if (GET_MODE (true_cond) != result_mode)
3148ad6d 11759 return 0;
178c3eff 11760 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
11761 return 0;
11762
50a0b056 11763 /* First, work out if the hardware can do this at all, or
a3c9585f 11764 if it's too slow.... */
50a0b056 11765 if (! rs6000_compare_fp_p)
a3170dc6
AH
11766 {
11767 if (TARGET_ISEL)
11768 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
11769 return 0;
11770 }
fef98bf2 11771 else if (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS
ebb109ad 11772 && SCALAR_FLOAT_MODE_P (compare_mode))
fef98bf2 11773 return 0;
50a0b056 11774
add2402e 11775 is_against_zero = op1 == CONST0_RTX (compare_mode);
94ff898d 11776
add2402e
GK
11777 /* A floating-point subtract might overflow, underflow, or produce
11778 an inexact result, thus changing the floating-point flags, so it
11779 can't be generated if we care about that. It's safe if one side
11780 of the construct is zero, since then no subtract will be
11781 generated. */
ebb109ad 11782 if (SCALAR_FLOAT_MODE_P (compare_mode)
add2402e
GK
11783 && flag_trapping_math && ! is_against_zero)
11784 return 0;
11785
50a0b056
GK
11786 /* Eliminate half of the comparisons by switching operands, this
11787 makes the remaining code simpler. */
11788 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
bc9ec0e0 11789 || code == LTGT || code == LT || code == UNLE)
50a0b056
GK
11790 {
11791 code = reverse_condition_maybe_unordered (code);
11792 temp = true_cond;
11793 true_cond = false_cond;
11794 false_cond = temp;
11795 }
11796
11797 /* UNEQ and LTGT take four instructions for a comparison with zero,
11798 it'll probably be faster to use a branch here too. */
bc9ec0e0 11799 if (code == UNEQ && HONOR_NANS (compare_mode))
50a0b056 11800 return 0;
f676971a 11801
50a0b056
GK
11802 if (GET_CODE (op1) == CONST_DOUBLE)
11803 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
f676971a 11804
b6d08ca1 11805 /* We're going to try to implement comparisons by performing
50a0b056
GK
11806 a subtract, then comparing against zero. Unfortunately,
11807 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 11808 know that the operand is finite and the comparison
50a0b056 11809 would treat EQ different to UNORDERED, we can't do it. */
bc9ec0e0 11810 if (HONOR_INFINITIES (compare_mode)
50a0b056 11811 && code != GT && code != UNGE
045572c7 11812 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
11813 /* Constructs of the form (a OP b ? a : b) are safe. */
11814 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
f676971a 11815 || (! rtx_equal_p (op0, true_cond)
50a0b056
GK
11816 && ! rtx_equal_p (op1, true_cond))))
11817 return 0;
add2402e 11818
50a0b056
GK
11819 /* At this point we know we can use fsel. */
11820
11821 /* Reduce the comparison to a comparison against zero. */
add2402e
GK
11822 if (! is_against_zero)
11823 {
11824 temp = gen_reg_rtx (compare_mode);
11825 emit_insn (gen_rtx_SET (VOIDmode, temp,
11826 gen_rtx_MINUS (compare_mode, op0, op1)));
11827 op0 = temp;
11828 op1 = CONST0_RTX (compare_mode);
11829 }
50a0b056
GK
11830
11831 /* If we don't care about NaNs we can reduce some of the comparisons
11832 down to faster ones. */
bc9ec0e0 11833 if (! HONOR_NANS (compare_mode))
50a0b056
GK
11834 switch (code)
11835 {
11836 case GT:
11837 code = LE;
11838 temp = true_cond;
11839 true_cond = false_cond;
11840 false_cond = temp;
11841 break;
11842 case UNGE:
11843 code = GE;
11844 break;
11845 case UNEQ:
11846 code = EQ;
11847 break;
11848 default:
11849 break;
11850 }
11851
11852 /* Now, reduce everything down to a GE. */
11853 switch (code)
11854 {
11855 case GE:
11856 break;
11857
11858 case LE:
3148ad6d
DJ
11859 temp = gen_reg_rtx (compare_mode);
11860 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
11861 op0 = temp;
11862 break;
11863
11864 case ORDERED:
3148ad6d
DJ
11865 temp = gen_reg_rtx (compare_mode);
11866 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
11867 op0 = temp;
11868 break;
11869
11870 case EQ:
3148ad6d 11871 temp = gen_reg_rtx (compare_mode);
f676971a 11872 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
11873 gen_rtx_NEG (compare_mode,
11874 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
11875 op0 = temp;
11876 break;
11877
11878 case UNGE:
bc9ec0e0 11879 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
3148ad6d 11880 temp = gen_reg_rtx (result_mode);
50a0b056 11881 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 11882 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
11883 gen_rtx_GE (VOIDmode,
11884 op0, op1),
11885 true_cond, false_cond)));
bc9ec0e0
GK
11886 false_cond = true_cond;
11887 true_cond = temp;
50a0b056 11888
3148ad6d
DJ
11889 temp = gen_reg_rtx (compare_mode);
11890 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
11891 op0 = temp;
11892 break;
11893
11894 case GT:
bc9ec0e0 11895 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
3148ad6d 11896 temp = gen_reg_rtx (result_mode);
50a0b056 11897 emit_insn (gen_rtx_SET (VOIDmode, temp,
f676971a 11898 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
11899 gen_rtx_GE (VOIDmode,
11900 op0, op1),
11901 true_cond, false_cond)));
bc9ec0e0
GK
11902 true_cond = false_cond;
11903 false_cond = temp;
50a0b056 11904
3148ad6d
DJ
11905 temp = gen_reg_rtx (compare_mode);
11906 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
11907 op0 = temp;
11908 break;
11909
11910 default:
37409796 11911 gcc_unreachable ();
50a0b056
GK
11912 }
11913
11914 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 11915 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
11916 gen_rtx_GE (VOIDmode,
11917 op0, op1),
11918 true_cond, false_cond)));
11919 return 1;
11920}
11921
a3170dc6
AH
11922/* Same as above, but for ints (isel). */
11923
11924static int
a2369ed3 11925rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
a3170dc6
AH
11926{
11927 rtx condition_rtx, cr;
11928
11929 /* All isel implementations thus far are 32-bits. */
11930 if (GET_MODE (rs6000_compare_op0) != SImode)
11931 return 0;
11932
11933 /* We still have to do the compare, because isel doesn't do a
11934 compare, it just looks at the CRx bits set by a previous compare
11935 instruction. */
11936 condition_rtx = rs6000_generate_compare (GET_CODE (op));
11937 cr = XEXP (condition_rtx, 0);
11938
11939 if (GET_MODE (cr) == CCmode)
11940 emit_insn (gen_isel_signed (dest, condition_rtx,
11941 true_cond, false_cond, cr));
11942 else
11943 emit_insn (gen_isel_unsigned (dest, condition_rtx,
11944 true_cond, false_cond, cr));
11945
11946 return 1;
11947}
11948
11949const char *
a2369ed3 11950output_isel (rtx *operands)
a3170dc6
AH
11951{
11952 enum rtx_code code;
11953
11954 code = GET_CODE (operands[1]);
11955 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
11956 {
11957 PUT_CODE (operands[1], reverse_condition (code));
11958 return "isel %0,%3,%2,%j1";
11959 }
11960 else
11961 return "isel %0,%2,%3,%j1";
11962}
11963
50a0b056 11964void
a2369ed3 11965rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
50a0b056
GK
11966{
11967 enum machine_mode mode = GET_MODE (op0);
5dc8d536 11968 enum rtx_code c;
50a0b056 11969 rtx target;
5dc8d536
AH
11970
11971 if (code == SMAX || code == SMIN)
11972 c = GE;
11973 else
11974 c = GEU;
11975
50a0b056 11976 if (code == SMAX || code == UMAX)
f676971a 11977 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
11978 op0, op1, mode, 0);
11979 else
f676971a 11980 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056 11981 op1, op0, mode, 0);
37409796 11982 gcc_assert (target);
50a0b056
GK
11983 if (target != dest)
11984 emit_move_insn (dest, target);
11985}
46c07df8 11986
915167f5
GK
11987/* Emit instructions to perform a load-reserved/store-conditional operation.
11988 The operation performed is an atomic
11989 (set M (CODE:MODE M OP))
11990 If not NULL, BEFORE is atomically set to M before the operation, and
11991 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
bb8df8a6 11992 If SYNC_P then a memory barrier is emitted before the operation.
915167f5
GK
11993 Either OP or M may be wrapped in a NOT operation. */
11994
11995void
11996rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
11997 rtx m, rtx op, rtx before_param, rtx after_param,
11998 bool sync_p)
11999{
12000 enum machine_mode used_mode;
12001 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
12002 rtx used_m;
12003 rtvec vec;
12004 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12005 rtx shift = NULL_RTX;
bb8df8a6 12006
915167f5
GK
12007 if (sync_p)
12008 emit_insn (gen_memory_barrier ());
bb8df8a6 12009
915167f5
GK
12010 if (GET_CODE (m) == NOT)
12011 used_m = XEXP (m, 0);
12012 else
12013 used_m = m;
12014
12015 /* If this is smaller than SImode, we'll have to use SImode with
12016 adjustments. */
12017 if (mode == QImode || mode == HImode)
12018 {
12019 rtx newop, oldop;
12020
12021 if (MEM_ALIGN (used_m) >= 32)
12022 {
12023 int ishift = 0;
12024 if (BYTES_BIG_ENDIAN)
12025 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
bb8df8a6 12026
915167f5
GK
12027 shift = GEN_INT (ishift);
12028 }
12029 else
12030 {
12031 rtx addrSI, aligned_addr;
a9c9d3fa 12032 int shift_mask = mode == QImode ? 0x18 : 0x10;
bb8df8a6 12033
915167f5
GK
12034 addrSI = force_reg (SImode, gen_lowpart_common (SImode,
12035 XEXP (used_m, 0)));
12036 shift = gen_reg_rtx (SImode);
12037
12038 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
a9c9d3fa
GK
12039 GEN_INT (shift_mask)));
12040 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
915167f5
GK
12041
12042 aligned_addr = expand_binop (Pmode, and_optab,
12043 XEXP (used_m, 0),
12044 GEN_INT (-4), NULL_RTX,
12045 1, OPTAB_LIB_WIDEN);
12046 used_m = change_address (used_m, SImode, aligned_addr);
12047 set_mem_align (used_m, 32);
12048 /* It's safe to keep the old alias set of USED_M, because
12049 the operation is atomic and only affects the original
12050 USED_M. */
12051 if (GET_CODE (m) == NOT)
12052 m = gen_rtx_NOT (SImode, used_m);
12053 else
12054 m = used_m;
12055 }
12056
12057 if (GET_CODE (op) == NOT)
12058 {
12059 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
12060 oldop = gen_rtx_NOT (SImode, oldop);
12061 }
12062 else
12063 oldop = lowpart_subreg (SImode, op, mode);
9f0076e5 12064
915167f5
GK
12065 switch (code)
12066 {
12067 case IOR:
12068 case XOR:
12069 newop = expand_binop (SImode, and_optab,
12070 oldop, GEN_INT (imask), NULL_RTX,
12071 1, OPTAB_LIB_WIDEN);
12072 emit_insn (gen_ashlsi3 (newop, newop, shift));
12073 break;
12074
12075 case AND:
12076 newop = expand_binop (SImode, ior_optab,
12077 oldop, GEN_INT (~imask), NULL_RTX,
12078 1, OPTAB_LIB_WIDEN);
a9c9d3fa 12079 emit_insn (gen_rotlsi3 (newop, newop, shift));
915167f5
GK
12080 break;
12081
12082 case PLUS:
9f0076e5 12083 case MINUS:
915167f5
GK
12084 {
12085 rtx mask;
bb8df8a6 12086
915167f5
GK
12087 newop = expand_binop (SImode, and_optab,
12088 oldop, GEN_INT (imask), NULL_RTX,
12089 1, OPTAB_LIB_WIDEN);
12090 emit_insn (gen_ashlsi3 (newop, newop, shift));
12091
12092 mask = gen_reg_rtx (SImode);
12093 emit_move_insn (mask, GEN_INT (imask));
12094 emit_insn (gen_ashlsi3 (mask, mask, shift));
12095
9f0076e5
DE
12096 if (code == PLUS)
12097 newop = gen_rtx_PLUS (SImode, m, newop);
12098 else
12099 newop = gen_rtx_MINUS (SImode, m, newop);
12100 newop = gen_rtx_AND (SImode, newop, mask);
915167f5
GK
12101 newop = gen_rtx_IOR (SImode, newop,
12102 gen_rtx_AND (SImode,
12103 gen_rtx_NOT (SImode, mask),
12104 m));
12105 break;
12106 }
12107
12108 default:
12109 gcc_unreachable ();
12110 }
12111
a9c9d3fa
GK
12112 if (GET_CODE (m) == NOT)
12113 {
12114 rtx mask, xorm;
12115
12116 mask = gen_reg_rtx (SImode);
12117 emit_move_insn (mask, GEN_INT (imask));
12118 emit_insn (gen_ashlsi3 (mask, mask, shift));
12119
12120 xorm = gen_rtx_XOR (SImode, used_m, mask);
12121 /* Depending on the value of 'op', the XOR or the operation might
12122 be able to be simplified away. */
12123 newop = simplify_gen_binary (code, SImode, xorm, newop);
12124 }
915167f5
GK
12125 op = newop;
12126 used_mode = SImode;
12127 before = gen_reg_rtx (used_mode);
12128 after = gen_reg_rtx (used_mode);
12129 }
12130 else
12131 {
12132 used_mode = mode;
12133 before = before_param;
12134 after = after_param;
12135
12136 if (before == NULL_RTX)
12137 before = gen_reg_rtx (used_mode);
12138 if (after == NULL_RTX)
12139 after = gen_reg_rtx (used_mode);
12140 }
bb8df8a6 12141
9f0076e5
DE
12142 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
12143 && used_mode != mode)
915167f5
GK
12144 the_op = op; /* Computed above. */
12145 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
12146 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
12147 else
12148 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
12149
12150 set_after = gen_rtx_SET (VOIDmode, after, the_op);
12151 set_before = gen_rtx_SET (VOIDmode, before, used_m);
12152 set_atomic = gen_rtx_SET (VOIDmode, used_m,
9f0076e5
DE
12153 gen_rtx_UNSPEC (used_mode,
12154 gen_rtvec (1, the_op),
12155 UNSPEC_SYNC_OP));
915167f5
GK
12156 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
12157
9f0076e5 12158 if ((code == PLUS || code == MINUS) && used_mode != mode)
915167f5
GK
12159 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
12160 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
12161 else
12162 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
12163 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
12164
12165 /* Shift and mask the return values properly. */
12166 if (used_mode != mode && before_param)
12167 {
12168 emit_insn (gen_lshrsi3 (before, before, shift));
12169 convert_move (before_param, before, 1);
12170 }
12171
12172 if (used_mode != mode && after_param)
12173 {
12174 emit_insn (gen_lshrsi3 (after, after, shift));
12175 convert_move (after_param, after, 1);
12176 }
12177
12178 /* The previous sequence will end with a branch that's dependent on
12179 the conditional store, so placing an isync will ensure that no
12180 other instructions (especially, no load or store instructions)
12181 can start before the atomic operation completes. */
12182 if (sync_p)
12183 emit_insn (gen_isync ());
12184}
12185
b52110d4
DE
12186/* A subroutine of the atomic operation splitters. Jump to LABEL if
12187 COND is true. Mark the jump as unlikely to be taken. */
12188
12189static void
12190emit_unlikely_jump (rtx cond, rtx label)
12191{
12192 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
12193 rtx x;
12194
12195 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
12196 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
12197 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
12198}
12199
12200/* A subroutine of the atomic operation splitters. Emit a load-locked
12201 instruction in MODE. */
12202
12203static void
12204emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
12205{
12206 rtx (*fn) (rtx, rtx) = NULL;
12207 if (mode == SImode)
12208 fn = gen_load_locked_si;
12209 else if (mode == DImode)
12210 fn = gen_load_locked_di;
12211 emit_insn (fn (reg, mem));
12212}
12213
12214/* A subroutine of the atomic operation splitters. Emit a store-conditional
12215 instruction in MODE. */
12216
12217static void
12218emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
12219{
12220 rtx (*fn) (rtx, rtx, rtx) = NULL;
12221 if (mode == SImode)
12222 fn = gen_store_conditional_si;
12223 else if (mode == DImode)
12224 fn = gen_store_conditional_di;
12225
9f0076e5 12226 /* Emit sync before stwcx. to address PPC405 Erratum. */
b52110d4
DE
12227 if (PPC405_ERRATUM77)
12228 emit_insn (gen_memory_barrier ());
12229
12230 emit_insn (fn (res, mem, val));
12231}
12232
9f0076e5 12233/* Expand an an atomic fetch-and-operate pattern. CODE is the binary operation
bb8df8a6 12234 to perform. MEM is the memory on which to operate. VAL is the second
9f0076e5
DE
12235 operand of the binary operator. BEFORE and AFTER are optional locations to
12236 return the value of MEM either before of after the operation. SCRATCH is
12237 a scratch register. */
12238
12239void
12240rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
12241 rtx before, rtx after, rtx scratch)
12242{
12243 enum machine_mode mode = GET_MODE (mem);
12244 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12245
12246 emit_insn (gen_memory_barrier ());
12247
12248 label = gen_label_rtx ();
12249 emit_label (label);
12250 label = gen_rtx_LABEL_REF (VOIDmode, label);
12251
12252 if (before == NULL_RTX)
12253 before = scratch;
12254 emit_load_locked (mode, before, mem);
12255
12256 if (code == NOT)
12257 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
12258 else if (code == AND)
12259 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
12260 else
12261 x = gen_rtx_fmt_ee (code, mode, before, val);
12262
12263 if (after != NULL_RTX)
12264 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
12265 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
12266
12267 emit_store_conditional (mode, cond, mem, scratch);
12268
12269 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12270 emit_unlikely_jump (x, label);
12271
12272 emit_insn (gen_isync ());
12273}
12274
b52110d4
DE
12275/* Expand an atomic compare and swap operation. MEM is the memory on which
12276 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
12277 value to be stored. SCRATCH is a scratch GPR. */
12278
12279void
12280rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
12281 rtx scratch)
12282{
12283 enum machine_mode mode = GET_MODE (mem);
12284 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12285
12286 emit_insn (gen_memory_barrier ());
12287
12288 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12289 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12290 emit_label (XEXP (label1, 0));
12291
12292 emit_load_locked (mode, retval, mem);
12293
12294 x = gen_rtx_COMPARE (CCmode, retval, oldval);
12295 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12296
12297 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12298 emit_unlikely_jump (x, label2);
12299
12300 emit_move_insn (scratch, newval);
12301 emit_store_conditional (mode, cond, mem, scratch);
12302
12303 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12304 emit_unlikely_jump (x, label1);
12305
12306 emit_insn (gen_isync ());
12307 emit_label (XEXP (label2, 0));
12308}
12309
12310/* Expand an atomic test and set operation. MEM is the memory on which
12311 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
12312
12313void
12314rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
12315{
12316 enum machine_mode mode = GET_MODE (mem);
12317 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12318
12319 emit_insn (gen_memory_barrier ());
12320
12321 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12322 emit_label (XEXP (label, 0));
12323
12324 emit_load_locked (mode, retval, mem);
12325 emit_move_insn (scratch, val);
12326 emit_store_conditional (mode, cond, mem, scratch);
12327
12328 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12329 emit_unlikely_jump (x, label);
12330
12331 emit_insn (gen_isync ());
12332}
12333
9fc75b97
DE
12334void
12335rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
12336{
12337 enum machine_mode mode = GET_MODE (mem);
12338 rtx addrSI, align, wdst, shift, mask;
12339 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
12340 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
12341
12342 /* Shift amount for subword relative to aligned word. */
12343 addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
12344 shift = gen_reg_rtx (SImode);
12345 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
12346 GEN_INT (shift_mask)));
12347 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
12348
12349 /* Shift and mask old value into position within word. */
12350 oldval = convert_modes (SImode, mode, oldval, 1);
12351 oldval = expand_binop (SImode, and_optab,
12352 oldval, GEN_INT (imask), NULL_RTX,
12353 1, OPTAB_LIB_WIDEN);
12354 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
12355
12356 /* Shift and mask new value into position within word. */
12357 newval = convert_modes (SImode, mode, newval, 1);
12358 newval = expand_binop (SImode, and_optab,
12359 newval, GEN_INT (imask), NULL_RTX,
12360 1, OPTAB_LIB_WIDEN);
12361 emit_insn (gen_ashlsi3 (newval, newval, shift));
12362
12363 /* Mask for insertion. */
12364 mask = gen_reg_rtx (SImode);
12365 emit_move_insn (mask, GEN_INT (imask));
12366 emit_insn (gen_ashlsi3 (mask, mask, shift));
12367
12368 /* Address of aligned word containing subword. */
12369 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
12370 NULL_RTX, 1, OPTAB_LIB_WIDEN);
12371 mem = change_address (mem, SImode, align);
12372 set_mem_align (mem, 32);
12373 MEM_VOLATILE_P (mem) = 1;
12374
12375 wdst = gen_reg_rtx (SImode);
12376 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
12377 oldval, newval, mem));
12378
12379 emit_move_insn (dst, gen_lowpart (mode, wdst));
12380}
12381
12382void
12383rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
12384 rtx oldval, rtx newval, rtx mem,
12385 rtx scratch)
12386{
12387 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
12388
12389 emit_insn (gen_memory_barrier ());
12390 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12391 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
12392 emit_label (XEXP (label1, 0));
12393
12394 emit_load_locked (SImode, scratch, mem);
12395
12396 /* Mask subword within loaded value for comparison with oldval.
12397 Use UNSPEC_AND to avoid clobber.*/
12398 emit_insn (gen_rtx_SET (SImode, dest,
12399 gen_rtx_UNSPEC (SImode,
12400 gen_rtvec (2, scratch, mask),
12401 UNSPEC_AND)));
12402
12403 x = gen_rtx_COMPARE (CCmode, dest, oldval);
12404 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
12405
12406 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12407 emit_unlikely_jump (x, label2);
12408
12409 /* Clear subword within loaded value for insertion of new value. */
12410 emit_insn (gen_rtx_SET (SImode, scratch,
12411 gen_rtx_AND (SImode,
12412 gen_rtx_NOT (SImode, mask), scratch)));
12413 emit_insn (gen_iorsi3 (scratch, scratch, newval));
12414 emit_store_conditional (SImode, cond, mem, scratch);
12415
12416 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
12417 emit_unlikely_jump (x, label1);
12418
12419 emit_insn (gen_isync ());
12420 emit_label (XEXP (label2, 0));
12421}
12422
12423
b52110d4 12424 /* Emit instructions to move SRC to DST. Called by splitters for
a9baceb1
GK
12425 multi-register moves. It will emit at most one instruction for
12426 each register that is accessed; that is, it won't emit li/lis pairs
12427 (or equivalent for 64-bit code). One of SRC or DST must be a hard
12428 register. */
46c07df8 12429
46c07df8 12430void
a9baceb1 12431rs6000_split_multireg_move (rtx dst, rtx src)
46c07df8 12432{
a9baceb1
GK
12433 /* The register number of the first register being moved. */
12434 int reg;
12435 /* The mode that is to be moved. */
12436 enum machine_mode mode;
12437 /* The mode that the move is being done in, and its size. */
12438 enum machine_mode reg_mode;
12439 int reg_mode_size;
12440 /* The number of registers that will be moved. */
12441 int nregs;
12442
12443 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
12444 mode = GET_MODE (dst);
c8b622ff 12445 nregs = hard_regno_nregs[reg][mode];
a9baceb1
GK
12446 if (FP_REGNO_P (reg))
12447 reg_mode = DFmode;
12448 else if (ALTIVEC_REGNO_P (reg))
12449 reg_mode = V16QImode;
12450 else
12451 reg_mode = word_mode;
12452 reg_mode_size = GET_MODE_SIZE (reg_mode);
f676971a 12453
37409796 12454 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
f676971a 12455
a9baceb1
GK
12456 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
12457 {
12458 /* Move register range backwards, if we might have destructive
12459 overlap. */
12460 int i;
12461 for (i = nregs - 1; i >= 0; i--)
f676971a 12462 emit_insn (gen_rtx_SET (VOIDmode,
a9baceb1
GK
12463 simplify_gen_subreg (reg_mode, dst, mode,
12464 i * reg_mode_size),
12465 simplify_gen_subreg (reg_mode, src, mode,
12466 i * reg_mode_size)));
12467 }
46c07df8
HP
12468 else
12469 {
a9baceb1
GK
12470 int i;
12471 int j = -1;
12472 bool used_update = false;
46c07df8 12473
c1e55850 12474 if (MEM_P (src) && INT_REGNO_P (reg))
c4ad648e
AM
12475 {
12476 rtx breg;
3a1f863f 12477
a9baceb1
GK
12478 if (GET_CODE (XEXP (src, 0)) == PRE_INC
12479 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
3a1f863f
DE
12480 {
12481 rtx delta_rtx;
a9baceb1 12482 breg = XEXP (XEXP (src, 0), 0);
c4ad648e
AM
12483 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
12484 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
12485 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
a9baceb1
GK
12486 emit_insn (TARGET_32BIT
12487 ? gen_addsi3 (breg, breg, delta_rtx)
12488 : gen_adddi3 (breg, breg, delta_rtx));
13e2e16e 12489 src = replace_equiv_address (src, breg);
3a1f863f 12490 }
c1e55850
GK
12491 else if (! offsettable_memref_p (src))
12492 {
13e2e16e 12493 rtx basereg;
c1e55850
GK
12494 basereg = gen_rtx_REG (Pmode, reg);
12495 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
13e2e16e 12496 src = replace_equiv_address (src, basereg);
c1e55850 12497 }
3a1f863f 12498
0423421f
AM
12499 breg = XEXP (src, 0);
12500 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
12501 breg = XEXP (breg, 0);
12502
12503 /* If the base register we are using to address memory is
12504 also a destination reg, then change that register last. */
12505 if (REG_P (breg)
12506 && REGNO (breg) >= REGNO (dst)
3a1f863f
DE
12507 && REGNO (breg) < REGNO (dst) + nregs)
12508 j = REGNO (breg) - REGNO (dst);
c4ad648e 12509 }
46c07df8 12510
a9baceb1 12511 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
3a1f863f
DE
12512 {
12513 rtx breg;
12514
a9baceb1
GK
12515 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
12516 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
3a1f863f
DE
12517 {
12518 rtx delta_rtx;
a9baceb1 12519 breg = XEXP (XEXP (dst, 0), 0);
c4ad648e
AM
12520 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
12521 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
12522 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
3a1f863f
DE
12523
12524 /* We have to update the breg before doing the store.
12525 Use store with update, if available. */
12526
12527 if (TARGET_UPDATE)
12528 {
a9baceb1 12529 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
c4ad648e
AM
12530 emit_insn (TARGET_32BIT
12531 ? (TARGET_POWERPC64
12532 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
12533 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
12534 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
a9baceb1 12535 used_update = true;
3a1f863f
DE
12536 }
12537 else
a9baceb1
GK
12538 emit_insn (TARGET_32BIT
12539 ? gen_addsi3 (breg, breg, delta_rtx)
12540 : gen_adddi3 (breg, breg, delta_rtx));
13e2e16e 12541 dst = replace_equiv_address (dst, breg);
3a1f863f 12542 }
37409796
NS
12543 else
12544 gcc_assert (offsettable_memref_p (dst));
3a1f863f
DE
12545 }
12546
46c07df8 12547 for (i = 0; i < nregs; i++)
f676971a 12548 {
3a1f863f
DE
12549 /* Calculate index to next subword. */
12550 ++j;
f676971a 12551 if (j == nregs)
3a1f863f 12552 j = 0;
46c07df8 12553
112cdef5 12554 /* If compiler already emitted move of first word by
a9baceb1 12555 store with update, no need to do anything. */
3a1f863f 12556 if (j == 0 && used_update)
a9baceb1 12557 continue;
f676971a 12558
a9baceb1
GK
12559 emit_insn (gen_rtx_SET (VOIDmode,
12560 simplify_gen_subreg (reg_mode, dst, mode,
12561 j * reg_mode_size),
12562 simplify_gen_subreg (reg_mode, src, mode,
12563 j * reg_mode_size)));
3a1f863f 12564 }
46c07df8
HP
12565 }
12566}
12567
12a4e8c5 12568\f
a4f6c312
SS
12569/* This page contains routines that are used to determine what the
12570 function prologue and epilogue code will do and write them out. */
9878760c 12571
a4f6c312
SS
12572/* Return the first fixed-point register that is required to be
12573 saved. 32 if none. */
9878760c
RK
12574
12575int
863d938c 12576first_reg_to_save (void)
9878760c
RK
12577{
12578 int first_reg;
12579
12580 /* Find lowest numbered live register. */
12581 for (first_reg = 13; first_reg <= 31; first_reg++)
f676971a 12582 if (regs_ever_live[first_reg]
a38d360d 12583 && (! call_used_regs[first_reg]
1db02437 12584 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 12585 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
b4db40bf
JJ
12586 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
12587 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
9878760c
RK
12588 break;
12589
ee890fe2 12590#if TARGET_MACHO
93638d7a
AM
12591 if (flag_pic
12592 && current_function_uses_pic_offset_table
12593 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 12594 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
12595#endif
12596
9878760c
RK
12597 return first_reg;
12598}
12599
12600/* Similar, for FP regs. */
12601
12602int
863d938c 12603first_fp_reg_to_save (void)
9878760c
RK
12604{
12605 int first_reg;
12606
12607 /* Find lowest numbered live register. */
12608 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
12609 if (regs_ever_live[first_reg])
12610 break;
12611
12612 return first_reg;
12613}
00b960c7
AH
12614
12615/* Similar, for AltiVec regs. */
12616
12617static int
863d938c 12618first_altivec_reg_to_save (void)
00b960c7
AH
12619{
12620 int i;
12621
12622 /* Stack frame remains as is unless we are in AltiVec ABI. */
12623 if (! TARGET_ALTIVEC_ABI)
12624 return LAST_ALTIVEC_REGNO + 1;
12625
12626 /* Find lowest numbered live register. */
12627 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
12628 if (regs_ever_live[i])
12629 break;
12630
12631 return i;
12632}
12633
12634/* Return a 32-bit mask of the AltiVec registers we need to set in
12635 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
12636 the 32-bit word is 0. */
12637
12638static unsigned int
863d938c 12639compute_vrsave_mask (void)
00b960c7
AH
12640{
12641 unsigned int i, mask = 0;
12642
12643 /* First, find out if we use _any_ altivec registers. */
12644 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
12645 if (regs_ever_live[i])
12646 mask |= ALTIVEC_REG_BIT (i);
12647
12648 if (mask == 0)
12649 return mask;
12650
00b960c7
AH
12651 /* Next, remove the argument registers from the set. These must
12652 be in the VRSAVE mask set by the caller, so we don't need to add
12653 them in again. More importantly, the mask we compute here is
12654 used to generate CLOBBERs in the set_vrsave insn, and we do not
12655 wish the argument registers to die. */
a6cf80f2 12656 for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
00b960c7
AH
12657 mask &= ~ALTIVEC_REG_BIT (i);
12658
12659 /* Similarly, remove the return value from the set. */
12660 {
12661 bool yes = false;
12662 diddle_return_value (is_altivec_return_reg, &yes);
12663 if (yes)
12664 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
12665 }
12666
12667 return mask;
12668}
12669
d62294f5 12670/* For a very restricted set of circumstances, we can cut down the
f57fe068
AM
12671 size of prologues/epilogues by calling our own save/restore-the-world
12672 routines. */
d62294f5
FJ
12673
12674static void
f57fe068
AM
12675compute_save_world_info (rs6000_stack_t *info_ptr)
12676{
12677 info_ptr->world_save_p = 1;
12678 info_ptr->world_save_p
12679 = (WORLD_SAVE_P (info_ptr)
12680 && DEFAULT_ABI == ABI_DARWIN
12681 && ! (current_function_calls_setjmp && flag_exceptions)
12682 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
12683 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
12684 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
12685 && info_ptr->cr_save_p);
f676971a 12686
d62294f5
FJ
12687 /* This will not work in conjunction with sibcalls. Make sure there
12688 are none. (This check is expensive, but seldom executed.) */
f57fe068 12689 if (WORLD_SAVE_P (info_ptr))
f676971a 12690 {
d62294f5
FJ
12691 rtx insn;
12692 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
c4ad648e
AM
12693 if ( GET_CODE (insn) == CALL_INSN
12694 && SIBLING_CALL_P (insn))
12695 {
12696 info_ptr->world_save_p = 0;
12697 break;
12698 }
d62294f5 12699 }
f676971a 12700
f57fe068 12701 if (WORLD_SAVE_P (info_ptr))
d62294f5
FJ
12702 {
12703 /* Even if we're not touching VRsave, make sure there's room on the
12704 stack for it, if it looks like we're calling SAVE_WORLD, which
c4ad648e 12705 will attempt to save it. */
d62294f5
FJ
12706 info_ptr->vrsave_size = 4;
12707
12708 /* "Save" the VRsave register too if we're saving the world. */
12709 if (info_ptr->vrsave_mask == 0)
c4ad648e 12710 info_ptr->vrsave_mask = compute_vrsave_mask ();
d62294f5
FJ
12711
12712 /* Because the Darwin register save/restore routines only handle
c4ad648e 12713 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
992d08b1 12714 check. */
37409796
NS
12715 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
12716 && (info_ptr->first_altivec_reg_save
12717 >= FIRST_SAVED_ALTIVEC_REGNO));
d62294f5 12718 }
f676971a 12719 return;
d62294f5
FJ
12720}
12721
12722
00b960c7 12723static void
a2369ed3 12724is_altivec_return_reg (rtx reg, void *xyes)
00b960c7
AH
12725{
12726 bool *yes = (bool *) xyes;
12727 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
12728 *yes = true;
12729}
12730
4697a36c
MM
12731\f
12732/* Calculate the stack information for the current function. This is
12733 complicated by having two separate calling sequences, the AIX calling
12734 sequence and the V.4 calling sequence.
12735
592696dd 12736 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 12737 32-bit 64-bit
4697a36c 12738 SP----> +---------------------------------------+
a260abc9 12739 | back chain to caller | 0 0
4697a36c 12740 +---------------------------------------+
a260abc9 12741 | saved CR | 4 8 (8-11)
4697a36c 12742 +---------------------------------------+
a260abc9 12743 | saved LR | 8 16
4697a36c 12744 +---------------------------------------+
a260abc9 12745 | reserved for compilers | 12 24
4697a36c 12746 +---------------------------------------+
a260abc9 12747 | reserved for binders | 16 32
4697a36c 12748 +---------------------------------------+
a260abc9 12749 | saved TOC pointer | 20 40
4697a36c 12750 +---------------------------------------+
a260abc9 12751 | Parameter save area (P) | 24 48
4697a36c 12752 +---------------------------------------+
a260abc9 12753 | Alloca space (A) | 24+P etc.
802a0058 12754 +---------------------------------------+
a7df97e6 12755 | Local variable space (L) | 24+P+A
4697a36c 12756 +---------------------------------------+
a7df97e6 12757 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 12758 +---------------------------------------+
00b960c7
AH
12759 | Save area for AltiVec registers (W) | 24+P+A+L+X
12760 +---------------------------------------+
12761 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
12762 +---------------------------------------+
12763 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 12764 +---------------------------------------+
00b960c7
AH
12765 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
12766 +---------------------------------------+
12767 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
12768 +---------------------------------------+
12769 old SP->| back chain to caller's caller |
12770 +---------------------------------------+
12771
5376a30c
KR
12772 The required alignment for AIX configurations is two words (i.e., 8
12773 or 16 bytes).
12774
12775
4697a36c
MM
12776 V.4 stack frames look like:
12777
12778 SP----> +---------------------------------------+
12779 | back chain to caller | 0
12780 +---------------------------------------+
5eb387b8 12781 | caller's saved LR | 4
4697a36c
MM
12782 +---------------------------------------+
12783 | Parameter save area (P) | 8
12784 +---------------------------------------+
a7df97e6 12785 | Alloca space (A) | 8+P
f676971a 12786 +---------------------------------------+
a7df97e6 12787 | Varargs save area (V) | 8+P+A
f676971a 12788 +---------------------------------------+
a7df97e6 12789 | Local variable space (L) | 8+P+A+V
f676971a 12790 +---------------------------------------+
a7df97e6 12791 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 12792 +---------------------------------------+
00b960c7
AH
12793 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
12794 +---------------------------------------+
12795 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
12796 +---------------------------------------+
12797 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
12798 +---------------------------------------+
c4ad648e
AM
12799 | SPE: area for 64-bit GP registers |
12800 +---------------------------------------+
12801 | SPE alignment padding |
12802 +---------------------------------------+
00b960c7 12803 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
f676971a 12804 +---------------------------------------+
00b960c7 12805 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
f676971a 12806 +---------------------------------------+
00b960c7 12807 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
12808 +---------------------------------------+
12809 old SP->| back chain to caller's caller |
12810 +---------------------------------------+
b6c9286a 12811
5376a30c
KR
12812 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
12813 given. (But note below and in sysv4.h that we require only 8 and
12814 may round up the size of our stack frame anyways. The historical
12815 reason is early versions of powerpc-linux which didn't properly
12816 align the stack at program startup. A happy side-effect is that
12817 -mno-eabi libraries can be used with -meabi programs.)
12818
50d440bc 12819 The EABI configuration defaults to the V.4 layout. However,
5376a30c
KR
12820 the stack alignment requirements may differ. If -mno-eabi is not
12821 given, the required stack alignment is 8 bytes; if -mno-eabi is
12822 given, the required alignment is 16 bytes. (But see V.4 comment
12823 above.) */
4697a36c 12824
61b2fbe7
MM
12825#ifndef ABI_STACK_BOUNDARY
12826#define ABI_STACK_BOUNDARY STACK_BOUNDARY
12827#endif
12828
d1d0c603 12829static rs6000_stack_t *
863d938c 12830rs6000_stack_info (void)
4697a36c 12831{
022123e6 12832 static rs6000_stack_t info;
4697a36c 12833 rs6000_stack_t *info_ptr = &info;
327e5343 12834 int reg_size = TARGET_32BIT ? 4 : 8;
83720594 12835 int ehrd_size;
64045029 12836 int save_align;
44688022 12837 HOST_WIDE_INT non_fixed_size;
4697a36c 12838
022123e6 12839 memset (&info, 0, sizeof (info));
4697a36c 12840
c19de7aa
AH
12841 if (TARGET_SPE)
12842 {
12843 /* Cache value so we don't rescan instruction chain over and over. */
9b7b447f 12844 if (cfun->machine->insn_chain_scanned_p == 0)
b5a5beb9
AH
12845 cfun->machine->insn_chain_scanned_p
12846 = spe_func_has_64bit_regs_p () + 1;
12847 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
c19de7aa
AH
12848 }
12849
a4f6c312 12850 /* Select which calling sequence. */
178274da 12851 info_ptr->abi = DEFAULT_ABI;
9878760c 12852
a4f6c312 12853 /* Calculate which registers need to be saved & save area size. */
4697a36c 12854 info_ptr->first_gp_reg_save = first_reg_to_save ();
f676971a 12855 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 12856 even if it currently looks like we won't. */
2bfcf297 12857 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
178274da
AM
12858 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
12859 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
1db02437
FS
12860 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
12861 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
12862 else
12863 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 12864
a3170dc6
AH
12865 /* For the SPE, we have an additional upper 32-bits on each GPR.
12866 Ideally we should save the entire 64-bits only when the upper
12867 half is used in SIMD instructions. Since we only record
12868 registers live (not the size they are used in), this proves
12869 difficult because we'd have to traverse the instruction chain at
12870 the right time, taking reload into account. This is a real pain,
c19de7aa
AH
12871 so we opt to save the GPRs in 64-bits always if but one register
12872 gets used in 64-bits. Otherwise, all the registers in the frame
12873 get saved in 32-bits.
a3170dc6 12874
c19de7aa 12875 So... since when we save all GPRs (except the SP) in 64-bits, the
a3170dc6 12876 traditional GP save area will be empty. */
c19de7aa 12877 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
12878 info_ptr->gp_size = 0;
12879
4697a36c
MM
12880 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
12881 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
12882
00b960c7
AH
12883 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
12884 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
12885 - info_ptr->first_altivec_reg_save);
12886
592696dd 12887 /* Does this function call anything? */
71f123ca
FS
12888 info_ptr->calls_p = (! current_function_is_leaf
12889 || cfun->machine->ra_needs_full_frame);
b6c9286a 12890
a4f6c312 12891 /* Determine if we need to save the link register. */
022123e6
AM
12892 if ((DEFAULT_ABI == ABI_AIX
12893 && current_function_profile
12894 && !TARGET_PROFILE_KERNEL)
4697a36c
MM
12895#ifdef TARGET_RELOCATABLE
12896 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
12897#endif
12898 || (info_ptr->first_fp_reg_save != 64
12899 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 12900 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
178274da 12901 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
022123e6
AM
12902 || info_ptr->calls_p
12903 || rs6000_ra_ever_killed ())
4697a36c
MM
12904 {
12905 info_ptr->lr_save_p = 1;
9ebbca7d 12906 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
12907 }
12908
9ebbca7d 12909 /* Determine if we need to save the condition code registers. */
f676971a 12910 if (regs_ever_live[CR2_REGNO]
9ebbca7d
GK
12911 || regs_ever_live[CR3_REGNO]
12912 || regs_ever_live[CR4_REGNO])
4697a36c
MM
12913 {
12914 info_ptr->cr_save_p = 1;
178274da 12915 if (DEFAULT_ABI == ABI_V4)
4697a36c
MM
12916 info_ptr->cr_size = reg_size;
12917 }
12918
83720594
RH
12919 /* If the current function calls __builtin_eh_return, then we need
12920 to allocate stack space for registers that will hold data for
12921 the exception handler. */
12922 if (current_function_calls_eh_return)
12923 {
12924 unsigned int i;
12925 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
12926 continue;
a3170dc6
AH
12927
12928 /* SPE saves EH registers in 64-bits. */
c19de7aa
AH
12929 ehrd_size = i * (TARGET_SPE_ABI
12930 && info_ptr->spe_64bit_regs_used != 0
12931 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
12932 }
12933 else
12934 ehrd_size = 0;
12935
592696dd 12936 /* Determine various sizes. */
4697a36c
MM
12937 info_ptr->reg_size = reg_size;
12938 info_ptr->fixed_size = RS6000_SAVE_AREA;
189e03e3 12939 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312 12940 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
03e007d7 12941 TARGET_ALTIVEC ? 16 : 8);
7d5175e1
JJ
12942 if (FRAME_GROWS_DOWNWARD)
12943 info_ptr->vars_size
5b667039
JJ
12944 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
12945 + info_ptr->parm_size,
7d5175e1 12946 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
5b667039
JJ
12947 - (info_ptr->fixed_size + info_ptr->vars_size
12948 + info_ptr->parm_size);
00b960c7 12949
c19de7aa 12950 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
12951 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
12952 else
12953 info_ptr->spe_gp_size = 0;
12954
4d774ff8
HP
12955 if (TARGET_ALTIVEC_ABI)
12956 info_ptr->vrsave_mask = compute_vrsave_mask ();
00b960c7 12957 else
4d774ff8
HP
12958 info_ptr->vrsave_mask = 0;
12959
12960 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
12961 info_ptr->vrsave_size = 4;
12962 else
12963 info_ptr->vrsave_size = 0;
b6c9286a 12964
d62294f5
FJ
12965 compute_save_world_info (info_ptr);
12966
592696dd 12967 /* Calculate the offsets. */
178274da 12968 switch (DEFAULT_ABI)
4697a36c 12969 {
b6c9286a 12970 case ABI_NONE:
24d304eb 12971 default:
37409796 12972 gcc_unreachable ();
b6c9286a
MM
12973
12974 case ABI_AIX:
ee890fe2 12975 case ABI_DARWIN:
b6c9286a
MM
12976 info_ptr->fp_save_offset = - info_ptr->fp_size;
12977 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
12978
12979 if (TARGET_ALTIVEC_ABI)
12980 {
12981 info_ptr->vrsave_save_offset
12982 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
12983
12984 /* Align stack so vector save area is on a quadword boundary. */
12985 if (info_ptr->altivec_size != 0)
12986 info_ptr->altivec_padding_size
12987 = 16 - (-info_ptr->vrsave_save_offset % 16);
12988 else
12989 info_ptr->altivec_padding_size = 0;
12990
12991 info_ptr->altivec_save_offset
12992 = info_ptr->vrsave_save_offset
12993 - info_ptr->altivec_padding_size
12994 - info_ptr->altivec_size;
12995
12996 /* Adjust for AltiVec case. */
12997 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
12998 }
12999 else
13000 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
13001 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
13002 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
13003 break;
13004
13005 case ABI_V4:
b6c9286a
MM
13006 info_ptr->fp_save_offset = - info_ptr->fp_size;
13007 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 13008 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 13009
c19de7aa 13010 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
c4ad648e
AM
13011 {
13012 /* Align stack so SPE GPR save area is aligned on a
13013 double-word boundary. */
13014 if (info_ptr->spe_gp_size != 0)
13015 info_ptr->spe_padding_size
13016 = 8 - (-info_ptr->cr_save_offset % 8);
13017 else
13018 info_ptr->spe_padding_size = 0;
13019
13020 info_ptr->spe_gp_save_offset
13021 = info_ptr->cr_save_offset
13022 - info_ptr->spe_padding_size
13023 - info_ptr->spe_gp_size;
13024
13025 /* Adjust for SPE case. */
022123e6 13026 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
c4ad648e 13027 }
a3170dc6 13028 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
13029 {
13030 info_ptr->vrsave_save_offset
13031 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
13032
13033 /* Align stack so vector save area is on a quadword boundary. */
13034 if (info_ptr->altivec_size != 0)
13035 info_ptr->altivec_padding_size
13036 = 16 - (-info_ptr->vrsave_save_offset % 16);
13037 else
13038 info_ptr->altivec_padding_size = 0;
13039
13040 info_ptr->altivec_save_offset
13041 = info_ptr->vrsave_save_offset
13042 - info_ptr->altivec_padding_size
13043 - info_ptr->altivec_size;
13044
13045 /* Adjust for AltiVec case. */
022123e6 13046 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
00b960c7
AH
13047 }
13048 else
022123e6
AM
13049 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
13050 info_ptr->ehrd_offset -= ehrd_size;
b6c9286a
MM
13051 info_ptr->lr_save_offset = reg_size;
13052 break;
4697a36c
MM
13053 }
13054
64045029 13055 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
00b960c7
AH
13056 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
13057 + info_ptr->gp_size
13058 + info_ptr->altivec_size
13059 + info_ptr->altivec_padding_size
a3170dc6
AH
13060 + info_ptr->spe_gp_size
13061 + info_ptr->spe_padding_size
00b960c7
AH
13062 + ehrd_size
13063 + info_ptr->cr_size
022123e6 13064 + info_ptr->vrsave_size,
64045029 13065 save_align);
00b960c7 13066
44688022 13067 non_fixed_size = (info_ptr->vars_size
ff381587 13068 + info_ptr->parm_size
5b667039 13069 + info_ptr->save_size);
ff381587 13070
44688022
AM
13071 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
13072 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
13073
13074 /* Determine if we need to allocate any stack frame:
13075
a4f6c312
SS
13076 For AIX we need to push the stack if a frame pointer is needed
13077 (because the stack might be dynamically adjusted), if we are
13078 debugging, if we make calls, or if the sum of fp_save, gp_save,
13079 and local variables are more than the space needed to save all
13080 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
13081 + 18*8 = 288 (GPR13 reserved).
ff381587 13082
a4f6c312
SS
13083 For V.4 we don't have the stack cushion that AIX uses, but assume
13084 that the debugger can handle stackless frames. */
ff381587
MM
13085
13086 if (info_ptr->calls_p)
13087 info_ptr->push_p = 1;
13088
178274da 13089 else if (DEFAULT_ABI == ABI_V4)
44688022 13090 info_ptr->push_p = non_fixed_size != 0;
ff381587 13091
178274da
AM
13092 else if (frame_pointer_needed)
13093 info_ptr->push_p = 1;
13094
13095 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
13096 info_ptr->push_p = 1;
13097
ff381587 13098 else
44688022 13099 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
ff381587 13100
a4f6c312 13101 /* Zero offsets if we're not saving those registers. */
8dda1a21 13102 if (info_ptr->fp_size == 0)
4697a36c
MM
13103 info_ptr->fp_save_offset = 0;
13104
8dda1a21 13105 if (info_ptr->gp_size == 0)
4697a36c
MM
13106 info_ptr->gp_save_offset = 0;
13107
00b960c7
AH
13108 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
13109 info_ptr->altivec_save_offset = 0;
13110
13111 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
13112 info_ptr->vrsave_save_offset = 0;
13113
c19de7aa
AH
13114 if (! TARGET_SPE_ABI
13115 || info_ptr->spe_64bit_regs_used == 0
13116 || info_ptr->spe_gp_size == 0)
a3170dc6
AH
13117 info_ptr->spe_gp_save_offset = 0;
13118
c81fc13e 13119 if (! info_ptr->lr_save_p)
4697a36c
MM
13120 info_ptr->lr_save_offset = 0;
13121
c81fc13e 13122 if (! info_ptr->cr_save_p)
4697a36c
MM
13123 info_ptr->cr_save_offset = 0;
13124
13125 return info_ptr;
13126}
13127
c19de7aa
AH
13128/* Return true if the current function uses any GPRs in 64-bit SIMD
13129 mode. */
13130
13131static bool
863d938c 13132spe_func_has_64bit_regs_p (void)
c19de7aa
AH
13133{
13134 rtx insns, insn;
13135
13136 /* Functions that save and restore all the call-saved registers will
13137 need to save/restore the registers in 64-bits. */
13138 if (current_function_calls_eh_return
13139 || current_function_calls_setjmp
13140 || current_function_has_nonlocal_goto)
13141 return true;
13142
13143 insns = get_insns ();
13144
13145 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
13146 {
13147 if (INSN_P (insn))
13148 {
13149 rtx i;
13150
b5a5beb9
AH
13151 /* FIXME: This should be implemented with attributes...
13152
13153 (set_attr "spe64" "true")....then,
13154 if (get_spe64(insn)) return true;
13155
13156 It's the only reliable way to do the stuff below. */
13157
c19de7aa 13158 i = PATTERN (insn);
f82f556d
AH
13159 if (GET_CODE (i) == SET)
13160 {
13161 enum machine_mode mode = GET_MODE (SET_SRC (i));
13162
13163 if (SPE_VECTOR_MODE (mode))
13164 return true;
13165 if (TARGET_E500_DOUBLE && mode == DFmode)
13166 return true;
13167 }
c19de7aa
AH
13168 }
13169 }
13170
13171 return false;
13172}
13173
d1d0c603 13174static void
a2369ed3 13175debug_stack_info (rs6000_stack_t *info)
9878760c 13176{
d330fd93 13177 const char *abi_string;
24d304eb 13178
c81fc13e 13179 if (! info)
4697a36c
MM
13180 info = rs6000_stack_info ();
13181
13182 fprintf (stderr, "\nStack information for function %s:\n",
13183 ((current_function_decl && DECL_NAME (current_function_decl))
13184 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
13185 : "<unknown>"));
13186
24d304eb
RK
13187 switch (info->abi)
13188 {
b6c9286a
MM
13189 default: abi_string = "Unknown"; break;
13190 case ABI_NONE: abi_string = "NONE"; break;
50d440bc 13191 case ABI_AIX: abi_string = "AIX"; break;
ee890fe2 13192 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 13193 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
13194 }
13195
13196 fprintf (stderr, "\tABI = %5s\n", abi_string);
13197
00b960c7
AH
13198 if (TARGET_ALTIVEC_ABI)
13199 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
13200
a3170dc6
AH
13201 if (TARGET_SPE_ABI)
13202 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
13203
4697a36c
MM
13204 if (info->first_gp_reg_save != 32)
13205 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
13206
13207 if (info->first_fp_reg_save != 64)
13208 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 13209
00b960c7
AH
13210 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
13211 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
13212 info->first_altivec_reg_save);
13213
4697a36c
MM
13214 if (info->lr_save_p)
13215 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 13216
4697a36c
MM
13217 if (info->cr_save_p)
13218 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
13219
00b960c7
AH
13220 if (info->vrsave_mask)
13221 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
13222
4697a36c
MM
13223 if (info->push_p)
13224 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
13225
13226 if (info->calls_p)
13227 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
13228
4697a36c
MM
13229 if (info->gp_save_offset)
13230 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
13231
13232 if (info->fp_save_offset)
13233 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
13234
00b960c7
AH
13235 if (info->altivec_save_offset)
13236 fprintf (stderr, "\taltivec_save_offset = %5d\n",
13237 info->altivec_save_offset);
13238
a3170dc6
AH
13239 if (info->spe_gp_save_offset)
13240 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
13241 info->spe_gp_save_offset);
13242
00b960c7
AH
13243 if (info->vrsave_save_offset)
13244 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
13245 info->vrsave_save_offset);
13246
4697a36c
MM
13247 if (info->lr_save_offset)
13248 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
13249
13250 if (info->cr_save_offset)
13251 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
13252
13253 if (info->varargs_save_offset)
13254 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
13255
13256 if (info->total_size)
d1d0c603
JJ
13257 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13258 info->total_size);
4697a36c 13259
4697a36c 13260 if (info->vars_size)
d1d0c603
JJ
13261 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
13262 info->vars_size);
4697a36c
MM
13263
13264 if (info->parm_size)
13265 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
13266
13267 if (info->fixed_size)
13268 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
13269
13270 if (info->gp_size)
13271 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
13272
a3170dc6
AH
13273 if (info->spe_gp_size)
13274 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
13275
4697a36c
MM
13276 if (info->fp_size)
13277 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
13278
00b960c7
AH
13279 if (info->altivec_size)
13280 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
13281
13282 if (info->vrsave_size)
13283 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
13284
13285 if (info->altivec_padding_size)
13286 fprintf (stderr, "\taltivec_padding_size= %5d\n",
13287 info->altivec_padding_size);
13288
a3170dc6
AH
13289 if (info->spe_padding_size)
13290 fprintf (stderr, "\tspe_padding_size = %5d\n",
13291 info->spe_padding_size);
13292
4697a36c
MM
13293 if (info->cr_size)
13294 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
13295
13296 if (info->save_size)
13297 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
13298
13299 if (info->reg_size != 4)
13300 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
13301
13302 fprintf (stderr, "\n");
9878760c 13303}
71f123ca
FS
13304
13305rtx
a2369ed3 13306rs6000_return_addr (int count, rtx frame)
71f123ca 13307{
a4f6c312
SS
13308 /* Currently we don't optimize very well between prolog and body
13309 code and for PIC code the code can be actually quite bad, so
13310 don't try to be too clever here. */
f1384257 13311 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
71f123ca
FS
13312 {
13313 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
13314
13315 return
13316 gen_rtx_MEM
13317 (Pmode,
13318 memory_address
13319 (Pmode,
13320 plus_constant (copy_to_reg
13321 (gen_rtx_MEM (Pmode,
13322 memory_address (Pmode, frame))),
13323 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
13324 }
13325
8c29550d 13326 cfun->machine->ra_need_lr = 1;
9e2f7ec7 13327 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
13328}
13329
5e1bf043
DJ
13330/* Say whether a function is a candidate for sibcall handling or not.
13331 We do not allow indirect calls to be optimized into sibling calls.
13332 Also, we can't do it if there are any vector parameters; there's
13333 nowhere to put the VRsave code so it works; note that functions with
13334 vector parameters are required to have a prototype, so the argument
13335 type info must be available here. (The tail recursion case can work
13336 with vector parameters, but there's no way to distinguish here.) */
4977bab6 13337static bool
a2369ed3 13338rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
5e1bf043
DJ
13339{
13340 tree type;
4977bab6 13341 if (decl)
5e1bf043
DJ
13342 {
13343 if (TARGET_ALTIVEC_VRSAVE)
c4ad648e 13344 {
4977bab6 13345 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
5e1bf043
DJ
13346 type; type = TREE_CHAIN (type))
13347 {
c15b529f 13348 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
4977bab6 13349 return false;
5e1bf043 13350 }
c4ad648e 13351 }
5e1bf043 13352 if (DEFAULT_ABI == ABI_DARWIN
4977bab6 13353 || (*targetm.binds_local_p) (decl))
2bcc50d0 13354 {
4977bab6 13355 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
2bcc50d0
AM
13356
13357 if (!lookup_attribute ("longcall", attr_list)
13358 || lookup_attribute ("shortcall", attr_list))
4977bab6 13359 return true;
2bcc50d0 13360 }
5e1bf043 13361 }
4977bab6 13362 return false;
5e1bf043
DJ
13363}
13364
e7e64a25
AS
13365/* NULL if INSN insn is valid within a low-overhead loop.
13366 Otherwise return why doloop cannot be applied.
9419649c
DE
13367 PowerPC uses the COUNT register for branch on table instructions. */
13368
e7e64a25
AS
13369static const char *
13370rs6000_invalid_within_doloop (rtx insn)
9419649c
DE
13371{
13372 if (CALL_P (insn))
e7e64a25 13373 return "Function call in the loop.";
9419649c
DE
13374
13375 if (JUMP_P (insn)
13376 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
13377 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
e7e64a25 13378 return "Computed branch in the loop.";
9419649c 13379
e7e64a25 13380 return NULL;
9419649c
DE
13381}
13382
71f123ca 13383static int
863d938c 13384rs6000_ra_ever_killed (void)
71f123ca
FS
13385{
13386 rtx top;
5e1bf043
DJ
13387 rtx reg;
13388 rtx insn;
71f123ca 13389
dd292d0a 13390 if (current_function_is_thunk)
71f123ca 13391 return 0;
eb0424da 13392
36f7e964
AH
13393 /* regs_ever_live has LR marked as used if any sibcalls are present,
13394 but this should not force saving and restoring in the
13395 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
a3c9585f 13396 clobbers LR, so that is inappropriate. */
36f7e964 13397
5e1bf043
DJ
13398 /* Also, the prologue can generate a store into LR that
13399 doesn't really count, like this:
36f7e964 13400
5e1bf043
DJ
13401 move LR->R0
13402 bcl to set PIC register
13403 move LR->R31
13404 move R0->LR
36f7e964
AH
13405
13406 When we're called from the epilogue, we need to avoid counting
13407 this as a store. */
f676971a 13408
71f123ca
FS
13409 push_topmost_sequence ();
13410 top = get_insns ();
13411 pop_topmost_sequence ();
5e1bf043 13412 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 13413
5e1bf043
DJ
13414 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
13415 {
13416 if (INSN_P (insn))
13417 {
022123e6
AM
13418 if (CALL_P (insn))
13419 {
13420 if (!SIBLING_CALL_P (insn))
13421 return 1;
13422 }
13423 else if (find_regno_note (insn, REG_INC, LINK_REGISTER_REGNUM))
5e1bf043 13424 return 1;
36f7e964
AH
13425 else if (set_of (reg, insn) != NULL_RTX
13426 && !prologue_epilogue_contains (insn))
5e1bf043
DJ
13427 return 1;
13428 }
13429 }
13430 return 0;
71f123ca 13431}
4697a36c 13432\f
8cd8f856
GK
13433/* Add a REG_MAYBE_DEAD note to the insn. */
13434static void
a2369ed3 13435rs6000_maybe_dead (rtx insn)
8cd8f856
GK
13436{
13437 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
13438 const0_rtx,
13439 REG_NOTES (insn));
13440}
13441
9ebbca7d 13442/* Emit instructions needed to load the TOC register.
c7ca610e 13443 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 13444 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
13445
13446void
a2369ed3 13447rs6000_emit_load_toc_table (int fromprolog)
c7ca610e 13448{
027fbf43 13449 rtx dest, insn;
1db02437 13450 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 13451
7f970b70 13452 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
20b71b17 13453 {
7f970b70
AM
13454 char buf[30];
13455 rtx lab, tmp1, tmp2, got, tempLR;
13456
13457 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13458 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13459 if (flag_pic == 2)
13460 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
13461 else
13462 got = rs6000_got_sym ();
13463 tmp1 = tmp2 = dest;
13464 if (!fromprolog)
13465 {
13466 tmp1 = gen_reg_rtx (Pmode);
13467 tmp2 = gen_reg_rtx (Pmode);
13468 }
13469 tempLR = (fromprolog
13470 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13471 : gen_reg_rtx (Pmode));
13472 insn = emit_insn (gen_load_toc_v4_PIC_1 (tempLR, lab));
13473 if (fromprolog)
13474 rs6000_maybe_dead (insn);
13475 insn = emit_move_insn (tmp1, tempLR);
13476 if (fromprolog)
13477 rs6000_maybe_dead (insn);
13478 insn = emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
13479 if (fromprolog)
13480 rs6000_maybe_dead (insn);
13481 insn = emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
13482 if (fromprolog)
13483 rs6000_maybe_dead (insn);
13484 }
13485 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
13486 {
13487 rtx tempLR = (fromprolog
13488 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13489 : gen_reg_rtx (Pmode));
13490
13491 insn = emit_insn (gen_load_toc_v4_pic_si (tempLR));
027fbf43
JJ
13492 if (fromprolog)
13493 rs6000_maybe_dead (insn);
7f970b70 13494 insn = emit_move_insn (dest, tempLR);
027fbf43
JJ
13495 if (fromprolog)
13496 rs6000_maybe_dead (insn);
20b71b17
AM
13497 }
13498 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
13499 {
13500 char buf[30];
13501 rtx tempLR = (fromprolog
13502 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
13503 : gen_reg_rtx (Pmode));
13504 rtx temp0 = (fromprolog
13505 ? gen_rtx_REG (Pmode, 0)
13506 : gen_reg_rtx (Pmode));
20b71b17 13507
20b71b17
AM
13508 if (fromprolog)
13509 {
ccbca5e4 13510 rtx symF, symL;
38c1f2d7 13511
20b71b17
AM
13512 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
13513 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 13514
20b71b17
AM
13515 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
13516 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13517
13518 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
13519 symF)));
13520 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
13521 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
13522 symL,
13523 symF)));
9ebbca7d
GK
13524 }
13525 else
20b71b17
AM
13526 {
13527 rtx tocsym;
20b71b17
AM
13528
13529 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
ccbca5e4 13530 emit_insn (gen_load_toc_v4_PIC_1b (tempLR, tocsym));
027fbf43
JJ
13531 emit_move_insn (dest, tempLR);
13532 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
20b71b17 13533 }
027fbf43
JJ
13534 insn = emit_insn (gen_addsi3 (dest, temp0, dest));
13535 if (fromprolog)
13536 rs6000_maybe_dead (insn);
9ebbca7d 13537 }
20b71b17
AM
13538 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
13539 {
13540 /* This is for AIX code running in non-PIC ELF32. */
13541 char buf[30];
13542 rtx realsym;
13543 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
13544 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
13545
027fbf43
JJ
13546 insn = emit_insn (gen_elf_high (dest, realsym));
13547 if (fromprolog)
13548 rs6000_maybe_dead (insn);
13549 insn = emit_insn (gen_elf_low (dest, dest, realsym));
13550 if (fromprolog)
13551 rs6000_maybe_dead (insn);
20b71b17 13552 }
37409796 13553 else
9ebbca7d 13554 {
37409796 13555 gcc_assert (DEFAULT_ABI == ABI_AIX);
bb8df8a6 13556
9ebbca7d 13557 if (TARGET_32BIT)
027fbf43 13558 insn = emit_insn (gen_load_toc_aix_si (dest));
9ebbca7d 13559 else
027fbf43
JJ
13560 insn = emit_insn (gen_load_toc_aix_di (dest));
13561 if (fromprolog)
13562 rs6000_maybe_dead (insn);
9ebbca7d
GK
13563 }
13564}
13565
d1d0c603
JJ
13566/* Emit instructions to restore the link register after determining where
13567 its value has been stored. */
13568
13569void
13570rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
13571{
13572 rs6000_stack_t *info = rs6000_stack_info ();
13573 rtx operands[2];
13574
13575 operands[0] = source;
13576 operands[1] = scratch;
13577
13578 if (info->lr_save_p)
13579 {
13580 rtx frame_rtx = stack_pointer_rtx;
13581 HOST_WIDE_INT sp_offset = 0;
13582 rtx tmp;
13583
13584 if (frame_pointer_needed
13585 || current_function_calls_alloca
13586 || info->total_size > 32767)
13587 {
0be76840 13588 tmp = gen_frame_mem (Pmode, frame_rtx);
8308679f 13589 emit_move_insn (operands[1], tmp);
d1d0c603
JJ
13590 frame_rtx = operands[1];
13591 }
13592 else if (info->push_p)
13593 sp_offset = info->total_size;
13594
13595 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
0be76840 13596 tmp = gen_frame_mem (Pmode, tmp);
d1d0c603
JJ
13597 emit_move_insn (tmp, operands[0]);
13598 }
13599 else
13600 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), operands[0]);
13601}
13602
f103e34d
GK
13603static GTY(()) int set = -1;
13604
f676971a 13605int
863d938c 13606get_TOC_alias_set (void)
9ebbca7d 13607{
f103e34d
GK
13608 if (set == -1)
13609 set = new_alias_set ();
13610 return set;
f676971a 13611}
9ebbca7d 13612
c1207243 13613/* This returns nonzero if the current function uses the TOC. This is
3c9eb5f4
AM
13614 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
13615 is generated by the ABI_V4 load_toc_* patterns. */
c954844a 13616#if TARGET_ELF
3c9eb5f4 13617static int
f676971a 13618uses_TOC (void)
9ebbca7d 13619{
c4501e62 13620 rtx insn;
38c1f2d7 13621
c4501e62
JJ
13622 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
13623 if (INSN_P (insn))
13624 {
13625 rtx pat = PATTERN (insn);
13626 int i;
9ebbca7d 13627
f676971a 13628 if (GET_CODE (pat) == PARALLEL)
c4501e62
JJ
13629 for (i = 0; i < XVECLEN (pat, 0); i++)
13630 {
13631 rtx sub = XVECEXP (pat, 0, i);
13632 if (GET_CODE (sub) == USE)
13633 {
13634 sub = XEXP (sub, 0);
13635 if (GET_CODE (sub) == UNSPEC
13636 && XINT (sub, 1) == UNSPEC_TOC)
13637 return 1;
13638 }
13639 }
13640 }
13641 return 0;
9ebbca7d 13642}
c954844a 13643#endif
38c1f2d7 13644
9ebbca7d 13645rtx
f676971a 13646create_TOC_reference (rtx symbol)
9ebbca7d 13647{
b69542f7
AM
13648 if (no_new_pseudos)
13649 regs_ever_live[TOC_REGISTER] = 1;
f676971a 13650 return gen_rtx_PLUS (Pmode,
a8a05998 13651 gen_rtx_REG (Pmode, TOC_REGISTER),
f676971a
EC
13652 gen_rtx_CONST (Pmode,
13653 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 13654 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 13655}
38c1f2d7 13656
fc4767bb
JJ
13657/* If _Unwind_* has been called from within the same module,
13658 toc register is not guaranteed to be saved to 40(1) on function
13659 entry. Save it there in that case. */
c7ca610e 13660
9ebbca7d 13661void
863d938c 13662rs6000_aix_emit_builtin_unwind_init (void)
9ebbca7d
GK
13663{
13664 rtx mem;
13665 rtx stack_top = gen_reg_rtx (Pmode);
13666 rtx opcode_addr = gen_reg_rtx (Pmode);
fc4767bb
JJ
13667 rtx opcode = gen_reg_rtx (SImode);
13668 rtx tocompare = gen_reg_rtx (SImode);
13669 rtx no_toc_save_needed = gen_label_rtx ();
9ebbca7d 13670
8308679f 13671 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
9ebbca7d
GK
13672 emit_move_insn (stack_top, mem);
13673
8308679f
DE
13674 mem = gen_frame_mem (Pmode,
13675 gen_rtx_PLUS (Pmode, stack_top,
13676 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9ebbca7d 13677 emit_move_insn (opcode_addr, mem);
fc4767bb
JJ
13678 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
13679 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
2496c7bd 13680 : 0xE8410028, SImode));
9ebbca7d 13681
fc4767bb 13682 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
06f4e019 13683 SImode, NULL_RTX, NULL_RTX,
fc4767bb 13684 no_toc_save_needed);
9ebbca7d 13685
8308679f
DE
13686 mem = gen_frame_mem (Pmode,
13687 gen_rtx_PLUS (Pmode, stack_top,
13688 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
fc4767bb
JJ
13689 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
13690 emit_label (no_toc_save_needed);
9ebbca7d 13691}
38c1f2d7 13692\f
0be76840
DE
13693/* This ties together stack memory (MEM with an alias set of frame_alias_set)
13694 and the change to the stack pointer. */
ba4828e0 13695
9ebbca7d 13696static void
863d938c 13697rs6000_emit_stack_tie (void)
9ebbca7d 13698{
0be76840
DE
13699 rtx mem = gen_frame_mem (BLKmode,
13700 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
ba4828e0 13701
9ebbca7d
GK
13702 emit_insn (gen_stack_tie (mem));
13703}
38c1f2d7 13704
9ebbca7d
GK
13705/* Emit the correct code for allocating stack space, as insns.
13706 If COPY_R12, make sure a copy of the old frame is left in r12.
13707 The generated code may use hard register 0 as a temporary. */
13708
13709static void
a2369ed3 13710rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
38c1f2d7 13711{
9ebbca7d
GK
13712 rtx insn;
13713 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
13714 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
61168ff1
RS
13715 rtx todec = gen_int_mode (-size, Pmode);
13716
13717 if (INTVAL (todec) != -size)
13718 {
d4ee4d25 13719 warning (0, "stack frame too large");
61168ff1
RS
13720 emit_insn (gen_trap ());
13721 return;
13722 }
a157febd
GK
13723
13724 if (current_function_limit_stack)
13725 {
13726 if (REG_P (stack_limit_rtx)
f676971a 13727 && REGNO (stack_limit_rtx) > 1
a157febd
GK
13728 && REGNO (stack_limit_rtx) <= 31)
13729 {
5b71a4e7 13730 emit_insn (TARGET_32BIT
9ebbca7d
GK
13731 ? gen_addsi3 (tmp_reg,
13732 stack_limit_rtx,
13733 GEN_INT (size))
13734 : gen_adddi3 (tmp_reg,
13735 stack_limit_rtx,
13736 GEN_INT (size)));
5b71a4e7 13737
9ebbca7d
GK
13738 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
13739 const0_rtx));
a157febd
GK
13740 }
13741 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 13742 && TARGET_32BIT
f607bc57 13743 && DEFAULT_ABI == ABI_V4)
a157febd 13744 {
9ebbca7d 13745 rtx toload = gen_rtx_CONST (VOIDmode,
f676971a
EC
13746 gen_rtx_PLUS (Pmode,
13747 stack_limit_rtx,
9ebbca7d 13748 GEN_INT (size)));
5b71a4e7 13749
9ebbca7d
GK
13750 emit_insn (gen_elf_high (tmp_reg, toload));
13751 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
13752 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
13753 const0_rtx));
a157febd
GK
13754 }
13755 else
d4ee4d25 13756 warning (0, "stack limit expression is not supported");
a157febd
GK
13757 }
13758
9ebbca7d
GK
13759 if (copy_r12 || ! TARGET_UPDATE)
13760 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
13761
38c1f2d7
MM
13762 if (TARGET_UPDATE)
13763 {
9ebbca7d 13764 if (size > 32767)
38c1f2d7 13765 {
9ebbca7d 13766 /* Need a note here so that try_split doesn't get confused. */
9390387d 13767 if (get_last_insn () == NULL_RTX)
2e040219 13768 emit_note (NOTE_INSN_DELETED);
9ebbca7d
GK
13769 insn = emit_move_insn (tmp_reg, todec);
13770 try_split (PATTERN (insn), insn, 0);
13771 todec = tmp_reg;
38c1f2d7 13772 }
5b71a4e7
DE
13773
13774 insn = emit_insn (TARGET_32BIT
13775 ? gen_movsi_update (stack_reg, stack_reg,
13776 todec, stack_reg)
c4ad648e 13777 : gen_movdi_di_update (stack_reg, stack_reg,
9ebbca7d 13778 todec, stack_reg));
38c1f2d7
MM
13779 }
13780 else
13781 {
5b71a4e7
DE
13782 insn = emit_insn (TARGET_32BIT
13783 ? gen_addsi3 (stack_reg, stack_reg, todec)
13784 : gen_adddi3 (stack_reg, stack_reg, todec));
9ebbca7d
GK
13785 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
13786 gen_rtx_REG (Pmode, 12));
13787 }
f676971a 13788
9ebbca7d 13789 RTX_FRAME_RELATED_P (insn) = 1;
f676971a 13790 REG_NOTES (insn) =
9ebbca7d 13791 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
f676971a 13792 gen_rtx_SET (VOIDmode, stack_reg,
9ebbca7d
GK
13793 gen_rtx_PLUS (Pmode, stack_reg,
13794 GEN_INT (-size))),
13795 REG_NOTES (insn));
13796}
13797
a4f6c312
SS
13798/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
13799 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
13800 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
13801 deduce these equivalences by itself so it wasn't necessary to hold
13802 its hand so much. */
9ebbca7d
GK
13803
13804static void
f676971a 13805rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
a2369ed3 13806 rtx reg2, rtx rreg)
9ebbca7d
GK
13807{
13808 rtx real, temp;
13809
e56c4463
JL
13810 /* copy_rtx will not make unique copies of registers, so we need to
13811 ensure we don't have unwanted sharing here. */
13812 if (reg == reg2)
13813 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
13814
13815 if (reg == rreg)
13816 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
13817
9ebbca7d
GK
13818 real = copy_rtx (PATTERN (insn));
13819
89e7058f
AH
13820 if (reg2 != NULL_RTX)
13821 real = replace_rtx (real, reg2, rreg);
f676971a
EC
13822
13823 real = replace_rtx (real, reg,
9ebbca7d
GK
13824 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
13825 STACK_POINTER_REGNUM),
13826 GEN_INT (val)));
f676971a 13827
9ebbca7d
GK
13828 /* We expect that 'real' is either a SET or a PARALLEL containing
13829 SETs (and possibly other stuff). In a PARALLEL, all the SETs
13830 are important so they all have to be marked RTX_FRAME_RELATED_P. */
13831
13832 if (GET_CODE (real) == SET)
13833 {
13834 rtx set = real;
f676971a 13835
9ebbca7d
GK
13836 temp = simplify_rtx (SET_SRC (set));
13837 if (temp)
13838 SET_SRC (set) = temp;
13839 temp = simplify_rtx (SET_DEST (set));
13840 if (temp)
13841 SET_DEST (set) = temp;
13842 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 13843 {
9ebbca7d
GK
13844 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
13845 if (temp)
13846 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 13847 }
38c1f2d7 13848 }
37409796 13849 else
9ebbca7d
GK
13850 {
13851 int i;
37409796
NS
13852
13853 gcc_assert (GET_CODE (real) == PARALLEL);
9ebbca7d
GK
13854 for (i = 0; i < XVECLEN (real, 0); i++)
13855 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
13856 {
13857 rtx set = XVECEXP (real, 0, i);
f676971a 13858
9ebbca7d
GK
13859 temp = simplify_rtx (SET_SRC (set));
13860 if (temp)
13861 SET_SRC (set) = temp;
13862 temp = simplify_rtx (SET_DEST (set));
13863 if (temp)
13864 SET_DEST (set) = temp;
13865 if (GET_CODE (SET_DEST (set)) == MEM)
13866 {
13867 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
13868 if (temp)
13869 XEXP (SET_DEST (set), 0) = temp;
13870 }
13871 RTX_FRAME_RELATED_P (set) = 1;
13872 }
13873 }
c19de7aa
AH
13874
13875 if (TARGET_SPE)
13876 real = spe_synthesize_frame_save (real);
13877
9ebbca7d
GK
13878 RTX_FRAME_RELATED_P (insn) = 1;
13879 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
13880 real,
13881 REG_NOTES (insn));
38c1f2d7
MM
13882}
13883
c19de7aa
AH
13884/* Given an SPE frame note, return a PARALLEL of SETs with the
13885 original note, plus a synthetic register save. */
13886
13887static rtx
a2369ed3 13888spe_synthesize_frame_save (rtx real)
c19de7aa
AH
13889{
13890 rtx synth, offset, reg, real2;
13891
13892 if (GET_CODE (real) != SET
13893 || GET_MODE (SET_SRC (real)) != V2SImode)
13894 return real;
13895
13896 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
13897 frame related note. The parallel contains a set of the register
41f3a930 13898 being saved, and another set to a synthetic register (n+1200).
c19de7aa
AH
13899 This is so we can differentiate between 64-bit and 32-bit saves.
13900 Words cannot describe this nastiness. */
13901
37409796
NS
13902 gcc_assert (GET_CODE (SET_DEST (real)) == MEM
13903 && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
13904 && GET_CODE (SET_SRC (real)) == REG);
c19de7aa
AH
13905
13906 /* Transform:
13907 (set (mem (plus (reg x) (const y)))
13908 (reg z))
13909 into:
13910 (set (mem (plus (reg x) (const y+4)))
41f3a930 13911 (reg z+1200))
c19de7aa
AH
13912 */
13913
13914 real2 = copy_rtx (real);
13915 PUT_MODE (SET_DEST (real2), SImode);
13916 reg = SET_SRC (real2);
13917 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
13918 synth = copy_rtx (real2);
13919
13920 if (BYTES_BIG_ENDIAN)
13921 {
13922 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
13923 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
13924 }
13925
13926 reg = SET_SRC (synth);
41f3a930 13927
c19de7aa 13928 synth = replace_rtx (synth, reg,
41f3a930 13929 gen_rtx_REG (SImode, REGNO (reg) + 1200));
c19de7aa
AH
13930
13931 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
13932 synth = replace_rtx (synth, offset,
13933 GEN_INT (INTVAL (offset)
13934 + (BYTES_BIG_ENDIAN ? 0 : 4)));
13935
13936 RTX_FRAME_RELATED_P (synth) = 1;
13937 RTX_FRAME_RELATED_P (real2) = 1;
13938 if (BYTES_BIG_ENDIAN)
13939 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
13940 else
13941 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
13942
13943 return real;
13944}
13945
00b960c7
AH
13946/* Returns an insn that has a vrsave set operation with the
13947 appropriate CLOBBERs. */
13948
13949static rtx
a2369ed3 13950generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
00b960c7
AH
13951{
13952 int nclobs, i;
13953 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 13954 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 13955
a004eb82
AH
13956 clobs[0]
13957 = gen_rtx_SET (VOIDmode,
13958 vrsave,
13959 gen_rtx_UNSPEC_VOLATILE (SImode,
13960 gen_rtvec (2, reg, vrsave),
3aca4bff 13961 UNSPECV_SET_VRSAVE));
00b960c7
AH
13962
13963 nclobs = 1;
13964
9aa86737
AH
13965 /* We need to clobber the registers in the mask so the scheduler
13966 does not move sets to VRSAVE before sets of AltiVec registers.
13967
13968 However, if the function receives nonlocal gotos, reload will set
13969 all call saved registers live. We will end up with:
13970
13971 (set (reg 999) (mem))
13972 (parallel [ (set (reg vrsave) (unspec blah))
13973 (clobber (reg 999))])
13974
13975 The clobber will cause the store into reg 999 to be dead, and
13976 flow will attempt to delete an epilogue insn. In this case, we
13977 need an unspec use/set of the register. */
00b960c7
AH
13978
13979 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
44688022 13980 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
9aa86737
AH
13981 {
13982 if (!epiloguep || call_used_regs [i])
13983 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
13984 gen_rtx_REG (V4SImode, i));
13985 else
13986 {
13987 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
13988
13989 clobs[nclobs++]
a004eb82
AH
13990 = gen_rtx_SET (VOIDmode,
13991 reg,
13992 gen_rtx_UNSPEC (V4SImode,
13993 gen_rtvec (1, reg), 27));
9aa86737
AH
13994 }
13995 }
00b960c7
AH
13996
13997 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
13998
13999 for (i = 0; i < nclobs; ++i)
14000 XVECEXP (insn, 0, i) = clobs[i];
14001
14002 return insn;
14003}
14004
89e7058f
AH
14005/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
14006 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
14007
14008static void
f676971a 14009emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
d1d0c603 14010 unsigned int regno, int offset, HOST_WIDE_INT total_size)
89e7058f
AH
14011{
14012 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
14013 rtx replacea, replaceb;
14014
14015 int_rtx = GEN_INT (offset);
14016
14017 /* Some cases that need register indexed addressing. */
14018 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
4d4cbc0e 14019 || (TARGET_E500_DOUBLE && mode == DFmode)
a3170dc6
AH
14020 || (TARGET_SPE_ABI
14021 && SPE_VECTOR_MODE (mode)
14022 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
14023 {
14024 /* Whomever calls us must make sure r11 is available in the
c4ad648e 14025 flow path of instructions in the prologue. */
89e7058f
AH
14026 offset_rtx = gen_rtx_REG (Pmode, 11);
14027 emit_move_insn (offset_rtx, int_rtx);
14028
14029 replacea = offset_rtx;
14030 replaceb = int_rtx;
14031 }
14032 else
14033 {
14034 offset_rtx = int_rtx;
14035 replacea = NULL_RTX;
14036 replaceb = NULL_RTX;
14037 }
14038
14039 reg = gen_rtx_REG (mode, regno);
14040 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
0be76840 14041 mem = gen_frame_mem (mode, addr);
89e7058f
AH
14042
14043 insn = emit_move_insn (mem, reg);
14044
14045 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
14046}
14047
a3170dc6
AH
14048/* Emit an offset memory reference suitable for a frame store, while
14049 converting to a valid addressing mode. */
14050
14051static rtx
a2369ed3 14052gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
a3170dc6
AH
14053{
14054 rtx int_rtx, offset_rtx;
14055
14056 int_rtx = GEN_INT (offset);
14057
4d4cbc0e
AH
14058 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
14059 || (TARGET_E500_DOUBLE && mode == DFmode))
a3170dc6
AH
14060 {
14061 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14062 emit_move_insn (offset_rtx, int_rtx);
14063 }
14064 else
14065 offset_rtx = int_rtx;
14066
0be76840 14067 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
a3170dc6
AH
14068}
14069
6d0a8091
DJ
14070/* Look for user-defined global regs. We should not save and restore these,
14071 and cannot use stmw/lmw if there are any in its range. */
14072
14073static bool
14074no_global_regs_above (int first_greg)
14075{
14076 int i;
14077 for (i = 0; i < 32 - first_greg; i++)
14078 if (global_regs[first_greg + i])
14079 return false;
14080 return true;
14081}
14082
699c914a
MS
14083#ifndef TARGET_FIX_AND_CONTINUE
14084#define TARGET_FIX_AND_CONTINUE 0
14085#endif
14086
9ebbca7d
GK
14087/* Emit function prologue as insns. */
14088
9878760c 14089void
863d938c 14090rs6000_emit_prologue (void)
9878760c 14091{
4697a36c 14092 rs6000_stack_t *info = rs6000_stack_info ();
0e67400a 14093 enum machine_mode reg_mode = Pmode;
327e5343 14094 int reg_size = TARGET_32BIT ? 4 : 8;
9ebbca7d
GK
14095 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14096 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
14097 rtx frame_reg_rtx = sp_reg_rtx;
b78d48dd 14098 rtx cr_save_rtx = NULL_RTX;
9ebbca7d
GK
14099 rtx insn;
14100 int saving_FPRs_inline;
14101 int using_store_multiple;
14102 HOST_WIDE_INT sp_offset = 0;
f676971a 14103
699c914a
MS
14104 if (TARGET_FIX_AND_CONTINUE)
14105 {
14106 /* gdb on darwin arranges to forward a function from the old
de2ab0ca 14107 address by modifying the first 5 instructions of the function
699c914a
MS
14108 to branch to the overriding function. This is necessary to
14109 permit function pointers that point to the old function to
14110 actually forward to the new function. */
14111 emit_insn (gen_nop ());
14112 emit_insn (gen_nop ());
de2ab0ca 14113 emit_insn (gen_nop ());
699c914a
MS
14114 emit_insn (gen_nop ());
14115 emit_insn (gen_nop ());
14116 }
14117
14118 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
14119 {
14120 reg_mode = V2SImode;
14121 reg_size = 8;
14122 }
a3170dc6 14123
9ebbca7d 14124 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
14125 && (!TARGET_SPE_ABI
14126 || info->spe_64bit_regs_used == 0)
6d0a8091
DJ
14127 && info->first_gp_reg_save < 31
14128 && no_global_regs_above (info->first_gp_reg_save));
9ebbca7d 14129 saving_FPRs_inline = (info->first_fp_reg_save == 64
8c29550d 14130 || FP_SAVE_INLINE (info->first_fp_reg_save)
acd0b319 14131 || current_function_calls_eh_return
8c29550d 14132 || cfun->machine->ra_need_lr);
9ebbca7d
GK
14133
14134 /* For V.4, update stack before we do any saving and set back pointer. */
fc4767bb 14135 if (info->push_p
acd0b319
AM
14136 && (DEFAULT_ABI == ABI_V4
14137 || current_function_calls_eh_return))
9ebbca7d
GK
14138 {
14139 if (info->total_size < 32767)
14140 sp_offset = info->total_size;
14141 else
14142 frame_reg_rtx = frame_ptr_rtx;
f676971a 14143 rs6000_emit_allocate_stack (info->total_size,
9ebbca7d
GK
14144 (frame_reg_rtx != sp_reg_rtx
14145 && (info->cr_save_p
14146 || info->lr_save_p
14147 || info->first_fp_reg_save < 64
14148 || info->first_gp_reg_save < 32
14149 )));
14150 if (frame_reg_rtx != sp_reg_rtx)
14151 rs6000_emit_stack_tie ();
14152 }
14153
d62294f5 14154 /* Handle world saves specially here. */
f57fe068 14155 if (WORLD_SAVE_P (info))
d62294f5
FJ
14156 {
14157 int i, j, sz;
14158 rtx treg;
14159 rtvec p;
14160
14161 /* save_world expects lr in r0. */
14162 if (info->lr_save_p)
c4ad648e
AM
14163 {
14164 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14165 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14166 RTX_FRAME_RELATED_P (insn) = 1;
14167 }
d62294f5
FJ
14168
14169 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
c4ad648e 14170 assumptions about the offsets of various bits of the stack
992d08b1 14171 frame. */
37409796
NS
14172 gcc_assert (info->gp_save_offset == -220
14173 && info->fp_save_offset == -144
14174 && info->lr_save_offset == 8
14175 && info->cr_save_offset == 4
14176 && info->push_p
14177 && info->lr_save_p
14178 && (!current_function_calls_eh_return
14179 || info->ehrd_offset == -432)
14180 && info->vrsave_save_offset == -224
14181 && info->altivec_save_offset == (-224 -16 -192));
d62294f5
FJ
14182
14183 treg = gen_rtx_REG (SImode, 11);
14184 emit_move_insn (treg, GEN_INT (-info->total_size));
14185
14186 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
c4ad648e 14187 in R11. It also clobbers R12, so beware! */
d62294f5
FJ
14188
14189 /* Preserve CR2 for save_world prologues */
14190 sz = 6;
14191 sz += 32 - info->first_gp_reg_save;
14192 sz += 64 - info->first_fp_reg_save;
14193 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
14194 p = rtvec_alloc (sz);
14195 j = 0;
14196 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
c4ad648e
AM
14197 gen_rtx_REG (Pmode,
14198 LINK_REGISTER_REGNUM));
d62294f5 14199 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
c4ad648e
AM
14200 gen_rtx_SYMBOL_REF (Pmode,
14201 "*save_world"));
d62294f5 14202 /* We do floats first so that the instruction pattern matches
c4ad648e
AM
14203 properly. */
14204 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14205 {
14206 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14207 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14208 GEN_INT (info->fp_save_offset
14209 + sp_offset + 8 * i));
0be76840 14210 rtx mem = gen_frame_mem (DFmode, addr);
c4ad648e
AM
14211
14212 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14213 }
d62294f5 14214 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
c4ad648e
AM
14215 {
14216 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14217 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14218 GEN_INT (info->altivec_save_offset
14219 + sp_offset + 16 * i));
0be76840 14220 rtx mem = gen_frame_mem (V4SImode, addr);
c4ad648e
AM
14221
14222 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14223 }
d62294f5 14224 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
c4ad648e
AM
14225 {
14226 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14227 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14228 GEN_INT (info->gp_save_offset
14229 + sp_offset + reg_size * i));
0be76840 14230 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
14231
14232 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14233 }
14234
14235 {
14236 /* CR register traditionally saved as CR2. */
14237 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14238 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14239 GEN_INT (info->cr_save_offset
14240 + sp_offset));
0be76840 14241 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
14242
14243 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
14244 }
d62294f5
FJ
14245 /* Prevent any attempt to delete the setting of r0 and treg! */
14246 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 0));
14247 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, treg);
14248 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode, sp_reg_rtx);
14249
14250 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
14251 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
c4ad648e 14252 NULL_RTX, NULL_RTX);
d62294f5
FJ
14253
14254 if (current_function_calls_eh_return)
c4ad648e
AM
14255 {
14256 unsigned int i;
14257 for (i = 0; ; ++i)
14258 {
14259 unsigned int regno = EH_RETURN_DATA_REGNO (i);
14260 if (regno == INVALID_REGNUM)
14261 break;
14262 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14263 info->ehrd_offset + sp_offset
14264 + reg_size * (int) i,
14265 info->total_size);
14266 }
14267 }
d62294f5
FJ
14268 }
14269
9aa86737 14270 /* Save AltiVec registers if needed. */
f57fe068 14271 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
9aa86737
AH
14272 {
14273 int i;
14274
14275 /* There should be a non inline version of this, for when we
14276 are saving lots of vector registers. */
14277 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14278 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14279 {
14280 rtx areg, savereg, mem;
14281 int offset;
14282
14283 offset = info->altivec_save_offset + sp_offset
14284 + 16 * (i - info->first_altivec_reg_save);
14285
14286 savereg = gen_rtx_REG (V4SImode, i);
14287
14288 areg = gen_rtx_REG (Pmode, 0);
14289 emit_move_insn (areg, GEN_INT (offset));
14290
14291 /* AltiVec addressing mode is [reg+reg]. */
0be76840
DE
14292 mem = gen_frame_mem (V4SImode,
14293 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
9aa86737
AH
14294
14295 insn = emit_move_insn (mem, savereg);
14296
5c242421
SB
14297 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14298 areg, GEN_INT (offset));
9aa86737
AH
14299 }
14300 }
14301
14302 /* VRSAVE is a bit vector representing which AltiVec registers
14303 are used. The OS uses this to determine which vector
14304 registers to save on a context switch. We need to save
14305 VRSAVE on the stack frame, add whatever AltiVec registers we
14306 used in this function, and do the corresponding magic in the
14307 epilogue. */
14308
4d774ff8 14309 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
bcb604b6 14310 && info->vrsave_mask != 0)
9aa86737 14311 {
a004eb82 14312 rtx reg, mem, vrsave;
9aa86737
AH
14313 int offset;
14314
eab97e44
AM
14315 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
14316 as frame_reg_rtx and r11 as the static chain pointer for
14317 nested functions. */
14318 reg = gen_rtx_REG (SImode, 0);
a004eb82 14319 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
14320 if (TARGET_MACHO)
14321 emit_insn (gen_get_vrsave_internal (reg));
14322 else
14323 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737 14324
bcb604b6
FJ
14325 if (!WORLD_SAVE_P (info))
14326 {
14327 /* Save VRSAVE. */
14328 offset = info->vrsave_save_offset + sp_offset;
0be76840
DE
14329 mem = gen_frame_mem (SImode,
14330 gen_rtx_PLUS (Pmode, frame_reg_rtx,
14331 GEN_INT (offset)));
bcb604b6
FJ
14332 insn = emit_move_insn (mem, reg);
14333 }
9aa86737
AH
14334
14335 /* Include the registers in the mask. */
14336 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
14337
14338 insn = emit_insn (generate_set_vrsave (reg, info, 0));
14339 }
14340
9ebbca7d 14341 /* If we use the link register, get it into r0. */
f57fe068 14342 if (!WORLD_SAVE_P (info) && info->lr_save_p)
f8a57be8
GK
14343 {
14344 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
14345 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
14346 RTX_FRAME_RELATED_P (insn) = 1;
14347 }
9ebbca7d
GK
14348
14349 /* If we need to save CR, put it into r12. */
f57fe068 14350 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
9ebbca7d 14351 {
f8a57be8 14352 rtx set;
f676971a 14353
9ebbca7d 14354 cr_save_rtx = gen_rtx_REG (SImode, 12);
f8a57be8
GK
14355 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14356 RTX_FRAME_RELATED_P (insn) = 1;
14357 /* Now, there's no way that dwarf2out_frame_debug_expr is going
14358 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
14359 But that's OK. All we have to do is specify that _one_ condition
14360 code register is saved in this stack slot. The thrower's epilogue
14361 will then restore all the call-saved registers.
14362 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
14363 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
14364 gen_rtx_REG (SImode, CR2_REGNO));
14365 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14366 set,
14367 REG_NOTES (insn));
9ebbca7d
GK
14368 }
14369
a4f6c312
SS
14370 /* Do any required saving of fpr's. If only one or two to save, do
14371 it ourselves. Otherwise, call function. */
f57fe068 14372 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
9ebbca7d
GK
14373 {
14374 int i;
14375 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
f676971a 14376 if ((regs_ever_live[info->first_fp_reg_save+i]
9ebbca7d 14377 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
14378 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
14379 info->first_fp_reg_save + i,
14380 info->fp_save_offset + sp_offset + 8 * i,
14381 info->total_size);
9ebbca7d 14382 }
f57fe068 14383 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
9ebbca7d
GK
14384 {
14385 int i;
14386 char rname[30];
520a57c8 14387 const char *alloc_rname;
9ebbca7d
GK
14388 rtvec p;
14389 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
f676971a
EC
14390
14391 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
14392 gen_rtx_REG (Pmode,
9ebbca7d
GK
14393 LINK_REGISTER_REGNUM));
14394 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
14395 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 14396 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
14397 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
14398 gen_rtx_SYMBOL_REF (Pmode,
14399 alloc_rname));
14400 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
14401 {
14402 rtx addr, reg, mem;
14403 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14404 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
f676971a 14405 GEN_INT (info->fp_save_offset
9ebbca7d 14406 + sp_offset + 8*i));
0be76840 14407 mem = gen_frame_mem (DFmode, addr);
9ebbca7d
GK
14408
14409 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
14410 }
14411 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
f676971a 14412 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
9ebbca7d
GK
14413 NULL_RTX, NULL_RTX);
14414 }
b6c9286a 14415
9ebbca7d
GK
14416 /* Save GPRs. This is done as a PARALLEL if we are using
14417 the store-multiple instructions. */
f57fe068 14418 if (!WORLD_SAVE_P (info) && using_store_multiple)
b6c9286a 14419 {
308c142a 14420 rtvec p;
9ebbca7d
GK
14421 int i;
14422 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
14423 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
14424 {
14425 rtx addr, reg, mem;
14426 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
f676971a
EC
14427 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14428 GEN_INT (info->gp_save_offset
14429 + sp_offset
9ebbca7d 14430 + reg_size * i));
0be76840 14431 mem = gen_frame_mem (reg_mode, addr);
9ebbca7d
GK
14432
14433 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
14434 }
14435 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
f676971a 14436 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
9ebbca7d 14437 NULL_RTX, NULL_RTX);
b6c9286a 14438 }
f57fe068 14439 else if (!WORLD_SAVE_P (info))
b6c9286a 14440 {
9ebbca7d
GK
14441 int i;
14442 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
6d0a8091
DJ
14443 if ((regs_ever_live[info->first_gp_reg_save + i]
14444 && (!call_used_regs[info->first_gp_reg_save + i]
14445 || (i + info->first_gp_reg_save
b4db40bf
JJ
14446 == RS6000_PIC_OFFSET_TABLE_REGNUM
14447 && TARGET_TOC && TARGET_MINIMAL_TOC)))
6d0a8091 14448 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 14449 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 14450 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
14451 {
14452 rtx addr, reg, mem;
14453 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14454
c19de7aa 14455 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
14456 {
14457 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
14458 rtx b;
14459
14460 if (!SPE_CONST_OFFSET_OK (offset))
14461 {
14462 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
14463 emit_move_insn (b, GEN_INT (offset));
14464 }
14465 else
14466 b = GEN_INT (offset);
14467
14468 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
0be76840 14469 mem = gen_frame_mem (V2SImode, addr);
a3170dc6
AH
14470 insn = emit_move_insn (mem, reg);
14471
14472 if (GET_CODE (b) == CONST_INT)
14473 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14474 NULL_RTX, NULL_RTX);
14475 else
14476 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
14477 b, GEN_INT (offset));
14478 }
14479 else
14480 {
f676971a
EC
14481 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14482 GEN_INT (info->gp_save_offset
14483 + sp_offset
a3170dc6 14484 + reg_size * i));
0be76840 14485 mem = gen_frame_mem (reg_mode, addr);
a3170dc6
AH
14486
14487 insn = emit_move_insn (mem, reg);
f676971a 14488 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a3170dc6
AH
14489 NULL_RTX, NULL_RTX);
14490 }
14491 }
9ebbca7d
GK
14492 }
14493
83720594
RH
14494 /* ??? There's no need to emit actual instructions here, but it's the
14495 easiest way to get the frame unwind information emitted. */
f57fe068 14496 if (!WORLD_SAVE_P (info) && current_function_calls_eh_return)
83720594 14497 {
78e1b90d
DE
14498 unsigned int i, regno;
14499
fc4767bb
JJ
14500 /* In AIX ABI we need to pretend we save r2 here. */
14501 if (TARGET_AIX)
14502 {
14503 rtx addr, reg, mem;
14504
14505 reg = gen_rtx_REG (reg_mode, 2);
14506 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14507 GEN_INT (sp_offset + 5 * reg_size));
0be76840 14508 mem = gen_frame_mem (reg_mode, addr);
fc4767bb
JJ
14509
14510 insn = emit_move_insn (mem, reg);
f676971a 14511 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
fc4767bb
JJ
14512 NULL_RTX, NULL_RTX);
14513 PATTERN (insn) = gen_blockage ();
14514 }
14515
83720594
RH
14516 for (i = 0; ; ++i)
14517 {
83720594
RH
14518 regno = EH_RETURN_DATA_REGNO (i);
14519 if (regno == INVALID_REGNUM)
14520 break;
14521
89e7058f
AH
14522 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
14523 info->ehrd_offset + sp_offset
14524 + reg_size * (int) i,
14525 info->total_size);
83720594
RH
14526 }
14527 }
14528
9ebbca7d 14529 /* Save lr if we used it. */
f57fe068 14530 if (!WORLD_SAVE_P (info) && info->lr_save_p)
9ebbca7d
GK
14531 {
14532 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14533 GEN_INT (info->lr_save_offset + sp_offset));
14534 rtx reg = gen_rtx_REG (Pmode, 0);
14535 rtx mem = gen_rtx_MEM (Pmode, addr);
0be76840 14536 /* This should not be of frame_alias_set, because of
9ebbca7d 14537 __builtin_return_address. */
f676971a 14538
9ebbca7d 14539 insn = emit_move_insn (mem, reg);
f676971a 14540 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
f8a57be8 14541 NULL_RTX, NULL_RTX);
9ebbca7d
GK
14542 }
14543
14544 /* Save CR if we use any that must be preserved. */
f57fe068 14545 if (!WORLD_SAVE_P (info) && info->cr_save_p)
9ebbca7d
GK
14546 {
14547 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14548 GEN_INT (info->cr_save_offset + sp_offset));
0be76840 14549 rtx mem = gen_frame_mem (SImode, addr);
f8a57be8
GK
14550 /* See the large comment above about why CR2_REGNO is used. */
14551 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
ba4828e0 14552
9ebbca7d
GK
14553 /* If r12 was used to hold the original sp, copy cr into r0 now
14554 that it's free. */
14555 if (REGNO (frame_reg_rtx) == 12)
14556 {
f8a57be8
GK
14557 rtx set;
14558
9ebbca7d 14559 cr_save_rtx = gen_rtx_REG (SImode, 0);
f8a57be8
GK
14560 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
14561 RTX_FRAME_RELATED_P (insn) = 1;
14562 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
14563 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14564 set,
14565 REG_NOTES (insn));
f676971a 14566
9ebbca7d
GK
14567 }
14568 insn = emit_move_insn (mem, cr_save_rtx);
14569
f676971a 14570 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
f8a57be8 14571 NULL_RTX, NULL_RTX);
9ebbca7d
GK
14572 }
14573
f676971a 14574 /* Update stack and set back pointer unless this is V.4,
9ebbca7d 14575 for which it was done previously. */
f57fe068 14576 if (!WORLD_SAVE_P (info) && info->push_p
fc4767bb 14577 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
9ebbca7d
GK
14578 rs6000_emit_allocate_stack (info->total_size, FALSE);
14579
14580 /* Set frame pointer, if needed. */
14581 if (frame_pointer_needed)
14582 {
7d5175e1 14583 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
9ebbca7d
GK
14584 sp_reg_rtx);
14585 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 14586 }
9878760c 14587
1db02437 14588 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 14589 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
7f970b70
AM
14590 || (DEFAULT_ABI == ABI_V4
14591 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
1db02437 14592 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
c4ad648e
AM
14593 {
14594 /* If emit_load_toc_table will use the link register, we need to save
14595 it. We use R12 for this purpose because emit_load_toc_table
14596 can use register 0. This allows us to use a plain 'blr' to return
14597 from the procedure more often. */
14598 int save_LR_around_toc_setup = (TARGET_ELF
14599 && DEFAULT_ABI != ABI_AIX
14600 && flag_pic
14601 && ! info->lr_save_p
14602 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
14603 if (save_LR_around_toc_setup)
14604 {
14605 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
f8a57be8 14606
c4ad648e
AM
14607 insn = emit_move_insn (frame_ptr_rtx, lr);
14608 rs6000_maybe_dead (insn);
14609 RTX_FRAME_RELATED_P (insn) = 1;
f8a57be8 14610
c4ad648e 14611 rs6000_emit_load_toc_table (TRUE);
f8a57be8 14612
c4ad648e
AM
14613 insn = emit_move_insn (lr, frame_ptr_rtx);
14614 rs6000_maybe_dead (insn);
14615 RTX_FRAME_RELATED_P (insn) = 1;
14616 }
14617 else
14618 rs6000_emit_load_toc_table (TRUE);
14619 }
ee890fe2 14620
fcce224d 14621#if TARGET_MACHO
ee890fe2
SS
14622 if (DEFAULT_ABI == ABI_DARWIN
14623 && flag_pic && current_function_uses_pic_offset_table)
14624 {
f8a57be8 14625 rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
11abc112 14626 rtx src = machopic_function_base_sym ();
ee890fe2 14627
6d0a8091
DJ
14628 /* Save and restore LR locally around this call (in R0). */
14629 if (!info->lr_save_p)
14630 rs6000_maybe_dead (emit_move_insn (gen_rtx_REG (Pmode, 0), lr));
14631
f8a57be8 14632 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (lr, src)));
ee890fe2 14633
f676971a 14634 insn = emit_move_insn (gen_rtx_REG (Pmode,
f8a57be8
GK
14635 RS6000_PIC_OFFSET_TABLE_REGNUM),
14636 lr);
14637 rs6000_maybe_dead (insn);
6d0a8091
DJ
14638
14639 if (!info->lr_save_p)
14640 rs6000_maybe_dead (emit_move_insn (lr, gen_rtx_REG (Pmode, 0)));
ee890fe2 14641 }
fcce224d 14642#endif
9ebbca7d
GK
14643}
14644
9ebbca7d 14645/* Write function prologue. */
a4f6c312 14646
08c148a8 14647static void
f676971a 14648rs6000_output_function_prologue (FILE *file,
a2369ed3 14649 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
9ebbca7d
GK
14650{
14651 rs6000_stack_t *info = rs6000_stack_info ();
14652
4697a36c
MM
14653 if (TARGET_DEBUG_STACK)
14654 debug_stack_info (info);
9878760c 14655
a4f6c312
SS
14656 /* Write .extern for any function we will call to save and restore
14657 fp values. */
14658 if (info->first_fp_reg_save < 64
14659 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 14660 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 14661 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
14662 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
14663 RESTORE_FP_SUFFIX);
9878760c 14664
c764f757
RK
14665 /* Write .extern for AIX common mode routines, if needed. */
14666 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
14667 {
f6709c70
JW
14668 fputs ("\t.extern __mulh\n", file);
14669 fputs ("\t.extern __mull\n", file);
14670 fputs ("\t.extern __divss\n", file);
14671 fputs ("\t.extern __divus\n", file);
14672 fputs ("\t.extern __quoss\n", file);
14673 fputs ("\t.extern __quous\n", file);
c764f757
RK
14674 common_mode_defined = 1;
14675 }
9878760c 14676
9ebbca7d 14677 if (! HAVE_prologue)
979721f8 14678 {
9ebbca7d 14679 start_sequence ();
9dda4cc8 14680
a4f6c312
SS
14681 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
14682 the "toplevel" insn chain. */
2e040219 14683 emit_note (NOTE_INSN_DELETED);
9ebbca7d 14684 rs6000_emit_prologue ();
2e040219 14685 emit_note (NOTE_INSN_DELETED);
178c3eff 14686
a3c9585f 14687 /* Expand INSN_ADDRESSES so final() doesn't crash. */
178c3eff
DJ
14688 {
14689 rtx insn;
14690 unsigned addr = 0;
14691 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
14692 {
14693 INSN_ADDRESSES_NEW (insn, addr);
14694 addr += 4;
14695 }
14696 }
9dda4cc8 14697
9ebbca7d 14698 if (TARGET_DEBUG_STACK)
a4f6c312 14699 debug_rtx_list (get_insns (), 100);
c9d691e9 14700 final (get_insns (), file, FALSE);
9ebbca7d 14701 end_sequence ();
979721f8
MM
14702 }
14703
9ebbca7d
GK
14704 rs6000_pic_labelno++;
14705}
f676971a 14706
9ebbca7d 14707/* Emit function epilogue as insns.
9878760c 14708
9ebbca7d
GK
14709 At present, dwarf2out_frame_debug_expr doesn't understand
14710 register restores, so we don't bother setting RTX_FRAME_RELATED_P
14711 anywhere in the epilogue. Most of the insns below would in any case
14712 need special notes to explain where r11 is in relation to the stack. */
9878760c 14713
9ebbca7d 14714void
a2369ed3 14715rs6000_emit_epilogue (int sibcall)
9ebbca7d
GK
14716{
14717 rs6000_stack_t *info;
14718 int restoring_FPRs_inline;
14719 int using_load_multiple;
14720 int using_mfcr_multiple;
14721 int use_backchain_to_restore_sp;
14722 int sp_offset = 0;
14723 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
14724 rtx frame_reg_rtx = sp_reg_rtx;
0e67400a 14725 enum machine_mode reg_mode = Pmode;
327e5343 14726 int reg_size = TARGET_32BIT ? 4 : 8;
9ebbca7d
GK
14727 int i;
14728
c19de7aa
AH
14729 info = rs6000_stack_info ();
14730
14731 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
14732 {
14733 reg_mode = V2SImode;
14734 reg_size = 8;
14735 }
14736
9ebbca7d 14737 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
14738 && (!TARGET_SPE_ABI
14739 || info->spe_64bit_regs_used == 0)
6d0a8091
DJ
14740 && info->first_gp_reg_save < 31
14741 && no_global_regs_above (info->first_gp_reg_save));
9ebbca7d 14742 restoring_FPRs_inline = (sibcall
83720594 14743 || current_function_calls_eh_return
9ebbca7d
GK
14744 || info->first_fp_reg_save == 64
14745 || FP_SAVE_INLINE (info->first_fp_reg_save));
f676971a 14746 use_backchain_to_restore_sp = (frame_pointer_needed
9ebbca7d
GK
14747 || current_function_calls_alloca
14748 || info->total_size > 32767);
14749 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
14750 || rs6000_cpu == PROCESSOR_PPC603
14751 || rs6000_cpu == PROCESSOR_PPC750
14752 || optimize_size);
14753
f57fe068 14754 if (WORLD_SAVE_P (info))
d62294f5
FJ
14755 {
14756 int i, j;
14757 char rname[30];
14758 const char *alloc_rname;
14759 rtvec p;
14760
14761 /* eh_rest_world_r10 will return to the location saved in the LR
c4ad648e
AM
14762 stack slot (which is not likely to be our caller.)
14763 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
14764 rest_world is similar, except any R10 parameter is ignored.
14765 The exception-handling stuff that was here in 2.95 is no
14766 longer necessary. */
d62294f5
FJ
14767
14768 p = rtvec_alloc (9
14769 + 1
f676971a 14770 + 32 - info->first_gp_reg_save
c4ad648e
AM
14771 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
14772 + 63 + 1 - info->first_fp_reg_save);
d62294f5 14773
c4ad648e
AM
14774 strcpy (rname, ((current_function_calls_eh_return) ?
14775 "*eh_rest_world_r10" : "*rest_world"));
d62294f5
FJ
14776 alloc_rname = ggc_strdup (rname);
14777
14778 j = 0;
14779 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
14780 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
c4ad648e
AM
14781 gen_rtx_REG (Pmode,
14782 LINK_REGISTER_REGNUM));
d62294f5 14783 RTVEC_ELT (p, j++)
c4ad648e 14784 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
d62294f5 14785 /* The instruction pattern requires a clobber here;
c4ad648e 14786 it is shared with the restVEC helper. */
d62294f5 14787 RTVEC_ELT (p, j++)
c4ad648e 14788 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
d62294f5
FJ
14789
14790 {
c4ad648e
AM
14791 /* CR register traditionally saved as CR2. */
14792 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
14793 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14794 GEN_INT (info->cr_save_offset));
0be76840 14795 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
14796
14797 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
d62294f5
FJ
14798 }
14799
14800 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
c4ad648e
AM
14801 {
14802 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
14803 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14804 GEN_INT (info->gp_save_offset
14805 + reg_size * i));
0be76840 14806 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
14807
14808 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14809 }
d62294f5 14810 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
c4ad648e
AM
14811 {
14812 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
14813 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14814 GEN_INT (info->altivec_save_offset
14815 + 16 * i));
0be76840 14816 rtx mem = gen_frame_mem (V4SImode, addr);
c4ad648e
AM
14817
14818 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14819 }
d62294f5 14820 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
c4ad648e
AM
14821 {
14822 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
14823 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14824 GEN_INT (info->fp_save_offset
14825 + 8 * i));
0be76840 14826 rtx mem = gen_frame_mem (DFmode, addr);
c4ad648e
AM
14827
14828 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
14829 }
d62294f5 14830 RTVEC_ELT (p, j++)
c4ad648e 14831 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
d62294f5 14832 RTVEC_ELT (p, j++)
c4ad648e 14833 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
d62294f5 14834 RTVEC_ELT (p, j++)
c4ad648e 14835 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
d62294f5 14836 RTVEC_ELT (p, j++)
c4ad648e 14837 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
d62294f5 14838 RTVEC_ELT (p, j++)
c4ad648e 14839 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
d62294f5
FJ
14840 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
14841
14842 return;
14843 }
14844
9ebbca7d
GK
14845 /* If we have a frame pointer, a call to alloca, or a large stack
14846 frame, restore the old stack pointer using the backchain. Otherwise,
14847 we know what size to update it with. */
14848 if (use_backchain_to_restore_sp)
bacbde18 14849 {
9ebbca7d
GK
14850 /* Under V.4, don't reset the stack pointer until after we're done
14851 loading the saved registers. */
f607bc57 14852 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 14853 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 14854
9ebbca7d
GK
14855 emit_move_insn (frame_reg_rtx,
14856 gen_rtx_MEM (Pmode, sp_reg_rtx));
bacbde18 14857 }
9ebbca7d 14858 else if (info->push_p)
85638c0d 14859 {
fc4767bb
JJ
14860 if (DEFAULT_ABI == ABI_V4
14861 || current_function_calls_eh_return)
9ebbca7d
GK
14862 sp_offset = info->total_size;
14863 else
14864 {
14865 emit_insn (TARGET_32BIT
14866 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
14867 GEN_INT (info->total_size))
14868 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
14869 GEN_INT (info->total_size)));
14870 }
85638c0d 14871 }
f676971a 14872
9aa86737
AH
14873 /* Restore AltiVec registers if needed. */
14874 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
14875 {
14876 int i;
14877
14878 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
14879 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
14880 {
14881 rtx addr, areg, mem;
14882
14883 areg = gen_rtx_REG (Pmode, 0);
14884 emit_move_insn
14885 (areg, GEN_INT (info->altivec_save_offset
14886 + sp_offset
14887 + 16 * (i - info->first_altivec_reg_save)));
14888
14889 /* AltiVec addressing mode is [reg+reg]. */
14890 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
0be76840 14891 mem = gen_frame_mem (V4SImode, addr);
9aa86737
AH
14892
14893 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
14894 }
14895 }
14896
14897 /* Restore VRSAVE if needed. */
44688022 14898 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
4d774ff8 14899 && info->vrsave_mask != 0)
9aa86737
AH
14900 {
14901 rtx addr, mem, reg;
14902
14903 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14904 GEN_INT (info->vrsave_save_offset + sp_offset));
0be76840 14905 mem = gen_frame_mem (SImode, addr);
9aa86737
AH
14906 reg = gen_rtx_REG (SImode, 12);
14907 emit_move_insn (reg, mem);
14908
14909 emit_insn (generate_set_vrsave (reg, info, 1));
14910 }
14911
9ebbca7d
GK
14912 /* Get the old lr if we saved it. */
14913 if (info->lr_save_p)
b6c9286a 14914 {
a3170dc6
AH
14915 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
14916 info->lr_save_offset + sp_offset);
ba4828e0 14917
9ebbca7d 14918 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 14919 }
f676971a 14920
9ebbca7d
GK
14921 /* Get the old cr if we saved it. */
14922 if (info->cr_save_p)
14923 {
14924 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14925 GEN_INT (info->cr_save_offset + sp_offset));
0be76840 14926 rtx mem = gen_frame_mem (SImode, addr);
b6c9286a 14927
9ebbca7d
GK
14928 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
14929 }
f676971a 14930
9ebbca7d 14931 /* Set LR here to try to overlap restores below. */
4697a36c 14932 if (info->lr_save_p)
9ebbca7d
GK
14933 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
14934 gen_rtx_REG (Pmode, 0));
f676971a 14935
83720594
RH
14936 /* Load exception handler data registers, if needed. */
14937 if (current_function_calls_eh_return)
14938 {
78e1b90d
DE
14939 unsigned int i, regno;
14940
fc4767bb
JJ
14941 if (TARGET_AIX)
14942 {
14943 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14944 GEN_INT (sp_offset + 5 * reg_size));
0be76840 14945 rtx mem = gen_frame_mem (reg_mode, addr);
fc4767bb
JJ
14946
14947 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
14948 }
14949
83720594
RH
14950 for (i = 0; ; ++i)
14951 {
a3170dc6 14952 rtx mem;
83720594
RH
14953
14954 regno = EH_RETURN_DATA_REGNO (i);
14955 if (regno == INVALID_REGNUM)
14956 break;
14957
a3170dc6
AH
14958 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
14959 info->ehrd_offset + sp_offset
14960 + reg_size * (int) i);
83720594
RH
14961
14962 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
14963 }
14964 }
f676971a 14965
9ebbca7d
GK
14966 /* Restore GPRs. This is done as a PARALLEL if we are using
14967 the load-multiple instructions. */
14968 if (using_load_multiple)
979721f8 14969 {
9ebbca7d
GK
14970 rtvec p;
14971 p = rtvec_alloc (32 - info->first_gp_reg_save);
14972 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 14973 {
f676971a
EC
14974 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14975 GEN_INT (info->gp_save_offset
14976 + sp_offset
9ebbca7d 14977 + reg_size * i));
0be76840 14978 rtx mem = gen_frame_mem (reg_mode, addr);
9ebbca7d 14979
f676971a 14980 RTVEC_ELT (p, i) =
9ebbca7d
GK
14981 gen_rtx_SET (VOIDmode,
14982 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
14983 mem);
979721f8 14984 }
9ebbca7d 14985 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 14986 }
9ebbca7d
GK
14987 else
14988 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
6d0a8091
DJ
14989 if ((regs_ever_live[info->first_gp_reg_save + i]
14990 && (!call_used_regs[info->first_gp_reg_save + i]
14991 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
b4db40bf 14992 && TARGET_TOC && TARGET_MINIMAL_TOC)))
6d0a8091 14993 || (i + info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 14994 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 14995 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d 14996 {
f676971a
EC
14997 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
14998 GEN_INT (info->gp_save_offset
14999 + sp_offset
9ebbca7d 15000 + reg_size * i));
0be76840 15001 rtx mem = gen_frame_mem (reg_mode, addr);
ba4828e0 15002
a3170dc6 15003 /* Restore 64-bit quantities for SPE. */
c19de7aa 15004 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
15005 {
15006 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
15007 rtx b;
15008
15009 if (!SPE_CONST_OFFSET_OK (offset))
15010 {
15011 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
15012 emit_move_insn (b, GEN_INT (offset));
15013 }
15014 else
15015 b = GEN_INT (offset);
15016
15017 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
0be76840 15018 mem = gen_frame_mem (V2SImode, addr);
a3170dc6
AH
15019 }
15020
f676971a 15021 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 15022 info->first_gp_reg_save + i), mem);
9ebbca7d 15023 }
9878760c 15024
9ebbca7d
GK
15025 /* Restore fpr's if we need to do it without calling a function. */
15026 if (restoring_FPRs_inline)
15027 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
f676971a 15028 if ((regs_ever_live[info->first_fp_reg_save+i]
9ebbca7d
GK
15029 && ! call_used_regs[info->first_fp_reg_save+i]))
15030 {
15031 rtx addr, mem;
15032 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
f676971a
EC
15033 GEN_INT (info->fp_save_offset
15034 + sp_offset
a4f6c312 15035 + 8 * i));
0be76840 15036 mem = gen_frame_mem (DFmode, addr);
9ebbca7d 15037
f676971a 15038 emit_move_insn (gen_rtx_REG (DFmode,
9ebbca7d
GK
15039 info->first_fp_reg_save + i),
15040 mem);
15041 }
8d30c4ee 15042
9ebbca7d
GK
15043 /* If we saved cr, restore it here. Just those that were used. */
15044 if (info->cr_save_p)
979721f8 15045 {
9ebbca7d 15046 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 15047 int count = 0;
f676971a 15048
9ebbca7d 15049 if (using_mfcr_multiple)
979721f8 15050 {
9ebbca7d
GK
15051 for (i = 0; i < 8; i++)
15052 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 15053 count++;
37409796 15054 gcc_assert (count);
e35b9579
GK
15055 }
15056
15057 if (using_mfcr_multiple && count > 1)
15058 {
15059 rtvec p;
15060 int ndx;
f676971a 15061
e35b9579 15062 p = rtvec_alloc (count);
9ebbca7d 15063
e35b9579 15064 ndx = 0;
9ebbca7d
GK
15065 for (i = 0; i < 8; i++)
15066 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
15067 {
15068 rtvec r = rtvec_alloc (2);
15069 RTVEC_ELT (r, 0) = r12_rtx;
15070 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 15071 RTVEC_ELT (p, ndx) =
f676971a 15072 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
615158e2 15073 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
e35b9579 15074 ndx++;
9ebbca7d
GK
15075 }
15076 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
37409796 15077 gcc_assert (ndx == count);
979721f8
MM
15078 }
15079 else
9ebbca7d
GK
15080 for (i = 0; i < 8; i++)
15081 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 15082 {
f676971a 15083 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
9ebbca7d
GK
15084 CR0_REGNO+i),
15085 r12_rtx));
979721f8 15086 }
979721f8
MM
15087 }
15088
9ebbca7d 15089 /* If this is V.4, unwind the stack pointer after all of the loads
022123e6
AM
15090 have been done. */
15091 if (frame_reg_rtx != sp_reg_rtx)
15092 {
15093 /* This blockage is needed so that sched doesn't decide to move
15094 the sp change before the register restores. */
15095 rs6000_emit_stack_tie ();
15096 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
15097 }
15098 else if (sp_offset != 0)
15099 emit_insn (TARGET_32BIT
15100 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
15101 GEN_INT (sp_offset))
15102 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
15103 GEN_INT (sp_offset)));
b6c9286a 15104
83720594
RH
15105 if (current_function_calls_eh_return)
15106 {
15107 rtx sa = EH_RETURN_STACKADJ_RTX;
5b71a4e7 15108 emit_insn (TARGET_32BIT
83720594
RH
15109 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
15110 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
15111 }
15112
9ebbca7d
GK
15113 if (!sibcall)
15114 {
15115 rtvec p;
15116 if (! restoring_FPRs_inline)
15117 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
15118 else
15119 p = rtvec_alloc (2);
b6c9286a 15120
e35b9579 15121 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
f676971a
EC
15122 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15123 gen_rtx_REG (Pmode,
9ebbca7d 15124 LINK_REGISTER_REGNUM));
9ebbca7d
GK
15125
15126 /* If we have to restore more than two FP registers, branch to the
15127 restore function. It will return to our caller. */
15128 if (! restoring_FPRs_inline)
15129 {
15130 int i;
15131 char rname[30];
520a57c8 15132 const char *alloc_rname;
979721f8 15133
f676971a 15134 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
9ebbca7d 15135 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 15136 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
15137 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
15138 gen_rtx_SYMBOL_REF (Pmode,
15139 alloc_rname));
b6c9286a 15140
9ebbca7d
GK
15141 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15142 {
15143 rtx addr, mem;
15144 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
15145 GEN_INT (info->fp_save_offset + 8*i));
0be76840 15146 mem = gen_frame_mem (DFmode, addr);
9ebbca7d 15147
f676971a 15148 RTVEC_ELT (p, i+3) =
9ebbca7d
GK
15149 gen_rtx_SET (VOIDmode,
15150 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
15151 mem);
b6c9286a
MM
15152 }
15153 }
f676971a 15154
9ebbca7d 15155 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 15156 }
9878760c
RK
15157}
15158
15159/* Write function epilogue. */
15160
08c148a8 15161static void
f676971a 15162rs6000_output_function_epilogue (FILE *file,
a2369ed3 15163 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
9878760c 15164{
9ebbca7d 15165 if (! HAVE_epilogue)
9878760c 15166 {
9ebbca7d
GK
15167 rtx insn = get_last_insn ();
15168 /* If the last insn was a BARRIER, we don't have to write anything except
15169 the trace table. */
15170 if (GET_CODE (insn) == NOTE)
15171 insn = prev_nonnote_insn (insn);
15172 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 15173 {
9ebbca7d
GK
15174 /* This is slightly ugly, but at least we don't have two
15175 copies of the epilogue-emitting code. */
15176 start_sequence ();
15177
15178 /* A NOTE_INSN_DELETED is supposed to be at the start
15179 and end of the "toplevel" insn chain. */
2e040219 15180 emit_note (NOTE_INSN_DELETED);
9ebbca7d 15181 rs6000_emit_epilogue (FALSE);
2e040219 15182 emit_note (NOTE_INSN_DELETED);
9ebbca7d 15183
a3c9585f 15184 /* Expand INSN_ADDRESSES so final() doesn't crash. */
178c3eff
DJ
15185 {
15186 rtx insn;
15187 unsigned addr = 0;
15188 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15189 {
15190 INSN_ADDRESSES_NEW (insn, addr);
15191 addr += 4;
15192 }
15193 }
15194
9ebbca7d 15195 if (TARGET_DEBUG_STACK)
a4f6c312 15196 debug_rtx_list (get_insns (), 100);
c9d691e9 15197 final (get_insns (), file, FALSE);
9ebbca7d 15198 end_sequence ();
4697a36c 15199 }
9878760c 15200 }
b4ac57ab 15201
efdba735
SH
15202#if TARGET_MACHO
15203 macho_branch_islands ();
0e5da0be
GK
15204 /* Mach-O doesn't support labels at the end of objects, so if
15205 it looks like we might want one, insert a NOP. */
15206 {
15207 rtx insn = get_last_insn ();
15208 while (insn
15209 && NOTE_P (insn)
15210 && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED_LABEL)
15211 insn = PREV_INSN (insn);
f676971a
EC
15212 if (insn
15213 && (LABEL_P (insn)
0e5da0be
GK
15214 || (NOTE_P (insn)
15215 && NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)))
15216 fputs ("\tnop\n", file);
15217 }
15218#endif
15219
9b30bae2 15220 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
15221 on its format.
15222
15223 We don't output a traceback table if -finhibit-size-directive was
15224 used. The documentation for -finhibit-size-directive reads
15225 ``don't output a @code{.size} assembler directive, or anything
15226 else that would cause trouble if the function is split in the
15227 middle, and the two halves are placed at locations far apart in
15228 memory.'' The traceback table has this property, since it
15229 includes the offset from the start of the function to the
4d30c363
MM
15230 traceback table itself.
15231
15232 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 15233 different traceback table. */
57ac7be9 15234 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
8097c268 15235 && rs6000_traceback != traceback_none && !current_function_is_thunk)
9b30bae2 15236 {
69c75916 15237 const char *fname = NULL;
3ac88239 15238 const char *language_string = lang_hooks.name;
6041bf2f 15239 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 15240 int i;
57ac7be9 15241 int optional_tbtab;
8097c268 15242 rs6000_stack_t *info = rs6000_stack_info ();
57ac7be9
AM
15243
15244 if (rs6000_traceback == traceback_full)
15245 optional_tbtab = 1;
15246 else if (rs6000_traceback == traceback_part)
15247 optional_tbtab = 0;
15248 else
15249 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 15250
69c75916
AM
15251 if (optional_tbtab)
15252 {
15253 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
15254 while (*fname == '.') /* V.4 encodes . in the name */
15255 fname++;
15256
15257 /* Need label immediately before tbtab, so we can compute
15258 its offset from the function start. */
15259 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
15260 ASM_OUTPUT_LABEL (file, fname);
15261 }
314fc5a9
ILT
15262
15263 /* The .tbtab pseudo-op can only be used for the first eight
15264 expressions, since it can't handle the possibly variable
15265 length fields that follow. However, if you omit the optional
15266 fields, the assembler outputs zeros for all optional fields
15267 anyways, giving each variable length field is minimum length
15268 (as defined in sys/debug.h). Thus we can not use the .tbtab
15269 pseudo-op at all. */
15270
15271 /* An all-zero word flags the start of the tbtab, for debuggers
15272 that have to find it by searching forward from the entry
15273 point or from the current pc. */
19d2d16f 15274 fputs ("\t.long 0\n", file);
314fc5a9
ILT
15275
15276 /* Tbtab format type. Use format type 0. */
19d2d16f 15277 fputs ("\t.byte 0,", file);
314fc5a9 15278
5fc921c1
DE
15279 /* Language type. Unfortunately, there does not seem to be any
15280 official way to discover the language being compiled, so we
15281 use language_string.
15282 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
15283 Java is 13. Objective-C is 14. */
15284 if (! strcmp (language_string, "GNU C"))
314fc5a9 15285 i = 0;
6de9cd9a
DN
15286 else if (! strcmp (language_string, "GNU F77")
15287 || ! strcmp (language_string, "GNU F95"))
314fc5a9 15288 i = 1;
8b83775b 15289 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9 15290 i = 2;
5fc921c1
DE
15291 else if (! strcmp (language_string, "GNU Ada"))
15292 i = 3;
314fc5a9
ILT
15293 else if (! strcmp (language_string, "GNU C++"))
15294 i = 9;
9517ead8
AG
15295 else if (! strcmp (language_string, "GNU Java"))
15296 i = 13;
5fc921c1
DE
15297 else if (! strcmp (language_string, "GNU Objective-C"))
15298 i = 14;
314fc5a9 15299 else
37409796 15300 gcc_unreachable ();
314fc5a9
ILT
15301 fprintf (file, "%d,", i);
15302
15303 /* 8 single bit fields: global linkage (not set for C extern linkage,
15304 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
15305 from start of procedure stored in tbtab, internal function, function
15306 has controlled storage, function has no toc, function uses fp,
15307 function logs/aborts fp operations. */
15308 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
15309 fprintf (file, "%d,",
15310 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
15311
15312 /* 6 bitfields: function is interrupt handler, name present in
15313 proc table, function calls alloca, on condition directives
15314 (controls stack walks, 3 bits), saves condition reg, saves
15315 link reg. */
15316 /* The `function calls alloca' bit seems to be set whenever reg 31 is
15317 set up as a frame pointer, even when there is no alloca call. */
15318 fprintf (file, "%d,",
6041bf2f
DE
15319 ((optional_tbtab << 6)
15320 | ((optional_tbtab & frame_pointer_needed) << 5)
15321 | (info->cr_save_p << 1)
15322 | (info->lr_save_p)));
314fc5a9 15323
6041bf2f 15324 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
15325 (6 bits). */
15326 fprintf (file, "%d,",
4697a36c 15327 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
15328
15329 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
15330 fprintf (file, "%d,", (32 - first_reg_to_save ()));
15331
6041bf2f
DE
15332 if (optional_tbtab)
15333 {
15334 /* Compute the parameter info from the function decl argument
15335 list. */
15336 tree decl;
15337 int next_parm_info_bit = 31;
314fc5a9 15338
6041bf2f
DE
15339 for (decl = DECL_ARGUMENTS (current_function_decl);
15340 decl; decl = TREE_CHAIN (decl))
15341 {
15342 rtx parameter = DECL_INCOMING_RTL (decl);
15343 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 15344
6041bf2f
DE
15345 if (GET_CODE (parameter) == REG)
15346 {
ebb109ad 15347 if (SCALAR_FLOAT_MODE_P (mode))
6041bf2f
DE
15348 {
15349 int bits;
15350
15351 float_parms++;
15352
37409796
NS
15353 switch (mode)
15354 {
15355 case SFmode:
15356 bits = 0x2;
15357 break;
15358
15359 case DFmode:
15360 case TFmode:
15361 bits = 0x3;
15362 break;
15363
15364 default:
15365 gcc_unreachable ();
15366 }
6041bf2f
DE
15367
15368 /* If only one bit will fit, don't or in this entry. */
15369 if (next_parm_info_bit > 0)
15370 parm_info |= (bits << (next_parm_info_bit - 1));
15371 next_parm_info_bit -= 2;
15372 }
15373 else
15374 {
15375 fixed_parms += ((GET_MODE_SIZE (mode)
15376 + (UNITS_PER_WORD - 1))
15377 / UNITS_PER_WORD);
15378 next_parm_info_bit -= 1;
15379 }
15380 }
15381 }
15382 }
314fc5a9
ILT
15383
15384 /* Number of fixed point parameters. */
15385 /* This is actually the number of words of fixed point parameters; thus
15386 an 8 byte struct counts as 2; and thus the maximum value is 8. */
15387 fprintf (file, "%d,", fixed_parms);
15388
15389 /* 2 bitfields: number of floating point parameters (7 bits), parameters
15390 all on stack. */
15391 /* This is actually the number of fp registers that hold parameters;
15392 and thus the maximum value is 13. */
15393 /* Set parameters on stack bit if parameters are not in their original
15394 registers, regardless of whether they are on the stack? Xlc
15395 seems to set the bit when not optimizing. */
15396 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
15397
6041bf2f
DE
15398 if (! optional_tbtab)
15399 return;
15400
314fc5a9
ILT
15401 /* Optional fields follow. Some are variable length. */
15402
15403 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
15404 11 double float. */
15405 /* There is an entry for each parameter in a register, in the order that
15406 they occur in the parameter list. Any intervening arguments on the
15407 stack are ignored. If the list overflows a long (max possible length
15408 34 bits) then completely leave off all elements that don't fit. */
15409 /* Only emit this long if there was at least one parameter. */
15410 if (fixed_parms || float_parms)
15411 fprintf (file, "\t.long %d\n", parm_info);
15412
15413 /* Offset from start of code to tb table. */
19d2d16f 15414 fputs ("\t.long ", file);
314fc5a9 15415 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
85b776df
AM
15416 if (TARGET_AIX)
15417 RS6000_OUTPUT_BASENAME (file, fname);
15418 else
15419 assemble_name (file, fname);
15420 putc ('-', file);
15421 rs6000_output_function_entry (file, fname);
19d2d16f 15422 putc ('\n', file);
314fc5a9
ILT
15423
15424 /* Interrupt handler mask. */
15425 /* Omit this long, since we never set the interrupt handler bit
15426 above. */
15427
15428 /* Number of CTL (controlled storage) anchors. */
15429 /* Omit this long, since the has_ctl bit is never set above. */
15430
15431 /* Displacement into stack of each CTL anchor. */
15432 /* Omit this list of longs, because there are no CTL anchors. */
15433
15434 /* Length of function name. */
69c75916
AM
15435 if (*fname == '*')
15436 ++fname;
296b8152 15437 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
15438
15439 /* Function name. */
15440 assemble_string (fname, strlen (fname));
15441
15442 /* Register for alloca automatic storage; this is always reg 31.
15443 Only emit this if the alloca bit was set above. */
15444 if (frame_pointer_needed)
19d2d16f 15445 fputs ("\t.byte 31\n", file);
b1765bde
DE
15446
15447 fputs ("\t.align 2\n", file);
9b30bae2 15448 }
9878760c 15449}
17167fd8 15450\f
a4f6c312
SS
15451/* A C compound statement that outputs the assembler code for a thunk
15452 function, used to implement C++ virtual function calls with
15453 multiple inheritance. The thunk acts as a wrapper around a virtual
15454 function, adjusting the implicit object parameter before handing
15455 control off to the real function.
15456
15457 First, emit code to add the integer DELTA to the location that
15458 contains the incoming first argument. Assume that this argument
15459 contains a pointer, and is the one used to pass the `this' pointer
15460 in C++. This is the incoming argument *before* the function
15461 prologue, e.g. `%o0' on a sparc. The addition must preserve the
15462 values of all other incoming arguments.
17167fd8
MM
15463
15464 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
15465 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
15466 not touch the return address. Hence returning from FUNCTION will
15467 return to whoever called the current `thunk'.
17167fd8 15468
a4f6c312
SS
15469 The effect must be as if FUNCTION had been called directly with the
15470 adjusted first argument. This macro is responsible for emitting
15471 all of the code for a thunk function; output_function_prologue()
15472 and output_function_epilogue() are not invoked.
17167fd8 15473
a4f6c312
SS
15474 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
15475 been extracted from it.) It might possibly be useful on some
15476 targets, but probably not.
17167fd8 15477
a4f6c312
SS
15478 If you do not define this macro, the target-independent code in the
15479 C++ frontend will generate a less efficient heavyweight thunk that
15480 calls FUNCTION instead of jumping to it. The generic approach does
15481 not support varargs. */
17167fd8 15482
3961e8fe 15483static void
f676971a
EC
15484rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
15485 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
a2369ed3 15486 tree function)
17167fd8 15487{
5b71a4e7 15488 rtx this, insn, funexp;
17167fd8 15489
5b71a4e7 15490 reload_completed = 1;
fe3ad572 15491 epilogue_completed = 1;
5b71a4e7 15492 no_new_pseudos = 1;
6429e3be 15493 reset_block_changes ();
56a7189a 15494
5b71a4e7 15495 /* Mark the end of the (empty) prologue. */
2e040219 15496 emit_note (NOTE_INSN_PROLOGUE_END);
17167fd8 15497
5b71a4e7
DE
15498 /* Find the "this" pointer. If the function returns a structure,
15499 the structure return pointer is in r3. */
61f71b34 15500 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
5b71a4e7 15501 this = gen_rtx_REG (Pmode, 4);
56a7189a 15502 else
5b71a4e7 15503 this = gen_rtx_REG (Pmode, 3);
17167fd8 15504
5b71a4e7
DE
15505 /* Apply the constant offset, if required. */
15506 if (delta)
15507 {
15508 rtx delta_rtx = GEN_INT (delta);
15509 emit_insn (TARGET_32BIT
15510 ? gen_addsi3 (this, this, delta_rtx)
15511 : gen_adddi3 (this, this, delta_rtx));
17167fd8
MM
15512 }
15513
5b71a4e7
DE
15514 /* Apply the offset from the vtable, if required. */
15515 if (vcall_offset)
17167fd8 15516 {
5b71a4e7
DE
15517 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
15518 rtx tmp = gen_rtx_REG (Pmode, 12);
17167fd8 15519
5b71a4e7 15520 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
eeff9307
JJ
15521 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
15522 {
15523 emit_insn (TARGET_32BIT
15524 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
15525 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
15526 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
15527 }
15528 else
15529 {
15530 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
15531
15532 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
15533 }
5b71a4e7
DE
15534 emit_insn (TARGET_32BIT
15535 ? gen_addsi3 (this, this, tmp)
15536 : gen_adddi3 (this, this, tmp));
17167fd8
MM
15537 }
15538
5b71a4e7
DE
15539 /* Generate a tail call to the target function. */
15540 if (!TREE_USED (function))
15541 {
15542 assemble_external (function);
15543 TREE_USED (function) = 1;
15544 }
15545 funexp = XEXP (DECL_RTL (function), 0);
5b71a4e7 15546 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
ee890fe2
SS
15547
15548#if TARGET_MACHO
ab82a49f 15549 if (MACHOPIC_INDIRECT)
5b71a4e7 15550 funexp = machopic_indirect_call_target (funexp);
ee890fe2 15551#endif
5b71a4e7
DE
15552
15553 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
992d08b1 15554 generate sibcall RTL explicitly. */
5b71a4e7
DE
15555 insn = emit_call_insn (
15556 gen_rtx_PARALLEL (VOIDmode,
15557 gen_rtvec (4,
15558 gen_rtx_CALL (VOIDmode,
15559 funexp, const0_rtx),
15560 gen_rtx_USE (VOIDmode, const0_rtx),
15561 gen_rtx_USE (VOIDmode,
15562 gen_rtx_REG (SImode,
15563 LINK_REGISTER_REGNUM)),
15564 gen_rtx_RETURN (VOIDmode))));
15565 SIBLING_CALL_P (insn) = 1;
15566 emit_barrier ();
15567
15568 /* Run just enough of rest_of_compilation to get the insns emitted.
15569 There's not really enough bulk here to make other passes such as
15570 instruction scheduling worth while. Note that use_thunk calls
15571 assemble_start_function and assemble_end_function. */
15572 insn = get_insns ();
a2855205 15573 insn_locators_initialize ();
5b71a4e7
DE
15574 shorten_branches (insn);
15575 final_start_function (insn, file, 1);
c9d691e9 15576 final (insn, file, 1);
5b71a4e7
DE
15577 final_end_function ();
15578
15579 reload_completed = 0;
fe3ad572 15580 epilogue_completed = 0;
5b71a4e7 15581 no_new_pseudos = 0;
9ebbca7d 15582}
9ebbca7d
GK
15583\f
15584/* A quick summary of the various types of 'constant-pool tables'
15585 under PowerPC:
15586
f676971a 15587 Target Flags Name One table per
9ebbca7d
GK
15588 AIX (none) AIX TOC object file
15589 AIX -mfull-toc AIX TOC object file
15590 AIX -mminimal-toc AIX minimal TOC translation unit
15591 SVR4/EABI (none) SVR4 SDATA object file
15592 SVR4/EABI -fpic SVR4 pic object file
15593 SVR4/EABI -fPIC SVR4 PIC translation unit
15594 SVR4/EABI -mrelocatable EABI TOC function
15595 SVR4/EABI -maix AIX TOC object file
f676971a 15596 SVR4/EABI -maix -mminimal-toc
9ebbca7d
GK
15597 AIX minimal TOC translation unit
15598
15599 Name Reg. Set by entries contains:
15600 made by addrs? fp? sum?
15601
15602 AIX TOC 2 crt0 as Y option option
15603 AIX minimal TOC 30 prolog gcc Y Y option
15604 SVR4 SDATA 13 crt0 gcc N Y N
15605 SVR4 pic 30 prolog ld Y not yet N
15606 SVR4 PIC 30 prolog gcc Y option option
15607 EABI TOC 30 prolog gcc Y option option
15608
15609*/
15610
9ebbca7d
GK
15611/* Hash functions for the hash table. */
15612
15613static unsigned
a2369ed3 15614rs6000_hash_constant (rtx k)
9ebbca7d 15615{
46b33600
RH
15616 enum rtx_code code = GET_CODE (k);
15617 enum machine_mode mode = GET_MODE (k);
15618 unsigned result = (code << 3) ^ mode;
15619 const char *format;
15620 int flen, fidx;
f676971a 15621
46b33600
RH
15622 format = GET_RTX_FORMAT (code);
15623 flen = strlen (format);
15624 fidx = 0;
9ebbca7d 15625
46b33600
RH
15626 switch (code)
15627 {
15628 case LABEL_REF:
15629 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
15630
15631 case CONST_DOUBLE:
15632 if (mode != VOIDmode)
15633 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
15634 flen = 2;
15635 break;
15636
15637 case CODE_LABEL:
15638 fidx = 3;
15639 break;
15640
15641 default:
15642 break;
15643 }
9ebbca7d
GK
15644
15645 for (; fidx < flen; fidx++)
15646 switch (format[fidx])
15647 {
15648 case 's':
15649 {
15650 unsigned i, len;
15651 const char *str = XSTR (k, fidx);
15652 len = strlen (str);
15653 result = result * 613 + len;
15654 for (i = 0; i < len; i++)
15655 result = result * 613 + (unsigned) str[i];
17167fd8
MM
15656 break;
15657 }
9ebbca7d
GK
15658 case 'u':
15659 case 'e':
15660 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
15661 break;
15662 case 'i':
15663 case 'n':
15664 result = result * 613 + (unsigned) XINT (k, fidx);
15665 break;
15666 case 'w':
15667 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
15668 result = result * 613 + (unsigned) XWINT (k, fidx);
15669 else
15670 {
15671 size_t i;
9390387d 15672 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
9ebbca7d
GK
15673 result = result * 613 + (unsigned) (XWINT (k, fidx)
15674 >> CHAR_BIT * i);
15675 }
15676 break;
09501938
DE
15677 case '0':
15678 break;
9ebbca7d 15679 default:
37409796 15680 gcc_unreachable ();
9ebbca7d 15681 }
46b33600 15682
9ebbca7d
GK
15683 return result;
15684}
15685
15686static unsigned
a2369ed3 15687toc_hash_function (const void *hash_entry)
9ebbca7d 15688{
f676971a 15689 const struct toc_hash_struct *thc =
a9098fd0
GK
15690 (const struct toc_hash_struct *) hash_entry;
15691 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
15692}
15693
15694/* Compare H1 and H2 for equivalence. */
15695
15696static int
a2369ed3 15697toc_hash_eq (const void *h1, const void *h2)
9ebbca7d
GK
15698{
15699 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
15700 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
15701
a9098fd0
GK
15702 if (((const struct toc_hash_struct *) h1)->key_mode
15703 != ((const struct toc_hash_struct *) h2)->key_mode)
15704 return 0;
15705
5692c7bc 15706 return rtx_equal_p (r1, r2);
9ebbca7d
GK
15707}
15708
28e510bd
MM
15709/* These are the names given by the C++ front-end to vtables, and
15710 vtable-like objects. Ideally, this logic should not be here;
15711 instead, there should be some programmatic way of inquiring as
15712 to whether or not an object is a vtable. */
15713
15714#define VTABLE_NAME_P(NAME) \
9390387d 15715 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
28e510bd
MM
15716 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
15717 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
26be75db 15718 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
f676971a 15719 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
28e510bd
MM
15720
15721void
a2369ed3 15722rs6000_output_symbol_ref (FILE *file, rtx x)
28e510bd
MM
15723{
15724 /* Currently C++ toc references to vtables can be emitted before it
15725 is decided whether the vtable is public or private. If this is
15726 the case, then the linker will eventually complain that there is
f676971a 15727 a reference to an unknown section. Thus, for vtables only,
28e510bd
MM
15728 we emit the TOC reference to reference the symbol and not the
15729 section. */
15730 const char *name = XSTR (x, 0);
54ee9799 15731
f676971a 15732 if (VTABLE_NAME_P (name))
54ee9799
DE
15733 {
15734 RS6000_OUTPUT_BASENAME (file, name);
15735 }
15736 else
15737 assemble_name (file, name);
28e510bd
MM
15738}
15739
a4f6c312
SS
15740/* Output a TOC entry. We derive the entry name from what is being
15741 written. */
9878760c
RK
15742
15743void
a2369ed3 15744output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
9878760c
RK
15745{
15746 char buf[256];
3cce094d 15747 const char *name = buf;
ec940faa 15748 const char *real_name;
9878760c 15749 rtx base = x;
16fdeb48 15750 HOST_WIDE_INT offset = 0;
9878760c 15751
37409796 15752 gcc_assert (!TARGET_NO_TOC);
4697a36c 15753
9ebbca7d
GK
15754 /* When the linker won't eliminate them, don't output duplicate
15755 TOC entries (this happens on AIX if there is any kind of TOC,
17211ab5
GK
15756 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
15757 CODE_LABELs. */
15758 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
9ebbca7d
GK
15759 {
15760 struct toc_hash_struct *h;
15761 void * * found;
f676971a 15762
17211ab5 15763 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
c4ad648e 15764 time because GGC is not initialized at that point. */
17211ab5 15765 if (toc_hash_table == NULL)
f676971a 15766 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
17211ab5
GK
15767 toc_hash_eq, NULL);
15768
9ebbca7d
GK
15769 h = ggc_alloc (sizeof (*h));
15770 h->key = x;
a9098fd0 15771 h->key_mode = mode;
9ebbca7d 15772 h->labelno = labelno;
f676971a 15773
9ebbca7d
GK
15774 found = htab_find_slot (toc_hash_table, h, 1);
15775 if (*found == NULL)
15776 *found = h;
f676971a 15777 else /* This is indeed a duplicate.
9ebbca7d
GK
15778 Set this label equal to that label. */
15779 {
15780 fputs ("\t.set ", file);
15781 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
15782 fprintf (file, "%d,", labelno);
15783 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
f676971a 15784 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
9ebbca7d
GK
15785 found)->labelno));
15786 return;
15787 }
15788 }
15789
15790 /* If we're going to put a double constant in the TOC, make sure it's
15791 aligned properly when strict alignment is on. */
ff1720ed
RK
15792 if (GET_CODE (x) == CONST_DOUBLE
15793 && STRICT_ALIGNMENT
a9098fd0 15794 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
15795 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
15796 ASM_OUTPUT_ALIGN (file, 3);
15797 }
15798
4977bab6 15799 (*targetm.asm_out.internal_label) (file, "LC", labelno);
9878760c 15800
37c37a57
RK
15801 /* Handle FP constants specially. Note that if we have a minimal
15802 TOC, things we put here aren't actually in the TOC, so we can allow
15803 FP constants. */
00b79d54
BE
15804 if (GET_CODE (x) == CONST_DOUBLE &&
15805 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
fcce224d
DE
15806 {
15807 REAL_VALUE_TYPE rv;
15808 long k[4];
15809
15810 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
00b79d54
BE
15811 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
15812 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
15813 else
15814 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
fcce224d
DE
15815
15816 if (TARGET_64BIT)
15817 {
15818 if (TARGET_MINIMAL_TOC)
15819 fputs (DOUBLE_INT_ASM_OP, file);
15820 else
15821 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15822 k[0] & 0xffffffff, k[1] & 0xffffffff,
15823 k[2] & 0xffffffff, k[3] & 0xffffffff);
15824 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
15825 k[0] & 0xffffffff, k[1] & 0xffffffff,
15826 k[2] & 0xffffffff, k[3] & 0xffffffff);
15827 return;
15828 }
15829 else
15830 {
15831 if (TARGET_MINIMAL_TOC)
15832 fputs ("\t.long ", file);
15833 else
15834 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
15835 k[0] & 0xffffffff, k[1] & 0xffffffff,
15836 k[2] & 0xffffffff, k[3] & 0xffffffff);
15837 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
15838 k[0] & 0xffffffff, k[1] & 0xffffffff,
15839 k[2] & 0xffffffff, k[3] & 0xffffffff);
15840 return;
15841 }
15842 }
00b79d54
BE
15843 else if (GET_CODE (x) == CONST_DOUBLE &&
15844 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
9878760c 15845 {
042259f2
DE
15846 REAL_VALUE_TYPE rv;
15847 long k[2];
0adc764e 15848
042259f2 15849 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
00b79d54
BE
15850
15851 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
15852 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
15853 else
15854 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 15855
13ded975
DE
15856 if (TARGET_64BIT)
15857 {
15858 if (TARGET_MINIMAL_TOC)
2bfcf297 15859 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 15860 else
2f0552b6
AM
15861 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
15862 k[0] & 0xffffffff, k[1] & 0xffffffff);
15863 fprintf (file, "0x%lx%08lx\n",
15864 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
15865 return;
15866 }
1875cc88 15867 else
13ded975
DE
15868 {
15869 if (TARGET_MINIMAL_TOC)
2bfcf297 15870 fputs ("\t.long ", file);
13ded975 15871 else
2f0552b6
AM
15872 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
15873 k[0] & 0xffffffff, k[1] & 0xffffffff);
15874 fprintf (file, "0x%lx,0x%lx\n",
15875 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
15876 return;
15877 }
9878760c 15878 }
00b79d54
BE
15879 else if (GET_CODE (x) == CONST_DOUBLE &&
15880 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
9878760c 15881 {
042259f2
DE
15882 REAL_VALUE_TYPE rv;
15883 long l;
9878760c 15884
042259f2 15885 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
00b79d54
BE
15886 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
15887 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
15888 else
15889 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
042259f2 15890
31bfaa0b
DE
15891 if (TARGET_64BIT)
15892 {
15893 if (TARGET_MINIMAL_TOC)
2bfcf297 15894 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 15895 else
2f0552b6
AM
15896 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
15897 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
15898 return;
15899 }
042259f2 15900 else
31bfaa0b
DE
15901 {
15902 if (TARGET_MINIMAL_TOC)
2bfcf297 15903 fputs ("\t.long ", file);
31bfaa0b 15904 else
2f0552b6
AM
15905 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
15906 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
15907 return;
15908 }
042259f2 15909 }
f176e826 15910 else if (GET_MODE (x) == VOIDmode
a9098fd0 15911 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 15912 {
e2c953b6 15913 unsigned HOST_WIDE_INT low;
042259f2
DE
15914 HOST_WIDE_INT high;
15915
15916 if (GET_CODE (x) == CONST_DOUBLE)
15917 {
15918 low = CONST_DOUBLE_LOW (x);
15919 high = CONST_DOUBLE_HIGH (x);
15920 }
15921 else
15922#if HOST_BITS_PER_WIDE_INT == 32
15923 {
15924 low = INTVAL (x);
0858c623 15925 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
15926 }
15927#else
15928 {
c4ad648e
AM
15929 low = INTVAL (x) & 0xffffffff;
15930 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
042259f2
DE
15931 }
15932#endif
9878760c 15933
a9098fd0
GK
15934 /* TOC entries are always Pmode-sized, but since this
15935 is a bigendian machine then if we're putting smaller
15936 integer constants in the TOC we have to pad them.
15937 (This is still a win over putting the constants in
15938 a separate constant pool, because then we'd have
02a4ec28
FS
15939 to have both a TOC entry _and_ the actual constant.)
15940
15941 For a 32-bit target, CONST_INT values are loaded and shifted
15942 entirely within `low' and can be stored in one TOC entry. */
15943
37409796
NS
15944 /* It would be easy to make this work, but it doesn't now. */
15945 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
02a4ec28
FS
15946
15947 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
15948 {
15949#if HOST_BITS_PER_WIDE_INT == 32
15950 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
15951 POINTER_SIZE, &low, &high, 0);
15952#else
15953 low |= high << 32;
15954 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
15955 high = (HOST_WIDE_INT) low >> 32;
15956 low &= 0xffffffff;
15957#endif
15958 }
a9098fd0 15959
13ded975
DE
15960 if (TARGET_64BIT)
15961 {
15962 if (TARGET_MINIMAL_TOC)
2bfcf297 15963 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 15964 else
2f0552b6
AM
15965 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
15966 (long) high & 0xffffffff, (long) low & 0xffffffff);
15967 fprintf (file, "0x%lx%08lx\n",
15968 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
15969 return;
15970 }
1875cc88 15971 else
13ded975 15972 {
02a4ec28
FS
15973 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
15974 {
15975 if (TARGET_MINIMAL_TOC)
2bfcf297 15976 fputs ("\t.long ", file);
02a4ec28 15977 else
2bfcf297 15978 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
15979 (long) high & 0xffffffff, (long) low & 0xffffffff);
15980 fprintf (file, "0x%lx,0x%lx\n",
15981 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 15982 }
13ded975 15983 else
02a4ec28
FS
15984 {
15985 if (TARGET_MINIMAL_TOC)
2bfcf297 15986 fputs ("\t.long ", file);
02a4ec28 15987 else
2f0552b6
AM
15988 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
15989 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 15990 }
13ded975
DE
15991 return;
15992 }
9878760c
RK
15993 }
15994
15995 if (GET_CODE (x) == CONST)
15996 {
37409796 15997 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
2bfcf297 15998
9878760c
RK
15999 base = XEXP (XEXP (x, 0), 0);
16000 offset = INTVAL (XEXP (XEXP (x, 0), 1));
16001 }
f676971a 16002
37409796
NS
16003 switch (GET_CODE (base))
16004 {
16005 case SYMBOL_REF:
16006 name = XSTR (base, 0);
16007 break;
16008
16009 case LABEL_REF:
16010 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
16011 CODE_LABEL_NUMBER (XEXP (base, 0)));
16012 break;
16013
16014 case CODE_LABEL:
16015 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
16016 break;
16017
16018 default:
16019 gcc_unreachable ();
16020 }
9878760c 16021
772c5265 16022 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 16023 if (TARGET_MINIMAL_TOC)
2bfcf297 16024 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
16025 else
16026 {
b6c9286a 16027 fprintf (file, "\t.tc %s", real_name);
9878760c 16028
1875cc88 16029 if (offset < 0)
16fdeb48 16030 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
1875cc88 16031 else if (offset)
16fdeb48 16032 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
9878760c 16033
19d2d16f 16034 fputs ("[TC],", file);
1875cc88 16035 }
581bc4de
MM
16036
16037 /* Currently C++ toc references to vtables can be emitted before it
16038 is decided whether the vtable is public or private. If this is
16039 the case, then the linker will eventually complain that there is
16040 a TOC reference to an unknown section. Thus, for vtables only,
16041 we emit the TOC reference to reference the symbol and not the
16042 section. */
28e510bd 16043 if (VTABLE_NAME_P (name))
581bc4de 16044 {
54ee9799 16045 RS6000_OUTPUT_BASENAME (file, name);
581bc4de 16046 if (offset < 0)
16fdeb48 16047 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
581bc4de 16048 else if (offset > 0)
16fdeb48 16049 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
581bc4de
MM
16050 }
16051 else
16052 output_addr_const (file, x);
19d2d16f 16053 putc ('\n', file);
9878760c
RK
16054}
16055\f
16056/* Output an assembler pseudo-op to write an ASCII string of N characters
16057 starting at P to FILE.
16058
16059 On the RS/6000, we have to do this using the .byte operation and
16060 write out special characters outside the quoted string.
16061 Also, the assembler is broken; very long strings are truncated,
a4f6c312 16062 so we must artificially break them up early. */
9878760c
RK
16063
16064void
a2369ed3 16065output_ascii (FILE *file, const char *p, int n)
9878760c
RK
16066{
16067 char c;
16068 int i, count_string;
d330fd93
KG
16069 const char *for_string = "\t.byte \"";
16070 const char *for_decimal = "\t.byte ";
16071 const char *to_close = NULL;
9878760c
RK
16072
16073 count_string = 0;
16074 for (i = 0; i < n; i++)
16075 {
16076 c = *p++;
16077 if (c >= ' ' && c < 0177)
16078 {
16079 if (for_string)
16080 fputs (for_string, file);
16081 putc (c, file);
16082
16083 /* Write two quotes to get one. */
16084 if (c == '"')
16085 {
16086 putc (c, file);
16087 ++count_string;
16088 }
16089
16090 for_string = NULL;
16091 for_decimal = "\"\n\t.byte ";
16092 to_close = "\"\n";
16093 ++count_string;
16094
16095 if (count_string >= 512)
16096 {
16097 fputs (to_close, file);
16098
16099 for_string = "\t.byte \"";
16100 for_decimal = "\t.byte ";
16101 to_close = NULL;
16102 count_string = 0;
16103 }
16104 }
16105 else
16106 {
16107 if (for_decimal)
16108 fputs (for_decimal, file);
16109 fprintf (file, "%d", c);
16110
16111 for_string = "\n\t.byte \"";
16112 for_decimal = ", ";
16113 to_close = "\n";
16114 count_string = 0;
16115 }
16116 }
16117
16118 /* Now close the string if we have written one. Then end the line. */
16119 if (to_close)
9ebbca7d 16120 fputs (to_close, file);
9878760c
RK
16121}
16122\f
16123/* Generate a unique section name for FILENAME for a section type
16124 represented by SECTION_DESC. Output goes into BUF.
16125
16126 SECTION_DESC can be any string, as long as it is different for each
16127 possible section type.
16128
16129 We name the section in the same manner as xlc. The name begins with an
16130 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
16131 names) with the last period replaced by the string SECTION_DESC. If
16132 FILENAME does not contain a period, SECTION_DESC is appended to the end of
16133 the name. */
9878760c
RK
16134
16135void
f676971a 16136rs6000_gen_section_name (char **buf, const char *filename,
c4ad648e 16137 const char *section_desc)
9878760c 16138{
9ebbca7d 16139 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
16140 char *p;
16141 int len;
9878760c
RK
16142
16143 after_last_slash = filename;
16144 for (q = filename; *q; q++)
11e5fe42
RK
16145 {
16146 if (*q == '/')
16147 after_last_slash = q + 1;
16148 else if (*q == '.')
16149 last_period = q;
16150 }
9878760c 16151
11e5fe42 16152 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 16153 *buf = (char *) xmalloc (len);
9878760c
RK
16154
16155 p = *buf;
16156 *p++ = '_';
16157
16158 for (q = after_last_slash; *q; q++)
16159 {
11e5fe42 16160 if (q == last_period)
c4ad648e 16161 {
9878760c
RK
16162 strcpy (p, section_desc);
16163 p += strlen (section_desc);
e3981aab 16164 break;
c4ad648e 16165 }
9878760c 16166
e9a780ec 16167 else if (ISALNUM (*q))
c4ad648e 16168 *p++ = *q;
9878760c
RK
16169 }
16170
11e5fe42 16171 if (last_period == 0)
9878760c
RK
16172 strcpy (p, section_desc);
16173 else
16174 *p = '\0';
16175}
e165f3f0 16176\f
a4f6c312 16177/* Emit profile function. */
411707f4 16178
411707f4 16179void
a2369ed3 16180output_profile_hook (int labelno ATTRIBUTE_UNUSED)
411707f4 16181{
858081ad
AH
16182 /* Non-standard profiling for kernels, which just saves LR then calls
16183 _mcount without worrying about arg saves. The idea is to change
16184 the function prologue as little as possible as it isn't easy to
16185 account for arg save/restore code added just for _mcount. */
ffcfcb5f
AM
16186 if (TARGET_PROFILE_KERNEL)
16187 return;
16188
8480e480
CC
16189 if (DEFAULT_ABI == ABI_AIX)
16190 {
9739c90c
JJ
16191#ifndef NO_PROFILE_COUNTERS
16192# define NO_PROFILE_COUNTERS 0
16193#endif
f676971a 16194 if (NO_PROFILE_COUNTERS)
9739c90c
JJ
16195 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
16196 else
16197 {
16198 char buf[30];
16199 const char *label_name;
16200 rtx fun;
411707f4 16201
9739c90c
JJ
16202 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
16203 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
16204 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 16205
9739c90c
JJ
16206 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
16207 fun, Pmode);
16208 }
8480e480 16209 }
ee890fe2
SS
16210 else if (DEFAULT_ABI == ABI_DARWIN)
16211 {
d5fa86ba 16212 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
16213 int caller_addr_regno = LINK_REGISTER_REGNUM;
16214
16215 /* Be conservative and always set this, at least for now. */
16216 current_function_uses_pic_offset_table = 1;
16217
16218#if TARGET_MACHO
16219 /* For PIC code, set up a stub and collect the caller's address
16220 from r0, which is where the prologue puts it. */
11abc112
MM
16221 if (MACHOPIC_INDIRECT
16222 && current_function_uses_pic_offset_table)
16223 caller_addr_regno = 0;
ee890fe2
SS
16224#endif
16225 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
16226 0, VOIDmode, 1,
16227 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
16228 }
411707f4
CC
16229}
16230
a4f6c312 16231/* Write function profiler code. */
e165f3f0
RK
16232
16233void
a2369ed3 16234output_function_profiler (FILE *file, int labelno)
e165f3f0 16235{
3daf36a4 16236 char buf[100];
e165f3f0 16237
38c1f2d7 16238 switch (DEFAULT_ABI)
3daf36a4 16239 {
38c1f2d7 16240 default:
37409796 16241 gcc_unreachable ();
38c1f2d7
MM
16242
16243 case ABI_V4:
09eeeacb
AM
16244 if (!TARGET_32BIT)
16245 {
d4ee4d25 16246 warning (0, "no profiling of 64-bit code for this ABI");
09eeeacb
AM
16247 return;
16248 }
ffcfcb5f 16249 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 16250 fprintf (file, "\tmflr %s\n", reg_names[0]);
71625f3d
AM
16251 if (NO_PROFILE_COUNTERS)
16252 {
16253 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16254 reg_names[0], reg_names[1]);
16255 }
16256 else if (TARGET_SECURE_PLT && flag_pic)
16257 {
16258 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
16259 reg_names[0], reg_names[1]);
16260 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
16261 asm_fprintf (file, "\t{cau|addis} %s,%s,",
16262 reg_names[12], reg_names[12]);
16263 assemble_name (file, buf);
16264 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
16265 assemble_name (file, buf);
16266 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
16267 }
16268 else if (flag_pic == 1)
38c1f2d7 16269 {
dfdfa60f 16270 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
71625f3d
AM
16271 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16272 reg_names[0], reg_names[1]);
17167fd8 16273 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 16274 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 16275 assemble_name (file, buf);
17167fd8 16276 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 16277 }
9ebbca7d 16278 else if (flag_pic > 1)
38c1f2d7 16279 {
71625f3d
AM
16280 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16281 reg_names[0], reg_names[1]);
9ebbca7d 16282 /* Now, we need to get the address of the label. */
71625f3d 16283 fputs ("\tbcl 20,31,1f\n\t.long ", file);
034e84c4 16284 assemble_name (file, buf);
9ebbca7d
GK
16285 fputs ("-.\n1:", file);
16286 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
f676971a 16287 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
9ebbca7d
GK
16288 reg_names[0], reg_names[11]);
16289 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
16290 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 16291 }
38c1f2d7
MM
16292 else
16293 {
17167fd8 16294 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 16295 assemble_name (file, buf);
dfdfa60f 16296 fputs ("@ha\n", file);
71625f3d
AM
16297 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
16298 reg_names[0], reg_names[1]);
a260abc9 16299 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 16300 assemble_name (file, buf);
17167fd8 16301 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
16302 }
16303
50d440bc 16304 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
3b6ce0af
DE
16305 fprintf (file, "\tbl %s%s\n",
16306 RS6000_MCOUNT, flag_pic ? "@plt" : "");
38c1f2d7
MM
16307 break;
16308
16309 case ABI_AIX:
ee890fe2 16310 case ABI_DARWIN:
ffcfcb5f
AM
16311 if (!TARGET_PROFILE_KERNEL)
16312 {
a3c9585f 16313 /* Don't do anything, done in output_profile_hook (). */
ffcfcb5f
AM
16314 }
16315 else
16316 {
37409796 16317 gcc_assert (!TARGET_32BIT);
ffcfcb5f
AM
16318
16319 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
16320 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
16321
6de9cd9a 16322 if (cfun->static_chain_decl != NULL)
ffcfcb5f
AM
16323 {
16324 asm_fprintf (file, "\tstd %s,24(%s)\n",
16325 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16326 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16327 asm_fprintf (file, "\tld %s,24(%s)\n",
16328 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
16329 }
16330 else
16331 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
16332 }
38c1f2d7
MM
16333 break;
16334 }
e165f3f0 16335}
a251ffd0 16336
b54cf83a 16337\f
b54cf83a
DE
16338/* Power4 load update and store update instructions are cracked into a
16339 load or store and an integer insn which are executed in the same cycle.
16340 Branches have their own dispatch slot which does not count against the
16341 GCC issue rate, but it changes the program flow so there are no other
16342 instructions to issue in this cycle. */
16343
16344static int
f676971a
EC
16345rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
16346 int verbose ATTRIBUTE_UNUSED,
a2369ed3 16347 rtx insn, int more)
b54cf83a
DE
16348{
16349 if (GET_CODE (PATTERN (insn)) == USE
16350 || GET_CODE (PATTERN (insn)) == CLOBBER)
16351 return more;
16352
ec507f2d 16353 if (rs6000_sched_groups)
b54cf83a 16354 {
cbe26ab8 16355 if (is_microcoded_insn (insn))
c4ad648e 16356 return 0;
cbe26ab8 16357 else if (is_cracked_insn (insn))
c4ad648e 16358 return more > 2 ? more - 2 : 0;
b54cf83a 16359 }
165b263e
DE
16360
16361 return more - 1;
b54cf83a
DE
16362}
16363
a251ffd0
TG
16364/* Adjust the cost of a scheduling dependency. Return the new cost of
16365 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
16366
c237e94a 16367static int
0a4f0294 16368rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
a251ffd0
TG
16369{
16370 if (! recog_memoized (insn))
16371 return 0;
16372
16373 if (REG_NOTE_KIND (link) != 0)
16374 return 0;
16375
16376 if (REG_NOTE_KIND (link) == 0)
16377 {
ed947a96
DJ
16378 /* Data dependency; DEP_INSN writes a register that INSN reads
16379 some cycles later. */
c9dbf840
DE
16380
16381 /* Separate a load from a narrower, dependent store. */
16382 if (rs6000_sched_groups
16383 && GET_CODE (PATTERN (insn)) == SET
16384 && GET_CODE (PATTERN (dep_insn)) == SET
16385 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
16386 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
16387 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
16388 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
16389 return cost + 14;
16390
ed947a96
DJ
16391 switch (get_attr_type (insn))
16392 {
16393 case TYPE_JMPREG:
309323c2 16394 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
16395 a mtctr and bctr (and mtlr and br/blr). The first
16396 scheduling pass will not know about this latency since
16397 the mtctr instruction, which has the latency associated
16398 to it, will be generated by reload. */
309323c2 16399 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
16400 case TYPE_BRANCH:
16401 /* Leave some extra cycles between a compare and its
16402 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
16403 if ((rs6000_cpu_attr == CPU_PPC603
16404 || rs6000_cpu_attr == CPU_PPC604
16405 || rs6000_cpu_attr == CPU_PPC604E
16406 || rs6000_cpu_attr == CPU_PPC620
16407 || rs6000_cpu_attr == CPU_PPC630
16408 || rs6000_cpu_attr == CPU_PPC750
16409 || rs6000_cpu_attr == CPU_PPC7400
16410 || rs6000_cpu_attr == CPU_PPC7450
ec507f2d
DE
16411 || rs6000_cpu_attr == CPU_POWER4
16412 || rs6000_cpu_attr == CPU_POWER5)
ed947a96
DJ
16413 && recog_memoized (dep_insn)
16414 && (INSN_CODE (dep_insn) >= 0)
b54cf83a
DE
16415 && (get_attr_type (dep_insn) == TYPE_CMP
16416 || get_attr_type (dep_insn) == TYPE_COMPARE
ed947a96 16417 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
9259f3b0
DE
16418 || get_attr_type (dep_insn) == TYPE_IMUL_COMPARE
16419 || get_attr_type (dep_insn) == TYPE_LMUL_COMPARE
ed947a96 16420 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
b54cf83a
DE
16421 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL
16422 || get_attr_type (dep_insn) == TYPE_DELAYED_CR))
ed947a96
DJ
16423 return cost + 2;
16424 default:
16425 break;
16426 }
a251ffd0
TG
16427 /* Fall out to return default cost. */
16428 }
16429
16430 return cost;
16431}
b6c9286a 16432
cbe26ab8 16433/* The function returns a true if INSN is microcoded.
839a4992 16434 Return false otherwise. */
cbe26ab8
DN
16435
16436static bool
16437is_microcoded_insn (rtx insn)
16438{
16439 if (!insn || !INSN_P (insn)
16440 || GET_CODE (PATTERN (insn)) == USE
16441 || GET_CODE (PATTERN (insn)) == CLOBBER)
16442 return false;
16443
ec507f2d 16444 if (rs6000_sched_groups)
cbe26ab8
DN
16445 {
16446 enum attr_type type = get_attr_type (insn);
16447 if (type == TYPE_LOAD_EXT_U
16448 || type == TYPE_LOAD_EXT_UX
16449 || type == TYPE_LOAD_UX
16450 || type == TYPE_STORE_UX
16451 || type == TYPE_MFCR)
c4ad648e 16452 return true;
cbe26ab8
DN
16453 }
16454
16455 return false;
16456}
16457
5c425df5 16458/* The function returns a nonzero value if INSN can be scheduled only
cbe26ab8
DN
16459 as the first insn in a dispatch group ("dispatch-slot restricted").
16460 In this case, the returned value indicates how many dispatch slots
16461 the insn occupies (at the beginning of the group).
79ae11c4
DN
16462 Return 0 otherwise. */
16463
cbe26ab8 16464static int
79ae11c4
DN
16465is_dispatch_slot_restricted (rtx insn)
16466{
16467 enum attr_type type;
16468
ec507f2d 16469 if (!rs6000_sched_groups)
79ae11c4
DN
16470 return 0;
16471
16472 if (!insn
16473 || insn == NULL_RTX
16474 || GET_CODE (insn) == NOTE
16475 || GET_CODE (PATTERN (insn)) == USE
16476 || GET_CODE (PATTERN (insn)) == CLOBBER)
16477 return 0;
16478
16479 type = get_attr_type (insn);
16480
ec507f2d
DE
16481 switch (type)
16482 {
16483 case TYPE_MFCR:
16484 case TYPE_MFCRF:
16485 case TYPE_MTCR:
16486 case TYPE_DELAYED_CR:
16487 case TYPE_CR_LOGICAL:
16488 case TYPE_MTJMPR:
16489 case TYPE_MFJMPR:
16490 return 1;
16491 case TYPE_IDIV:
16492 case TYPE_LDIV:
16493 return 2;
b52110d4
DE
16494 case TYPE_LOAD_L:
16495 case TYPE_STORE_C:
16496 case TYPE_ISYNC:
16497 case TYPE_SYNC:
16498 return 4;
ec507f2d
DE
16499 default:
16500 if (rs6000_cpu == PROCESSOR_POWER5
16501 && is_cracked_insn (insn))
16502 return 2;
16503 return 0;
16504 }
79ae11c4
DN
16505}
16506
cbe26ab8
DN
16507/* The function returns true if INSN is cracked into 2 instructions
16508 by the processor (and therefore occupies 2 issue slots). */
16509
16510static bool
16511is_cracked_insn (rtx insn)
16512{
16513 if (!insn || !INSN_P (insn)
16514 || GET_CODE (PATTERN (insn)) == USE
16515 || GET_CODE (PATTERN (insn)) == CLOBBER)
16516 return false;
16517
ec507f2d 16518 if (rs6000_sched_groups)
cbe26ab8
DN
16519 {
16520 enum attr_type type = get_attr_type (insn);
16521 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
c4ad648e
AM
16522 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
16523 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
16524 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
16525 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
16526 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
16527 || type == TYPE_IDIV || type == TYPE_LDIV
16528 || type == TYPE_INSERT_WORD)
16529 return true;
cbe26ab8
DN
16530 }
16531
16532 return false;
16533}
16534
16535/* The function returns true if INSN can be issued only from
a3c9585f 16536 the branch slot. */
cbe26ab8
DN
16537
16538static bool
16539is_branch_slot_insn (rtx insn)
16540{
16541 if (!insn || !INSN_P (insn)
16542 || GET_CODE (PATTERN (insn)) == USE
16543 || GET_CODE (PATTERN (insn)) == CLOBBER)
16544 return false;
16545
ec507f2d 16546 if (rs6000_sched_groups)
cbe26ab8
DN
16547 {
16548 enum attr_type type = get_attr_type (insn);
16549 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
f676971a 16550 return true;
cbe26ab8
DN
16551 return false;
16552 }
16553
16554 return false;
16555}
79ae11c4 16556
a4f6c312 16557/* A C statement (sans semicolon) to update the integer scheduling
79ae11c4
DN
16558 priority INSN_PRIORITY (INSN). Increase the priority to execute the
16559 INSN earlier, reduce the priority to execute INSN later. Do not
a4f6c312
SS
16560 define this macro if you do not need to adjust the scheduling
16561 priorities of insns. */
bef84347 16562
c237e94a 16563static int
a2369ed3 16564rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
bef84347 16565{
a4f6c312
SS
16566 /* On machines (like the 750) which have asymmetric integer units,
16567 where one integer unit can do multiply and divides and the other
16568 can't, reduce the priority of multiply/divide so it is scheduled
16569 before other integer operations. */
bef84347
VM
16570
16571#if 0
2c3c49de 16572 if (! INSN_P (insn))
bef84347
VM
16573 return priority;
16574
16575 if (GET_CODE (PATTERN (insn)) == USE)
16576 return priority;
16577
16578 switch (rs6000_cpu_attr) {
16579 case CPU_PPC750:
16580 switch (get_attr_type (insn))
16581 {
16582 default:
16583 break;
16584
16585 case TYPE_IMUL:
16586 case TYPE_IDIV:
3cb999d8
DE
16587 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
16588 priority, priority);
bef84347
VM
16589 if (priority >= 0 && priority < 0x01000000)
16590 priority >>= 3;
16591 break;
16592 }
16593 }
16594#endif
16595
79ae11c4
DN
16596 if (is_dispatch_slot_restricted (insn)
16597 && reload_completed
f676971a 16598 && current_sched_info->sched_max_insns_priority
79ae11c4
DN
16599 && rs6000_sched_restricted_insns_priority)
16600 {
16601
c4ad648e
AM
16602 /* Prioritize insns that can be dispatched only in the first
16603 dispatch slot. */
79ae11c4 16604 if (rs6000_sched_restricted_insns_priority == 1)
f676971a
EC
16605 /* Attach highest priority to insn. This means that in
16606 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
79ae11c4 16607 precede 'priority' (critical path) considerations. */
f676971a 16608 return current_sched_info->sched_max_insns_priority;
79ae11c4 16609 else if (rs6000_sched_restricted_insns_priority == 2)
f676971a 16610 /* Increase priority of insn by a minimal amount. This means that in
c4ad648e
AM
16611 haifa-sched.c:ready_sort(), only 'priority' (critical path)
16612 considerations precede dispatch-slot restriction considerations. */
f676971a
EC
16613 return (priority + 1);
16614 }
79ae11c4 16615
bef84347
VM
16616 return priority;
16617}
16618
a4f6c312
SS
16619/* Return how many instructions the machine can issue per cycle. */
16620
c237e94a 16621static int
863d938c 16622rs6000_issue_rate (void)
b6c9286a 16623{
3317bab1
DE
16624 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
16625 if (!reload_completed)
16626 return 1;
16627
b6c9286a 16628 switch (rs6000_cpu_attr) {
3cb999d8
DE
16629 case CPU_RIOS1: /* ? */
16630 case CPU_RS64A:
16631 case CPU_PPC601: /* ? */
ed947a96 16632 case CPU_PPC7450:
3cb999d8 16633 return 3;
b54cf83a 16634 case CPU_PPC440:
b6c9286a 16635 case CPU_PPC603:
bef84347 16636 case CPU_PPC750:
ed947a96 16637 case CPU_PPC7400:
be12c2b0 16638 case CPU_PPC8540:
f676971a 16639 return 2;
3cb999d8 16640 case CPU_RIOS2:
b6c9286a 16641 case CPU_PPC604:
19684119 16642 case CPU_PPC604E:
b6c9286a 16643 case CPU_PPC620:
3cb999d8 16644 case CPU_PPC630:
b6c9286a 16645 return 4;
cbe26ab8 16646 case CPU_POWER4:
ec507f2d 16647 case CPU_POWER5:
cbe26ab8 16648 return 5;
b6c9286a
MM
16649 default:
16650 return 1;
16651 }
16652}
16653
be12c2b0
VM
16654/* Return how many instructions to look ahead for better insn
16655 scheduling. */
16656
16657static int
863d938c 16658rs6000_use_sched_lookahead (void)
be12c2b0
VM
16659{
16660 if (rs6000_cpu_attr == CPU_PPC8540)
16661 return 4;
16662 return 0;
16663}
16664
569fa502
DN
16665/* Determine is PAT refers to memory. */
16666
16667static bool
16668is_mem_ref (rtx pat)
16669{
16670 const char * fmt;
16671 int i, j;
16672 bool ret = false;
16673
16674 if (GET_CODE (pat) == MEM)
16675 return true;
16676
16677 /* Recursively process the pattern. */
16678 fmt = GET_RTX_FORMAT (GET_CODE (pat));
16679
16680 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
16681 {
16682 if (fmt[i] == 'e')
16683 ret |= is_mem_ref (XEXP (pat, i));
16684 else if (fmt[i] == 'E')
16685 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
16686 ret |= is_mem_ref (XVECEXP (pat, i, j));
16687 }
16688
16689 return ret;
16690}
16691
16692/* Determine if PAT is a PATTERN of a load insn. */
f676971a 16693
569fa502
DN
16694static bool
16695is_load_insn1 (rtx pat)
16696{
16697 if (!pat || pat == NULL_RTX)
16698 return false;
16699
16700 if (GET_CODE (pat) == SET)
16701 return is_mem_ref (SET_SRC (pat));
16702
16703 if (GET_CODE (pat) == PARALLEL)
16704 {
16705 int i;
16706
16707 for (i = 0; i < XVECLEN (pat, 0); i++)
16708 if (is_load_insn1 (XVECEXP (pat, 0, i)))
16709 return true;
16710 }
16711
16712 return false;
16713}
16714
16715/* Determine if INSN loads from memory. */
16716
16717static bool
16718is_load_insn (rtx insn)
16719{
16720 if (!insn || !INSN_P (insn))
16721 return false;
16722
16723 if (GET_CODE (insn) == CALL_INSN)
16724 return false;
16725
16726 return is_load_insn1 (PATTERN (insn));
16727}
16728
16729/* Determine if PAT is a PATTERN of a store insn. */
16730
16731static bool
16732is_store_insn1 (rtx pat)
16733{
16734 if (!pat || pat == NULL_RTX)
16735 return false;
16736
16737 if (GET_CODE (pat) == SET)
16738 return is_mem_ref (SET_DEST (pat));
16739
16740 if (GET_CODE (pat) == PARALLEL)
16741 {
16742 int i;
16743
16744 for (i = 0; i < XVECLEN (pat, 0); i++)
16745 if (is_store_insn1 (XVECEXP (pat, 0, i)))
16746 return true;
16747 }
16748
16749 return false;
16750}
16751
16752/* Determine if INSN stores to memory. */
16753
16754static bool
16755is_store_insn (rtx insn)
16756{
16757 if (!insn || !INSN_P (insn))
16758 return false;
16759
16760 return is_store_insn1 (PATTERN (insn));
16761}
16762
16763/* Returns whether the dependence between INSN and NEXT is considered
16764 costly by the given target. */
16765
16766static bool
c4ad648e
AM
16767rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost,
16768 int distance)
f676971a 16769{
aabcd309 16770 /* If the flag is not enabled - no dependence is considered costly;
f676971a 16771 allow all dependent insns in the same group.
569fa502
DN
16772 This is the most aggressive option. */
16773 if (rs6000_sched_costly_dep == no_dep_costly)
16774 return false;
16775
f676971a 16776 /* If the flag is set to 1 - a dependence is always considered costly;
569fa502
DN
16777 do not allow dependent instructions in the same group.
16778 This is the most conservative option. */
16779 if (rs6000_sched_costly_dep == all_deps_costly)
f676971a 16780 return true;
569fa502 16781
f676971a
EC
16782 if (rs6000_sched_costly_dep == store_to_load_dep_costly
16783 && is_load_insn (next)
569fa502
DN
16784 && is_store_insn (insn))
16785 /* Prevent load after store in the same group. */
16786 return true;
16787
16788 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
f676971a 16789 && is_load_insn (next)
569fa502
DN
16790 && is_store_insn (insn)
16791 && (!link || (int) REG_NOTE_KIND (link) == 0))
c4ad648e
AM
16792 /* Prevent load after store in the same group if it is a true
16793 dependence. */
569fa502 16794 return true;
f676971a
EC
16795
16796 /* The flag is set to X; dependences with latency >= X are considered costly,
569fa502
DN
16797 and will not be scheduled in the same group. */
16798 if (rs6000_sched_costly_dep <= max_dep_latency
16799 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
16800 return true;
16801
16802 return false;
16803}
16804
f676971a 16805/* Return the next insn after INSN that is found before TAIL is reached,
cbe26ab8
DN
16806 skipping any "non-active" insns - insns that will not actually occupy
16807 an issue slot. Return NULL_RTX if such an insn is not found. */
16808
16809static rtx
16810get_next_active_insn (rtx insn, rtx tail)
16811{
f489aff8 16812 if (insn == NULL_RTX || insn == tail)
cbe26ab8
DN
16813 return NULL_RTX;
16814
f489aff8 16815 while (1)
cbe26ab8 16816 {
f489aff8
AM
16817 insn = NEXT_INSN (insn);
16818 if (insn == NULL_RTX || insn == tail)
16819 return NULL_RTX;
cbe26ab8 16820
f489aff8
AM
16821 if (CALL_P (insn)
16822 || JUMP_P (insn)
16823 || (NONJUMP_INSN_P (insn)
16824 && GET_CODE (PATTERN (insn)) != USE
16825 && GET_CODE (PATTERN (insn)) != CLOBBER
309ebcd0 16826 && INSN_CODE (insn) != CODE_FOR_stack_tie))
f489aff8
AM
16827 break;
16828 }
16829 return insn;
cbe26ab8
DN
16830}
16831
839a4992 16832/* Return whether the presence of INSN causes a dispatch group termination
cbe26ab8
DN
16833 of group WHICH_GROUP.
16834
16835 If WHICH_GROUP == current_group, this function will return true if INSN
16836 causes the termination of the current group (i.e, the dispatch group to
16837 which INSN belongs). This means that INSN will be the last insn in the
16838 group it belongs to.
16839
16840 If WHICH_GROUP == previous_group, this function will return true if INSN
16841 causes the termination of the previous group (i.e, the dispatch group that
16842 precedes the group to which INSN belongs). This means that INSN will be
16843 the first insn in the group it belongs to). */
16844
16845static bool
16846insn_terminates_group_p (rtx insn, enum group_termination which_group)
16847{
16848 enum attr_type type;
16849
16850 if (! insn)
16851 return false;
569fa502 16852
cbe26ab8
DN
16853 type = get_attr_type (insn);
16854
16855 if (is_microcoded_insn (insn))
16856 return true;
16857
16858 if (which_group == current_group)
16859 {
16860 if (is_branch_slot_insn (insn))
c4ad648e 16861 return true;
cbe26ab8
DN
16862 return false;
16863 }
16864 else if (which_group == previous_group)
16865 {
16866 if (is_dispatch_slot_restricted (insn))
c4ad648e 16867 return true;
cbe26ab8
DN
16868 return false;
16869 }
16870
16871 return false;
16872}
16873
839a4992 16874/* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
cbe26ab8
DN
16875 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
16876
16877static bool
16878is_costly_group (rtx *group_insns, rtx next_insn)
16879{
16880 int i;
16881 rtx link;
16882 int cost;
16883 int issue_rate = rs6000_issue_rate ();
16884
16885 for (i = 0; i < issue_rate; i++)
16886 {
16887 rtx insn = group_insns[i];
16888 if (!insn)
c4ad648e 16889 continue;
cbe26ab8 16890 for (link = INSN_DEPEND (insn); link != 0; link = XEXP (link, 1))
c4ad648e
AM
16891 {
16892 rtx next = XEXP (link, 0);
16893 if (next == next_insn)
16894 {
16895 cost = insn_cost (insn, link, next_insn);
16896 if (rs6000_is_costly_dependence (insn, next_insn, link, cost, 0))
16897 return true;
16898 }
16899 }
cbe26ab8
DN
16900 }
16901
16902 return false;
16903}
16904
f676971a 16905/* Utility of the function redefine_groups.
cbe26ab8
DN
16906 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
16907 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
16908 to keep it "far" (in a separate group) from GROUP_INSNS, following
16909 one of the following schemes, depending on the value of the flag
16910 -minsert_sched_nops = X:
16911 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
839a4992 16912 in order to force NEXT_INSN into a separate group.
f676971a
EC
16913 (2) X < sched_finish_regroup_exact: insert exactly X nops.
16914 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
cbe26ab8
DN
16915 insertion (has a group just ended, how many vacant issue slots remain in the
16916 last group, and how many dispatch groups were encountered so far). */
16917
f676971a 16918static int
c4ad648e
AM
16919force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
16920 rtx next_insn, bool *group_end, int can_issue_more,
16921 int *group_count)
cbe26ab8
DN
16922{
16923 rtx nop;
16924 bool force;
16925 int issue_rate = rs6000_issue_rate ();
16926 bool end = *group_end;
16927 int i;
16928
16929 if (next_insn == NULL_RTX)
16930 return can_issue_more;
16931
16932 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
16933 return can_issue_more;
16934
16935 force = is_costly_group (group_insns, next_insn);
16936 if (!force)
16937 return can_issue_more;
16938
16939 if (sched_verbose > 6)
16940 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
c4ad648e 16941 *group_count ,can_issue_more);
cbe26ab8
DN
16942
16943 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
16944 {
16945 if (*group_end)
c4ad648e 16946 can_issue_more = 0;
cbe26ab8
DN
16947
16948 /* Since only a branch can be issued in the last issue_slot, it is
16949 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
16950 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
c4ad648e
AM
16951 in this case the last nop will start a new group and the branch
16952 will be forced to the new group. */
cbe26ab8 16953 if (can_issue_more && !is_branch_slot_insn (next_insn))
c4ad648e 16954 can_issue_more--;
cbe26ab8
DN
16955
16956 while (can_issue_more > 0)
c4ad648e 16957 {
9390387d 16958 nop = gen_nop ();
c4ad648e
AM
16959 emit_insn_before (nop, next_insn);
16960 can_issue_more--;
16961 }
cbe26ab8
DN
16962
16963 *group_end = true;
16964 return 0;
f676971a 16965 }
cbe26ab8
DN
16966
16967 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
16968 {
16969 int n_nops = rs6000_sched_insert_nops;
16970
f676971a 16971 /* Nops can't be issued from the branch slot, so the effective
c4ad648e 16972 issue_rate for nops is 'issue_rate - 1'. */
cbe26ab8 16973 if (can_issue_more == 0)
c4ad648e 16974 can_issue_more = issue_rate;
cbe26ab8
DN
16975 can_issue_more--;
16976 if (can_issue_more == 0)
c4ad648e
AM
16977 {
16978 can_issue_more = issue_rate - 1;
16979 (*group_count)++;
16980 end = true;
16981 for (i = 0; i < issue_rate; i++)
16982 {
16983 group_insns[i] = 0;
16984 }
16985 }
cbe26ab8
DN
16986
16987 while (n_nops > 0)
c4ad648e
AM
16988 {
16989 nop = gen_nop ();
16990 emit_insn_before (nop, next_insn);
16991 if (can_issue_more == issue_rate - 1) /* new group begins */
16992 end = false;
16993 can_issue_more--;
16994 if (can_issue_more == 0)
16995 {
16996 can_issue_more = issue_rate - 1;
16997 (*group_count)++;
16998 end = true;
16999 for (i = 0; i < issue_rate; i++)
17000 {
17001 group_insns[i] = 0;
17002 }
17003 }
17004 n_nops--;
17005 }
cbe26ab8
DN
17006
17007 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
f676971a 17008 can_issue_more++;
cbe26ab8 17009
c4ad648e
AM
17010 /* Is next_insn going to start a new group? */
17011 *group_end
17012 = (end
cbe26ab8
DN
17013 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
17014 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
17015 || (can_issue_more < issue_rate &&
c4ad648e 17016 insn_terminates_group_p (next_insn, previous_group)));
cbe26ab8 17017 if (*group_end && end)
c4ad648e 17018 (*group_count)--;
cbe26ab8
DN
17019
17020 if (sched_verbose > 6)
c4ad648e
AM
17021 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
17022 *group_count, can_issue_more);
f676971a
EC
17023 return can_issue_more;
17024 }
cbe26ab8
DN
17025
17026 return can_issue_more;
17027}
17028
17029/* This function tries to synch the dispatch groups that the compiler "sees"
f676971a 17030 with the dispatch groups that the processor dispatcher is expected to
cbe26ab8
DN
17031 form in practice. It tries to achieve this synchronization by forcing the
17032 estimated processor grouping on the compiler (as opposed to the function
17033 'pad_goups' which tries to force the scheduler's grouping on the processor).
17034
17035 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
17036 examines the (estimated) dispatch groups that will be formed by the processor
17037 dispatcher. It marks these group boundaries to reflect the estimated
17038 processor grouping, overriding the grouping that the scheduler had marked.
17039 Depending on the value of the flag '-minsert-sched-nops' this function can
17040 force certain insns into separate groups or force a certain distance between
17041 them by inserting nops, for example, if there exists a "costly dependence"
17042 between the insns.
17043
17044 The function estimates the group boundaries that the processor will form as
0fa2e4df 17045 follows: It keeps track of how many vacant issue slots are available after
cbe26ab8
DN
17046 each insn. A subsequent insn will start a new group if one of the following
17047 4 cases applies:
17048 - no more vacant issue slots remain in the current dispatch group.
17049 - only the last issue slot, which is the branch slot, is vacant, but the next
17050 insn is not a branch.
17051 - only the last 2 or less issue slots, including the branch slot, are vacant,
17052 which means that a cracked insn (which occupies two issue slots) can't be
17053 issued in this group.
f676971a 17054 - less than 'issue_rate' slots are vacant, and the next insn always needs to
cbe26ab8
DN
17055 start a new group. */
17056
17057static int
17058redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
17059{
17060 rtx insn, next_insn;
17061 int issue_rate;
17062 int can_issue_more;
17063 int slot, i;
17064 bool group_end;
17065 int group_count = 0;
17066 rtx *group_insns;
17067
17068 /* Initialize. */
17069 issue_rate = rs6000_issue_rate ();
17070 group_insns = alloca (issue_rate * sizeof (rtx));
f676971a 17071 for (i = 0; i < issue_rate; i++)
cbe26ab8
DN
17072 {
17073 group_insns[i] = 0;
17074 }
17075 can_issue_more = issue_rate;
17076 slot = 0;
17077 insn = get_next_active_insn (prev_head_insn, tail);
17078 group_end = false;
17079
17080 while (insn != NULL_RTX)
17081 {
17082 slot = (issue_rate - can_issue_more);
17083 group_insns[slot] = insn;
17084 can_issue_more =
c4ad648e 17085 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
cbe26ab8 17086 if (insn_terminates_group_p (insn, current_group))
c4ad648e 17087 can_issue_more = 0;
cbe26ab8
DN
17088
17089 next_insn = get_next_active_insn (insn, tail);
17090 if (next_insn == NULL_RTX)
c4ad648e 17091 return group_count + 1;
cbe26ab8 17092
c4ad648e
AM
17093 /* Is next_insn going to start a new group? */
17094 group_end
17095 = (can_issue_more == 0
17096 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
17097 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
17098 || (can_issue_more < issue_rate &&
17099 insn_terminates_group_p (next_insn, previous_group)));
cbe26ab8 17100
f676971a 17101 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
c4ad648e
AM
17102 next_insn, &group_end, can_issue_more,
17103 &group_count);
cbe26ab8
DN
17104
17105 if (group_end)
c4ad648e
AM
17106 {
17107 group_count++;
17108 can_issue_more = 0;
17109 for (i = 0; i < issue_rate; i++)
17110 {
17111 group_insns[i] = 0;
17112 }
17113 }
cbe26ab8
DN
17114
17115 if (GET_MODE (next_insn) == TImode && can_issue_more)
9390387d 17116 PUT_MODE (next_insn, VOIDmode);
cbe26ab8 17117 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
c4ad648e 17118 PUT_MODE (next_insn, TImode);
cbe26ab8
DN
17119
17120 insn = next_insn;
17121 if (can_issue_more == 0)
c4ad648e
AM
17122 can_issue_more = issue_rate;
17123 } /* while */
cbe26ab8
DN
17124
17125 return group_count;
17126}
17127
17128/* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
17129 dispatch group boundaries that the scheduler had marked. Pad with nops
17130 any dispatch groups which have vacant issue slots, in order to force the
17131 scheduler's grouping on the processor dispatcher. The function
17132 returns the number of dispatch groups found. */
17133
17134static int
17135pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
17136{
17137 rtx insn, next_insn;
17138 rtx nop;
17139 int issue_rate;
17140 int can_issue_more;
17141 int group_end;
17142 int group_count = 0;
17143
17144 /* Initialize issue_rate. */
17145 issue_rate = rs6000_issue_rate ();
17146 can_issue_more = issue_rate;
17147
17148 insn = get_next_active_insn (prev_head_insn, tail);
17149 next_insn = get_next_active_insn (insn, tail);
17150
17151 while (insn != NULL_RTX)
17152 {
17153 can_issue_more =
17154 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
17155
17156 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
17157
17158 if (next_insn == NULL_RTX)
c4ad648e 17159 break;
cbe26ab8
DN
17160
17161 if (group_end)
c4ad648e
AM
17162 {
17163 /* If the scheduler had marked group termination at this location
17164 (between insn and next_indn), and neither insn nor next_insn will
17165 force group termination, pad the group with nops to force group
17166 termination. */
17167 if (can_issue_more
17168 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
17169 && !insn_terminates_group_p (insn, current_group)
17170 && !insn_terminates_group_p (next_insn, previous_group))
17171 {
9390387d 17172 if (!is_branch_slot_insn (next_insn))
c4ad648e
AM
17173 can_issue_more--;
17174
17175 while (can_issue_more)
17176 {
17177 nop = gen_nop ();
17178 emit_insn_before (nop, next_insn);
17179 can_issue_more--;
17180 }
17181 }
17182
17183 can_issue_more = issue_rate;
17184 group_count++;
17185 }
cbe26ab8
DN
17186
17187 insn = next_insn;
17188 next_insn = get_next_active_insn (insn, tail);
17189 }
17190
17191 return group_count;
17192}
17193
17194/* The following function is called at the end of scheduling BB.
17195 After reload, it inserts nops at insn group bundling. */
17196
17197static void
38f391a5 17198rs6000_sched_finish (FILE *dump, int sched_verbose)
cbe26ab8
DN
17199{
17200 int n_groups;
17201
17202 if (sched_verbose)
17203 fprintf (dump, "=== Finishing schedule.\n");
17204
ec507f2d 17205 if (reload_completed && rs6000_sched_groups)
cbe26ab8
DN
17206 {
17207 if (rs6000_sched_insert_nops == sched_finish_none)
c4ad648e 17208 return;
cbe26ab8
DN
17209
17210 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
c4ad648e
AM
17211 n_groups = pad_groups (dump, sched_verbose,
17212 current_sched_info->prev_head,
17213 current_sched_info->next_tail);
cbe26ab8 17214 else
c4ad648e
AM
17215 n_groups = redefine_groups (dump, sched_verbose,
17216 current_sched_info->prev_head,
17217 current_sched_info->next_tail);
cbe26ab8
DN
17218
17219 if (sched_verbose >= 6)
17220 {
17221 fprintf (dump, "ngroups = %d\n", n_groups);
17222 print_rtl (dump, current_sched_info->prev_head);
17223 fprintf (dump, "Done finish_sched\n");
17224 }
17225 }
17226}
b6c9286a 17227\f
b6c9286a
MM
17228/* Length in units of the trampoline for entering a nested function. */
17229
17230int
863d938c 17231rs6000_trampoline_size (void)
b6c9286a
MM
17232{
17233 int ret = 0;
17234
17235 switch (DEFAULT_ABI)
17236 {
17237 default:
37409796 17238 gcc_unreachable ();
b6c9286a
MM
17239
17240 case ABI_AIX:
8f802bfb 17241 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
17242 break;
17243
4dabc42d 17244 case ABI_DARWIN:
b6c9286a 17245 case ABI_V4:
03a7e1a5 17246 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 17247 break;
b6c9286a
MM
17248 }
17249
17250 return ret;
17251}
17252
17253/* Emit RTL insns to initialize the variable parts of a trampoline.
17254 FNADDR is an RTX for the address of the function's pure code.
17255 CXT is an RTX for the static chain value for the function. */
17256
17257void
a2369ed3 17258rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
b6c9286a 17259{
ac2a93a1 17260 enum machine_mode pmode = Pmode;
8bd04c56
MM
17261 int regsize = (TARGET_32BIT) ? 4 : 8;
17262 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
17263
17264 switch (DEFAULT_ABI)
17265 {
17266 default:
37409796 17267 gcc_unreachable ();
b6c9286a 17268
8bd04c56 17269/* Macros to shorten the code expansions below. */
39403d82 17270#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
17271#define MEM_PLUS(addr,offset) \
17272 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 17273
b6c9286a
MM
17274 /* Under AIX, just build the 3 word function descriptor */
17275 case ABI_AIX:
8bd04c56
MM
17276 {
17277 rtx fn_reg = gen_reg_rtx (pmode);
17278 rtx toc_reg = gen_reg_rtx (pmode);
17279 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 17280 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
17281 emit_move_insn (MEM_DEREF (addr), fn_reg);
17282 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
17283 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
17284 }
b6c9286a
MM
17285 break;
17286
4dabc42d
TC
17287 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
17288 case ABI_DARWIN:
b6c9286a 17289 case ABI_V4:
39403d82 17290 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
17291 FALSE, VOIDmode, 4,
17292 addr, pmode,
17293 GEN_INT (rs6000_trampoline_size ()), SImode,
17294 fnaddr, pmode,
17295 ctx_reg, pmode);
b6c9286a 17296 break;
b6c9286a
MM
17297 }
17298
17299 return;
17300}
7509c759
MM
17301
17302\f
91d231cb 17303/* Table of valid machine attributes. */
a4f6c312 17304
91d231cb 17305const struct attribute_spec rs6000_attribute_table[] =
7509c759 17306{
91d231cb 17307 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
8bb418a3 17308 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
a5c76ee6
ZW
17309 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
17310 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
005c1a13
GK
17311#ifdef SUBTARGET_ATTRIBUTE_TABLE
17312 SUBTARGET_ATTRIBUTE_TABLE,
17313#endif
a5c76ee6 17314 { NULL, 0, 0, false, false, false, NULL }
91d231cb 17315};
7509c759 17316
8bb418a3
ZL
17317/* Handle the "altivec" attribute. The attribute may have
17318 arguments as follows:
f676971a 17319
8bb418a3
ZL
17320 __attribute__((altivec(vector__)))
17321 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
17322 __attribute__((altivec(bool__))) (always followed by 'unsigned')
17323
17324 and may appear more than once (e.g., 'vector bool char') in a
17325 given declaration. */
17326
17327static tree
f90ac3f0
UP
17328rs6000_handle_altivec_attribute (tree *node,
17329 tree name ATTRIBUTE_UNUSED,
17330 tree args,
8bb418a3
ZL
17331 int flags ATTRIBUTE_UNUSED,
17332 bool *no_add_attrs)
17333{
17334 tree type = *node, result = NULL_TREE;
17335 enum machine_mode mode;
17336 int unsigned_p;
17337 char altivec_type
17338 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
17339 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
17340 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
f676971a 17341 : '?');
8bb418a3
ZL
17342
17343 while (POINTER_TYPE_P (type)
17344 || TREE_CODE (type) == FUNCTION_TYPE
17345 || TREE_CODE (type) == METHOD_TYPE
17346 || TREE_CODE (type) == ARRAY_TYPE)
17347 type = TREE_TYPE (type);
17348
17349 mode = TYPE_MODE (type);
17350
f90ac3f0
UP
17351 /* Check for invalid AltiVec type qualifiers. */
17352 if (type == long_unsigned_type_node || type == long_integer_type_node)
17353 {
17354 if (TARGET_64BIT)
17355 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
17356 else if (rs6000_warn_altivec_long)
d4ee4d25 17357 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
f90ac3f0
UP
17358 }
17359 else if (type == long_long_unsigned_type_node
17360 || type == long_long_integer_type_node)
17361 error ("use of %<long long%> in AltiVec types is invalid");
17362 else if (type == double_type_node)
17363 error ("use of %<double%> in AltiVec types is invalid");
17364 else if (type == long_double_type_node)
17365 error ("use of %<long double%> in AltiVec types is invalid");
17366 else if (type == boolean_type_node)
17367 error ("use of boolean types in AltiVec types is invalid");
17368 else if (TREE_CODE (type) == COMPLEX_TYPE)
17369 error ("use of %<complex%> in AltiVec types is invalid");
00b79d54
BE
17370 else if (DECIMAL_FLOAT_MODE_P (mode))
17371 error ("use of decimal floating point types in AltiVec types is invalid");
8bb418a3
ZL
17372
17373 switch (altivec_type)
17374 {
17375 case 'v':
8df83eae 17376 unsigned_p = TYPE_UNSIGNED (type);
8bb418a3
ZL
17377 switch (mode)
17378 {
c4ad648e
AM
17379 case SImode:
17380 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
17381 break;
17382 case HImode:
17383 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
17384 break;
17385 case QImode:
17386 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
17387 break;
17388 case SFmode: result = V4SF_type_node; break;
17389 /* If the user says 'vector int bool', we may be handed the 'bool'
17390 attribute _before_ the 'vector' attribute, and so select the
17391 proper type in the 'b' case below. */
17392 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
17393 result = type;
17394 default: break;
8bb418a3
ZL
17395 }
17396 break;
17397 case 'b':
17398 switch (mode)
17399 {
c4ad648e
AM
17400 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
17401 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
17402 case QImode: case V16QImode: result = bool_V16QI_type_node;
17403 default: break;
8bb418a3
ZL
17404 }
17405 break;
17406 case 'p':
17407 switch (mode)
17408 {
c4ad648e
AM
17409 case V8HImode: result = pixel_V8HI_type_node;
17410 default: break;
8bb418a3
ZL
17411 }
17412 default: break;
17413 }
17414
7958a2a6
FJ
17415 if (result && result != type && TYPE_READONLY (type))
17416 result = build_qualified_type (result, TYPE_QUAL_CONST);
17417
8bb418a3
ZL
17418 *no_add_attrs = true; /* No need to hang on to the attribute. */
17419
f90ac3f0 17420 if (result)
8bb418a3
ZL
17421 *node = reconstruct_complex_type (*node, result);
17422
17423 return NULL_TREE;
17424}
17425
f18eca82
ZL
17426/* AltiVec defines four built-in scalar types that serve as vector
17427 elements; we must teach the compiler how to mangle them. */
17428
17429static const char *
17430rs6000_mangle_fundamental_type (tree type)
17431{
17432 if (type == bool_char_type_node) return "U6__boolc";
17433 if (type == bool_short_type_node) return "U6__bools";
17434 if (type == pixel_type_node) return "u7__pixel";
17435 if (type == bool_int_type_node) return "U6__booli";
17436
337bde91
DE
17437 /* Mangle IBM extended float long double as `g' (__float128) on
17438 powerpc*-linux where long-double-64 previously was the default. */
17439 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
17440 && TARGET_ELF
17441 && TARGET_LONG_DOUBLE_128
17442 && !TARGET_IEEEQUAD)
17443 return "g";
17444
f18eca82
ZL
17445 /* For all other types, use normal C++ mangling. */
17446 return NULL;
17447}
17448
a5c76ee6
ZW
17449/* Handle a "longcall" or "shortcall" attribute; arguments as in
17450 struct attribute_spec.handler. */
a4f6c312 17451
91d231cb 17452static tree
f676971a
EC
17453rs6000_handle_longcall_attribute (tree *node, tree name,
17454 tree args ATTRIBUTE_UNUSED,
17455 int flags ATTRIBUTE_UNUSED,
a2369ed3 17456 bool *no_add_attrs)
91d231cb
JM
17457{
17458 if (TREE_CODE (*node) != FUNCTION_TYPE
17459 && TREE_CODE (*node) != FIELD_DECL
17460 && TREE_CODE (*node) != TYPE_DECL)
17461 {
5c498b10 17462 warning (OPT_Wattributes, "%qs attribute only applies to functions",
91d231cb
JM
17463 IDENTIFIER_POINTER (name));
17464 *no_add_attrs = true;
17465 }
6a4cee5f 17466
91d231cb 17467 return NULL_TREE;
7509c759
MM
17468}
17469
a5c76ee6
ZW
17470/* Set longcall attributes on all functions declared when
17471 rs6000_default_long_calls is true. */
17472static void
a2369ed3 17473rs6000_set_default_type_attributes (tree type)
a5c76ee6
ZW
17474{
17475 if (rs6000_default_long_calls
17476 && (TREE_CODE (type) == FUNCTION_TYPE
17477 || TREE_CODE (type) == METHOD_TYPE))
17478 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
17479 NULL_TREE,
17480 TYPE_ATTRIBUTES (type));
17481}
17482
3cb999d8
DE
17483/* Return a reference suitable for calling a function with the
17484 longcall attribute. */
a4f6c312 17485
9390387d 17486rtx
a2369ed3 17487rs6000_longcall_ref (rtx call_ref)
6a4cee5f 17488{
d330fd93 17489 const char *call_name;
6a4cee5f
MM
17490 tree node;
17491
17492 if (GET_CODE (call_ref) != SYMBOL_REF)
17493 return call_ref;
17494
17495 /* System V adds '.' to the internal name, so skip them. */
17496 call_name = XSTR (call_ref, 0);
17497 if (*call_name == '.')
17498 {
17499 while (*call_name == '.')
17500 call_name++;
17501
17502 node = get_identifier (call_name);
39403d82 17503 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
17504 }
17505
17506 return force_reg (Pmode, call_ref);
17507}
7509c759 17508\f
b64a1b53
RH
17509#ifdef USING_ELFOS_H
17510
d6b5193b 17511/* A get_unnamed_section callback, used for switching to toc_section. */
7509c759 17512
d6b5193b
RS
17513static void
17514rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
17515{
17516 if (DEFAULT_ABI == ABI_AIX
17517 && TARGET_MINIMAL_TOC
17518 && !TARGET_RELOCATABLE)
17519 {
17520 if (!toc_initialized)
17521 {
17522 toc_initialized = 1;
17523 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
17524 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
17525 fprintf (asm_out_file, "\t.tc ");
17526 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
17527 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
17528 fprintf (asm_out_file, "\n");
17529
17530 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
17531 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
17532 fprintf (asm_out_file, " = .+32768\n");
17533 }
17534 else
17535 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
17536 }
17537 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
17538 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
17539 else
17540 {
17541 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
17542 if (!toc_initialized)
17543 {
17544 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
17545 fprintf (asm_out_file, " = .+32768\n");
17546 toc_initialized = 1;
17547 }
17548 }
17549}
17550
17551/* Implement TARGET_ASM_INIT_SECTIONS. */
7509c759 17552
b64a1b53 17553static void
d6b5193b
RS
17554rs6000_elf_asm_init_sections (void)
17555{
17556 toc_section
17557 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
17558
17559 sdata2_section
17560 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
17561 SDATA2_SECTION_ASM_OP);
17562}
17563
17564/* Implement TARGET_SELECT_RTX_SECTION. */
17565
17566static section *
f676971a 17567rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
a2369ed3 17568 unsigned HOST_WIDE_INT align)
7509c759 17569{
a9098fd0 17570 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
d6b5193b 17571 return toc_section;
7509c759 17572 else
d6b5193b 17573 return default_elf_select_rtx_section (mode, x, align);
7509c759
MM
17574}
17575
d6b5193b 17576/* Implement TARGET_ASM_SELECT_SECTION for ELF targets. */
7509c759 17577
d6b5193b 17578static section *
f676971a 17579rs6000_elf_select_section (tree decl, int reloc,
a2369ed3 17580 unsigned HOST_WIDE_INT align)
7509c759 17581{
f1384257
AM
17582 /* Pretend that we're always building for a shared library when
17583 ABI_AIX, because otherwise we end up with dynamic relocations
17584 in read-only sections. This happens for function pointers,
17585 references to vtables in typeinfo, and probably other cases. */
d6b5193b
RS
17586 return default_elf_select_section_1 (decl, reloc, align,
17587 flag_pic || DEFAULT_ABI == ABI_AIX);
63019373
GK
17588}
17589
17590/* A C statement to build up a unique section name, expressed as a
17591 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
17592 RELOC indicates whether the initial value of EXP requires
17593 link-time relocations. If you do not define this macro, GCC will use
17594 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 17595 macro can now be called for uninitialized data items as well as
4912a07c 17596 initialized data and functions. */
63019373 17597
ae46c4e0 17598static void
a2369ed3 17599rs6000_elf_unique_section (tree decl, int reloc)
63019373 17600{
f1384257
AM
17601 /* As above, pretend that we're always building for a shared library
17602 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
0e5dbd9b
DE
17603 default_unique_section_1 (decl, reloc,
17604 flag_pic || DEFAULT_ABI == ABI_AIX);
7509c759 17605}
d9407988 17606\f
d1908feb
JJ
17607/* For a SYMBOL_REF, set generic flags and then perform some
17608 target-specific processing.
17609
d1908feb
JJ
17610 When the AIX ABI is requested on a non-AIX system, replace the
17611 function name with the real name (with a leading .) rather than the
17612 function descriptor name. This saves a lot of overriding code to
17613 read the prefixes. */
d9407988 17614
fb49053f 17615static void
a2369ed3 17616rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
d9407988 17617{
d1908feb 17618 default_encode_section_info (decl, rtl, first);
b2003250 17619
d1908feb
JJ
17620 if (first
17621 && TREE_CODE (decl) == FUNCTION_DECL
17622 && !TARGET_AIX
17623 && DEFAULT_ABI == ABI_AIX)
d9407988 17624 {
c6a2438a 17625 rtx sym_ref = XEXP (rtl, 0);
d1908feb
JJ
17626 size_t len = strlen (XSTR (sym_ref, 0));
17627 char *str = alloca (len + 2);
17628 str[0] = '.';
17629 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
17630 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988 17631 }
d9407988
MM
17632}
17633
c1b7d95a 17634bool
a2369ed3 17635rs6000_elf_in_small_data_p (tree decl)
0e5dbd9b
DE
17636{
17637 if (rs6000_sdata == SDATA_NONE)
17638 return false;
17639
7482ad25
AF
17640 /* We want to merge strings, so we never consider them small data. */
17641 if (TREE_CODE (decl) == STRING_CST)
17642 return false;
17643
17644 /* Functions are never in the small data area. */
17645 if (TREE_CODE (decl) == FUNCTION_DECL)
17646 return false;
17647
0e5dbd9b
DE
17648 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
17649 {
17650 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
17651 if (strcmp (section, ".sdata") == 0
17652 || strcmp (section, ".sdata2") == 0
20bfcd69
GK
17653 || strcmp (section, ".sbss") == 0
17654 || strcmp (section, ".sbss2") == 0
17655 || strcmp (section, ".PPC.EMB.sdata0") == 0
17656 || strcmp (section, ".PPC.EMB.sbss0") == 0)
0e5dbd9b
DE
17657 return true;
17658 }
17659 else
17660 {
17661 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
17662
17663 if (size > 0
307b599c 17664 && (unsigned HOST_WIDE_INT) size <= g_switch_value
20bfcd69
GK
17665 /* If it's not public, and we're not going to reference it there,
17666 there's no need to put it in the small data section. */
0e5dbd9b
DE
17667 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
17668 return true;
17669 }
17670
17671 return false;
17672}
17673
b91da81f 17674#endif /* USING_ELFOS_H */
aacd3885
RS
17675\f
17676/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
000034eb 17677
aacd3885
RS
17678static bool
17679rs6000_use_blocks_for_constant_p (enum machine_mode mode, rtx x)
17680{
17681 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
17682}
a6c2a102 17683\f
000034eb 17684/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
17685 ADDR can be effectively incremented by incrementing REG.
17686
17687 r0 is special and we must not select it as an address
17688 register by this routine since our caller will try to
17689 increment the returned register via an "la" instruction. */
000034eb 17690
9390387d 17691rtx
a2369ed3 17692find_addr_reg (rtx addr)
000034eb
DE
17693{
17694 while (GET_CODE (addr) == PLUS)
17695 {
02441cd6
JL
17696 if (GET_CODE (XEXP (addr, 0)) == REG
17697 && REGNO (XEXP (addr, 0)) != 0)
000034eb 17698 addr = XEXP (addr, 0);
02441cd6
JL
17699 else if (GET_CODE (XEXP (addr, 1)) == REG
17700 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
17701 addr = XEXP (addr, 1);
17702 else if (CONSTANT_P (XEXP (addr, 0)))
17703 addr = XEXP (addr, 1);
17704 else if (CONSTANT_P (XEXP (addr, 1)))
17705 addr = XEXP (addr, 0);
17706 else
37409796 17707 gcc_unreachable ();
000034eb 17708 }
37409796
NS
17709 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
17710 return addr;
000034eb
DE
17711}
17712
a6c2a102 17713void
a2369ed3 17714rs6000_fatal_bad_address (rtx op)
a6c2a102
DE
17715{
17716 fatal_insn ("bad address", op);
17717}
c8023011 17718
ee890fe2
SS
17719#if TARGET_MACHO
17720
efdba735 17721static tree branch_island_list = 0;
ee890fe2 17722
efdba735
SH
17723/* Remember to generate a branch island for far calls to the given
17724 function. */
ee890fe2 17725
f676971a 17726static void
c4ad648e
AM
17727add_compiler_branch_island (tree label_name, tree function_name,
17728 int line_number)
ee890fe2 17729{
efdba735 17730 tree branch_island = build_tree_list (function_name, label_name);
7d60be94 17731 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
efdba735
SH
17732 TREE_CHAIN (branch_island) = branch_island_list;
17733 branch_island_list = branch_island;
ee890fe2
SS
17734}
17735
efdba735
SH
17736#define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
17737#define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
17738#define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
17739 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
ee890fe2 17740
efdba735
SH
17741/* Generate far-jump branch islands for everything on the
17742 branch_island_list. Invoked immediately after the last instruction
17743 of the epilogue has been emitted; the branch-islands must be
17744 appended to, and contiguous with, the function body. Mach-O stubs
17745 are generated in machopic_output_stub(). */
ee890fe2 17746
efdba735
SH
17747static void
17748macho_branch_islands (void)
17749{
17750 char tmp_buf[512];
17751 tree branch_island;
17752
17753 for (branch_island = branch_island_list;
17754 branch_island;
17755 branch_island = TREE_CHAIN (branch_island))
17756 {
17757 const char *label =
17758 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
17759 const char *name =
11abc112 17760 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
efdba735
SH
17761 char name_buf[512];
17762 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
17763 if (name[0] == '*' || name[0] == '&')
17764 strcpy (name_buf, name+1);
17765 else
17766 {
17767 name_buf[0] = '_';
17768 strcpy (name_buf+1, name);
17769 }
17770 strcpy (tmp_buf, "\n");
17771 strcat (tmp_buf, label);
ee890fe2 17772#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
efdba735 17773 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
93a27b7b 17774 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
ee890fe2 17775#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
efdba735
SH
17776 if (flag_pic)
17777 {
17778 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
17779 strcat (tmp_buf, label);
17780 strcat (tmp_buf, "_pic\n");
17781 strcat (tmp_buf, label);
17782 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
f676971a 17783
efdba735
SH
17784 strcat (tmp_buf, "\taddis r11,r11,ha16(");
17785 strcat (tmp_buf, name_buf);
17786 strcat (tmp_buf, " - ");
17787 strcat (tmp_buf, label);
17788 strcat (tmp_buf, "_pic)\n");
f676971a 17789
efdba735 17790 strcat (tmp_buf, "\tmtlr r0\n");
f676971a 17791
efdba735
SH
17792 strcat (tmp_buf, "\taddi r12,r11,lo16(");
17793 strcat (tmp_buf, name_buf);
17794 strcat (tmp_buf, " - ");
17795 strcat (tmp_buf, label);
17796 strcat (tmp_buf, "_pic)\n");
f676971a 17797
efdba735
SH
17798 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
17799 }
17800 else
17801 {
17802 strcat (tmp_buf, ":\nlis r12,hi16(");
17803 strcat (tmp_buf, name_buf);
17804 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
17805 strcat (tmp_buf, name_buf);
17806 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
17807 }
17808 output_asm_insn (tmp_buf, 0);
ee890fe2 17809#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
efdba735 17810 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
93a27b7b 17811 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
ee890fe2 17812#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
efdba735 17813 }
ee890fe2 17814
efdba735 17815 branch_island_list = 0;
ee890fe2
SS
17816}
17817
17818/* NO_PREVIOUS_DEF checks in the link list whether the function name is
17819 already there or not. */
17820
efdba735 17821static int
a2369ed3 17822no_previous_def (tree function_name)
ee890fe2 17823{
efdba735
SH
17824 tree branch_island;
17825 for (branch_island = branch_island_list;
17826 branch_island;
17827 branch_island = TREE_CHAIN (branch_island))
17828 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
ee890fe2
SS
17829 return 0;
17830 return 1;
17831}
17832
17833/* GET_PREV_LABEL gets the label name from the previous definition of
17834 the function. */
17835
efdba735 17836static tree
a2369ed3 17837get_prev_label (tree function_name)
ee890fe2 17838{
efdba735
SH
17839 tree branch_island;
17840 for (branch_island = branch_island_list;
17841 branch_island;
17842 branch_island = TREE_CHAIN (branch_island))
17843 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
17844 return BRANCH_ISLAND_LABEL_NAME (branch_island);
ee890fe2
SS
17845 return 0;
17846}
17847
17848/* INSN is either a function call or a millicode call. It may have an
f676971a 17849 unconditional jump in its delay slot.
ee890fe2
SS
17850
17851 CALL_DEST is the routine we are calling. */
17852
17853char *
c4ad648e
AM
17854output_call (rtx insn, rtx *operands, int dest_operand_number,
17855 int cookie_operand_number)
ee890fe2
SS
17856{
17857 static char buf[256];
efdba735
SH
17858 if (GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
17859 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
ee890fe2
SS
17860 {
17861 tree labelname;
efdba735 17862 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
f676971a 17863
ee890fe2
SS
17864 if (no_previous_def (funname))
17865 {
308c142a 17866 int line_number = 0;
ee890fe2
SS
17867 rtx label_rtx = gen_label_rtx ();
17868 char *label_buf, temp_buf[256];
17869 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
17870 CODE_LABEL_NUMBER (label_rtx));
17871 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
17872 labelname = get_identifier (label_buf);
17873 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
17874 if (insn)
17875 line_number = NOTE_LINE_NUMBER (insn);
efdba735 17876 add_compiler_branch_island (labelname, funname, line_number);
ee890fe2
SS
17877 }
17878 else
17879 labelname = get_prev_label (funname);
17880
efdba735
SH
17881 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
17882 instruction will reach 'foo', otherwise link as 'bl L42'".
17883 "L42" should be a 'branch island', that will do a far jump to
17884 'foo'. Branch islands are generated in
17885 macho_branch_islands(). */
ee890fe2 17886 sprintf (buf, "jbsr %%z%d,%.246s",
efdba735 17887 dest_operand_number, IDENTIFIER_POINTER (labelname));
ee890fe2
SS
17888 }
17889 else
efdba735
SH
17890 sprintf (buf, "bl %%z%d", dest_operand_number);
17891 return buf;
ee890fe2
SS
17892}
17893
ee890fe2
SS
17894/* Generate PIC and indirect symbol stubs. */
17895
17896void
a2369ed3 17897machopic_output_stub (FILE *file, const char *symb, const char *stub)
ee890fe2
SS
17898{
17899 unsigned int length;
a4f6c312
SS
17900 char *symbol_name, *lazy_ptr_name;
17901 char *local_label_0;
ee890fe2
SS
17902 static int label = 0;
17903
df56a27f 17904 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 17905 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 17906
ee890fe2 17907
ee890fe2
SS
17908 length = strlen (symb);
17909 symbol_name = alloca (length + 32);
17910 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
17911
17912 lazy_ptr_name = alloca (length + 32);
17913 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
17914
ee890fe2 17915 if (flag_pic == 2)
56c779bc 17916 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
ee890fe2 17917 else
56c779bc 17918 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
ee890fe2
SS
17919
17920 if (flag_pic == 2)
17921 {
d974312d
DJ
17922 fprintf (file, "\t.align 5\n");
17923
17924 fprintf (file, "%s:\n", stub);
17925 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17926
876455fa 17927 label++;
89da1f32 17928 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
876455fa 17929 sprintf (local_label_0, "\"L%011d$spb\"", label);
f676971a 17930
ee890fe2
SS
17931 fprintf (file, "\tmflr r0\n");
17932 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
17933 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
17934 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
17935 lazy_ptr_name, local_label_0);
17936 fprintf (file, "\tmtlr r0\n");
3d0e2d58
SS
17937 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
17938 (TARGET_64BIT ? "ldu" : "lwzu"),
ee890fe2
SS
17939 lazy_ptr_name, local_label_0);
17940 fprintf (file, "\tmtctr r12\n");
ee890fe2
SS
17941 fprintf (file, "\tbctr\n");
17942 }
17943 else
d974312d
DJ
17944 {
17945 fprintf (file, "\t.align 4\n");
17946
17947 fprintf (file, "%s:\n", stub);
17948 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
17949
17950 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
d9e4e4f5
SS
17951 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
17952 (TARGET_64BIT ? "ldu" : "lwzu"),
17953 lazy_ptr_name);
d974312d
DJ
17954 fprintf (file, "\tmtctr r12\n");
17955 fprintf (file, "\tbctr\n");
17956 }
f676971a 17957
56c779bc 17958 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
ee890fe2
SS
17959 fprintf (file, "%s:\n", lazy_ptr_name);
17960 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
49bd1d27
SS
17961 fprintf (file, "%sdyld_stub_binding_helper\n",
17962 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
ee890fe2
SS
17963}
17964
17965/* Legitimize PIC addresses. If the address is already
17966 position-independent, we return ORIG. Newly generated
17967 position-independent addresses go into a reg. This is REG if non
17968 zero, otherwise we allocate register(s) as necessary. */
17969
9390387d 17970#define SMALL_INT(X) ((unsigned) (INTVAL (X) + 0x8000) < 0x10000)
ee890fe2
SS
17971
17972rtx
f676971a 17973rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
a2369ed3 17974 rtx reg)
ee890fe2
SS
17975{
17976 rtx base, offset;
17977
17978 if (reg == NULL && ! reload_in_progress && ! reload_completed)
17979 reg = gen_reg_rtx (Pmode);
17980
17981 if (GET_CODE (orig) == CONST)
17982 {
37409796
NS
17983 rtx reg_temp;
17984
ee890fe2
SS
17985 if (GET_CODE (XEXP (orig, 0)) == PLUS
17986 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
17987 return orig;
17988
37409796 17989 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
bb8df8a6 17990
37409796
NS
17991 /* Use a different reg for the intermediate value, as
17992 it will be marked UNCHANGING. */
17993 reg_temp = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
17994 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
17995 Pmode, reg_temp);
17996 offset =
17997 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
17998 Pmode, reg);
bb8df8a6 17999
ee890fe2
SS
18000 if (GET_CODE (offset) == CONST_INT)
18001 {
18002 if (SMALL_INT (offset))
ed8908e7 18003 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
18004 else if (! reload_in_progress && ! reload_completed)
18005 offset = force_reg (Pmode, offset);
18006 else
c859cda6
DJ
18007 {
18008 rtx mem = force_const_mem (Pmode, orig);
18009 return machopic_legitimize_pic_address (mem, Pmode, reg);
18010 }
ee890fe2 18011 }
f1c25d3b 18012 return gen_rtx_PLUS (Pmode, base, offset);
ee890fe2
SS
18013 }
18014
18015 /* Fall back on generic machopic code. */
18016 return machopic_legitimize_pic_address (orig, mode, reg);
18017}
18018
c4e18b1c
GK
18019/* Output a .machine directive for the Darwin assembler, and call
18020 the generic start_file routine. */
18021
18022static void
18023rs6000_darwin_file_start (void)
18024{
94ff898d 18025 static const struct
c4e18b1c
GK
18026 {
18027 const char *arg;
18028 const char *name;
18029 int if_set;
18030 } mapping[] = {
55dbfb48 18031 { "ppc64", "ppc64", MASK_64BIT },
c4e18b1c
GK
18032 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
18033 { "power4", "ppc970", 0 },
18034 { "G5", "ppc970", 0 },
18035 { "7450", "ppc7450", 0 },
18036 { "7400", "ppc7400", MASK_ALTIVEC },
18037 { "G4", "ppc7400", 0 },
18038 { "750", "ppc750", 0 },
18039 { "740", "ppc750", 0 },
18040 { "G3", "ppc750", 0 },
18041 { "604e", "ppc604e", 0 },
18042 { "604", "ppc604", 0 },
18043 { "603e", "ppc603", 0 },
18044 { "603", "ppc603", 0 },
18045 { "601", "ppc601", 0 },
18046 { NULL, "ppc", 0 } };
18047 const char *cpu_id = "";
18048 size_t i;
94ff898d 18049
9390387d 18050 rs6000_file_start ();
192d0f89 18051 darwin_file_start ();
c4e18b1c
GK
18052
18053 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
18054 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
18055 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
18056 && rs6000_select[i].string[0] != '\0')
18057 cpu_id = rs6000_select[i].string;
18058
18059 /* Look through the mapping array. Pick the first name that either
18060 matches the argument, has a bit set in IF_SET that is also set
18061 in the target flags, or has a NULL name. */
18062
18063 i = 0;
18064 while (mapping[i].arg != NULL
18065 && strcmp (mapping[i].arg, cpu_id) != 0
18066 && (mapping[i].if_set & target_flags) == 0)
18067 i++;
18068
18069 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
18070}
18071
ee890fe2 18072#endif /* TARGET_MACHO */
7c262518
RH
18073
18074#if TARGET_ELF
18075static unsigned int
a2369ed3 18076rs6000_elf_section_type_flags (tree decl, const char *name, int reloc)
7c262518 18077{
1ff8f81a
AM
18078 return default_section_type_flags_1 (decl, name, reloc,
18079 flag_pic || DEFAULT_ABI == ABI_AIX);
7c262518 18080}
d9f6800d
RH
18081
18082/* Record an element in the table of global constructors. SYMBOL is
18083 a SYMBOL_REF of the function to be called; PRIORITY is a number
18084 between 0 and MAX_INIT_PRIORITY.
18085
18086 This differs from default_named_section_asm_out_constructor in
18087 that we have special handling for -mrelocatable. */
18088
18089static void
a2369ed3 18090rs6000_elf_asm_out_constructor (rtx symbol, int priority)
d9f6800d
RH
18091{
18092 const char *section = ".ctors";
18093 char buf[16];
18094
18095 if (priority != DEFAULT_INIT_PRIORITY)
18096 {
18097 sprintf (buf, ".ctors.%.5u",
c4ad648e
AM
18098 /* Invert the numbering so the linker puts us in the proper
18099 order; constructors are run from right to left, and the
18100 linker sorts in increasing order. */
18101 MAX_INIT_PRIORITY - priority);
d9f6800d
RH
18102 section = buf;
18103 }
18104
d6b5193b 18105 switch_to_section (get_section (section, SECTION_WRITE, NULL));
715bdd29 18106 assemble_align (POINTER_SIZE);
d9f6800d
RH
18107
18108 if (TARGET_RELOCATABLE)
18109 {
18110 fputs ("\t.long (", asm_out_file);
18111 output_addr_const (asm_out_file, symbol);
18112 fputs (")@fixup\n", asm_out_file);
18113 }
18114 else
c8af3574 18115 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
18116}
18117
18118static void
a2369ed3 18119rs6000_elf_asm_out_destructor (rtx symbol, int priority)
d9f6800d
RH
18120{
18121 const char *section = ".dtors";
18122 char buf[16];
18123
18124 if (priority != DEFAULT_INIT_PRIORITY)
18125 {
18126 sprintf (buf, ".dtors.%.5u",
c4ad648e
AM
18127 /* Invert the numbering so the linker puts us in the proper
18128 order; constructors are run from right to left, and the
18129 linker sorts in increasing order. */
18130 MAX_INIT_PRIORITY - priority);
d9f6800d
RH
18131 section = buf;
18132 }
18133
d6b5193b 18134 switch_to_section (get_section (section, SECTION_WRITE, NULL));
715bdd29 18135 assemble_align (POINTER_SIZE);
d9f6800d
RH
18136
18137 if (TARGET_RELOCATABLE)
18138 {
18139 fputs ("\t.long (", asm_out_file);
18140 output_addr_const (asm_out_file, symbol);
18141 fputs (")@fixup\n", asm_out_file);
18142 }
18143 else
c8af3574 18144 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 18145}
9739c90c
JJ
18146
18147void
a2369ed3 18148rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
9739c90c
JJ
18149{
18150 if (TARGET_64BIT)
18151 {
18152 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
18153 ASM_OUTPUT_LABEL (file, name);
18154 fputs (DOUBLE_INT_ASM_OP, file);
85b776df
AM
18155 rs6000_output_function_entry (file, name);
18156 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
18157 if (DOT_SYMBOLS)
9739c90c 18158 {
85b776df 18159 fputs ("\t.size\t", file);
9739c90c 18160 assemble_name (file, name);
85b776df
AM
18161 fputs (",24\n\t.type\t.", file);
18162 assemble_name (file, name);
18163 fputs (",@function\n", file);
18164 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
18165 {
18166 fputs ("\t.globl\t.", file);
18167 assemble_name (file, name);
18168 putc ('\n', file);
18169 }
9739c90c 18170 }
85b776df
AM
18171 else
18172 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
9739c90c 18173 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
85b776df
AM
18174 rs6000_output_function_entry (file, name);
18175 fputs (":\n", file);
9739c90c
JJ
18176 return;
18177 }
18178
18179 if (TARGET_RELOCATABLE
7f970b70 18180 && !TARGET_SECURE_PLT
9739c90c 18181 && (get_pool_size () != 0 || current_function_profile)
3c9eb5f4 18182 && uses_TOC ())
9739c90c
JJ
18183 {
18184 char buf[256];
18185
18186 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
18187
18188 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
18189 fprintf (file, "\t.long ");
18190 assemble_name (file, buf);
18191 putc ('-', file);
18192 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
18193 assemble_name (file, buf);
18194 putc ('\n', file);
18195 }
18196
18197 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
18198 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
18199
18200 if (DEFAULT_ABI == ABI_AIX)
18201 {
18202 const char *desc_name, *orig_name;
18203
18204 orig_name = (*targetm.strip_name_encoding) (name);
18205 desc_name = orig_name;
18206 while (*desc_name == '.')
18207 desc_name++;
18208
18209 if (TREE_PUBLIC (decl))
18210 fprintf (file, "\t.globl %s\n", desc_name);
18211
18212 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
18213 fprintf (file, "%s:\n", desc_name);
18214 fprintf (file, "\t.long %s\n", orig_name);
18215 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
18216 if (DEFAULT_ABI == ABI_AIX)
18217 fputs ("\t.long 0\n", file);
18218 fprintf (file, "\t.previous\n");
18219 }
18220 ASM_OUTPUT_LABEL (file, name);
18221}
1334b570
AM
18222
18223static void
18224rs6000_elf_end_indicate_exec_stack (void)
18225{
18226 if (TARGET_32BIT)
18227 file_end_indicate_exec_stack ();
18228}
7c262518
RH
18229#endif
18230
cbaaba19 18231#if TARGET_XCOFF
0d5817b2
DE
18232static void
18233rs6000_xcoff_asm_output_anchor (rtx symbol)
18234{
18235 char buffer[100];
18236
18237 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
18238 SYMBOL_REF_BLOCK_OFFSET (symbol));
18239 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
18240}
18241
7c262518 18242static void
a2369ed3 18243rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
b275d088
DE
18244{
18245 fputs (GLOBAL_ASM_OP, stream);
18246 RS6000_OUTPUT_BASENAME (stream, name);
18247 putc ('\n', stream);
18248}
18249
d6b5193b
RS
18250/* A get_unnamed_decl callback, used for read-only sections. PTR
18251 points to the section string variable. */
18252
18253static void
18254rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
18255{
18256 fprintf (asm_out_file, "\t.csect %s[RO],3\n",
18257 *(const char *const *) directive);
18258}
18259
18260/* Likewise for read-write sections. */
18261
18262static void
18263rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
18264{
18265 fprintf (asm_out_file, "\t.csect %s[RW],3\n",
18266 *(const char *const *) directive);
18267}
18268
18269/* A get_unnamed_section callback, used for switching to toc_section. */
18270
18271static void
18272rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
18273{
18274 if (TARGET_MINIMAL_TOC)
18275 {
18276 /* toc_section is always selected at least once from
18277 rs6000_xcoff_file_start, so this is guaranteed to
18278 always be defined once and only once in each file. */
18279 if (!toc_initialized)
18280 {
18281 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
18282 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
18283 toc_initialized = 1;
18284 }
18285 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
18286 (TARGET_32BIT ? "" : ",3"));
18287 }
18288 else
18289 fputs ("\t.toc\n", asm_out_file);
18290}
18291
18292/* Implement TARGET_ASM_INIT_SECTIONS. */
18293
18294static void
18295rs6000_xcoff_asm_init_sections (void)
18296{
18297 read_only_data_section
18298 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
18299 &xcoff_read_only_section_name);
18300
18301 private_data_section
18302 = get_unnamed_section (SECTION_WRITE,
18303 rs6000_xcoff_output_readwrite_section_asm_op,
18304 &xcoff_private_data_section_name);
18305
18306 read_only_private_data_section
18307 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
18308 &xcoff_private_data_section_name);
18309
18310 toc_section
18311 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
18312
18313 readonly_data_section = read_only_data_section;
18314 exception_section = data_section;
18315}
18316
b275d088 18317static void
c18a5b6c
MM
18318rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
18319 tree decl ATTRIBUTE_UNUSED)
7c262518 18320{
0e5dbd9b
DE
18321 int smclass;
18322 static const char * const suffix[3] = { "PR", "RO", "RW" };
18323
18324 if (flags & SECTION_CODE)
18325 smclass = 0;
18326 else if (flags & SECTION_WRITE)
18327 smclass = 2;
18328 else
18329 smclass = 1;
18330
5b5198f7 18331 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 18332 (flags & SECTION_CODE) ? "." : "",
5b5198f7 18333 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 18334}
ae46c4e0 18335
d6b5193b 18336static section *
f676971a 18337rs6000_xcoff_select_section (tree decl, int reloc,
c4ad648e 18338 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
ae46c4e0 18339{
5add3202 18340 if (decl_readonly_section_1 (decl, reloc, 1))
ae46c4e0 18341 {
0e5dbd9b 18342 if (TREE_PUBLIC (decl))
d6b5193b 18343 return read_only_data_section;
ae46c4e0 18344 else
d6b5193b 18345 return read_only_private_data_section;
ae46c4e0
RH
18346 }
18347 else
18348 {
0e5dbd9b 18349 if (TREE_PUBLIC (decl))
d6b5193b 18350 return data_section;
ae46c4e0 18351 else
d6b5193b 18352 return private_data_section;
ae46c4e0
RH
18353 }
18354}
18355
18356static void
a2369ed3 18357rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
ae46c4e0
RH
18358{
18359 const char *name;
ae46c4e0 18360
5b5198f7
DE
18361 /* Use select_section for private and uninitialized data. */
18362 if (!TREE_PUBLIC (decl)
18363 || DECL_COMMON (decl)
0e5dbd9b
DE
18364 || DECL_INITIAL (decl) == NULL_TREE
18365 || DECL_INITIAL (decl) == error_mark_node
18366 || (flag_zero_initialized_in_bss
18367 && initializer_zerop (DECL_INITIAL (decl))))
18368 return;
18369
18370 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
18371 name = (*targetm.strip_name_encoding) (name);
18372 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 18373}
b64a1b53 18374
fb49053f
RH
18375/* Select section for constant in constant pool.
18376
18377 On RS/6000, all constants are in the private read-only data area.
18378 However, if this is being placed in the TOC it must be output as a
18379 toc entry. */
18380
d6b5193b 18381static section *
f676971a 18382rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
c4ad648e 18383 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
b64a1b53
RH
18384{
18385 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
d6b5193b 18386 return toc_section;
b64a1b53 18387 else
d6b5193b 18388 return read_only_private_data_section;
b64a1b53 18389}
772c5265
RH
18390
18391/* Remove any trailing [DS] or the like from the symbol name. */
18392
18393static const char *
a2369ed3 18394rs6000_xcoff_strip_name_encoding (const char *name)
772c5265
RH
18395{
18396 size_t len;
18397 if (*name == '*')
18398 name++;
18399 len = strlen (name);
18400 if (name[len - 1] == ']')
18401 return ggc_alloc_string (name, len - 4);
18402 else
18403 return name;
18404}
18405
5add3202
DE
18406/* Section attributes. AIX is always PIC. */
18407
18408static unsigned int
a2369ed3 18409rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
5add3202 18410{
5b5198f7
DE
18411 unsigned int align;
18412 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
18413
18414 /* Align to at least UNIT size. */
18415 if (flags & SECTION_CODE)
18416 align = MIN_UNITS_PER_WORD;
18417 else
18418 /* Increase alignment of large objects if not already stricter. */
18419 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
18420 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
18421 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
18422
18423 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202 18424}
a5fe455b 18425
1bc7c5b6
ZW
18426/* Output at beginning of assembler file.
18427
18428 Initialize the section names for the RS/6000 at this point.
18429
18430 Specify filename, including full path, to assembler.
18431
18432 We want to go into the TOC section so at least one .toc will be emitted.
18433 Also, in order to output proper .bs/.es pairs, we need at least one static
18434 [RW] section emitted.
18435
18436 Finally, declare mcount when profiling to make the assembler happy. */
18437
18438static void
863d938c 18439rs6000_xcoff_file_start (void)
1bc7c5b6
ZW
18440{
18441 rs6000_gen_section_name (&xcoff_bss_section_name,
18442 main_input_filename, ".bss_");
18443 rs6000_gen_section_name (&xcoff_private_data_section_name,
18444 main_input_filename, ".rw_");
18445 rs6000_gen_section_name (&xcoff_read_only_section_name,
18446 main_input_filename, ".ro_");
18447
18448 fputs ("\t.file\t", asm_out_file);
18449 output_quoted_string (asm_out_file, main_input_filename);
18450 fputc ('\n', asm_out_file);
1bc7c5b6 18451 if (write_symbols != NO_DEBUG)
d6b5193b
RS
18452 switch_to_section (private_data_section);
18453 switch_to_section (text_section);
1bc7c5b6
ZW
18454 if (profile_flag)
18455 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
18456 rs6000_file_start ();
18457}
18458
a5fe455b
ZW
18459/* Output at end of assembler file.
18460 On the RS/6000, referencing data should automatically pull in text. */
18461
18462static void
863d938c 18463rs6000_xcoff_file_end (void)
a5fe455b 18464{
d6b5193b 18465 switch_to_section (text_section);
a5fe455b 18466 fputs ("_section_.text:\n", asm_out_file);
d6b5193b 18467 switch_to_section (data_section);
a5fe455b
ZW
18468 fputs (TARGET_32BIT
18469 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
18470 asm_out_file);
18471}
f1384257 18472#endif /* TARGET_XCOFF */
0e5dbd9b 18473
3c50106f
RH
18474/* Compute a (partial) cost for rtx X. Return true if the complete
18475 cost has been computed, and false if subexpressions should be
18476 scanned. In either case, *TOTAL contains the cost result. */
18477
18478static bool
1494c534 18479rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
3c50106f 18480{
f0517163
RS
18481 enum machine_mode mode = GET_MODE (x);
18482
3c50106f
RH
18483 switch (code)
18484 {
30a555d9 18485 /* On the RS/6000, if it is valid in the insn, it is free. */
3c50106f 18486 case CONST_INT:
066cd967
DE
18487 if (((outer_code == SET
18488 || outer_code == PLUS
18489 || outer_code == MINUS)
18490 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18491 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')))
066cd967
DE
18492 || (outer_code == AND
18493 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
22e54023
DE
18494 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18495 mode == SImode ? 'L' : 'J'))
1990cd79
AM
18496 || mask_operand (x, mode)
18497 || (mode == DImode
18498 && mask64_operand (x, DImode))))
22e54023
DE
18499 || ((outer_code == IOR || outer_code == XOR)
18500 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18501 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18502 mode == SImode ? 'L' : 'J'))))
066cd967
DE
18503 || outer_code == ASHIFT
18504 || outer_code == ASHIFTRT
18505 || outer_code == LSHIFTRT
18506 || outer_code == ROTATE
18507 || outer_code == ROTATERT
d5861a7a 18508 || outer_code == ZERO_EXTRACT
066cd967
DE
18509 || (outer_code == MULT
18510 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
22e54023
DE
18511 || ((outer_code == DIV || outer_code == UDIV
18512 || outer_code == MOD || outer_code == UMOD)
18513 && exact_log2 (INTVAL (x)) >= 0)
066cd967
DE
18514 || (outer_code == COMPARE
18515 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
22e54023
DE
18516 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')))
18517 || (outer_code == EQ
18518 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')
18519 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18520 || (CONST_OK_FOR_LETTER_P (INTVAL (x),
18521 mode == SImode ? 'L' : 'J'))))
18522 || (outer_code == GTU
18523 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I'))
18524 || (outer_code == LTU
18525 && CONST_OK_FOR_LETTER_P (INTVAL (x), 'P')))
066cd967
DE
18526 {
18527 *total = 0;
18528 return true;
18529 }
18530 else if ((outer_code == PLUS
4ae234b0 18531 && reg_or_add_cint_operand (x, VOIDmode))
066cd967 18532 || (outer_code == MINUS
4ae234b0 18533 && reg_or_sub_cint_operand (x, VOIDmode))
066cd967
DE
18534 || ((outer_code == SET
18535 || outer_code == IOR
18536 || outer_code == XOR)
18537 && (INTVAL (x)
18538 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
18539 {
18540 *total = COSTS_N_INSNS (1);
18541 return true;
18542 }
18543 /* FALLTHRU */
18544
18545 case CONST_DOUBLE:
18546 if (mode == DImode
18547 && ((outer_code == AND
18548 && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')
18549 || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L')
1990cd79
AM
18550 || mask_operand (x, DImode)
18551 || mask64_operand (x, DImode)))
066cd967
DE
18552 || ((outer_code == IOR || outer_code == XOR)
18553 && CONST_DOUBLE_HIGH (x) == 0
18554 && (CONST_DOUBLE_LOW (x)
18555 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)))
18556 {
18557 *total = 0;
18558 return true;
18559 }
18560 else if (mode == DImode
18561 && (outer_code == SET
18562 || outer_code == IOR
18563 || outer_code == XOR)
18564 && CONST_DOUBLE_HIGH (x) == 0)
18565 {
18566 *total = COSTS_N_INSNS (1);
18567 return true;
18568 }
18569 /* FALLTHRU */
18570
3c50106f 18571 case CONST:
066cd967 18572 case HIGH:
3c50106f 18573 case SYMBOL_REF:
066cd967
DE
18574 case MEM:
18575 /* When optimizing for size, MEM should be slightly more expensive
18576 than generating address, e.g., (plus (reg) (const)).
c112cf2b 18577 L1 cache latency is about two instructions. */
066cd967 18578 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
3c50106f
RH
18579 return true;
18580
30a555d9
DE
18581 case LABEL_REF:
18582 *total = 0;
18583 return true;
18584
3c50106f 18585 case PLUS:
f0517163 18586 if (mode == DFmode)
066cd967
DE
18587 {
18588 if (GET_CODE (XEXP (x, 0)) == MULT)
18589 {
18590 /* FNMA accounted in outer NEG. */
18591 if (outer_code == NEG)
18592 *total = rs6000_cost->dmul - rs6000_cost->fp;
18593 else
18594 *total = rs6000_cost->dmul;
18595 }
18596 else
18597 *total = rs6000_cost->fp;
18598 }
f0517163 18599 else if (mode == SFmode)
066cd967
DE
18600 {
18601 /* FNMA accounted in outer NEG. */
18602 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
18603 *total = 0;
18604 else
18605 *total = rs6000_cost->fp;
18606 }
f0517163 18607 else
066cd967
DE
18608 *total = COSTS_N_INSNS (1);
18609 return false;
3c50106f 18610
52190329 18611 case MINUS:
f0517163 18612 if (mode == DFmode)
066cd967
DE
18613 {
18614 if (GET_CODE (XEXP (x, 0)) == MULT)
18615 {
18616 /* FNMA accounted in outer NEG. */
18617 if (outer_code == NEG)
18618 *total = 0;
18619 else
18620 *total = rs6000_cost->dmul;
18621 }
18622 else
18623 *total = rs6000_cost->fp;
18624 }
f0517163 18625 else if (mode == SFmode)
066cd967
DE
18626 {
18627 /* FNMA accounted in outer NEG. */
18628 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
18629 *total = 0;
18630 else
18631 *total = rs6000_cost->fp;
18632 }
f0517163 18633 else
c4ad648e 18634 *total = COSTS_N_INSNS (1);
066cd967 18635 return false;
3c50106f
RH
18636
18637 case MULT:
c9dbf840
DE
18638 if (GET_CODE (XEXP (x, 1)) == CONST_INT
18639 && CONST_OK_FOR_LETTER_P (INTVAL (XEXP (x, 1)), 'I'))
3c50106f 18640 {
8b897cfa
RS
18641 if (INTVAL (XEXP (x, 1)) >= -256
18642 && INTVAL (XEXP (x, 1)) <= 255)
06a67bdd 18643 *total = rs6000_cost->mulsi_const9;
8b897cfa 18644 else
06a67bdd 18645 *total = rs6000_cost->mulsi_const;
3c50106f 18646 }
066cd967
DE
18647 /* FMA accounted in outer PLUS/MINUS. */
18648 else if ((mode == DFmode || mode == SFmode)
18649 && (outer_code == PLUS || outer_code == MINUS))
18650 *total = 0;
f0517163 18651 else if (mode == DFmode)
06a67bdd 18652 *total = rs6000_cost->dmul;
f0517163 18653 else if (mode == SFmode)
06a67bdd 18654 *total = rs6000_cost->fp;
f0517163 18655 else if (mode == DImode)
06a67bdd 18656 *total = rs6000_cost->muldi;
8b897cfa 18657 else
06a67bdd 18658 *total = rs6000_cost->mulsi;
066cd967 18659 return false;
3c50106f
RH
18660
18661 case DIV:
18662 case MOD:
f0517163
RS
18663 if (FLOAT_MODE_P (mode))
18664 {
06a67bdd
RS
18665 *total = mode == DFmode ? rs6000_cost->ddiv
18666 : rs6000_cost->sdiv;
066cd967 18667 return false;
f0517163 18668 }
5efb1046 18669 /* FALLTHRU */
3c50106f
RH
18670
18671 case UDIV:
18672 case UMOD:
627b6fe2
DJ
18673 if (GET_CODE (XEXP (x, 1)) == CONST_INT
18674 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
18675 {
18676 if (code == DIV || code == MOD)
18677 /* Shift, addze */
18678 *total = COSTS_N_INSNS (2);
18679 else
18680 /* Shift */
18681 *total = COSTS_N_INSNS (1);
18682 }
c4ad648e 18683 else
627b6fe2
DJ
18684 {
18685 if (GET_MODE (XEXP (x, 1)) == DImode)
18686 *total = rs6000_cost->divdi;
18687 else
18688 *total = rs6000_cost->divsi;
18689 }
18690 /* Add in shift and subtract for MOD. */
18691 if (code == MOD || code == UMOD)
18692 *total += COSTS_N_INSNS (2);
066cd967 18693 return false;
3c50106f
RH
18694
18695 case FFS:
18696 *total = COSTS_N_INSNS (4);
066cd967 18697 return false;
3c50106f 18698
06a67bdd 18699 case NOT:
066cd967
DE
18700 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
18701 {
18702 *total = 0;
18703 return false;
18704 }
18705 /* FALLTHRU */
18706
18707 case AND:
18708 case IOR:
18709 case XOR:
d5861a7a
DE
18710 case ZERO_EXTRACT:
18711 *total = COSTS_N_INSNS (1);
18712 return false;
18713
066cd967
DE
18714 case ASHIFT:
18715 case ASHIFTRT:
18716 case LSHIFTRT:
18717 case ROTATE:
18718 case ROTATERT:
d5861a7a 18719 /* Handle mul_highpart. */
066cd967
DE
18720 if (outer_code == TRUNCATE
18721 && GET_CODE (XEXP (x, 0)) == MULT)
18722 {
18723 if (mode == DImode)
18724 *total = rs6000_cost->muldi;
18725 else
18726 *total = rs6000_cost->mulsi;
18727 return true;
18728 }
d5861a7a
DE
18729 else if (outer_code == AND)
18730 *total = 0;
18731 else
18732 *total = COSTS_N_INSNS (1);
18733 return false;
18734
18735 case SIGN_EXTEND:
18736 case ZERO_EXTEND:
18737 if (GET_CODE (XEXP (x, 0)) == MEM)
18738 *total = 0;
18739 else
18740 *total = COSTS_N_INSNS (1);
066cd967 18741 return false;
06a67bdd 18742
066cd967
DE
18743 case COMPARE:
18744 case NEG:
18745 case ABS:
18746 if (!FLOAT_MODE_P (mode))
18747 {
18748 *total = COSTS_N_INSNS (1);
18749 return false;
18750 }
18751 /* FALLTHRU */
18752
18753 case FLOAT:
18754 case UNSIGNED_FLOAT:
18755 case FIX:
18756 case UNSIGNED_FIX:
06a67bdd
RS
18757 case FLOAT_TRUNCATE:
18758 *total = rs6000_cost->fp;
066cd967 18759 return false;
06a67bdd 18760
a2af5043
DJ
18761 case FLOAT_EXTEND:
18762 if (mode == DFmode)
18763 *total = 0;
18764 else
18765 *total = rs6000_cost->fp;
18766 return false;
18767
06a67bdd
RS
18768 case UNSPEC:
18769 switch (XINT (x, 1))
18770 {
18771 case UNSPEC_FRSP:
18772 *total = rs6000_cost->fp;
18773 return true;
18774
18775 default:
18776 break;
18777 }
18778 break;
18779
18780 case CALL:
18781 case IF_THEN_ELSE:
18782 if (optimize_size)
18783 {
18784 *total = COSTS_N_INSNS (1);
18785 return true;
18786 }
066cd967
DE
18787 else if (FLOAT_MODE_P (mode)
18788 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
18789 {
18790 *total = rs6000_cost->fp;
18791 return false;
18792 }
06a67bdd
RS
18793 break;
18794
c0600ecd
DE
18795 case EQ:
18796 case GTU:
18797 case LTU:
22e54023
DE
18798 /* Carry bit requires mode == Pmode.
18799 NEG or PLUS already counted so only add one. */
18800 if (mode == Pmode
18801 && (outer_code == NEG || outer_code == PLUS))
c0600ecd 18802 {
22e54023
DE
18803 *total = COSTS_N_INSNS (1);
18804 return true;
18805 }
18806 if (outer_code == SET)
18807 {
18808 if (XEXP (x, 1) == const0_rtx)
c0600ecd 18809 {
22e54023 18810 *total = COSTS_N_INSNS (2);
c0600ecd 18811 return true;
c0600ecd 18812 }
22e54023
DE
18813 else if (mode == Pmode)
18814 {
18815 *total = COSTS_N_INSNS (3);
18816 return false;
18817 }
18818 }
18819 /* FALLTHRU */
18820
18821 case GT:
18822 case LT:
18823 case UNORDERED:
18824 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
18825 {
18826 *total = COSTS_N_INSNS (2);
18827 return true;
c0600ecd 18828 }
22e54023
DE
18829 /* CC COMPARE. */
18830 if (outer_code == COMPARE)
18831 {
18832 *total = 0;
18833 return true;
18834 }
18835 break;
c0600ecd 18836
3c50106f 18837 default:
06a67bdd 18838 break;
3c50106f 18839 }
06a67bdd
RS
18840
18841 return false;
3c50106f
RH
18842}
18843
34bb030a
DE
18844/* A C expression returning the cost of moving data from a register of class
18845 CLASS1 to one of CLASS2. */
18846
18847int
f676971a 18848rs6000_register_move_cost (enum machine_mode mode,
a2369ed3 18849 enum reg_class from, enum reg_class to)
34bb030a
DE
18850{
18851 /* Moves from/to GENERAL_REGS. */
18852 if (reg_classes_intersect_p (to, GENERAL_REGS)
18853 || reg_classes_intersect_p (from, GENERAL_REGS))
18854 {
18855 if (! reg_classes_intersect_p (to, GENERAL_REGS))
18856 from = to;
18857
18858 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
18859 return (rs6000_memory_move_cost (mode, from, 0)
18860 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
18861
c4ad648e
AM
18862 /* It's more expensive to move CR_REGS than CR0_REGS because of the
18863 shift. */
34bb030a
DE
18864 else if (from == CR_REGS)
18865 return 4;
18866
18867 else
c4ad648e 18868 /* A move will cost one instruction per GPR moved. */
c8b622ff 18869 return 2 * hard_regno_nregs[0][mode];
34bb030a
DE
18870 }
18871
c4ad648e 18872 /* Moving between two similar registers is just one instruction. */
34bb030a
DE
18873 else if (reg_classes_intersect_p (to, from))
18874 return mode == TFmode ? 4 : 2;
18875
c4ad648e 18876 /* Everything else has to go through GENERAL_REGS. */
34bb030a 18877 else
f676971a 18878 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
34bb030a
DE
18879 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
18880}
18881
18882/* A C expressions returning the cost of moving data of MODE from a register to
18883 or from memory. */
18884
18885int
f676971a 18886rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
a2369ed3 18887 int in ATTRIBUTE_UNUSED)
34bb030a
DE
18888{
18889 if (reg_classes_intersect_p (class, GENERAL_REGS))
c8b622ff 18890 return 4 * hard_regno_nregs[0][mode];
34bb030a 18891 else if (reg_classes_intersect_p (class, FLOAT_REGS))
c8b622ff 18892 return 4 * hard_regno_nregs[32][mode];
34bb030a 18893 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
c8b622ff 18894 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
34bb030a
DE
18895 else
18896 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
18897}
18898
ef765ea9
DE
18899/* Newton-Raphson approximation of single-precision floating point divide n/d.
18900 Assumes no trapping math and finite arguments. */
18901
18902void
18903rs6000_emit_swdivsf (rtx res, rtx n, rtx d)
18904{
18905 rtx x0, e0, e1, y1, u0, v0, one;
18906
18907 x0 = gen_reg_rtx (SFmode);
18908 e0 = gen_reg_rtx (SFmode);
18909 e1 = gen_reg_rtx (SFmode);
18910 y1 = gen_reg_rtx (SFmode);
18911 u0 = gen_reg_rtx (SFmode);
18912 v0 = gen_reg_rtx (SFmode);
18913 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
18914
18915 /* x0 = 1./d estimate */
18916 emit_insn (gen_rtx_SET (VOIDmode, x0,
18917 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
18918 UNSPEC_FRES)));
18919 /* e0 = 1. - d * x0 */
18920 emit_insn (gen_rtx_SET (VOIDmode, e0,
18921 gen_rtx_MINUS (SFmode, one,
18922 gen_rtx_MULT (SFmode, d, x0))));
18923 /* e1 = e0 + e0 * e0 */
18924 emit_insn (gen_rtx_SET (VOIDmode, e1,
18925 gen_rtx_PLUS (SFmode,
18926 gen_rtx_MULT (SFmode, e0, e0), e0)));
18927 /* y1 = x0 + e1 * x0 */
18928 emit_insn (gen_rtx_SET (VOIDmode, y1,
18929 gen_rtx_PLUS (SFmode,
18930 gen_rtx_MULT (SFmode, e1, x0), x0)));
18931 /* u0 = n * y1 */
18932 emit_insn (gen_rtx_SET (VOIDmode, u0,
18933 gen_rtx_MULT (SFmode, n, y1)));
18934 /* v0 = n - d * u0 */
18935 emit_insn (gen_rtx_SET (VOIDmode, v0,
18936 gen_rtx_MINUS (SFmode, n,
18937 gen_rtx_MULT (SFmode, d, u0))));
18938 /* res = u0 + v0 * y1 */
18939 emit_insn (gen_rtx_SET (VOIDmode, res,
18940 gen_rtx_PLUS (SFmode,
18941 gen_rtx_MULT (SFmode, v0, y1), u0)));
18942}
18943
18944/* Newton-Raphson approximation of double-precision floating point divide n/d.
18945 Assumes no trapping math and finite arguments. */
18946
18947void
18948rs6000_emit_swdivdf (rtx res, rtx n, rtx d)
18949{
18950 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
18951
18952 x0 = gen_reg_rtx (DFmode);
18953 e0 = gen_reg_rtx (DFmode);
18954 e1 = gen_reg_rtx (DFmode);
18955 e2 = gen_reg_rtx (DFmode);
18956 y1 = gen_reg_rtx (DFmode);
18957 y2 = gen_reg_rtx (DFmode);
18958 y3 = gen_reg_rtx (DFmode);
18959 u0 = gen_reg_rtx (DFmode);
18960 v0 = gen_reg_rtx (DFmode);
18961 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
18962
18963 /* x0 = 1./d estimate */
18964 emit_insn (gen_rtx_SET (VOIDmode, x0,
18965 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
18966 UNSPEC_FRES)));
18967 /* e0 = 1. - d * x0 */
18968 emit_insn (gen_rtx_SET (VOIDmode, e0,
18969 gen_rtx_MINUS (DFmode, one,
18970 gen_rtx_MULT (SFmode, d, x0))));
18971 /* y1 = x0 + e0 * x0 */
18972 emit_insn (gen_rtx_SET (VOIDmode, y1,
18973 gen_rtx_PLUS (DFmode,
18974 gen_rtx_MULT (DFmode, e0, x0), x0)));
18975 /* e1 = e0 * e0 */
18976 emit_insn (gen_rtx_SET (VOIDmode, e1,
18977 gen_rtx_MULT (DFmode, e0, e0)));
18978 /* y2 = y1 + e1 * y1 */
18979 emit_insn (gen_rtx_SET (VOIDmode, y2,
18980 gen_rtx_PLUS (DFmode,
18981 gen_rtx_MULT (DFmode, e1, y1), y1)));
18982 /* e2 = e1 * e1 */
18983 emit_insn (gen_rtx_SET (VOIDmode, e2,
18984 gen_rtx_MULT (DFmode, e1, e1)));
18985 /* y3 = y2 + e2 * y2 */
18986 emit_insn (gen_rtx_SET (VOIDmode, y3,
18987 gen_rtx_PLUS (DFmode,
18988 gen_rtx_MULT (DFmode, e2, y2), y2)));
18989 /* u0 = n * y3 */
18990 emit_insn (gen_rtx_SET (VOIDmode, u0,
18991 gen_rtx_MULT (DFmode, n, y3)));
18992 /* v0 = n - d * u0 */
18993 emit_insn (gen_rtx_SET (VOIDmode, v0,
18994 gen_rtx_MINUS (DFmode, n,
18995 gen_rtx_MULT (DFmode, d, u0))));
18996 /* res = u0 + v0 * y3 */
18997 emit_insn (gen_rtx_SET (VOIDmode, res,
18998 gen_rtx_PLUS (DFmode,
18999 gen_rtx_MULT (DFmode, v0, y3), u0)));
19000}
19001
ded9bf77
AH
19002/* Return an RTX representing where to find the function value of a
19003 function returning MODE. */
19004static rtx
19005rs6000_complex_function_value (enum machine_mode mode)
19006{
19007 unsigned int regno;
19008 rtx r1, r2;
19009 enum machine_mode inner = GET_MODE_INNER (mode);
fb7e4164 19010 unsigned int inner_bytes = GET_MODE_SIZE (inner);
ded9bf77 19011
18f63bfa
AH
19012 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
19013 regno = FP_ARG_RETURN;
354ed18f
AH
19014 else
19015 {
18f63bfa 19016 regno = GP_ARG_RETURN;
ded9bf77 19017
18f63bfa
AH
19018 /* 32-bit is OK since it'll go in r3/r4. */
19019 if (TARGET_32BIT && inner_bytes >= 4)
ded9bf77
AH
19020 return gen_rtx_REG (mode, regno);
19021 }
19022
18f63bfa
AH
19023 if (inner_bytes >= 8)
19024 return gen_rtx_REG (mode, regno);
19025
ded9bf77
AH
19026 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
19027 const0_rtx);
19028 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
fb7e4164 19029 GEN_INT (inner_bytes));
ded9bf77
AH
19030 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
19031}
19032
a6ebc39a
AH
19033/* Define how to find the value returned by a function.
19034 VALTYPE is the data type of the value (as a tree).
19035 If the precise function being called is known, FUNC is its FUNCTION_DECL;
19036 otherwise, FUNC is 0.
19037
19038 On the SPE, both FPs and vectors are returned in r3.
19039
19040 On RS/6000 an integer value is in r3 and a floating-point value is in
19041 fp1, unless -msoft-float. */
19042
19043rtx
19044rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
19045{
19046 enum machine_mode mode;
2a8fa26c 19047 unsigned int regno;
a6ebc39a 19048
594a51fe
SS
19049 /* Special handling for structs in darwin64. */
19050 if (rs6000_darwin64_abi
19051 && TYPE_MODE (valtype) == BLKmode
0b5383eb
DJ
19052 && TREE_CODE (valtype) == RECORD_TYPE
19053 && int_size_in_bytes (valtype) > 0)
594a51fe
SS
19054 {
19055 CUMULATIVE_ARGS valcum;
19056 rtx valret;
19057
0b5383eb 19058 valcum.words = 0;
594a51fe
SS
19059 valcum.fregno = FP_ARG_MIN_REG;
19060 valcum.vregno = ALTIVEC_ARG_MIN_REG;
0b5383eb
DJ
19061 /* Do a trial code generation as if this were going to be passed as
19062 an argument; if any part goes in memory, we return NULL. */
19063 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
594a51fe
SS
19064 if (valret)
19065 return valret;
19066 /* Otherwise fall through to standard ABI rules. */
19067 }
19068
0e67400a
FJ
19069 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
19070 {
19071 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
19072 return gen_rtx_PARALLEL (DImode,
19073 gen_rtvec (2,
19074 gen_rtx_EXPR_LIST (VOIDmode,
19075 gen_rtx_REG (SImode, GP_ARG_RETURN),
19076 const0_rtx),
19077 gen_rtx_EXPR_LIST (VOIDmode,
19078 gen_rtx_REG (SImode,
19079 GP_ARG_RETURN + 1),
19080 GEN_INT (4))));
19081 }
0f086e42
FJ
19082 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
19083 {
19084 return gen_rtx_PARALLEL (DCmode,
19085 gen_rtvec (4,
19086 gen_rtx_EXPR_LIST (VOIDmode,
19087 gen_rtx_REG (SImode, GP_ARG_RETURN),
19088 const0_rtx),
19089 gen_rtx_EXPR_LIST (VOIDmode,
19090 gen_rtx_REG (SImode,
19091 GP_ARG_RETURN + 1),
19092 GEN_INT (4)),
19093 gen_rtx_EXPR_LIST (VOIDmode,
19094 gen_rtx_REG (SImode,
19095 GP_ARG_RETURN + 2),
19096 GEN_INT (8)),
19097 gen_rtx_EXPR_LIST (VOIDmode,
19098 gen_rtx_REG (SImode,
19099 GP_ARG_RETURN + 3),
19100 GEN_INT (12))));
19101 }
602ea4d3 19102
a6ebc39a
AH
19103 if ((INTEGRAL_TYPE_P (valtype)
19104 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
19105 || POINTER_TYPE_P (valtype))
b78d48dd 19106 mode = TARGET_32BIT ? SImode : DImode;
a6ebc39a
AH
19107 else
19108 mode = TYPE_MODE (valtype);
19109
00b79d54
BE
19110 if (DECIMAL_FLOAT_MODE_P (mode))
19111 regno = GP_ARG_RETURN;
19112 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
2a8fa26c 19113 regno = FP_ARG_RETURN;
ded9bf77 19114 else if (TREE_CODE (valtype) == COMPLEX_TYPE
42ba5130 19115 && targetm.calls.split_complex_arg)
ded9bf77 19116 return rs6000_complex_function_value (mode);
44688022 19117 else if (TREE_CODE (valtype) == VECTOR_TYPE
d0b2079e 19118 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
23ba09f0 19119 && ALTIVEC_VECTOR_MODE (mode))
a6ebc39a 19120 regno = ALTIVEC_ARG_RETURN;
18f63bfa
AH
19121 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
19122 && (mode == DFmode || mode == DCmode))
19123 return spe_build_register_parallel (mode, GP_ARG_RETURN);
a6ebc39a
AH
19124 else
19125 regno = GP_ARG_RETURN;
19126
19127 return gen_rtx_REG (mode, regno);
19128}
19129
ded9bf77
AH
19130/* Define how to find the value returned by a library function
19131 assuming the value has mode MODE. */
19132rtx
19133rs6000_libcall_value (enum machine_mode mode)
19134{
19135 unsigned int regno;
19136
2e6c9641
FJ
19137 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
19138 {
19139 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
19140 return gen_rtx_PARALLEL (DImode,
19141 gen_rtvec (2,
19142 gen_rtx_EXPR_LIST (VOIDmode,
19143 gen_rtx_REG (SImode, GP_ARG_RETURN),
19144 const0_rtx),
19145 gen_rtx_EXPR_LIST (VOIDmode,
19146 gen_rtx_REG (SImode,
19147 GP_ARG_RETURN + 1),
19148 GEN_INT (4))));
19149 }
19150
00b79d54
BE
19151 if (DECIMAL_FLOAT_MODE_P (mode))
19152 regno = GP_ARG_RETURN;
19153 else if (SCALAR_FLOAT_MODE_P (mode)
ded9bf77
AH
19154 && TARGET_HARD_FLOAT && TARGET_FPRS)
19155 regno = FP_ARG_RETURN;
44688022
AM
19156 else if (ALTIVEC_VECTOR_MODE (mode)
19157 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
ded9bf77 19158 regno = ALTIVEC_ARG_RETURN;
42ba5130 19159 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
ded9bf77 19160 return rs6000_complex_function_value (mode);
18f63bfa
AH
19161 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
19162 && (mode == DFmode || mode == DCmode))
19163 return spe_build_register_parallel (mode, GP_ARG_RETURN);
ded9bf77
AH
19164 else
19165 regno = GP_ARG_RETURN;
19166
19167 return gen_rtx_REG (mode, regno);
19168}
19169
d1d0c603
JJ
19170/* Define the offset between two registers, FROM to be eliminated and its
19171 replacement TO, at the start of a routine. */
19172HOST_WIDE_INT
19173rs6000_initial_elimination_offset (int from, int to)
19174{
19175 rs6000_stack_t *info = rs6000_stack_info ();
19176 HOST_WIDE_INT offset;
19177
7d5175e1 19178 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
d1d0c603 19179 offset = info->push_p ? 0 : -info->total_size;
7d5175e1
JJ
19180 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
19181 {
19182 offset = info->push_p ? 0 : -info->total_size;
19183 if (FRAME_GROWS_DOWNWARD)
5b667039 19184 offset += info->fixed_size + info->vars_size + info->parm_size;
7d5175e1
JJ
19185 }
19186 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
19187 offset = FRAME_GROWS_DOWNWARD
5b667039 19188 ? info->fixed_size + info->vars_size + info->parm_size
7d5175e1
JJ
19189 : 0;
19190 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
d1d0c603
JJ
19191 offset = info->total_size;
19192 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
19193 offset = info->push_p ? info->total_size : 0;
19194 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
19195 offset = 0;
19196 else
37409796 19197 gcc_unreachable ();
d1d0c603
JJ
19198
19199 return offset;
19200}
19201
58646b77 19202/* Return true if TYPE is a SPE or AltiVec opaque type. */
62e1dfcf 19203
c8e4f0e9 19204static bool
58646b77 19205rs6000_is_opaque_type (tree type)
62e1dfcf 19206{
58646b77 19207 return (type == opaque_V2SI_type_node
2abe3e28 19208 || type == opaque_V2SF_type_node
58646b77
PB
19209 || type == opaque_p_V2SI_type_node
19210 || type == opaque_V4SI_type_node);
62e1dfcf
NC
19211}
19212
96714395 19213static rtx
a2369ed3 19214rs6000_dwarf_register_span (rtx reg)
96714395
AH
19215{
19216 unsigned regno;
19217
4d4cbc0e
AH
19218 if (TARGET_SPE
19219 && (SPE_VECTOR_MODE (GET_MODE (reg))
19220 || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
19221 ;
19222 else
96714395
AH
19223 return NULL_RTX;
19224
19225 regno = REGNO (reg);
19226
19227 /* The duality of the SPE register size wreaks all kinds of havoc.
19228 This is a way of distinguishing r0 in 32-bits from r0 in
19229 64-bits. */
19230 return
19231 gen_rtx_PARALLEL (VOIDmode,
3bd104d1
AH
19232 BYTES_BIG_ENDIAN
19233 ? gen_rtvec (2,
19234 gen_rtx_REG (SImode, regno + 1200),
19235 gen_rtx_REG (SImode, regno))
19236 : gen_rtvec (2,
19237 gen_rtx_REG (SImode, regno),
19238 gen_rtx_REG (SImode, regno + 1200)));
96714395
AH
19239}
19240
93c9d1ba
AM
19241/* Map internal gcc register numbers to DWARF2 register numbers. */
19242
19243unsigned int
19244rs6000_dbx_register_number (unsigned int regno)
19245{
19246 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
19247 return regno;
19248 if (regno == MQ_REGNO)
19249 return 100;
19250 if (regno == LINK_REGISTER_REGNUM)
19251 return 108;
19252 if (regno == COUNT_REGISTER_REGNUM)
19253 return 109;
19254 if (CR_REGNO_P (regno))
19255 return regno - CR0_REGNO + 86;
19256 if (regno == XER_REGNO)
19257 return 101;
19258 if (ALTIVEC_REGNO_P (regno))
19259 return regno - FIRST_ALTIVEC_REGNO + 1124;
19260 if (regno == VRSAVE_REGNO)
19261 return 356;
19262 if (regno == VSCR_REGNO)
19263 return 67;
19264 if (regno == SPE_ACC_REGNO)
19265 return 99;
19266 if (regno == SPEFSCR_REGNO)
19267 return 612;
19268 /* SPE high reg number. We get these values of regno from
19269 rs6000_dwarf_register_span. */
37409796
NS
19270 gcc_assert (regno >= 1200 && regno < 1232);
19271 return regno;
93c9d1ba
AM
19272}
19273
93f90be6 19274/* target hook eh_return_filter_mode */
f676971a 19275static enum machine_mode
93f90be6
FJ
19276rs6000_eh_return_filter_mode (void)
19277{
19278 return TARGET_32BIT ? SImode : word_mode;
19279}
19280
00b79d54
BE
19281/* Target hook for scalar_mode_supported_p. */
19282static bool
19283rs6000_scalar_mode_supported_p (enum machine_mode mode)
19284{
19285 if (DECIMAL_FLOAT_MODE_P (mode))
19286 return true;
19287 else
19288 return default_scalar_mode_supported_p (mode);
19289}
19290
f676971a
EC
19291/* Target hook for vector_mode_supported_p. */
19292static bool
19293rs6000_vector_mode_supported_p (enum machine_mode mode)
19294{
19295
19296 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
19297 return true;
19298
19299 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
19300 return true;
19301
19302 else
19303 return false;
19304}
19305
bb8df8a6
EC
19306/* Target hook for invalid_arg_for_unprototyped_fn. */
19307static const char *
4d3e6fae
FJ
19308invalid_arg_for_unprototyped_fn (tree typelist, tree funcdecl, tree val)
19309{
19310 return (!rs6000_darwin64_abi
19311 && typelist == 0
19312 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
19313 && (funcdecl == NULL_TREE
19314 || (TREE_CODE (funcdecl) == FUNCTION_DECL
19315 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
19316 ? N_("AltiVec argument passed to unprototyped function")
19317 : NULL;
19318}
19319
3aebbe5f
JJ
19320/* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
19321 setup by using __stack_chk_fail_local hidden function instead of
19322 calling __stack_chk_fail directly. Otherwise it is better to call
19323 __stack_chk_fail directly. */
19324
19325static tree
19326rs6000_stack_protect_fail (void)
19327{
19328 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
19329 ? default_hidden_stack_protect_fail ()
19330 : default_external_stack_protect_fail ();
19331}
19332
17211ab5 19333#include "gt-rs6000.h"