]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
re PR fortran/33566 (fortran : wrong rank of derived type parameters array components)
[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,
8ef65e3d 3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
337bde91 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
2f83c7d6 11 by the Free Software Foundation; either version 3, or (at your
5de601cf 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 19 You should have received a copy of the GNU General Public License
2f83c7d6
NC
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
9878760c 22
956d6950 23#include "config.h"
c4d38ccb 24#include "system.h"
4977bab6
ZW
25#include "coretypes.h"
26#include "tm.h"
9878760c
RK
27#include "rtl.h"
28#include "regs.h"
29#include "hard-reg-set.h"
30#include "real.h"
31#include "insn-config.h"
32#include "conditions.h"
9878760c
RK
33#include "insn-attr.h"
34#include "flags.h"
35#include "recog.h"
9878760c 36#include "obstack.h"
9b30bae2 37#include "tree.h"
dfafc897 38#include "expr.h"
2fc1c679 39#include "optabs.h"
2a430ec1 40#include "except.h"
a7df97e6 41#include "function.h"
296b8152 42#include "output.h"
d5fa86ba 43#include "basic-block.h"
d0101753 44#include "integrate.h"
296b8152 45#include "toplev.h"
c8023011 46#include "ggc.h"
9ebbca7d
GK
47#include "hashtab.h"
48#include "tm_p.h"
672a6f42
NB
49#include "target.h"
50#include "target-def.h"
3ac88239 51#include "langhooks.h"
24ea750e 52#include "reload.h"
117dca74 53#include "cfglayout.h"
79ae11c4 54#include "sched-int.h"
cd3ce9b4 55#include "tree-gimple.h"
4d3e6fae 56#include "intl.h"
59d6560b 57#include "params.h"
279bb624 58#include "tm-constrs.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
d296e02e
AP
141static GTY(()) bool rs6000_cell_dont_microcode;
142
ec507f2d
DE
143/* Always emit branch hint bits. */
144static GTY(()) bool rs6000_always_hint;
145
146/* Schedule instructions for group formation. */
147static GTY(()) bool rs6000_sched_groups;
148
44cd321e
PS
149/* Align branch targets. */
150static GTY(()) bool rs6000_align_branch_targets;
151
569fa502
DN
152/* Support for -msched-costly-dep option. */
153const char *rs6000_sched_costly_dep_str;
154enum rs6000_dependence_cost rs6000_sched_costly_dep;
155
cbe26ab8
DN
156/* Support for -minsert-sched-nops option. */
157const char *rs6000_sched_insert_nops_str;
158enum rs6000_nop_insertion rs6000_sched_insert_nops;
159
7ccf35ed 160/* Support targetm.vectorize.builtin_mask_for_load. */
13c62176 161static GTY(()) tree altivec_builtin_mask_for_load;
7ccf35ed 162
602ea4d3 163/* Size of long double. */
6fa3f289
ZW
164int rs6000_long_double_type_size;
165
602ea4d3
JJ
166/* IEEE quad extended precision long double. */
167int rs6000_ieeequad;
168
169/* Whether -mabi=altivec has appeared. */
6fa3f289
ZW
170int rs6000_altivec_abi;
171
a3170dc6
AH
172/* Nonzero if we want SPE ABI extensions. */
173int rs6000_spe_abi;
174
5da702b1
AH
175/* Nonzero if floating point operations are done in the GPRs. */
176int rs6000_float_gprs = 0;
177
594a51fe
SS
178/* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
179int rs6000_darwin64_abi;
180
a0ab749a 181/* Set to nonzero once AIX common-mode calls have been defined. */
bbfb86aa 182static GTY(()) int common_mode_defined;
c81bebd7 183
9878760c
RK
184/* Save information from a "cmpxx" operation until the branch or scc is
185 emitted. */
9878760c
RK
186rtx rs6000_compare_op0, rs6000_compare_op1;
187int rs6000_compare_fp_p;
874a0744 188
874a0744
MM
189/* Label number of label created for -mrelocatable, to call to so we can
190 get the address of the GOT section */
191int rs6000_pic_labelno;
c81bebd7 192
b91da81f 193#ifdef USING_ELFOS_H
c81bebd7 194/* Which abi to adhere to */
9739c90c 195const char *rs6000_abi_name;
d9407988
MM
196
197/* Semantics of the small data area */
198enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
199
200/* Which small data model to use */
815cdc52 201const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
202
203/* Counter for labels which are to be placed in .fixup. */
204int fixuplabelno = 0;
874a0744 205#endif
4697a36c 206
c4501e62
JJ
207/* Bit size of immediate TLS offsets and string from which it is decoded. */
208int rs6000_tls_size = 32;
209const char *rs6000_tls_size_string;
210
b6c9286a
MM
211/* ABI enumeration available for subtarget to use. */
212enum rs6000_abi rs6000_current_abi;
213
85b776df
AM
214/* Whether to use variant of AIX ABI for PowerPC64 Linux. */
215int dot_symbols;
216
38c1f2d7 217/* Debug flags */
815cdc52 218const char *rs6000_debug_name;
38c1f2d7
MM
219int rs6000_debug_stack; /* debug stack applications */
220int rs6000_debug_arg; /* debug argument handling */
221
aabcd309 222/* Value is TRUE if register/mode pair is acceptable. */
0d1fbc8c
AH
223bool rs6000_hard_regno_mode_ok_p[NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
224
58646b77
PB
225/* Built in types. */
226
227tree rs6000_builtin_types[RS6000_BTI_MAX];
228tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT];
8bb418a3 229
57ac7be9
AM
230const char *rs6000_traceback_name;
231static enum {
232 traceback_default = 0,
233 traceback_none,
234 traceback_part,
235 traceback_full
236} rs6000_traceback;
237
38c1f2d7
MM
238/* Flag to say the TOC is initialized */
239int toc_initialized;
9ebbca7d 240char toc_label_name[10];
38c1f2d7 241
44cd321e
PS
242/* Cached value of rs6000_variable_issue. This is cached in
243 rs6000_variable_issue hook and returned from rs6000_sched_reorder2. */
244static short cached_can_issue_more;
245
d6b5193b
RS
246static GTY(()) section *read_only_data_section;
247static GTY(()) section *private_data_section;
248static GTY(()) section *read_only_private_data_section;
249static GTY(()) section *sdata2_section;
250static GTY(()) section *toc_section;
251
a3c9585f
KH
252/* Control alignment for fields within structures. */
253/* String from -malign-XXXXX. */
025d9908
KH
254int rs6000_alignment_flags;
255
78f5898b
AH
256/* True for any options that were explicitly set. */
257struct {
df01da37 258 bool aix_struct_ret; /* True if -maix-struct-ret was used. */
78f5898b 259 bool alignment; /* True if -malign- was used. */
d3603e8c 260 bool abi; /* True if -mabi=spe/nospe was used. */
78f5898b
AH
261 bool spe; /* True if -mspe= was used. */
262 bool float_gprs; /* True if -mfloat-gprs= was used. */
263 bool isel; /* True if -misel was used. */
264 bool long_double; /* True if -mlong-double- was used. */
d3603e8c 265 bool ieee; /* True if -mabi=ieee/ibmlongdouble used. */
78f5898b
AH
266} rs6000_explicit_options;
267
a3170dc6
AH
268struct builtin_description
269{
270 /* mask is not const because we're going to alter it below. This
271 nonsense will go away when we rewrite the -march infrastructure
272 to give us more target flag bits. */
273 unsigned int mask;
274 const enum insn_code icode;
275 const char *const name;
276 const enum rs6000_builtins code;
277};
8b897cfa
RS
278\f
279/* Target cpu costs. */
280
281struct processor_costs {
c4ad648e 282 const int mulsi; /* cost of SImode multiplication. */
8b897cfa
RS
283 const int mulsi_const; /* cost of SImode multiplication by constant. */
284 const int mulsi_const9; /* cost of SImode mult by short constant. */
c4ad648e
AM
285 const int muldi; /* cost of DImode multiplication. */
286 const int divsi; /* cost of SImode division. */
287 const int divdi; /* cost of DImode division. */
288 const int fp; /* cost of simple SFmode and DFmode insns. */
289 const int dmul; /* cost of DFmode multiplication (and fmadd). */
290 const int sdiv; /* cost of SFmode division (fdivs). */
291 const int ddiv; /* cost of DFmode division (fdiv). */
5f732aba
DE
292 const int cache_line_size; /* cache line size in bytes. */
293 const int l1_cache_size; /* size of l1 cache, in kilobytes. */
294 const int l2_cache_size; /* size of l2 cache, in kilobytes. */
0b11da67
DE
295 const int simultaneous_prefetches; /* number of parallel prefetch
296 operations. */
8b897cfa
RS
297};
298
299const struct processor_costs *rs6000_cost;
300
301/* Processor costs (relative to an add) */
302
303/* Instruction size costs on 32bit processors. */
304static const
305struct processor_costs size32_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 */
0b11da67
DE
316 32,
317 0,
318 0,
5f732aba 319 0,
8b897cfa
RS
320};
321
322/* Instruction size costs on 64bit processors. */
323static const
324struct processor_costs size64_cost = {
06a67bdd
RS
325 COSTS_N_INSNS (1), /* mulsi */
326 COSTS_N_INSNS (1), /* mulsi_const */
327 COSTS_N_INSNS (1), /* mulsi_const9 */
328 COSTS_N_INSNS (1), /* muldi */
329 COSTS_N_INSNS (1), /* divsi */
330 COSTS_N_INSNS (1), /* divdi */
331 COSTS_N_INSNS (1), /* fp */
332 COSTS_N_INSNS (1), /* dmul */
333 COSTS_N_INSNS (1), /* sdiv */
334 COSTS_N_INSNS (1), /* ddiv */
0b11da67
DE
335 128,
336 0,
337 0,
5f732aba 338 0,
8b897cfa
RS
339};
340
341/* Instruction costs on RIOS1 processors. */
342static const
343struct processor_costs rios1_cost = {
06a67bdd
RS
344 COSTS_N_INSNS (5), /* mulsi */
345 COSTS_N_INSNS (4), /* mulsi_const */
346 COSTS_N_INSNS (3), /* mulsi_const9 */
347 COSTS_N_INSNS (5), /* muldi */
348 COSTS_N_INSNS (19), /* divsi */
349 COSTS_N_INSNS (19), /* divdi */
350 COSTS_N_INSNS (2), /* fp */
351 COSTS_N_INSNS (2), /* dmul */
352 COSTS_N_INSNS (19), /* sdiv */
353 COSTS_N_INSNS (19), /* ddiv */
5f732aba
DE
354 128,
355 64, /* l1 cache */
356 512, /* l2 cache */
0b11da67 357 0, /* streams */
8b897cfa
RS
358};
359
360/* Instruction costs on RIOS2 processors. */
361static const
362struct processor_costs rios2_cost = {
06a67bdd
RS
363 COSTS_N_INSNS (2), /* mulsi */
364 COSTS_N_INSNS (2), /* mulsi_const */
365 COSTS_N_INSNS (2), /* mulsi_const9 */
366 COSTS_N_INSNS (2), /* muldi */
367 COSTS_N_INSNS (13), /* divsi */
368 COSTS_N_INSNS (13), /* divdi */
369 COSTS_N_INSNS (2), /* fp */
370 COSTS_N_INSNS (2), /* dmul */
371 COSTS_N_INSNS (17), /* sdiv */
372 COSTS_N_INSNS (17), /* ddiv */
5f732aba
DE
373 256,
374 256, /* l1 cache */
375 1024, /* l2 cache */
0b11da67 376 0, /* streams */
8b897cfa
RS
377};
378
379/* Instruction costs on RS64A processors. */
380static const
381struct processor_costs rs64a_cost = {
06a67bdd
RS
382 COSTS_N_INSNS (20), /* mulsi */
383 COSTS_N_INSNS (12), /* mulsi_const */
384 COSTS_N_INSNS (8), /* mulsi_const9 */
385 COSTS_N_INSNS (34), /* muldi */
386 COSTS_N_INSNS (65), /* divsi */
387 COSTS_N_INSNS (67), /* divdi */
388 COSTS_N_INSNS (4), /* fp */
389 COSTS_N_INSNS (4), /* dmul */
390 COSTS_N_INSNS (31), /* sdiv */
391 COSTS_N_INSNS (31), /* ddiv */
0b11da67 392 128,
5f732aba
DE
393 128, /* l1 cache */
394 2048, /* l2 cache */
0b11da67 395 1, /* streams */
8b897cfa
RS
396};
397
398/* Instruction costs on MPCCORE processors. */
399static const
400struct processor_costs mpccore_cost = {
06a67bdd
RS
401 COSTS_N_INSNS (2), /* mulsi */
402 COSTS_N_INSNS (2), /* mulsi_const */
403 COSTS_N_INSNS (2), /* mulsi_const9 */
404 COSTS_N_INSNS (2), /* muldi */
405 COSTS_N_INSNS (6), /* divsi */
406 COSTS_N_INSNS (6), /* divdi */
407 COSTS_N_INSNS (4), /* fp */
408 COSTS_N_INSNS (5), /* dmul */
409 COSTS_N_INSNS (10), /* sdiv */
410 COSTS_N_INSNS (17), /* ddiv */
5f732aba
DE
411 32,
412 4, /* l1 cache */
413 16, /* l2 cache */
0b11da67 414 1, /* streams */
8b897cfa
RS
415};
416
417/* Instruction costs on PPC403 processors. */
418static const
419struct processor_costs ppc403_cost = {
06a67bdd
RS
420 COSTS_N_INSNS (4), /* mulsi */
421 COSTS_N_INSNS (4), /* mulsi_const */
422 COSTS_N_INSNS (4), /* mulsi_const9 */
423 COSTS_N_INSNS (4), /* muldi */
424 COSTS_N_INSNS (33), /* divsi */
425 COSTS_N_INSNS (33), /* divdi */
426 COSTS_N_INSNS (11), /* fp */
427 COSTS_N_INSNS (11), /* dmul */
428 COSTS_N_INSNS (11), /* sdiv */
429 COSTS_N_INSNS (11), /* ddiv */
0b11da67 430 32,
5f732aba
DE
431 4, /* l1 cache */
432 16, /* l2 cache */
0b11da67 433 1, /* streams */
8b897cfa
RS
434};
435
436/* Instruction costs on PPC405 processors. */
437static const
438struct processor_costs ppc405_cost = {
06a67bdd
RS
439 COSTS_N_INSNS (5), /* mulsi */
440 COSTS_N_INSNS (4), /* mulsi_const */
441 COSTS_N_INSNS (3), /* mulsi_const9 */
442 COSTS_N_INSNS (5), /* muldi */
443 COSTS_N_INSNS (35), /* divsi */
444 COSTS_N_INSNS (35), /* divdi */
445 COSTS_N_INSNS (11), /* fp */
446 COSTS_N_INSNS (11), /* dmul */
447 COSTS_N_INSNS (11), /* sdiv */
448 COSTS_N_INSNS (11), /* ddiv */
0b11da67 449 32,
5f732aba
DE
450 16, /* l1 cache */
451 128, /* l2 cache */
0b11da67 452 1, /* streams */
8b897cfa
RS
453};
454
455/* Instruction costs on PPC440 processors. */
456static const
457struct processor_costs ppc440_cost = {
06a67bdd
RS
458 COSTS_N_INSNS (3), /* mulsi */
459 COSTS_N_INSNS (2), /* mulsi_const */
460 COSTS_N_INSNS (2), /* mulsi_const9 */
461 COSTS_N_INSNS (3), /* muldi */
462 COSTS_N_INSNS (34), /* divsi */
463 COSTS_N_INSNS (34), /* divdi */
464 COSTS_N_INSNS (5), /* fp */
465 COSTS_N_INSNS (5), /* dmul */
466 COSTS_N_INSNS (19), /* sdiv */
467 COSTS_N_INSNS (33), /* ddiv */
0b11da67 468 32,
5f732aba
DE
469 32, /* l1 cache */
470 256, /* l2 cache */
0b11da67 471 1, /* streams */
8b897cfa
RS
472};
473
474/* Instruction costs on PPC601 processors. */
475static const
476struct processor_costs ppc601_cost = {
06a67bdd
RS
477 COSTS_N_INSNS (5), /* mulsi */
478 COSTS_N_INSNS (5), /* mulsi_const */
479 COSTS_N_INSNS (5), /* mulsi_const9 */
480 COSTS_N_INSNS (5), /* muldi */
481 COSTS_N_INSNS (36), /* divsi */
482 COSTS_N_INSNS (36), /* divdi */
483 COSTS_N_INSNS (4), /* fp */
484 COSTS_N_INSNS (5), /* dmul */
485 COSTS_N_INSNS (17), /* sdiv */
486 COSTS_N_INSNS (31), /* ddiv */
0b11da67 487 32,
5f732aba
DE
488 32, /* l1 cache */
489 256, /* l2 cache */
0b11da67 490 1, /* streams */
8b897cfa
RS
491};
492
493/* Instruction costs on PPC603 processors. */
494static const
495struct processor_costs ppc603_cost = {
06a67bdd
RS
496 COSTS_N_INSNS (5), /* mulsi */
497 COSTS_N_INSNS (3), /* mulsi_const */
498 COSTS_N_INSNS (2), /* mulsi_const9 */
499 COSTS_N_INSNS (5), /* muldi */
500 COSTS_N_INSNS (37), /* divsi */
501 COSTS_N_INSNS (37), /* divdi */
502 COSTS_N_INSNS (3), /* fp */
503 COSTS_N_INSNS (4), /* dmul */
504 COSTS_N_INSNS (18), /* sdiv */
505 COSTS_N_INSNS (33), /* ddiv */
0b11da67 506 32,
5f732aba
DE
507 8, /* l1 cache */
508 64, /* l2 cache */
0b11da67 509 1, /* streams */
8b897cfa
RS
510};
511
512/* Instruction costs on PPC604 processors. */
513static const
514struct processor_costs ppc604_cost = {
06a67bdd
RS
515 COSTS_N_INSNS (4), /* mulsi */
516 COSTS_N_INSNS (4), /* mulsi_const */
517 COSTS_N_INSNS (4), /* mulsi_const9 */
518 COSTS_N_INSNS (4), /* muldi */
519 COSTS_N_INSNS (20), /* divsi */
520 COSTS_N_INSNS (20), /* divdi */
521 COSTS_N_INSNS (3), /* fp */
522 COSTS_N_INSNS (3), /* dmul */
523 COSTS_N_INSNS (18), /* sdiv */
524 COSTS_N_INSNS (32), /* ddiv */
0b11da67 525 32,
5f732aba
DE
526 16, /* l1 cache */
527 512, /* l2 cache */
0b11da67 528 1, /* streams */
8b897cfa
RS
529};
530
531/* Instruction costs on PPC604e processors. */
532static const
533struct processor_costs ppc604e_cost = {
06a67bdd
RS
534 COSTS_N_INSNS (2), /* mulsi */
535 COSTS_N_INSNS (2), /* mulsi_const */
536 COSTS_N_INSNS (2), /* mulsi_const9 */
537 COSTS_N_INSNS (2), /* muldi */
538 COSTS_N_INSNS (20), /* divsi */
539 COSTS_N_INSNS (20), /* divdi */
540 COSTS_N_INSNS (3), /* fp */
541 COSTS_N_INSNS (3), /* dmul */
542 COSTS_N_INSNS (18), /* sdiv */
543 COSTS_N_INSNS (32), /* ddiv */
0b11da67 544 32,
5f732aba
DE
545 32, /* l1 cache */
546 1024, /* l2 cache */
0b11da67 547 1, /* streams */
8b897cfa
RS
548};
549
f0517163 550/* Instruction costs on PPC620 processors. */
8b897cfa
RS
551static const
552struct processor_costs ppc620_cost = {
06a67bdd
RS
553 COSTS_N_INSNS (5), /* mulsi */
554 COSTS_N_INSNS (4), /* mulsi_const */
555 COSTS_N_INSNS (3), /* mulsi_const9 */
556 COSTS_N_INSNS (7), /* muldi */
557 COSTS_N_INSNS (21), /* divsi */
558 COSTS_N_INSNS (37), /* divdi */
559 COSTS_N_INSNS (3), /* fp */
560 COSTS_N_INSNS (3), /* dmul */
561 COSTS_N_INSNS (18), /* sdiv */
562 COSTS_N_INSNS (32), /* ddiv */
0b11da67 563 128,
5f732aba
DE
564 32, /* l1 cache */
565 1024, /* l2 cache */
0b11da67 566 1, /* streams */
f0517163
RS
567};
568
569/* Instruction costs on PPC630 processors. */
570static const
571struct processor_costs ppc630_cost = {
06a67bdd
RS
572 COSTS_N_INSNS (5), /* mulsi */
573 COSTS_N_INSNS (4), /* mulsi_const */
574 COSTS_N_INSNS (3), /* mulsi_const9 */
575 COSTS_N_INSNS (7), /* muldi */
576 COSTS_N_INSNS (21), /* divsi */
577 COSTS_N_INSNS (37), /* divdi */
578 COSTS_N_INSNS (3), /* fp */
579 COSTS_N_INSNS (3), /* dmul */
580 COSTS_N_INSNS (17), /* sdiv */
581 COSTS_N_INSNS (21), /* ddiv */
0b11da67 582 128,
5f732aba
DE
583 64, /* l1 cache */
584 1024, /* l2 cache */
0b11da67 585 1, /* streams */
8b897cfa
RS
586};
587
d296e02e
AP
588/* Instruction costs on Cell processor. */
589/* COSTS_N_INSNS (1) ~ one add. */
590static const
591struct processor_costs ppccell_cost = {
592 COSTS_N_INSNS (9/2)+2, /* mulsi */
593 COSTS_N_INSNS (6/2), /* mulsi_const */
594 COSTS_N_INSNS (6/2), /* mulsi_const9 */
595 COSTS_N_INSNS (15/2)+2, /* muldi */
596 COSTS_N_INSNS (38/2), /* divsi */
597 COSTS_N_INSNS (70/2), /* divdi */
598 COSTS_N_INSNS (10/2), /* fp */
599 COSTS_N_INSNS (10/2), /* dmul */
600 COSTS_N_INSNS (74/2), /* sdiv */
601 COSTS_N_INSNS (74/2), /* ddiv */
0b11da67 602 128,
5f732aba
DE
603 32, /* l1 cache */
604 512, /* l2 cache */
605 6, /* streams */
d296e02e
AP
606};
607
8b897cfa
RS
608/* Instruction costs on PPC750 and PPC7400 processors. */
609static const
610struct processor_costs ppc750_cost = {
06a67bdd
RS
611 COSTS_N_INSNS (5), /* mulsi */
612 COSTS_N_INSNS (3), /* mulsi_const */
613 COSTS_N_INSNS (2), /* mulsi_const9 */
614 COSTS_N_INSNS (5), /* muldi */
615 COSTS_N_INSNS (17), /* divsi */
616 COSTS_N_INSNS (17), /* divdi */
617 COSTS_N_INSNS (3), /* fp */
618 COSTS_N_INSNS (3), /* dmul */
619 COSTS_N_INSNS (17), /* sdiv */
620 COSTS_N_INSNS (31), /* ddiv */
0b11da67 621 32,
5f732aba
DE
622 32, /* l1 cache */
623 512, /* l2 cache */
0b11da67 624 1, /* streams */
8b897cfa
RS
625};
626
627/* Instruction costs on PPC7450 processors. */
628static const
629struct processor_costs ppc7450_cost = {
06a67bdd
RS
630 COSTS_N_INSNS (4), /* mulsi */
631 COSTS_N_INSNS (3), /* mulsi_const */
632 COSTS_N_INSNS (3), /* mulsi_const9 */
633 COSTS_N_INSNS (4), /* muldi */
634 COSTS_N_INSNS (23), /* divsi */
635 COSTS_N_INSNS (23), /* divdi */
636 COSTS_N_INSNS (5), /* fp */
637 COSTS_N_INSNS (5), /* dmul */
638 COSTS_N_INSNS (21), /* sdiv */
639 COSTS_N_INSNS (35), /* ddiv */
0b11da67 640 32,
5f732aba
DE
641 32, /* l1 cache */
642 1024, /* l2 cache */
0b11da67 643 1, /* streams */
8b897cfa 644};
a3170dc6 645
8b897cfa
RS
646/* Instruction costs on PPC8540 processors. */
647static const
648struct processor_costs ppc8540_cost = {
06a67bdd
RS
649 COSTS_N_INSNS (4), /* mulsi */
650 COSTS_N_INSNS (4), /* mulsi_const */
651 COSTS_N_INSNS (4), /* mulsi_const9 */
652 COSTS_N_INSNS (4), /* muldi */
653 COSTS_N_INSNS (19), /* divsi */
654 COSTS_N_INSNS (19), /* divdi */
655 COSTS_N_INSNS (4), /* fp */
656 COSTS_N_INSNS (4), /* dmul */
657 COSTS_N_INSNS (29), /* sdiv */
658 COSTS_N_INSNS (29), /* ddiv */
0b11da67 659 32,
5f732aba
DE
660 32, /* l1 cache */
661 256, /* l2 cache */
0b11da67 662 1, /* prefetch streams /*/
8b897cfa
RS
663};
664
665/* Instruction costs on POWER4 and POWER5 processors. */
666static const
667struct processor_costs power4_cost = {
06a67bdd
RS
668 COSTS_N_INSNS (3), /* mulsi */
669 COSTS_N_INSNS (2), /* mulsi_const */
670 COSTS_N_INSNS (2), /* mulsi_const9 */
671 COSTS_N_INSNS (4), /* muldi */
672 COSTS_N_INSNS (18), /* divsi */
673 COSTS_N_INSNS (34), /* divdi */
674 COSTS_N_INSNS (3), /* fp */
675 COSTS_N_INSNS (3), /* dmul */
676 COSTS_N_INSNS (17), /* sdiv */
677 COSTS_N_INSNS (17), /* ddiv */
0b11da67 678 128,
5f732aba
DE
679 32, /* l1 cache */
680 1024, /* l2 cache */
0b11da67 681 8, /* prefetch streams /*/
8b897cfa
RS
682};
683
44cd321e
PS
684/* Instruction costs on POWER6 processors. */
685static const
686struct processor_costs power6_cost = {
687 COSTS_N_INSNS (8), /* mulsi */
688 COSTS_N_INSNS (8), /* mulsi_const */
689 COSTS_N_INSNS (8), /* mulsi_const9 */
690 COSTS_N_INSNS (8), /* muldi */
691 COSTS_N_INSNS (22), /* divsi */
692 COSTS_N_INSNS (28), /* divdi */
693 COSTS_N_INSNS (3), /* fp */
694 COSTS_N_INSNS (3), /* dmul */
695 COSTS_N_INSNS (13), /* sdiv */
696 COSTS_N_INSNS (16), /* ddiv */
0b11da67 697 128,
5f732aba
DE
698 64, /* l1 cache */
699 2048, /* l2 cache */
0b11da67 700 16, /* prefetch streams */
44cd321e
PS
701};
702
8b897cfa 703\f
a2369ed3 704static bool rs6000_function_ok_for_sibcall (tree, tree);
3101faab 705static const char *rs6000_invalid_within_doloop (const_rtx);
a2369ed3 706static rtx rs6000_generate_compare (enum rtx_code);
a2369ed3
DJ
707static void rs6000_emit_stack_tie (void);
708static void rs6000_frame_related (rtx, rtx, HOST_WIDE_INT, rtx, rtx);
709static rtx spe_synthesize_frame_save (rtx);
710static bool spe_func_has_64bit_regs_p (void);
b20a9cca 711static void emit_frame_save (rtx, rtx, enum machine_mode, unsigned int,
d1d0c603 712 int, HOST_WIDE_INT);
a2369ed3
DJ
713static rtx gen_frame_mem_offset (enum machine_mode, rtx, int);
714static void rs6000_emit_allocate_stack (HOST_WIDE_INT, int);
715static unsigned rs6000_hash_constant (rtx);
716static unsigned toc_hash_function (const void *);
717static int toc_hash_eq (const void *, const void *);
718static int constant_pool_expr_1 (rtx, int *, int *);
719static bool constant_pool_expr_p (rtx);
d04b6e6e 720static bool legitimate_small_data_p (enum machine_mode, rtx);
a2369ed3
DJ
721static bool legitimate_lo_sum_address_p (enum machine_mode, rtx, int);
722static struct machine_function * rs6000_init_machine_status (void);
723static bool rs6000_assemble_integer (rtx, unsigned int, int);
6d0a8091 724static bool no_global_regs_above (int);
5add3202 725#ifdef HAVE_GAS_HIDDEN
a2369ed3 726static void rs6000_assemble_visibility (tree, int);
5add3202 727#endif
a2369ed3
DJ
728static int rs6000_ra_ever_killed (void);
729static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *);
8bb418a3 730static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *);
3101faab 731static bool rs6000_ms_bitfield_layout_p (const_tree);
77ccdfed 732static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *);
76d2b81d 733static void rs6000_eliminate_indexed_memrefs (rtx operands[2]);
3101faab 734static const char *rs6000_mangle_type (const_tree);
b86fe7b4 735extern const struct attribute_spec rs6000_attribute_table[];
a2369ed3 736static void rs6000_set_default_type_attributes (tree);
52ff33d0 737static bool rs6000_reg_live_or_pic_offset_p (int);
a2369ed3
DJ
738static void rs6000_output_function_prologue (FILE *, HOST_WIDE_INT);
739static void rs6000_output_function_epilogue (FILE *, HOST_WIDE_INT);
b20a9cca
AM
740static void rs6000_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
741 tree);
a2369ed3 742static rtx rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, HOST_WIDE_INT);
586de218 743static bool rs6000_return_in_memory (const_tree, const_tree);
a2369ed3 744static void rs6000_file_start (void);
7c262518 745#if TARGET_ELF
9b580a0b 746static int rs6000_elf_reloc_rw_mask (void);
a2369ed3
DJ
747static void rs6000_elf_asm_out_constructor (rtx, int);
748static void rs6000_elf_asm_out_destructor (rtx, int);
1334b570 749static void rs6000_elf_end_indicate_exec_stack (void) ATTRIBUTE_UNUSED;
d6b5193b 750static void rs6000_elf_asm_init_sections (void);
d6b5193b
RS
751static section *rs6000_elf_select_rtx_section (enum machine_mode, rtx,
752 unsigned HOST_WIDE_INT);
a56d7372 753static void rs6000_elf_encode_section_info (tree, rtx, int)
0e5dbd9b 754 ATTRIBUTE_UNUSED;
7c262518 755#endif
3101faab 756static bool rs6000_use_blocks_for_constant_p (enum machine_mode, const_rtx);
cbaaba19 757#if TARGET_XCOFF
0d5817b2 758static void rs6000_xcoff_asm_output_anchor (rtx);
a2369ed3 759static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
d6b5193b 760static void rs6000_xcoff_asm_init_sections (void);
9b580a0b 761static int rs6000_xcoff_reloc_rw_mask (void);
8210e4c4 762static void rs6000_xcoff_asm_named_section (const char *, unsigned int, tree);
d6b5193b 763static section *rs6000_xcoff_select_section (tree, int,
b20a9cca 764 unsigned HOST_WIDE_INT);
d6b5193b
RS
765static void rs6000_xcoff_unique_section (tree, int);
766static section *rs6000_xcoff_select_rtx_section
767 (enum machine_mode, rtx, unsigned HOST_WIDE_INT);
a2369ed3
DJ
768static const char * rs6000_xcoff_strip_name_encoding (const char *);
769static unsigned int rs6000_xcoff_section_type_flags (tree, const char *, int);
770static void rs6000_xcoff_file_start (void);
771static void rs6000_xcoff_file_end (void);
f1384257 772#endif
a2369ed3
DJ
773static int rs6000_variable_issue (FILE *, int, rtx, int);
774static bool rs6000_rtx_costs (rtx, int, int, int *);
775static int rs6000_adjust_cost (rtx, rtx, rtx, int);
44cd321e 776static void rs6000_sched_init (FILE *, int, int);
cbe26ab8 777static bool is_microcoded_insn (rtx);
d296e02e 778static bool is_nonpipeline_insn (rtx);
cbe26ab8
DN
779static bool is_cracked_insn (rtx);
780static bool is_branch_slot_insn (rtx);
44cd321e 781static bool is_load_insn (rtx);
e3a0e200 782static rtx get_store_dest (rtx pat);
44cd321e
PS
783static bool is_store_insn (rtx);
784static bool set_to_load_agen (rtx,rtx);
982afe02 785static bool adjacent_mem_locations (rtx,rtx);
a2369ed3
DJ
786static int rs6000_adjust_priority (rtx, int);
787static int rs6000_issue_rate (void);
b198261f 788static bool rs6000_is_costly_dependence (dep_t, int, int);
cbe26ab8
DN
789static rtx get_next_active_insn (rtx, rtx);
790static bool insn_terminates_group_p (rtx , enum group_termination);
44cd321e
PS
791static bool insn_must_be_first_in_group (rtx);
792static bool insn_must_be_last_in_group (rtx);
cbe26ab8
DN
793static bool is_costly_group (rtx *, rtx);
794static int force_new_group (int, FILE *, rtx *, rtx, bool *, int, int *);
795static int redefine_groups (FILE *, int, rtx, rtx);
796static int pad_groups (FILE *, int, rtx, rtx);
797static void rs6000_sched_finish (FILE *, int);
44cd321e
PS
798static int rs6000_sched_reorder (FILE *, int, rtx *, int *, int);
799static int rs6000_sched_reorder2 (FILE *, int, rtx *, int *, int);
a2369ed3 800static int rs6000_use_sched_lookahead (void);
d296e02e 801static int rs6000_use_sched_lookahead_guard (rtx);
9c78b944 802static tree rs6000_builtin_reciprocal (unsigned int, bool, bool);
7ccf35ed 803static tree rs6000_builtin_mask_for_load (void);
89d67cca
DN
804static tree rs6000_builtin_mul_widen_even (tree);
805static tree rs6000_builtin_mul_widen_odd (tree);
f57d17f1 806static tree rs6000_builtin_conversion (enum tree_code, tree);
a2369ed3 807
58646b77 808static void def_builtin (int, const char *, tree, int);
3101faab 809static bool rs6000_vector_alignment_reachable (const_tree, bool);
a2369ed3
DJ
810static void rs6000_init_builtins (void);
811static rtx rs6000_expand_unop_builtin (enum insn_code, tree, rtx);
812static rtx rs6000_expand_binop_builtin (enum insn_code, tree, rtx);
813static rtx rs6000_expand_ternop_builtin (enum insn_code, tree, rtx);
814static rtx rs6000_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
815static void altivec_init_builtins (void);
816static void rs6000_common_init_builtins (void);
c15c90bb 817static void rs6000_init_libfuncs (void);
a2369ed3 818
96038623
DE
819static void paired_init_builtins (void);
820static rtx paired_expand_builtin (tree, rtx, bool *);
821static rtx paired_expand_lv_builtin (enum insn_code, tree, rtx);
822static rtx paired_expand_stv_builtin (enum insn_code, tree);
823static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
824
b20a9cca
AM
825static void enable_mask_for_builtins (struct builtin_description *, int,
826 enum rs6000_builtins,
827 enum rs6000_builtins);
7c62e993 828static tree build_opaque_vector_type (tree, int);
a2369ed3
DJ
829static void spe_init_builtins (void);
830static rtx spe_expand_builtin (tree, rtx, bool *);
61bea3b0 831static rtx spe_expand_stv_builtin (enum insn_code, tree);
a2369ed3
DJ
832static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
833static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
834static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
d1d0c603
JJ
835static rs6000_stack_t *rs6000_stack_info (void);
836static void debug_stack_info (rs6000_stack_t *);
a2369ed3
DJ
837
838static rtx altivec_expand_builtin (tree, rtx, bool *);
839static rtx altivec_expand_ld_builtin (tree, rtx, bool *);
840static rtx altivec_expand_st_builtin (tree, rtx, bool *);
841static rtx altivec_expand_dst_builtin (tree, rtx, bool *);
842static rtx altivec_expand_abs_builtin (enum insn_code, tree, rtx);
f676971a 843static rtx altivec_expand_predicate_builtin (enum insn_code,
c4ad648e 844 const char *, tree, rtx);
b4a62fa0 845static rtx altivec_expand_lv_builtin (enum insn_code, tree, rtx);
a2369ed3 846static rtx altivec_expand_stv_builtin (enum insn_code, tree);
7a4eca66
DE
847static rtx altivec_expand_vec_init_builtin (tree, tree, rtx);
848static rtx altivec_expand_vec_set_builtin (tree);
849static rtx altivec_expand_vec_ext_builtin (tree, rtx);
850static int get_element_number (tree, tree);
78f5898b 851static bool rs6000_handle_option (size_t, const char *, int);
a2369ed3 852static void rs6000_parse_tls_size_option (void);
5da702b1 853static void rs6000_parse_yes_no_option (const char *, const char *, int *);
a2369ed3
DJ
854static int first_altivec_reg_to_save (void);
855static unsigned int compute_vrsave_mask (void);
9390387d 856static void compute_save_world_info (rs6000_stack_t *info_ptr);
a2369ed3
DJ
857static void is_altivec_return_reg (rtx, void *);
858static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
859int easy_vector_constant (rtx, enum machine_mode);
3101faab 860static bool rs6000_is_opaque_type (const_tree);
a2369ed3 861static rtx rs6000_dwarf_register_span (rtx);
37ea0b7e 862static void rs6000_init_dwarf_reg_sizes_extra (tree);
a2369ed3 863static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
fdbe66f2 864static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
a2369ed3
DJ
865static rtx rs6000_tls_get_addr (void);
866static rtx rs6000_got_sym (void);
9390387d 867static int rs6000_tls_symbol_ref_1 (rtx *, void *);
a2369ed3
DJ
868static const char *rs6000_get_some_local_dynamic_name (void);
869static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
ded9bf77 870static rtx rs6000_complex_function_value (enum machine_mode);
b20a9cca 871static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
a2369ed3 872 enum machine_mode, tree);
0b5383eb
DJ
873static void rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *,
874 HOST_WIDE_INT);
875static void rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *,
876 tree, HOST_WIDE_INT);
877static void rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *,
878 HOST_WIDE_INT,
879 rtx[], int *);
880static void rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *,
586de218
KG
881 const_tree, HOST_WIDE_INT,
882 rtx[], int *);
883static rtx rs6000_darwin64_record_arg (CUMULATIVE_ARGS *, const_tree, int, bool);
ec6376ab 884static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
b1917422 885static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
c6e8c921
GK
886static void setup_incoming_varargs (CUMULATIVE_ARGS *,
887 enum machine_mode, tree,
888 int *, int);
8cd5a4e0 889static bool rs6000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
586de218 890 const_tree, bool);
78a52f11
RH
891static int rs6000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
892 tree, bool);
3101faab 893static const char *invalid_arg_for_unprototyped_fn (const_tree, const_tree, const_tree);
efdba735
SH
894#if TARGET_MACHO
895static void macho_branch_islands (void);
efdba735
SH
896static int no_previous_def (tree function_name);
897static tree get_prev_label (tree function_name);
c4e18b1c 898static void rs6000_darwin_file_start (void);
efdba735
SH
899#endif
900
c35d187f 901static tree rs6000_build_builtin_va_list (void);
23a60a04 902static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *);
586de218 903static bool rs6000_must_pass_in_stack (enum machine_mode, const_tree);
00b79d54 904static bool rs6000_scalar_mode_supported_p (enum machine_mode);
f676971a 905static bool rs6000_vector_mode_supported_p (enum machine_mode);
94ff898d 906static int get_vec_cmp_insn (enum rtx_code, enum machine_mode,
21213b4c 907 enum machine_mode);
94ff898d 908static rtx rs6000_emit_vector_compare (enum rtx_code, rtx, rtx,
21213b4c
DP
909 enum machine_mode);
910static int get_vsel_insn (enum machine_mode);
911static void rs6000_emit_vector_select (rtx, rtx, rtx, rtx);
3aebbe5f 912static tree rs6000_stack_protect_fail (void);
21213b4c
DP
913
914const int INSN_NOT_AVAILABLE = -1;
93f90be6
FJ
915static enum machine_mode rs6000_eh_return_filter_mode (void);
916
17211ab5
GK
917/* Hash table stuff for keeping track of TOC entries. */
918
919struct toc_hash_struct GTY(())
920{
921 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
922 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
923 rtx key;
924 enum machine_mode key_mode;
925 int labelno;
926};
927
928static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
c81bebd7
MM
929\f
930/* Default register names. */
931char rs6000_reg_names[][8] =
932{
802a0058
MM
933 "0", "1", "2", "3", "4", "5", "6", "7",
934 "8", "9", "10", "11", "12", "13", "14", "15",
935 "16", "17", "18", "19", "20", "21", "22", "23",
936 "24", "25", "26", "27", "28", "29", "30", "31",
937 "0", "1", "2", "3", "4", "5", "6", "7",
938 "8", "9", "10", "11", "12", "13", "14", "15",
939 "16", "17", "18", "19", "20", "21", "22", "23",
940 "24", "25", "26", "27", "28", "29", "30", "31",
941 "mq", "lr", "ctr","ap",
942 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
943 "xer",
944 /* AltiVec registers. */
0cd5e3a1
AH
945 "0", "1", "2", "3", "4", "5", "6", "7",
946 "8", "9", "10", "11", "12", "13", "14", "15",
947 "16", "17", "18", "19", "20", "21", "22", "23",
948 "24", "25", "26", "27", "28", "29", "30", "31",
59a4c851
AH
949 "vrsave", "vscr",
950 /* SPE registers. */
7d5175e1
JJ
951 "spe_acc", "spefscr",
952 /* Soft frame pointer. */
953 "sfp"
c81bebd7
MM
954};
955
956#ifdef TARGET_REGNAMES
8b60264b 957static const char alt_reg_names[][8] =
c81bebd7 958{
802a0058
MM
959 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
960 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
961 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
962 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
963 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
964 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
965 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
966 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
967 "mq", "lr", "ctr", "ap",
968 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6 969 "xer",
59a4c851 970 /* AltiVec registers. */
0ac081f6 971 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
59a4c851
AH
972 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
973 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
974 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
975 "vrsave", "vscr",
976 /* SPE registers. */
7d5175e1
JJ
977 "spe_acc", "spefscr",
978 /* Soft frame pointer. */
979 "sfp"
c81bebd7
MM
980};
981#endif
9878760c 982\f
daf11973
MM
983#ifndef MASK_STRICT_ALIGN
984#define MASK_STRICT_ALIGN 0
985#endif
ffcfcb5f
AM
986#ifndef TARGET_PROFILE_KERNEL
987#define TARGET_PROFILE_KERNEL 0
988#endif
3961e8fe
RH
989
990/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
991#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
672a6f42
NB
992\f
993/* Initialize the GCC target structure. */
91d231cb
JM
994#undef TARGET_ATTRIBUTE_TABLE
995#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
996#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
997#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 998
301d03af
RS
999#undef TARGET_ASM_ALIGNED_DI_OP
1000#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
1001
1002/* Default unaligned ops are only provided for ELF. Find the ops needed
1003 for non-ELF systems. */
1004#ifndef OBJECT_FORMAT_ELF
cbaaba19 1005#if TARGET_XCOFF
ae6c1efd 1006/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
1007 64-bit targets. */
1008#undef TARGET_ASM_UNALIGNED_HI_OP
1009#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
1010#undef TARGET_ASM_UNALIGNED_SI_OP
1011#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
1012#undef TARGET_ASM_UNALIGNED_DI_OP
1013#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
1014#else
1015/* For Darwin. */
1016#undef TARGET_ASM_UNALIGNED_HI_OP
1017#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
1018#undef TARGET_ASM_UNALIGNED_SI_OP
1019#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
49bd1d27
SS
1020#undef TARGET_ASM_UNALIGNED_DI_OP
1021#define TARGET_ASM_UNALIGNED_DI_OP "\t.quad\t"
1022#undef TARGET_ASM_ALIGNED_DI_OP
1023#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
301d03af
RS
1024#endif
1025#endif
1026
1027/* This hook deals with fixups for relocatable code and DI-mode objects
1028 in 64-bit code. */
1029#undef TARGET_ASM_INTEGER
1030#define TARGET_ASM_INTEGER rs6000_assemble_integer
1031
93638d7a
AM
1032#ifdef HAVE_GAS_HIDDEN
1033#undef TARGET_ASM_ASSEMBLE_VISIBILITY
1034#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
1035#endif
1036
c4501e62
JJ
1037#undef TARGET_HAVE_TLS
1038#define TARGET_HAVE_TLS HAVE_AS_TLS
1039
1040#undef TARGET_CANNOT_FORCE_CONST_MEM
a7e0b075 1041#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
c4501e62 1042
08c148a8
NB
1043#undef TARGET_ASM_FUNCTION_PROLOGUE
1044#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
1045#undef TARGET_ASM_FUNCTION_EPILOGUE
1046#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
1047
b54cf83a
DE
1048#undef TARGET_SCHED_VARIABLE_ISSUE
1049#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
1050
c237e94a
ZW
1051#undef TARGET_SCHED_ISSUE_RATE
1052#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
1053#undef TARGET_SCHED_ADJUST_COST
1054#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
1055#undef TARGET_SCHED_ADJUST_PRIORITY
1056#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
f676971a 1057#undef TARGET_SCHED_IS_COSTLY_DEPENDENCE
569fa502 1058#define TARGET_SCHED_IS_COSTLY_DEPENDENCE rs6000_is_costly_dependence
44cd321e
PS
1059#undef TARGET_SCHED_INIT
1060#define TARGET_SCHED_INIT rs6000_sched_init
cbe26ab8
DN
1061#undef TARGET_SCHED_FINISH
1062#define TARGET_SCHED_FINISH rs6000_sched_finish
44cd321e
PS
1063#undef TARGET_SCHED_REORDER
1064#define TARGET_SCHED_REORDER rs6000_sched_reorder
1065#undef TARGET_SCHED_REORDER2
1066#define TARGET_SCHED_REORDER2 rs6000_sched_reorder2
c237e94a 1067
be12c2b0
VM
1068#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
1069#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
1070
d296e02e
AP
1071#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD
1072#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD rs6000_use_sched_lookahead_guard
1073
7ccf35ed
DN
1074#undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
1075#define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
89d67cca
DN
1076#undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN
1077#define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN rs6000_builtin_mul_widen_even
1078#undef TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD
1079#define TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD rs6000_builtin_mul_widen_odd
f57d17f1
TM
1080#undef TARGET_VECTORIZE_BUILTIN_CONVERSION
1081#define TARGET_VECTORIZE_BUILTIN_CONVERSION rs6000_builtin_conversion
7ccf35ed 1082
5b900a4c
DN
1083#undef TARGET_VECTOR_ALIGNMENT_REACHABLE
1084#define TARGET_VECTOR_ALIGNMENT_REACHABLE rs6000_vector_alignment_reachable
1085
0ac081f6
AH
1086#undef TARGET_INIT_BUILTINS
1087#define TARGET_INIT_BUILTINS rs6000_init_builtins
1088
1089#undef TARGET_EXPAND_BUILTIN
1090#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
1091
608063c3
JB
1092#undef TARGET_MANGLE_TYPE
1093#define TARGET_MANGLE_TYPE rs6000_mangle_type
f18eca82 1094
c15c90bb
ZW
1095#undef TARGET_INIT_LIBFUNCS
1096#define TARGET_INIT_LIBFUNCS rs6000_init_libfuncs
1097
f1384257 1098#if TARGET_MACHO
0e5dbd9b 1099#undef TARGET_BINDS_LOCAL_P
31920d83 1100#define TARGET_BINDS_LOCAL_P darwin_binds_local_p
f1384257 1101#endif
0e5dbd9b 1102
77ccdfed
EC
1103#undef TARGET_MS_BITFIELD_LAYOUT_P
1104#define TARGET_MS_BITFIELD_LAYOUT_P rs6000_ms_bitfield_layout_p
1105
3961e8fe
RH
1106#undef TARGET_ASM_OUTPUT_MI_THUNK
1107#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
1108
3961e8fe 1109#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
3101faab 1110#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
00b960c7 1111
4977bab6
ZW
1112#undef TARGET_FUNCTION_OK_FOR_SIBCALL
1113#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
1114
2e3f0db6
DJ
1115#undef TARGET_INVALID_WITHIN_DOLOOP
1116#define TARGET_INVALID_WITHIN_DOLOOP rs6000_invalid_within_doloop
9419649c 1117
3c50106f
RH
1118#undef TARGET_RTX_COSTS
1119#define TARGET_RTX_COSTS rs6000_rtx_costs
dcefdf67
RH
1120#undef TARGET_ADDRESS_COST
1121#define TARGET_ADDRESS_COST hook_int_rtx_0
3c50106f 1122
c8e4f0e9 1123#undef TARGET_VECTOR_OPAQUE_P
58646b77 1124#define TARGET_VECTOR_OPAQUE_P rs6000_is_opaque_type
62e1dfcf 1125
96714395
AH
1126#undef TARGET_DWARF_REGISTER_SPAN
1127#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
1128
37ea0b7e
JM
1129#undef TARGET_INIT_DWARF_REG_SIZES_EXTRA
1130#define TARGET_INIT_DWARF_REG_SIZES_EXTRA rs6000_init_dwarf_reg_sizes_extra
1131
c6e8c921
GK
1132/* On rs6000, function arguments are promoted, as are function return
1133 values. */
1134#undef TARGET_PROMOTE_FUNCTION_ARGS
586de218 1135#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_const_tree_true
c6e8c921 1136#undef TARGET_PROMOTE_FUNCTION_RETURN
586de218 1137#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_const_tree_true
c6e8c921 1138
c6e8c921
GK
1139#undef TARGET_RETURN_IN_MEMORY
1140#define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory
1141
1142#undef TARGET_SETUP_INCOMING_VARARGS
1143#define TARGET_SETUP_INCOMING_VARARGS setup_incoming_varargs
1144
1145/* Always strict argument naming on rs6000. */
1146#undef TARGET_STRICT_ARGUMENT_NAMING
1147#define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
1148#undef TARGET_PRETEND_OUTGOING_VARARGS_NAMED
1149#define TARGET_PRETEND_OUTGOING_VARARGS_NAMED hook_bool_CUMULATIVE_ARGS_true
42ba5130 1150#undef TARGET_SPLIT_COMPLEX_ARG
3101faab 1151#define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
fe984136
RH
1152#undef TARGET_MUST_PASS_IN_STACK
1153#define TARGET_MUST_PASS_IN_STACK rs6000_must_pass_in_stack
8cd5a4e0
RH
1154#undef TARGET_PASS_BY_REFERENCE
1155#define TARGET_PASS_BY_REFERENCE rs6000_pass_by_reference
78a52f11
RH
1156#undef TARGET_ARG_PARTIAL_BYTES
1157#define TARGET_ARG_PARTIAL_BYTES rs6000_arg_partial_bytes
c6e8c921 1158
c35d187f
RH
1159#undef TARGET_BUILD_BUILTIN_VA_LIST
1160#define TARGET_BUILD_BUILTIN_VA_LIST rs6000_build_builtin_va_list
1161
cd3ce9b4
JM
1162#undef TARGET_GIMPLIFY_VA_ARG_EXPR
1163#define TARGET_GIMPLIFY_VA_ARG_EXPR rs6000_gimplify_va_arg
1164
93f90be6
FJ
1165#undef TARGET_EH_RETURN_FILTER_MODE
1166#define TARGET_EH_RETURN_FILTER_MODE rs6000_eh_return_filter_mode
1167
00b79d54
BE
1168#undef TARGET_SCALAR_MODE_SUPPORTED_P
1169#define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
1170
f676971a
EC
1171#undef TARGET_VECTOR_MODE_SUPPORTED_P
1172#define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
1173
4d3e6fae
FJ
1174#undef TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN
1175#define TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN invalid_arg_for_unprototyped_fn
1176
78f5898b
AH
1177#undef TARGET_HANDLE_OPTION
1178#define TARGET_HANDLE_OPTION rs6000_handle_option
1179
1180#undef TARGET_DEFAULT_TARGET_FLAGS
1181#define TARGET_DEFAULT_TARGET_FLAGS \
716019c0 1182 (TARGET_DEFAULT)
78f5898b 1183
3aebbe5f
JJ
1184#undef TARGET_STACK_PROTECT_FAIL
1185#define TARGET_STACK_PROTECT_FAIL rs6000_stack_protect_fail
1186
445cf5eb
JM
1187/* MPC604EUM 3.5.2 Weak Consistency between Multiple Processors
1188 The PowerPC architecture requires only weak consistency among
1189 processors--that is, memory accesses between processors need not be
1190 sequentially consistent and memory accesses among processors can occur
1191 in any order. The ability to order memory accesses weakly provides
1192 opportunities for more efficient use of the system bus. Unless a
1193 dependency exists, the 604e allows read operations to precede store
1194 operations. */
1195#undef TARGET_RELAXED_ORDERING
1196#define TARGET_RELAXED_ORDERING true
1197
fdbe66f2
EB
1198#ifdef HAVE_AS_TLS
1199#undef TARGET_ASM_OUTPUT_DWARF_DTPREL
1200#define TARGET_ASM_OUTPUT_DWARF_DTPREL rs6000_output_dwarf_dtprel
1201#endif
1202
aacd3885
RS
1203/* Use a 32-bit anchor range. This leads to sequences like:
1204
1205 addis tmp,anchor,high
1206 add dest,tmp,low
1207
1208 where tmp itself acts as an anchor, and can be shared between
1209 accesses to the same 64k page. */
1210#undef TARGET_MIN_ANCHOR_OFFSET
1211#define TARGET_MIN_ANCHOR_OFFSET -0x7fffffff - 1
1212#undef TARGET_MAX_ANCHOR_OFFSET
1213#define TARGET_MAX_ANCHOR_OFFSET 0x7fffffff
1214#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
1215#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
1216
9c78b944
DE
1217#undef TARGET_BUILTIN_RECIPROCAL
1218#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
1219
f6897b10 1220struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 1221\f
0d1fbc8c
AH
1222
1223/* Value is 1 if hard register REGNO can hold a value of machine-mode
1224 MODE. */
1225static int
1226rs6000_hard_regno_mode_ok (int regno, enum machine_mode mode)
1227{
1228 /* The GPRs can hold any mode, but values bigger than one register
1229 cannot go past R31. */
1230 if (INT_REGNO_P (regno))
1231 return INT_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1);
1232
a5a97921 1233 /* The float registers can only hold floating modes and DImode.
7393f7f8 1234 This excludes the 32-bit decimal float mode for now. */
0d1fbc8c
AH
1235 if (FP_REGNO_P (regno))
1236 return
96038623 1237 ((SCALAR_FLOAT_MODE_P (mode)
c092b045 1238 && (mode != TDmode || (regno % 2) == 0)
7393f7f8 1239 && mode != SDmode
0d1fbc8c
AH
1240 && FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
1241 || (GET_MODE_CLASS (mode) == MODE_INT
96038623
DE
1242 && GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD)
1243 || (PAIRED_SIMD_REGNO_P (regno) && TARGET_PAIRED_FLOAT
1244 && PAIRED_VECTOR_MODE (mode)));
0d1fbc8c
AH
1245
1246 /* The CR register can only hold CC modes. */
1247 if (CR_REGNO_P (regno))
1248 return GET_MODE_CLASS (mode) == MODE_CC;
1249
1250 if (XER_REGNO_P (regno))
1251 return mode == PSImode;
1252
1253 /* AltiVec only in AldyVec registers. */
1254 if (ALTIVEC_REGNO_P (regno))
1255 return ALTIVEC_VECTOR_MODE (mode);
1256
1257 /* ...but GPRs can hold SIMD data on the SPE in one register. */
1258 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
1259 return 1;
1260
1261 /* We cannot put TImode anywhere except general register and it must be
1262 able to fit within the register set. */
1263
1264 return GET_MODE_SIZE (mode) <= UNITS_PER_WORD;
1265}
1266
1267/* Initialize rs6000_hard_regno_mode_ok_p table. */
1268static void
1269rs6000_init_hard_regno_mode_ok (void)
1270{
1271 int r, m;
1272
1273 for (r = 0; r < FIRST_PSEUDO_REGISTER; ++r)
1274 for (m = 0; m < NUM_MACHINE_MODES; ++m)
1275 if (rs6000_hard_regno_mode_ok (r, m))
1276 rs6000_hard_regno_mode_ok_p[m][r] = true;
1277}
1278
e4cad568
GK
1279#if TARGET_MACHO
1280/* The Darwin version of SUBTARGET_OVERRIDE_OPTIONS. */
1281
1282static void
1283darwin_rs6000_override_options (void)
1284{
1285 /* The Darwin ABI always includes AltiVec, can't be (validly) turned
1286 off. */
1287 rs6000_altivec_abi = 1;
1288 TARGET_ALTIVEC_VRSAVE = 1;
1289 if (DEFAULT_ABI == ABI_DARWIN)
1290 {
1291 if (MACHO_DYNAMIC_NO_PIC_P)
1292 {
1293 if (flag_pic)
1294 warning (0, "-mdynamic-no-pic overrides -fpic or -fPIC");
1295 flag_pic = 0;
1296 }
1297 else if (flag_pic == 1)
1298 {
1299 flag_pic = 2;
1300 }
1301 }
1302 if (TARGET_64BIT && ! TARGET_POWERPC64)
1303 {
1304 target_flags |= MASK_POWERPC64;
1305 warning (0, "-m64 requires PowerPC64 architecture, enabling");
1306 }
1307 if (flag_mkernel)
1308 {
1309 rs6000_default_long_calls = 1;
1310 target_flags |= MASK_SOFT_FLOAT;
1311 }
1312
1313 /* Make -m64 imply -maltivec. Darwin's 64-bit ABI includes
1314 Altivec. */
1315 if (!flag_mkernel && !flag_apple_kext
1316 && TARGET_64BIT
1317 && ! (target_flags_explicit & MASK_ALTIVEC))
1318 target_flags |= MASK_ALTIVEC;
1319
1320 /* Unless the user (not the configurer) has explicitly overridden
1321 it with -mcpu=G3 or -mno-altivec, then 10.5+ targets default to
1322 G4 unless targetting the kernel. */
1323 if (!flag_mkernel
1324 && !flag_apple_kext
1325 && strverscmp (darwin_macosx_version_min, "10.5") >= 0
1326 && ! (target_flags_explicit & MASK_ALTIVEC)
1327 && ! rs6000_select[1].string)
1328 {
1329 target_flags |= MASK_ALTIVEC;
1330 }
1331}
1332#endif
1333
c1e55850
GK
1334/* If not otherwise specified by a target, make 'long double' equivalent to
1335 'double'. */
1336
1337#ifndef RS6000_DEFAULT_LONG_DOUBLE_SIZE
1338#define RS6000_DEFAULT_LONG_DOUBLE_SIZE 64
1339#endif
1340
5248c961
RK
1341/* Override command line options. Mostly we process the processor
1342 type and sometimes adjust other TARGET_ options. */
1343
1344void
d779d0dc 1345rs6000_override_options (const char *default_cpu)
5248c961 1346{
c4d38ccb 1347 size_t i, j;
8e3f41e7 1348 struct rs6000_cpu_select *ptr;
66188a7e 1349 int set_masks;
5248c961 1350
66188a7e 1351 /* Simplifications for entries below. */
85638c0d 1352
66188a7e
GK
1353 enum {
1354 POWERPC_BASE_MASK = MASK_POWERPC | MASK_NEW_MNEMONICS,
1355 POWERPC_7400_MASK = POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_ALTIVEC
1356 };
85638c0d 1357
66188a7e
GK
1358 /* This table occasionally claims that a processor does not support
1359 a particular feature even though it does, but the feature is slower
1360 than the alternative. Thus, it shouldn't be relied on as a
f676971a 1361 complete description of the processor's support.
66188a7e
GK
1362
1363 Please keep this list in order, and don't forget to update the
1364 documentation in invoke.texi when adding a new processor or
1365 flag. */
5248c961
RK
1366 static struct ptt
1367 {
8b60264b
KG
1368 const char *const name; /* Canonical processor name. */
1369 const enum processor_type processor; /* Processor type enum value. */
1370 const int target_enable; /* Target flags to enable. */
8b60264b 1371 } const processor_target_table[]
66188a7e 1372 = {{"401", PROCESSOR_PPC403, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
49a0b204 1373 {"403", PROCESSOR_PPC403,
66188a7e 1374 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_STRICT_ALIGN},
131aeb82 1375 {"405", PROCESSOR_PPC405,
716019c0
JM
1376 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1377 {"405fp", PROCESSOR_PPC405,
1378 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
131aeb82 1379 {"440", PROCESSOR_PPC440,
716019c0
JM
1380 POWERPC_BASE_MASK | MASK_SOFT_FLOAT | MASK_MULHW | MASK_DLMZB},
1381 {"440fp", PROCESSOR_PPC440,
1382 POWERPC_BASE_MASK | MASK_MULHW | MASK_DLMZB},
66188a7e 1383 {"505", PROCESSOR_MPCCORE, POWERPC_BASE_MASK},
5248c961 1384 {"601", PROCESSOR_PPC601,
66188a7e
GK
1385 MASK_POWER | POWERPC_BASE_MASK | MASK_MULTIPLE | MASK_STRING},
1386 {"602", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1387 {"603", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1388 {"603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1389 {"604", PROCESSOR_PPC604, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1390 {"604e", PROCESSOR_PPC604e, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
7ddb6568
AM
1391 {"620", PROCESSOR_PPC620,
1392 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1393 {"630", PROCESSOR_PPC630,
1394 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
66188a7e
GK
1395 {"740", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1396 {"7400", PROCESSOR_PPC7400, POWERPC_7400_MASK},
1397 {"7450", PROCESSOR_PPC7450, POWERPC_7400_MASK},
1398 {"750", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1399 {"801", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1400 {"821", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1401 {"823", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
a45bce6e 1402 {"8540", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
4d4cbc0e 1403 /* 8548 has a dummy entry for now. */
a45bce6e 1404 {"8548", PROCESSOR_PPC8540, POWERPC_BASE_MASK | MASK_STRICT_ALIGN},
66188a7e 1405 {"860", PROCESSOR_MPCCORE, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
7177e720 1406 {"970", PROCESSOR_POWER4,
66188a7e 1407 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
d296e02e
AP
1408 {"cell", PROCESSOR_CELL,
1409 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
66188a7e
GK
1410 {"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS},
1411 {"ec603e", PROCESSOR_PPC603, POWERPC_BASE_MASK | MASK_SOFT_FLOAT},
1412 {"G3", PROCESSOR_PPC750, POWERPC_BASE_MASK | MASK_PPC_GFXOPT},
1413 {"G4", PROCESSOR_PPC7450, POWERPC_7400_MASK},
49ffe578 1414 {"G5", PROCESSOR_POWER4,
66188a7e
GK
1415 POWERPC_7400_MASK | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64},
1416 {"power", PROCESSOR_POWER, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1417 {"power2", PROCESSOR_POWER,
1418 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
7ddb6568
AM
1419 {"power3", PROCESSOR_PPC630,
1420 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
1421 {"power4", PROCESSOR_POWER4,
fc091c8e 1422 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_MFCRF | MASK_POWERPC64},
ec507f2d 1423 {"power5", PROCESSOR_POWER5,
432218ba
DE
1424 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1425 | MASK_MFCRF | MASK_POPCNTB},
9719f3b7
DE
1426 {"power5+", PROCESSOR_POWER5,
1427 POWERPC_BASE_MASK | MASK_POWERPC64 | MASK_PPC_GFXOPT
1428 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND},
44cd321e 1429 {"power6", PROCESSOR_POWER6,
e118597e 1430 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
b639c3c2 1431 | MASK_FPRND | MASK_CMPB | MASK_DFP },
44cd321e
PS
1432 {"power6x", PROCESSOR_POWER6,
1433 POWERPC_7400_MASK | MASK_POWERPC64 | MASK_MFCRF | MASK_POPCNTB
b639c3c2 1434 | MASK_FPRND | MASK_CMPB | MASK_MFPGPR | MASK_DFP },
66188a7e
GK
1435 {"powerpc", PROCESSOR_POWERPC, POWERPC_BASE_MASK},
1436 {"powerpc64", PROCESSOR_POWERPC64,
98c41d98 1437 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64},
66188a7e
GK
1438 {"rios", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1439 {"rios1", PROCESSOR_RIOS1, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1440 {"rios2", PROCESSOR_RIOS2,
1441 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING},
1442 {"rsc", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
1443 {"rsc1", PROCESSOR_PPC601, MASK_POWER | MASK_MULTIPLE | MASK_STRING},
98c41d98
DE
1444 {"rs64", PROCESSOR_RS64A,
1445 POWERPC_BASE_MASK | MASK_PPC_GFXOPT | MASK_POWERPC64}
66188a7e 1446 };
5248c961 1447
ca7558fc 1448 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 1449
66188a7e
GK
1450 /* Some OSs don't support saving the high part of 64-bit registers on
1451 context switch. Other OSs don't support saving Altivec registers.
1452 On those OSs, we don't touch the MASK_POWERPC64 or MASK_ALTIVEC
1453 settings; if the user wants either, the user must explicitly specify
1454 them and we won't interfere with the user's specification. */
1455
1456 enum {
1457 POWER_MASKS = MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
db2675d3 1458 POWERPC_MASKS = (POWERPC_BASE_MASK | MASK_PPC_GPOPT | MASK_STRICT_ALIGN
66188a7e 1459 | MASK_PPC_GFXOPT | MASK_POWERPC64 | MASK_ALTIVEC
716019c0 1460 | MASK_MFCRF | MASK_POPCNTB | MASK_FPRND | MASK_MULHW
b639c3c2 1461 | MASK_DLMZB | MASK_CMPB | MASK_MFPGPR | MASK_DFP)
66188a7e 1462 };
0d1fbc8c
AH
1463
1464 rs6000_init_hard_regno_mode_ok ();
1465
c4ad648e 1466 set_masks = POWER_MASKS | POWERPC_MASKS | MASK_SOFT_FLOAT;
66188a7e
GK
1467#ifdef OS_MISSING_POWERPC64
1468 if (OS_MISSING_POWERPC64)
1469 set_masks &= ~MASK_POWERPC64;
1470#endif
1471#ifdef OS_MISSING_ALTIVEC
1472 if (OS_MISSING_ALTIVEC)
1473 set_masks &= ~MASK_ALTIVEC;
1474#endif
1475
768875a8
AM
1476 /* Don't override by the processor default if given explicitly. */
1477 set_masks &= ~target_flags_explicit;
957211c3 1478
a4f6c312 1479 /* Identify the processor type. */
8e3f41e7 1480 rs6000_select[0].string = default_cpu;
3cb999d8 1481 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 1482
b6a1cbae 1483 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 1484 {
8e3f41e7
MM
1485 ptr = &rs6000_select[i];
1486 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 1487 {
8e3f41e7
MM
1488 for (j = 0; j < ptt_size; j++)
1489 if (! strcmp (ptr->string, processor_target_table[j].name))
1490 {
1491 if (ptr->set_tune_p)
1492 rs6000_cpu = processor_target_table[j].processor;
1493
1494 if (ptr->set_arch_p)
1495 {
66188a7e
GK
1496 target_flags &= ~set_masks;
1497 target_flags |= (processor_target_table[j].target_enable
1498 & set_masks);
8e3f41e7
MM
1499 }
1500 break;
1501 }
1502
4406229e 1503 if (j == ptt_size)
8e3f41e7 1504 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
1505 }
1506 }
8a61d227 1507
993f19a8 1508 if (TARGET_E500)
a3170dc6
AH
1509 rs6000_isel = 1;
1510
dff9f1b6
DE
1511 /* If we are optimizing big endian systems for space, use the load/store
1512 multiple and string instructions. */
ef792183 1513 if (BYTES_BIG_ENDIAN && optimize_size)
957211c3 1514 target_flags |= ~target_flags_explicit & (MASK_MULTIPLE | MASK_STRING);
938937d8 1515
a4f6c312
SS
1516 /* Don't allow -mmultiple or -mstring on little endian systems
1517 unless the cpu is a 750, because the hardware doesn't support the
1518 instructions used in little endian mode, and causes an alignment
1519 trap. The 750 does not cause an alignment trap (except when the
1520 target is unaligned). */
bef84347 1521
b21fb038 1522 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
1523 {
1524 if (TARGET_MULTIPLE)
1525 {
1526 target_flags &= ~MASK_MULTIPLE;
b21fb038 1527 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
d4ee4d25 1528 warning (0, "-mmultiple is not supported on little endian systems");
7e69e155
MM
1529 }
1530
1531 if (TARGET_STRING)
1532 {
1533 target_flags &= ~MASK_STRING;
b21fb038 1534 if ((target_flags_explicit & MASK_STRING) != 0)
d4ee4d25 1535 warning (0, "-mstring is not supported on little endian systems");
7e69e155
MM
1536 }
1537 }
3933e0e1 1538
38c1f2d7
MM
1539 /* Set debug flags */
1540 if (rs6000_debug_name)
1541 {
bfc79d3b 1542 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 1543 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 1544 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 1545 rs6000_debug_stack = 1;
bfc79d3b 1546 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
1547 rs6000_debug_arg = 1;
1548 else
c725bd79 1549 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
1550 }
1551
57ac7be9
AM
1552 if (rs6000_traceback_name)
1553 {
1554 if (! strncmp (rs6000_traceback_name, "full", 4))
1555 rs6000_traceback = traceback_full;
1556 else if (! strncmp (rs6000_traceback_name, "part", 4))
1557 rs6000_traceback = traceback_part;
1558 else if (! strncmp (rs6000_traceback_name, "no", 2))
1559 rs6000_traceback = traceback_none;
1560 else
9e637a26 1561 error ("unknown -mtraceback arg %qs; expecting %<full%>, %<partial%> or %<none%>",
57ac7be9
AM
1562 rs6000_traceback_name);
1563 }
1564
78f5898b
AH
1565 if (!rs6000_explicit_options.long_double)
1566 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
6fa3f289 1567
602ea4d3 1568#ifndef POWERPC_LINUX
d3603e8c 1569 if (!rs6000_explicit_options.ieee)
602ea4d3
JJ
1570 rs6000_ieeequad = 1;
1571#endif
1572
6d0ef01e
HP
1573 /* Set Altivec ABI as default for powerpc64 linux. */
1574 if (TARGET_ELF && TARGET_64BIT)
1575 {
1576 rs6000_altivec_abi = 1;
78f5898b 1577 TARGET_ALTIVEC_VRSAVE = 1;
6d0ef01e
HP
1578 }
1579
594a51fe
SS
1580 /* Set the Darwin64 ABI as default for 64-bit Darwin. */
1581 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
1582 {
1583 rs6000_darwin64_abi = 1;
9c7956fd 1584#if TARGET_MACHO
6ac49599 1585 darwin_one_byte_bool = 1;
9c7956fd 1586#endif
d9168963
SS
1587 /* Default to natural alignment, for better performance. */
1588 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
594a51fe
SS
1589 }
1590
194c524a
DE
1591 /* Place FP constants in the constant pool instead of TOC
1592 if section anchors enabled. */
1593 if (flag_section_anchors)
1594 TARGET_NO_FP_IN_TOC = 1;
1595
c4501e62
JJ
1596 /* Handle -mtls-size option. */
1597 rs6000_parse_tls_size_option ();
1598
a7ae18e2
AH
1599#ifdef SUBTARGET_OVERRIDE_OPTIONS
1600 SUBTARGET_OVERRIDE_OPTIONS;
1601#endif
1602#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
1603 SUBSUBTARGET_OVERRIDE_OPTIONS;
1604#endif
4d4cbc0e
AH
1605#ifdef SUB3TARGET_OVERRIDE_OPTIONS
1606 SUB3TARGET_OVERRIDE_OPTIONS;
1607#endif
a7ae18e2 1608
5da702b1
AH
1609 if (TARGET_E500)
1610 {
1611 /* The e500 does not have string instructions, and we set
1612 MASK_STRING above when optimizing for size. */
1613 if ((target_flags & MASK_STRING) != 0)
1614 target_flags = target_flags & ~MASK_STRING;
1615 }
1616 else if (rs6000_select[1].string != NULL)
1617 {
1618 /* For the powerpc-eabispe configuration, we set all these by
1619 default, so let's unset them if we manually set another
1620 CPU that is not the E500. */
78f5898b 1621 if (!rs6000_explicit_options.abi)
5da702b1 1622 rs6000_spe_abi = 0;
78f5898b 1623 if (!rs6000_explicit_options.spe)
5da702b1 1624 rs6000_spe = 0;
78f5898b 1625 if (!rs6000_explicit_options.float_gprs)
5da702b1 1626 rs6000_float_gprs = 0;
78f5898b 1627 if (!rs6000_explicit_options.isel)
5da702b1
AH
1628 rs6000_isel = 0;
1629 }
b5044283 1630
eca0d5e8
JM
1631 /* Detect invalid option combinations with E500. */
1632 CHECK_E500_OPTIONS;
1633
ec507f2d 1634 rs6000_always_hint = (rs6000_cpu != PROCESSOR_POWER4
44cd321e 1635 && rs6000_cpu != PROCESSOR_POWER5
d296e02e
AP
1636 && rs6000_cpu != PROCESSOR_POWER6
1637 && rs6000_cpu != PROCESSOR_CELL);
ec507f2d
DE
1638 rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4
1639 || rs6000_cpu == PROCESSOR_POWER5);
44cd321e
PS
1640 rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4
1641 || rs6000_cpu == PROCESSOR_POWER5
1642 || rs6000_cpu == PROCESSOR_POWER6);
ec507f2d 1643
ec507f2d
DE
1644 rs6000_sched_restricted_insns_priority
1645 = (rs6000_sched_groups ? 1 : 0);
79ae11c4 1646
569fa502 1647 /* Handle -msched-costly-dep option. */
ec507f2d
DE
1648 rs6000_sched_costly_dep
1649 = (rs6000_sched_groups ? store_to_load_dep_costly : no_dep_costly);
432218ba 1650
569fa502
DN
1651 if (rs6000_sched_costly_dep_str)
1652 {
f676971a 1653 if (! strcmp (rs6000_sched_costly_dep_str, "no"))
c4ad648e 1654 rs6000_sched_costly_dep = no_dep_costly;
569fa502 1655 else if (! strcmp (rs6000_sched_costly_dep_str, "all"))
c4ad648e 1656 rs6000_sched_costly_dep = all_deps_costly;
569fa502 1657 else if (! strcmp (rs6000_sched_costly_dep_str, "true_store_to_load"))
c4ad648e 1658 rs6000_sched_costly_dep = true_store_to_load_dep_costly;
569fa502 1659 else if (! strcmp (rs6000_sched_costly_dep_str, "store_to_load"))
c4ad648e 1660 rs6000_sched_costly_dep = store_to_load_dep_costly;
f676971a 1661 else
c4ad648e 1662 rs6000_sched_costly_dep = atoi (rs6000_sched_costly_dep_str);
cbe26ab8
DN
1663 }
1664
1665 /* Handle -minsert-sched-nops option. */
ec507f2d
DE
1666 rs6000_sched_insert_nops
1667 = (rs6000_sched_groups ? sched_finish_regroup_exact : sched_finish_none);
432218ba 1668
cbe26ab8
DN
1669 if (rs6000_sched_insert_nops_str)
1670 {
1671 if (! strcmp (rs6000_sched_insert_nops_str, "no"))
c4ad648e 1672 rs6000_sched_insert_nops = sched_finish_none;
cbe26ab8 1673 else if (! strcmp (rs6000_sched_insert_nops_str, "pad"))
c4ad648e 1674 rs6000_sched_insert_nops = sched_finish_pad_groups;
cbe26ab8 1675 else if (! strcmp (rs6000_sched_insert_nops_str, "regroup_exact"))
c4ad648e 1676 rs6000_sched_insert_nops = sched_finish_regroup_exact;
cbe26ab8 1677 else
c4ad648e 1678 rs6000_sched_insert_nops = atoi (rs6000_sched_insert_nops_str);
569fa502
DN
1679 }
1680
c81bebd7 1681#ifdef TARGET_REGNAMES
a4f6c312
SS
1682 /* If the user desires alternate register names, copy in the
1683 alternate names now. */
c81bebd7 1684 if (TARGET_REGNAMES)
4e135bdd 1685 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
1686#endif
1687
df01da37 1688 /* Set aix_struct_return last, after the ABI is determined.
6fa3f289
ZW
1689 If -maix-struct-return or -msvr4-struct-return was explicitly
1690 used, don't override with the ABI default. */
df01da37
DE
1691 if (!rs6000_explicit_options.aix_struct_ret)
1692 aix_struct_return = (DEFAULT_ABI != ABI_V4 || DRAFT_V4_STRUCT_RET);
6fa3f289 1693
602ea4d3 1694 if (TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD)
70a01792 1695 REAL_MODE_FORMAT (TFmode) = &ibm_extended_format;
fcce224d 1696
f676971a 1697 if (TARGET_TOC)
9ebbca7d 1698 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 1699
301d03af
RS
1700 /* We can only guarantee the availability of DI pseudo-ops when
1701 assembling for 64-bit targets. */
ae6c1efd 1702 if (!TARGET_64BIT)
301d03af
RS
1703 {
1704 targetm.asm_out.aligned_op.di = NULL;
1705 targetm.asm_out.unaligned_op.di = NULL;
1706 }
1707
1494c534
DE
1708 /* Set branch target alignment, if not optimizing for size. */
1709 if (!optimize_size)
1710 {
d296e02e
AP
1711 /* Cell wants to be aligned 8byte for dual issue. */
1712 if (rs6000_cpu == PROCESSOR_CELL)
1713 {
1714 if (align_functions <= 0)
1715 align_functions = 8;
1716 if (align_jumps <= 0)
1717 align_jumps = 8;
1718 if (align_loops <= 0)
1719 align_loops = 8;
1720 }
44cd321e 1721 if (rs6000_align_branch_targets)
1494c534
DE
1722 {
1723 if (align_functions <= 0)
1724 align_functions = 16;
1725 if (align_jumps <= 0)
1726 align_jumps = 16;
1727 if (align_loops <= 0)
1728 align_loops = 16;
1729 }
1730 if (align_jumps_max_skip <= 0)
1731 align_jumps_max_skip = 15;
1732 if (align_loops_max_skip <= 0)
1733 align_loops_max_skip = 15;
1734 }
2792d578 1735
71f123ca
FS
1736 /* Arrange to save and restore machine status around nested functions. */
1737 init_machine_status = rs6000_init_machine_status;
42ba5130
RH
1738
1739 /* We should always be splitting complex arguments, but we can't break
1740 Linux and Darwin ABIs at the moment. For now, only AIX is fixed. */
18f63bfa 1741 if (DEFAULT_ABI != ABI_AIX)
42ba5130 1742 targetm.calls.split_complex_arg = NULL;
8b897cfa
RS
1743
1744 /* Initialize rs6000_cost with the appropriate target costs. */
1745 if (optimize_size)
1746 rs6000_cost = TARGET_POWERPC64 ? &size64_cost : &size32_cost;
1747 else
1748 switch (rs6000_cpu)
1749 {
1750 case PROCESSOR_RIOS1:
1751 rs6000_cost = &rios1_cost;
1752 break;
1753
1754 case PROCESSOR_RIOS2:
1755 rs6000_cost = &rios2_cost;
1756 break;
1757
1758 case PROCESSOR_RS64A:
1759 rs6000_cost = &rs64a_cost;
1760 break;
1761
1762 case PROCESSOR_MPCCORE:
1763 rs6000_cost = &mpccore_cost;
1764 break;
1765
1766 case PROCESSOR_PPC403:
1767 rs6000_cost = &ppc403_cost;
1768 break;
1769
1770 case PROCESSOR_PPC405:
1771 rs6000_cost = &ppc405_cost;
1772 break;
1773
1774 case PROCESSOR_PPC440:
1775 rs6000_cost = &ppc440_cost;
1776 break;
1777
1778 case PROCESSOR_PPC601:
1779 rs6000_cost = &ppc601_cost;
1780 break;
1781
1782 case PROCESSOR_PPC603:
1783 rs6000_cost = &ppc603_cost;
1784 break;
1785
1786 case PROCESSOR_PPC604:
1787 rs6000_cost = &ppc604_cost;
1788 break;
1789
1790 case PROCESSOR_PPC604e:
1791 rs6000_cost = &ppc604e_cost;
1792 break;
1793
1794 case PROCESSOR_PPC620:
8b897cfa
RS
1795 rs6000_cost = &ppc620_cost;
1796 break;
1797
f0517163
RS
1798 case PROCESSOR_PPC630:
1799 rs6000_cost = &ppc630_cost;
1800 break;
1801
982afe02 1802 case PROCESSOR_CELL:
d296e02e
AP
1803 rs6000_cost = &ppccell_cost;
1804 break;
1805
8b897cfa
RS
1806 case PROCESSOR_PPC750:
1807 case PROCESSOR_PPC7400:
1808 rs6000_cost = &ppc750_cost;
1809 break;
1810
1811 case PROCESSOR_PPC7450:
1812 rs6000_cost = &ppc7450_cost;
1813 break;
1814
1815 case PROCESSOR_PPC8540:
1816 rs6000_cost = &ppc8540_cost;
1817 break;
1818
1819 case PROCESSOR_POWER4:
1820 case PROCESSOR_POWER5:
1821 rs6000_cost = &power4_cost;
1822 break;
1823
44cd321e
PS
1824 case PROCESSOR_POWER6:
1825 rs6000_cost = &power6_cost;
1826 break;
1827
8b897cfa 1828 default:
37409796 1829 gcc_unreachable ();
8b897cfa 1830 }
0b11da67
DE
1831
1832 if (!PARAM_SET_P (PARAM_SIMULTANEOUS_PREFETCHES))
1833 set_param_value ("simultaneous-prefetches",
1834 rs6000_cost->simultaneous_prefetches);
1835 if (!PARAM_SET_P (PARAM_L1_CACHE_SIZE))
5f732aba 1836 set_param_value ("l1-cache-size", rs6000_cost->l1_cache_size);
0b11da67
DE
1837 if (!PARAM_SET_P (PARAM_L1_CACHE_LINE_SIZE))
1838 set_param_value ("l1-cache-line-size", rs6000_cost->cache_line_size);
5f732aba
DE
1839 if (!PARAM_SET_P (PARAM_L2_CACHE_SIZE))
1840 set_param_value ("l2-cache-size", rs6000_cost->l2_cache_size);
5248c961 1841}
5accd822 1842
7ccf35ed
DN
1843/* Implement targetm.vectorize.builtin_mask_for_load. */
1844static tree
1845rs6000_builtin_mask_for_load (void)
1846{
1847 if (TARGET_ALTIVEC)
1848 return altivec_builtin_mask_for_load;
1849 else
1850 return 0;
1851}
1852
f57d17f1
TM
1853/* Implement targetm.vectorize.builtin_conversion. */
1854static tree
1855rs6000_builtin_conversion (enum tree_code code, tree type)
1856{
1857 if (!TARGET_ALTIVEC)
1858 return NULL_TREE;
982afe02 1859
f57d17f1
TM
1860 switch (code)
1861 {
1862 case FLOAT_EXPR:
1863 switch (TYPE_MODE (type))
1864 {
1865 case V4SImode:
982afe02 1866 return TYPE_UNSIGNED (type) ?
f57d17f1
TM
1867 rs6000_builtin_decls[ALTIVEC_BUILTIN_VCFUX] :
1868 rs6000_builtin_decls[ALTIVEC_BUILTIN_VCFSX];
1869 default:
1870 return NULL_TREE;
1871 }
1872 default:
1873 return NULL_TREE;
1874 }
1875}
1876
89d67cca
DN
1877/* Implement targetm.vectorize.builtin_mul_widen_even. */
1878static tree
1879rs6000_builtin_mul_widen_even (tree type)
1880{
1881 if (!TARGET_ALTIVEC)
1882 return NULL_TREE;
1883
1884 switch (TYPE_MODE (type))
1885 {
1886 case V8HImode:
982afe02 1887 return TYPE_UNSIGNED (type) ?
89d67cca
DN
1888 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUH] :
1889 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESH];
1890
1891 case V16QImode:
1892 return TYPE_UNSIGNED (type) ?
1893 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULEUB] :
1894 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULESB];
1895 default:
1896 return NULL_TREE;
1897 }
1898}
1899
1900/* Implement targetm.vectorize.builtin_mul_widen_odd. */
1901static tree
1902rs6000_builtin_mul_widen_odd (tree type)
1903{
1904 if (!TARGET_ALTIVEC)
1905 return NULL_TREE;
1906
1907 switch (TYPE_MODE (type))
1908 {
1909 case V8HImode:
1910 return TYPE_UNSIGNED (type) ?
1911 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUH] :
1912 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSH];
1913
1914 case V16QImode:
1915 return TYPE_UNSIGNED (type) ?
1916 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOUB] :
1917 rs6000_builtin_decls[ALTIVEC_BUILTIN_VMULOSB];
1918 default:
1919 return NULL_TREE;
1920 }
1921}
1922
5b900a4c
DN
1923
1924/* Return true iff, data reference of TYPE can reach vector alignment (16)
1925 after applying N number of iterations. This routine does not determine
1926 how may iterations are required to reach desired alignment. */
1927
1928static bool
3101faab 1929rs6000_vector_alignment_reachable (const_tree type ATTRIBUTE_UNUSED, bool is_packed)
5b900a4c
DN
1930{
1931 if (is_packed)
1932 return false;
1933
1934 if (TARGET_32BIT)
1935 {
1936 if (rs6000_alignment_flags == MASK_ALIGN_NATURAL)
1937 return true;
1938
1939 if (rs6000_alignment_flags == MASK_ALIGN_POWER)
1940 return true;
1941
1942 return false;
1943 }
1944 else
1945 {
1946 if (TARGET_MACHO)
1947 return false;
1948
1949 /* Assuming that all other types are naturally aligned. CHECKME! */
1950 return true;
1951 }
1952}
1953
5da702b1
AH
1954/* Handle generic options of the form -mfoo=yes/no.
1955 NAME is the option name.
1956 VALUE is the option value.
1957 FLAG is the pointer to the flag where to store a 1 or 0, depending on
1958 whether the option value is 'yes' or 'no' respectively. */
993f19a8 1959static void
5da702b1 1960rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
993f19a8 1961{
5da702b1 1962 if (value == 0)
993f19a8 1963 return;
5da702b1
AH
1964 else if (!strcmp (value, "yes"))
1965 *flag = 1;
1966 else if (!strcmp (value, "no"))
1967 *flag = 0;
08b57fb3 1968 else
5da702b1 1969 error ("unknown -m%s= option specified: '%s'", name, value);
08b57fb3
AH
1970}
1971
c4501e62
JJ
1972/* Validate and record the size specified with the -mtls-size option. */
1973
1974static void
863d938c 1975rs6000_parse_tls_size_option (void)
c4501e62
JJ
1976{
1977 if (rs6000_tls_size_string == 0)
1978 return;
1979 else if (strcmp (rs6000_tls_size_string, "16") == 0)
1980 rs6000_tls_size = 16;
1981 else if (strcmp (rs6000_tls_size_string, "32") == 0)
1982 rs6000_tls_size = 32;
1983 else if (strcmp (rs6000_tls_size_string, "64") == 0)
1984 rs6000_tls_size = 64;
1985 else
9e637a26 1986 error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
c4501e62
JJ
1987}
1988
5accd822 1989void
a2369ed3 1990optimization_options (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
5accd822 1991{
2e3f0db6
DJ
1992 if (DEFAULT_ABI == ABI_DARWIN)
1993 /* The Darwin libraries never set errno, so we might as well
1994 avoid calling them when that's the only reason we would. */
1995 flag_errno_math = 0;
59d6560b
DE
1996
1997 /* Double growth factor to counter reduced min jump length. */
1998 set_param_value ("max-grow-copy-bb-insns", 16);
194c524a
DE
1999
2000 /* Enable section anchors by default.
2001 Skip section anchors for Objective C and Objective C++
2002 until front-ends fixed. */
23f99493 2003 if (!TARGET_MACHO && lang_hooks.name[4] != 'O')
194c524a 2004 flag_section_anchors = 1;
5accd822 2005}
78f5898b
AH
2006
2007/* Implement TARGET_HANDLE_OPTION. */
2008
2009static bool
2010rs6000_handle_option (size_t code, const char *arg, int value)
2011{
2012 switch (code)
2013 {
2014 case OPT_mno_power:
2015 target_flags &= ~(MASK_POWER | MASK_POWER2
2016 | MASK_MULTIPLE | MASK_STRING);
c2dba4ab
AH
2017 target_flags_explicit |= (MASK_POWER | MASK_POWER2
2018 | MASK_MULTIPLE | MASK_STRING);
78f5898b
AH
2019 break;
2020 case OPT_mno_powerpc:
2021 target_flags &= ~(MASK_POWERPC | MASK_PPC_GPOPT
2022 | MASK_PPC_GFXOPT | MASK_POWERPC64);
c2dba4ab
AH
2023 target_flags_explicit |= (MASK_POWERPC | MASK_PPC_GPOPT
2024 | MASK_PPC_GFXOPT | MASK_POWERPC64);
78f5898b
AH
2025 break;
2026 case OPT_mfull_toc:
d2894ab5
DE
2027 target_flags &= ~MASK_MINIMAL_TOC;
2028 TARGET_NO_FP_IN_TOC = 0;
2029 TARGET_NO_SUM_IN_TOC = 0;
2030 target_flags_explicit |= MASK_MINIMAL_TOC;
78f5898b
AH
2031#ifdef TARGET_USES_SYSV4_OPT
2032 /* Note, V.4 no longer uses a normal TOC, so make -mfull-toc, be
2033 just the same as -mminimal-toc. */
2034 target_flags |= MASK_MINIMAL_TOC;
c2dba4ab 2035 target_flags_explicit |= MASK_MINIMAL_TOC;
78f5898b
AH
2036#endif
2037 break;
2038
2039#ifdef TARGET_USES_SYSV4_OPT
2040 case OPT_mtoc:
2041 /* Make -mtoc behave like -mminimal-toc. */
2042 target_flags |= MASK_MINIMAL_TOC;
c2dba4ab 2043 target_flags_explicit |= MASK_MINIMAL_TOC;
78f5898b
AH
2044 break;
2045#endif
2046
2047#ifdef TARGET_USES_AIX64_OPT
2048 case OPT_maix64:
2049#else
2050 case OPT_m64:
2051#endif
2c9c9afd
AM
2052 target_flags |= MASK_POWERPC64 | MASK_POWERPC;
2053 target_flags |= ~target_flags_explicit & MASK_PPC_GFXOPT;
2054 target_flags_explicit |= MASK_POWERPC64 | MASK_POWERPC;
78f5898b
AH
2055 break;
2056
2057#ifdef TARGET_USES_AIX64_OPT
2058 case OPT_maix32:
2059#else
2060 case OPT_m32:
2061#endif
2062 target_flags &= ~MASK_POWERPC64;
c2dba4ab 2063 target_flags_explicit |= MASK_POWERPC64;
78f5898b
AH
2064 break;
2065
2066 case OPT_minsert_sched_nops_:
2067 rs6000_sched_insert_nops_str = arg;
2068 break;
2069
2070 case OPT_mminimal_toc:
2071 if (value == 1)
2072 {
d2894ab5
DE
2073 TARGET_NO_FP_IN_TOC = 0;
2074 TARGET_NO_SUM_IN_TOC = 0;
78f5898b
AH
2075 }
2076 break;
2077
2078 case OPT_mpower:
2079 if (value == 1)
c2dba4ab
AH
2080 {
2081 target_flags |= (MASK_MULTIPLE | MASK_STRING);
2082 target_flags_explicit |= (MASK_MULTIPLE | MASK_STRING);
2083 }
78f5898b
AH
2084 break;
2085
2086 case OPT_mpower2:
2087 if (value == 1)
c2dba4ab
AH
2088 {
2089 target_flags |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
2090 target_flags_explicit |= (MASK_POWER | MASK_MULTIPLE | MASK_STRING);
2091 }
78f5898b
AH
2092 break;
2093
2094 case OPT_mpowerpc_gpopt:
2095 case OPT_mpowerpc_gfxopt:
2096 if (value == 1)
c2dba4ab
AH
2097 {
2098 target_flags |= MASK_POWERPC;
2099 target_flags_explicit |= MASK_POWERPC;
2100 }
78f5898b
AH
2101 break;
2102
df01da37
DE
2103 case OPT_maix_struct_return:
2104 case OPT_msvr4_struct_return:
2105 rs6000_explicit_options.aix_struct_ret = true;
2106 break;
2107
78f5898b
AH
2108 case OPT_mvrsave_:
2109 rs6000_parse_yes_no_option ("vrsave", arg, &(TARGET_ALTIVEC_VRSAVE));
2110 break;
78f5898b
AH
2111
2112 case OPT_misel_:
2113 rs6000_explicit_options.isel = true;
2114 rs6000_parse_yes_no_option ("isel", arg, &(rs6000_isel));
2115 break;
2116
2117 case OPT_mspe_:
2118 rs6000_explicit_options.spe = true;
2119 rs6000_parse_yes_no_option ("spe", arg, &(rs6000_spe));
78f5898b
AH
2120 break;
2121
2122 case OPT_mdebug_:
2123 rs6000_debug_name = arg;
2124 break;
2125
2126#ifdef TARGET_USES_SYSV4_OPT
2127 case OPT_mcall_:
2128 rs6000_abi_name = arg;
2129 break;
2130
2131 case OPT_msdata_:
2132 rs6000_sdata_name = arg;
2133 break;
2134
2135 case OPT_mtls_size_:
2136 rs6000_tls_size_string = arg;
2137 break;
2138
2139 case OPT_mrelocatable:
2140 if (value == 1)
c2dba4ab 2141 {
e0bf274f
AM
2142 target_flags |= MASK_MINIMAL_TOC;
2143 target_flags_explicit |= MASK_MINIMAL_TOC;
2144 TARGET_NO_FP_IN_TOC = 1;
c2dba4ab 2145 }
78f5898b
AH
2146 break;
2147
2148 case OPT_mrelocatable_lib:
2149 if (value == 1)
c2dba4ab 2150 {
e0bf274f
AM
2151 target_flags |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
2152 target_flags_explicit |= MASK_RELOCATABLE | MASK_MINIMAL_TOC;
2153 TARGET_NO_FP_IN_TOC = 1;
c2dba4ab 2154 }
78f5898b 2155 else
c2dba4ab
AH
2156 {
2157 target_flags &= ~MASK_RELOCATABLE;
2158 target_flags_explicit |= MASK_RELOCATABLE;
2159 }
78f5898b
AH
2160 break;
2161#endif
2162
2163 case OPT_mabi_:
78f5898b
AH
2164 if (!strcmp (arg, "altivec"))
2165 {
d3603e8c 2166 rs6000_explicit_options.abi = true;
78f5898b
AH
2167 rs6000_altivec_abi = 1;
2168 rs6000_spe_abi = 0;
2169 }
2170 else if (! strcmp (arg, "no-altivec"))
d3603e8c
AM
2171 {
2172 /* ??? Don't set rs6000_explicit_options.abi here, to allow
2173 the default for rs6000_spe_abi to be chosen later. */
2174 rs6000_altivec_abi = 0;
2175 }
78f5898b
AH
2176 else if (! strcmp (arg, "spe"))
2177 {
d3603e8c 2178 rs6000_explicit_options.abi = true;
78f5898b
AH
2179 rs6000_spe_abi = 1;
2180 rs6000_altivec_abi = 0;
2181 if (!TARGET_SPE_ABI)
2182 error ("not configured for ABI: '%s'", arg);
2183 }
2184 else if (! strcmp (arg, "no-spe"))
d3603e8c
AM
2185 {
2186 rs6000_explicit_options.abi = true;
2187 rs6000_spe_abi = 0;
2188 }
78f5898b
AH
2189
2190 /* These are here for testing during development only, do not
2191 document in the manual please. */
2192 else if (! strcmp (arg, "d64"))
2193 {
2194 rs6000_darwin64_abi = 1;
2195 warning (0, "Using darwin64 ABI");
2196 }
2197 else if (! strcmp (arg, "d32"))
2198 {
2199 rs6000_darwin64_abi = 0;
2200 warning (0, "Using old darwin ABI");
2201 }
2202
602ea4d3
JJ
2203 else if (! strcmp (arg, "ibmlongdouble"))
2204 {
d3603e8c 2205 rs6000_explicit_options.ieee = true;
602ea4d3
JJ
2206 rs6000_ieeequad = 0;
2207 warning (0, "Using IBM extended precision long double");
2208 }
2209 else if (! strcmp (arg, "ieeelongdouble"))
2210 {
d3603e8c 2211 rs6000_explicit_options.ieee = true;
602ea4d3
JJ
2212 rs6000_ieeequad = 1;
2213 warning (0, "Using IEEE extended precision long double");
2214 }
2215
78f5898b
AH
2216 else
2217 {
2218 error ("unknown ABI specified: '%s'", arg);
2219 return false;
2220 }
2221 break;
2222
2223 case OPT_mcpu_:
2224 rs6000_select[1].string = arg;
2225 break;
2226
2227 case OPT_mtune_:
2228 rs6000_select[2].string = arg;
2229 break;
2230
2231 case OPT_mtraceback_:
2232 rs6000_traceback_name = arg;
2233 break;
2234
2235 case OPT_mfloat_gprs_:
2236 rs6000_explicit_options.float_gprs = true;
2237 if (! strcmp (arg, "yes") || ! strcmp (arg, "single"))
2238 rs6000_float_gprs = 1;
2239 else if (! strcmp (arg, "double"))
2240 rs6000_float_gprs = 2;
2241 else if (! strcmp (arg, "no"))
2242 rs6000_float_gprs = 0;
2243 else
2244 {
2245 error ("invalid option for -mfloat-gprs: '%s'", arg);
2246 return false;
2247 }
2248 break;
2249
2250 case OPT_mlong_double_:
2251 rs6000_explicit_options.long_double = true;
2252 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2253 if (value != 64 && value != 128)
2254 {
2255 error ("Unknown switch -mlong-double-%s", arg);
2256 rs6000_long_double_type_size = RS6000_DEFAULT_LONG_DOUBLE_SIZE;
2257 return false;
2258 }
2259 else
2260 rs6000_long_double_type_size = value;
2261 break;
2262
2263 case OPT_msched_costly_dep_:
2264 rs6000_sched_costly_dep_str = arg;
2265 break;
2266
2267 case OPT_malign_:
2268 rs6000_explicit_options.alignment = true;
2269 if (! strcmp (arg, "power"))
2270 {
2271 /* On 64-bit Darwin, power alignment is ABI-incompatible with
2272 some C library functions, so warn about it. The flag may be
2273 useful for performance studies from time to time though, so
2274 don't disable it entirely. */
2275 if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
2276 warning (0, "-malign-power is not supported for 64-bit Darwin;"
2277 " it is incompatible with the installed C and C++ libraries");
2278 rs6000_alignment_flags = MASK_ALIGN_POWER;
2279 }
2280 else if (! strcmp (arg, "natural"))
2281 rs6000_alignment_flags = MASK_ALIGN_NATURAL;
2282 else
2283 {
2284 error ("unknown -malign-XXXXX option specified: '%s'", arg);
2285 return false;
2286 }
2287 break;
2288 }
2289 return true;
2290}
3cfa4909
MM
2291\f
2292/* Do anything needed at the start of the asm file. */
2293
1bc7c5b6 2294static void
863d938c 2295rs6000_file_start (void)
3cfa4909 2296{
c4d38ccb 2297 size_t i;
3cfa4909 2298 char buffer[80];
d330fd93 2299 const char *start = buffer;
3cfa4909 2300 struct rs6000_cpu_select *ptr;
1bc7c5b6
ZW
2301 const char *default_cpu = TARGET_CPU_DEFAULT;
2302 FILE *file = asm_out_file;
2303
2304 default_file_start ();
2305
2306#ifdef TARGET_BI_ARCH
2307 if ((TARGET_DEFAULT ^ target_flags) & MASK_64BIT)
2308 default_cpu = 0;
2309#endif
3cfa4909
MM
2310
2311 if (flag_verbose_asm)
2312 {
2313 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
2314 rs6000_select[0].string = default_cpu;
2315
b6a1cbae 2316 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
2317 {
2318 ptr = &rs6000_select[i];
2319 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
2320 {
2321 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
2322 start = "";
2323 }
2324 }
2325
9c6b4ed9 2326 if (PPC405_ERRATUM77)
b0bfee6e 2327 {
9c6b4ed9 2328 fprintf (file, "%s PPC405CR_ERRATUM77", start);
b0bfee6e
DE
2329 start = "";
2330 }
b0bfee6e 2331
b91da81f 2332#ifdef USING_ELFOS_H
3cfa4909
MM
2333 switch (rs6000_sdata)
2334 {
2335 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
2336 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
2337 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
2338 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
2339 }
2340
2341 if (rs6000_sdata && g_switch_value)
2342 {
307b599c
MK
2343 fprintf (file, "%s -G " HOST_WIDE_INT_PRINT_UNSIGNED, start,
2344 g_switch_value);
3cfa4909
MM
2345 start = "";
2346 }
2347#endif
2348
2349 if (*start == '\0')
949ea356 2350 putc ('\n', file);
3cfa4909 2351 }
b723e82f 2352
e51917ae
JM
2353#ifdef HAVE_AS_GNU_ATTRIBUTE
2354 if (TARGET_32BIT && DEFAULT_ABI == ABI_V4)
aaa42494
DJ
2355 {
2356 fprintf (file, "\t.gnu_attribute 4, %d\n",
2357 (TARGET_HARD_FLOAT && TARGET_FPRS) ? 1 : 2);
2358 fprintf (file, "\t.gnu_attribute 8, %d\n",
2359 (TARGET_ALTIVEC_ABI ? 2
2360 : TARGET_SPE_ABI ? 3
2361 : 1));
2362 }
e51917ae
JM
2363#endif
2364
b723e82f
JJ
2365 if (DEFAULT_ABI == ABI_AIX || (TARGET_ELF && flag_pic == 2))
2366 {
d6b5193b
RS
2367 switch_to_section (toc_section);
2368 switch_to_section (text_section);
b723e82f 2369 }
3cfa4909 2370}
c4e18b1c 2371
5248c961 2372\f
a0ab749a 2373/* Return nonzero if this function is known to have a null epilogue. */
9878760c
RK
2374
2375int
863d938c 2376direct_return (void)
9878760c 2377{
4697a36c
MM
2378 if (reload_completed)
2379 {
2380 rs6000_stack_t *info = rs6000_stack_info ();
2381
2382 if (info->first_gp_reg_save == 32
2383 && info->first_fp_reg_save == 64
00b960c7 2384 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
2385 && ! info->lr_save_p
2386 && ! info->cr_save_p
00b960c7 2387 && info->vrsave_mask == 0
c81fc13e 2388 && ! info->push_p)
4697a36c
MM
2389 return 1;
2390 }
2391
2392 return 0;
9878760c
RK
2393}
2394
4e74d8ec
MM
2395/* Return the number of instructions it takes to form a constant in an
2396 integer register. */
2397
48d72335 2398int
a2369ed3 2399num_insns_constant_wide (HOST_WIDE_INT value)
4e74d8ec
MM
2400{
2401 /* signed constant loadable with {cal|addi} */
547b216d 2402 if ((unsigned HOST_WIDE_INT) (value + 0x8000) < 0x10000)
0865c631
GK
2403 return 1;
2404
4e74d8ec 2405 /* constant loadable with {cau|addis} */
547b216d
DE
2406 else if ((value & 0xffff) == 0
2407 && (value >> 31 == -1 || value >> 31 == 0))
4e74d8ec
MM
2408 return 1;
2409
5f59ecb7 2410#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 2411 else if (TARGET_POWERPC64)
4e74d8ec 2412 {
a65c591c
DE
2413 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
2414 HOST_WIDE_INT high = value >> 31;
4e74d8ec 2415
a65c591c 2416 if (high == 0 || high == -1)
4e74d8ec
MM
2417 return 2;
2418
a65c591c 2419 high >>= 1;
4e74d8ec 2420
a65c591c 2421 if (low == 0)
4e74d8ec 2422 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
2423 else
2424 return (num_insns_constant_wide (high)
e396202a 2425 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
2426 }
2427#endif
2428
2429 else
2430 return 2;
2431}
2432
2433int
a2369ed3 2434num_insns_constant (rtx op, enum machine_mode mode)
4e74d8ec 2435{
37409796 2436 HOST_WIDE_INT low, high;
bb8df8a6 2437
37409796 2438 switch (GET_CODE (op))
0d30d435 2439 {
37409796 2440 case CONST_INT:
0d30d435 2441#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44 2442 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1990cd79 2443 && mask64_operand (op, mode))
c4ad648e 2444 return 2;
0d30d435
DE
2445 else
2446#endif
2447 return num_insns_constant_wide (INTVAL (op));
4e74d8ec 2448
37409796
NS
2449 case CONST_DOUBLE:
2450 if (mode == SFmode)
2451 {
2452 long l;
2453 REAL_VALUE_TYPE rv;
bb8df8a6 2454
37409796
NS
2455 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
2456 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
2457 return num_insns_constant_wide ((HOST_WIDE_INT) l);
2458 }
a260abc9 2459
37409796
NS
2460 if (mode == VOIDmode || mode == DImode)
2461 {
2462 high = CONST_DOUBLE_HIGH (op);
2463 low = CONST_DOUBLE_LOW (op);
2464 }
2465 else
2466 {
2467 long l[2];
2468 REAL_VALUE_TYPE rv;
bb8df8a6 2469
37409796 2470 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
7393f7f8
BE
2471 if (DECIMAL_FLOAT_MODE_P (mode))
2472 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, l);
2473 else
2474 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
37409796
NS
2475 high = l[WORDS_BIG_ENDIAN == 0];
2476 low = l[WORDS_BIG_ENDIAN != 0];
2477 }
47ad8c61 2478
37409796
NS
2479 if (TARGET_32BIT)
2480 return (num_insns_constant_wide (low)
2481 + num_insns_constant_wide (high));
2482 else
2483 {
2484 if ((high == 0 && low >= 0)
2485 || (high == -1 && low < 0))
2486 return num_insns_constant_wide (low);
bb8df8a6 2487
1990cd79 2488 else if (mask64_operand (op, mode))
37409796 2489 return 2;
bb8df8a6 2490
37409796
NS
2491 else if (low == 0)
2492 return num_insns_constant_wide (high) + 1;
bb8df8a6 2493
37409796
NS
2494 else
2495 return (num_insns_constant_wide (high)
2496 + num_insns_constant_wide (low) + 1);
2497 }
bb8df8a6 2498
37409796
NS
2499 default:
2500 gcc_unreachable ();
4e74d8ec 2501 }
4e74d8ec
MM
2502}
2503
0972012c
RS
2504/* Interpret element ELT of the CONST_VECTOR OP as an integer value.
2505 If the mode of OP is MODE_VECTOR_INT, this simply returns the
2506 corresponding element of the vector, but for V4SFmode and V2SFmode,
2507 the corresponding "float" is interpreted as an SImode integer. */
2508
2509static HOST_WIDE_INT
2510const_vector_elt_as_int (rtx op, unsigned int elt)
2511{
2512 rtx tmp = CONST_VECTOR_ELT (op, elt);
2513 if (GET_MODE (op) == V4SFmode
2514 || GET_MODE (op) == V2SFmode)
2515 tmp = gen_lowpart (SImode, tmp);
2516 return INTVAL (tmp);
2517}
452a7d36 2518
77ccdfed 2519/* Return true if OP can be synthesized with a particular vspltisb, vspltish
66180ff3
PB
2520 or vspltisw instruction. OP is a CONST_VECTOR. Which instruction is used
2521 depends on STEP and COPIES, one of which will be 1. If COPIES > 1,
2522 all items are set to the same value and contain COPIES replicas of the
2523 vsplt's operand; if STEP > 1, one in STEP elements is set to the vsplt's
2524 operand and the others are set to the value of the operand's msb. */
2525
2526static bool
2527vspltis_constant (rtx op, unsigned step, unsigned copies)
452a7d36 2528{
66180ff3
PB
2529 enum machine_mode mode = GET_MODE (op);
2530 enum machine_mode inner = GET_MODE_INNER (mode);
2531
2532 unsigned i;
2533 unsigned nunits = GET_MODE_NUNITS (mode);
2534 unsigned bitsize = GET_MODE_BITSIZE (inner);
2535 unsigned mask = GET_MODE_MASK (inner);
2536
0972012c 2537 HOST_WIDE_INT val = const_vector_elt_as_int (op, nunits - 1);
66180ff3
PB
2538 HOST_WIDE_INT splat_val = val;
2539 HOST_WIDE_INT msb_val = val > 0 ? 0 : -1;
2540
2541 /* Construct the value to be splatted, if possible. If not, return 0. */
2542 for (i = 2; i <= copies; i *= 2)
452a7d36 2543 {
66180ff3
PB
2544 HOST_WIDE_INT small_val;
2545 bitsize /= 2;
2546 small_val = splat_val >> bitsize;
2547 mask >>= bitsize;
2548 if (splat_val != ((small_val << bitsize) | (small_val & mask)))
2549 return false;
2550 splat_val = small_val;
2551 }
c4ad648e 2552
66180ff3
PB
2553 /* Check if SPLAT_VAL can really be the operand of a vspltis[bhw]. */
2554 if (EASY_VECTOR_15 (splat_val))
2555 ;
2556
2557 /* Also check if we can splat, and then add the result to itself. Do so if
2558 the value is positive, of if the splat instruction is using OP's mode;
2559 for splat_val < 0, the splat and the add should use the same mode. */
2560 else if (EASY_VECTOR_15_ADD_SELF (splat_val)
2561 && (splat_val >= 0 || (step == 1 && copies == 1)))
2562 ;
2563
2564 else
2565 return false;
2566
2567 /* Check if VAL is present in every STEP-th element, and the
2568 other elements are filled with its most significant bit. */
2569 for (i = 0; i < nunits - 1; ++i)
2570 {
2571 HOST_WIDE_INT desired_val;
2572 if (((i + 1) & (step - 1)) == 0)
2573 desired_val = val;
2574 else
2575 desired_val = msb_val;
2576
0972012c 2577 if (desired_val != const_vector_elt_as_int (op, i))
66180ff3 2578 return false;
452a7d36 2579 }
66180ff3
PB
2580
2581 return true;
452a7d36
HP
2582}
2583
69ef87e2 2584
77ccdfed 2585/* Return true if OP is of the given MODE and can be synthesized
66180ff3
PB
2586 with a vspltisb, vspltish or vspltisw. */
2587
2588bool
2589easy_altivec_constant (rtx op, enum machine_mode mode)
d744e06e 2590{
66180ff3 2591 unsigned step, copies;
d744e06e 2592
66180ff3
PB
2593 if (mode == VOIDmode)
2594 mode = GET_MODE (op);
2595 else if (mode != GET_MODE (op))
2596 return false;
d744e06e 2597
66180ff3
PB
2598 /* Start with a vspltisw. */
2599 step = GET_MODE_NUNITS (mode) / 4;
2600 copies = 1;
2601
2602 if (vspltis_constant (op, step, copies))
2603 return true;
2604
2605 /* Then try with a vspltish. */
2606 if (step == 1)
2607 copies <<= 1;
2608 else
2609 step >>= 1;
2610
2611 if (vspltis_constant (op, step, copies))
2612 return true;
2613
2614 /* And finally a vspltisb. */
2615 if (step == 1)
2616 copies <<= 1;
2617 else
2618 step >>= 1;
2619
2620 if (vspltis_constant (op, step, copies))
2621 return true;
2622
2623 return false;
d744e06e
AH
2624}
2625
66180ff3
PB
2626/* Generate a VEC_DUPLICATE representing a vspltis[bhw] instruction whose
2627 result is OP. Abort if it is not possible. */
d744e06e 2628
f676971a 2629rtx
66180ff3 2630gen_easy_altivec_constant (rtx op)
452a7d36 2631{
66180ff3
PB
2632 enum machine_mode mode = GET_MODE (op);
2633 int nunits = GET_MODE_NUNITS (mode);
2634 rtx last = CONST_VECTOR_ELT (op, nunits - 1);
2635 unsigned step = nunits / 4;
2636 unsigned copies = 1;
2637
2638 /* Start with a vspltisw. */
2639 if (vspltis_constant (op, step, copies))
2640 return gen_rtx_VEC_DUPLICATE (V4SImode, gen_lowpart (SImode, last));
2641
2642 /* Then try with a vspltish. */
2643 if (step == 1)
2644 copies <<= 1;
2645 else
2646 step >>= 1;
2647
2648 if (vspltis_constant (op, step, copies))
2649 return gen_rtx_VEC_DUPLICATE (V8HImode, gen_lowpart (HImode, last));
2650
2651 /* And finally a vspltisb. */
2652 if (step == 1)
2653 copies <<= 1;
2654 else
2655 step >>= 1;
2656
2657 if (vspltis_constant (op, step, copies))
2658 return gen_rtx_VEC_DUPLICATE (V16QImode, gen_lowpart (QImode, last));
2659
2660 gcc_unreachable ();
d744e06e
AH
2661}
2662
2663const char *
a2369ed3 2664output_vec_const_move (rtx *operands)
d744e06e
AH
2665{
2666 int cst, cst2;
2667 enum machine_mode mode;
2668 rtx dest, vec;
2669
2670 dest = operands[0];
2671 vec = operands[1];
d744e06e 2672 mode = GET_MODE (dest);
69ef87e2 2673
d744e06e
AH
2674 if (TARGET_ALTIVEC)
2675 {
66180ff3 2676 rtx splat_vec;
d744e06e
AH
2677 if (zero_constant (vec, mode))
2678 return "vxor %0,%0,%0";
37409796 2679
66180ff3
PB
2680 splat_vec = gen_easy_altivec_constant (vec);
2681 gcc_assert (GET_CODE (splat_vec) == VEC_DUPLICATE);
2682 operands[1] = XEXP (splat_vec, 0);
2683 if (!EASY_VECTOR_15 (INTVAL (operands[1])))
2684 return "#";
bb8df8a6 2685
66180ff3 2686 switch (GET_MODE (splat_vec))
98ef3137 2687 {
37409796 2688 case V4SImode:
66180ff3 2689 return "vspltisw %0,%1";
c4ad648e 2690
37409796 2691 case V8HImode:
66180ff3 2692 return "vspltish %0,%1";
c4ad648e 2693
37409796 2694 case V16QImode:
66180ff3 2695 return "vspltisb %0,%1";
bb8df8a6 2696
37409796
NS
2697 default:
2698 gcc_unreachable ();
98ef3137 2699 }
69ef87e2
AH
2700 }
2701
37409796 2702 gcc_assert (TARGET_SPE);
bb8df8a6 2703
37409796
NS
2704 /* Vector constant 0 is handled as a splitter of V2SI, and in the
2705 pattern of V1DI, V4HI, and V2SF.
2706
2707 FIXME: We should probably return # and add post reload
2708 splitters for these, but this way is so easy ;-). */
e20dcbef
PB
2709 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
2710 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
2711 operands[1] = CONST_VECTOR_ELT (vec, 0);
2712 operands[2] = CONST_VECTOR_ELT (vec, 1);
37409796
NS
2713 if (cst == cst2)
2714 return "li %0,%1\n\tevmergelo %0,%0,%0";
2715 else
2716 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
69ef87e2
AH
2717}
2718
7a4eca66
DE
2719/* Initialize vector TARGET to VALS. */
2720
2721void
2722rs6000_expand_vector_init (rtx target, rtx vals)
2723{
2724 enum machine_mode mode = GET_MODE (target);
2725 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2726 int n_elts = GET_MODE_NUNITS (mode);
2727 int n_var = 0, one_var = -1;
2728 bool all_same = true, all_const_zero = true;
2729 rtx x, mem;
2730 int i;
2731
2732 for (i = 0; i < n_elts; ++i)
2733 {
2734 x = XVECEXP (vals, 0, i);
2735 if (!CONSTANT_P (x))
2736 ++n_var, one_var = i;
2737 else if (x != CONST0_RTX (inner_mode))
2738 all_const_zero = false;
2739
2740 if (i > 0 && !rtx_equal_p (x, XVECEXP (vals, 0, 0)))
2741 all_same = false;
2742 }
2743
2744 if (n_var == 0)
2745 {
2746 if (mode != V4SFmode && all_const_zero)
2747 {
2748 /* Zero register. */
2749 emit_insn (gen_rtx_SET (VOIDmode, target,
2750 gen_rtx_XOR (mode, target, target)));
2751 return;
2752 }
66180ff3 2753 else if (mode != V4SFmode && easy_vector_constant (vals, mode))
7a4eca66
DE
2754 {
2755 /* Splat immediate. */
66180ff3 2756 emit_insn (gen_rtx_SET (VOIDmode, target, vals));
7a4eca66
DE
2757 return;
2758 }
2759 else if (all_same)
2760 ; /* Splat vector element. */
2761 else
2762 {
2763 /* Load from constant pool. */
2764 emit_move_insn (target, gen_rtx_CONST_VECTOR (mode, XVEC (vals, 0)));
2765 return;
2766 }
2767 }
2768
2769 /* Store value to stack temp. Load vector element. Splat. */
2770 if (all_same)
2771 {
2772 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2773 emit_move_insn (adjust_address_nv (mem, inner_mode, 0),
2774 XVECEXP (vals, 0, 0));
2775 x = gen_rtx_UNSPEC (VOIDmode,
2776 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2777 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2778 gen_rtvec (2,
2779 gen_rtx_SET (VOIDmode,
2780 target, mem),
2781 x)));
2782 x = gen_rtx_VEC_SELECT (inner_mode, target,
2783 gen_rtx_PARALLEL (VOIDmode,
2784 gen_rtvec (1, const0_rtx)));
2785 emit_insn (gen_rtx_SET (VOIDmode, target,
2786 gen_rtx_VEC_DUPLICATE (mode, x)));
2787 return;
2788 }
2789
2790 /* One field is non-constant. Load constant then overwrite
2791 varying field. */
2792 if (n_var == 1)
2793 {
2794 rtx copy = copy_rtx (vals);
2795
57b51d4d 2796 /* Load constant part of vector, substitute neighboring value for
7a4eca66
DE
2797 varying element. */
2798 XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
2799 rs6000_expand_vector_init (target, copy);
2800
2801 /* Insert variable. */
2802 rs6000_expand_vector_set (target, XVECEXP (vals, 0, one_var), one_var);
2803 return;
2804 }
2805
2806 /* Construct the vector in memory one field at a time
2807 and load the whole vector. */
2808 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2809 for (i = 0; i < n_elts; i++)
2810 emit_move_insn (adjust_address_nv (mem, inner_mode,
2811 i * GET_MODE_SIZE (inner_mode)),
2812 XVECEXP (vals, 0, i));
2813 emit_move_insn (target, mem);
2814}
2815
2816/* Set field ELT of TARGET to VAL. */
2817
2818void
2819rs6000_expand_vector_set (rtx target, rtx val, int elt)
2820{
2821 enum machine_mode mode = GET_MODE (target);
2822 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2823 rtx reg = gen_reg_rtx (mode);
2824 rtx mask, mem, x;
2825 int width = GET_MODE_SIZE (inner_mode);
2826 int i;
2827
2828 /* Load single variable value. */
2829 mem = assign_stack_temp (mode, GET_MODE_SIZE (inner_mode), 0);
2830 emit_move_insn (adjust_address_nv (mem, inner_mode, 0), val);
2831 x = gen_rtx_UNSPEC (VOIDmode,
2832 gen_rtvec (1, const0_rtx), UNSPEC_LVE);
2833 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2834 gen_rtvec (2,
2835 gen_rtx_SET (VOIDmode,
2836 reg, mem),
2837 x)));
2838
2839 /* Linear sequence. */
2840 mask = gen_rtx_PARALLEL (V16QImode, rtvec_alloc (16));
2841 for (i = 0; i < 16; ++i)
2842 XVECEXP (mask, 0, i) = GEN_INT (i);
2843
2844 /* Set permute mask to insert element into target. */
2845 for (i = 0; i < width; ++i)
2846 XVECEXP (mask, 0, elt*width + i)
2847 = GEN_INT (i + 0x10);
2848 x = gen_rtx_CONST_VECTOR (V16QImode, XVEC (mask, 0));
2849 x = gen_rtx_UNSPEC (mode,
2850 gen_rtvec (3, target, reg,
2851 force_reg (V16QImode, x)),
2852 UNSPEC_VPERM);
2853 emit_insn (gen_rtx_SET (VOIDmode, target, x));
2854}
2855
2856/* Extract field ELT from VEC into TARGET. */
2857
2858void
2859rs6000_expand_vector_extract (rtx target, rtx vec, int elt)
2860{
2861 enum machine_mode mode = GET_MODE (vec);
2862 enum machine_mode inner_mode = GET_MODE_INNER (mode);
2863 rtx mem, x;
2864
2865 /* Allocate mode-sized buffer. */
2866 mem = assign_stack_temp (mode, GET_MODE_SIZE (mode), 0);
2867
2868 /* Add offset to field within buffer matching vector element. */
2869 mem = adjust_address_nv (mem, mode, elt * GET_MODE_SIZE (inner_mode));
2870
2871 /* Store single field into mode-sized buffer. */
2872 x = gen_rtx_UNSPEC (VOIDmode,
2873 gen_rtvec (1, const0_rtx), UNSPEC_STVE);
2874 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2875 gen_rtvec (2,
2876 gen_rtx_SET (VOIDmode,
2877 mem, vec),
2878 x)));
2879 emit_move_insn (target, adjust_address_nv (mem, inner_mode, 0));
2880}
2881
0ba1b2ff
AM
2882/* Generates shifts and masks for a pair of rldicl or rldicr insns to
2883 implement ANDing by the mask IN. */
2884void
a2369ed3 2885build_mask64_2_operands (rtx in, rtx *out)
0ba1b2ff
AM
2886{
2887#if HOST_BITS_PER_WIDE_INT >= 64
2888 unsigned HOST_WIDE_INT c, lsb, m1, m2;
2889 int shift;
2890
37409796 2891 gcc_assert (GET_CODE (in) == CONST_INT);
0ba1b2ff
AM
2892
2893 c = INTVAL (in);
2894 if (c & 1)
2895 {
2896 /* Assume c initially something like 0x00fff000000fffff. The idea
2897 is to rotate the word so that the middle ^^^^^^ group of zeros
2898 is at the MS end and can be cleared with an rldicl mask. We then
2899 rotate back and clear off the MS ^^ group of zeros with a
2900 second rldicl. */
2901 c = ~c; /* c == 0xff000ffffff00000 */
2902 lsb = c & -c; /* lsb == 0x0000000000100000 */
2903 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
2904 c = ~c; /* c == 0x00fff000000fffff */
2905 c &= -lsb; /* c == 0x00fff00000000000 */
2906 lsb = c & -c; /* lsb == 0x0000100000000000 */
2907 c = ~c; /* c == 0xff000fffffffffff */
2908 c &= -lsb; /* c == 0xff00000000000000 */
2909 shift = 0;
2910 while ((lsb >>= 1) != 0)
2911 shift++; /* shift == 44 on exit from loop */
2912 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
2913 m1 = ~m1; /* m1 == 0x000000ffffffffff */
2914 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
2915 }
2916 else
0ba1b2ff
AM
2917 {
2918 /* Assume c initially something like 0xff000f0000000000. The idea
2919 is to rotate the word so that the ^^^ middle group of zeros
2920 is at the LS end and can be cleared with an rldicr mask. We then
2921 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
2922 a second rldicr. */
2923 lsb = c & -c; /* lsb == 0x0000010000000000 */
2924 m2 = -lsb; /* m2 == 0xffffff0000000000 */
2925 c = ~c; /* c == 0x00fff0ffffffffff */
2926 c &= -lsb; /* c == 0x00fff00000000000 */
2927 lsb = c & -c; /* lsb == 0x0000100000000000 */
2928 c = ~c; /* c == 0xff000fffffffffff */
2929 c &= -lsb; /* c == 0xff00000000000000 */
2930 shift = 0;
2931 while ((lsb >>= 1) != 0)
2932 shift++; /* shift == 44 on exit from loop */
2933 m1 = ~c; /* m1 == 0x00ffffffffffffff */
2934 m1 >>= shift; /* m1 == 0x0000000000000fff */
2935 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
2936 }
2937
2938 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
2939 masks will be all 1's. We are guaranteed more than one transition. */
2940 out[0] = GEN_INT (64 - shift);
2941 out[1] = GEN_INT (m1);
2942 out[2] = GEN_INT (shift);
2943 out[3] = GEN_INT (m2);
2944#else
045572c7
GK
2945 (void)in;
2946 (void)out;
37409796 2947 gcc_unreachable ();
0ba1b2ff 2948#endif
a260abc9
DE
2949}
2950
54b695e7 2951/* Return TRUE if OP is an invalid SUBREG operation on the e500. */
48d72335
DE
2952
2953bool
54b695e7
AH
2954invalid_e500_subreg (rtx op, enum machine_mode mode)
2955{
61c76239
JM
2956 if (TARGET_E500_DOUBLE)
2957 {
17caeff2
JM
2958 /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or
2959 subreg:TI and reg:TF. */
61c76239 2960 if (GET_CODE (op) == SUBREG
17caeff2 2961 && (mode == SImode || mode == DImode || mode == TImode)
61c76239 2962 && REG_P (SUBREG_REG (op))
17caeff2
JM
2963 && (GET_MODE (SUBREG_REG (op)) == DFmode
2964 || GET_MODE (SUBREG_REG (op)) == TFmode))
61c76239
JM
2965 return true;
2966
17caeff2
JM
2967 /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
2968 reg:TI. */
61c76239 2969 if (GET_CODE (op) == SUBREG
17caeff2 2970 && (mode == DFmode || mode == TFmode)
61c76239 2971 && REG_P (SUBREG_REG (op))
17caeff2
JM
2972 && (GET_MODE (SUBREG_REG (op)) == DImode
2973 || GET_MODE (SUBREG_REG (op)) == TImode))
61c76239
JM
2974 return true;
2975 }
54b695e7 2976
61c76239
JM
2977 if (TARGET_SPE
2978 && GET_CODE (op) == SUBREG
2979 && mode == SImode
54b695e7 2980 && REG_P (SUBREG_REG (op))
14502dad 2981 && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
54b695e7
AH
2982 return true;
2983
2984 return false;
2985}
2986
58182de3 2987/* AIX increases natural record alignment to doubleword if the first
95727fb8
AP
2988 field is an FP double while the FP fields remain word aligned. */
2989
19d66194 2990unsigned int
fa5b0972
AM
2991rs6000_special_round_type_align (tree type, unsigned int computed,
2992 unsigned int specified)
95727fb8 2993{
fa5b0972 2994 unsigned int align = MAX (computed, specified);
95727fb8 2995 tree field = TYPE_FIELDS (type);
95727fb8 2996
bb8df8a6 2997 /* Skip all non field decls */
85962ac8 2998 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
95727fb8
AP
2999 field = TREE_CHAIN (field);
3000
fa5b0972
AM
3001 if (field != NULL && field != type)
3002 {
3003 type = TREE_TYPE (field);
3004 while (TREE_CODE (type) == ARRAY_TYPE)
3005 type = TREE_TYPE (type);
3006
3007 if (type != error_mark_node && TYPE_MODE (type) == DFmode)
3008 align = MAX (align, 64);
3009 }
95727fb8 3010
fa5b0972 3011 return align;
95727fb8
AP
3012}
3013
58182de3
GK
3014/* Darwin increases record alignment to the natural alignment of
3015 the first field. */
3016
3017unsigned int
3018darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
3019 unsigned int specified)
3020{
3021 unsigned int align = MAX (computed, specified);
3022
3023 if (TYPE_PACKED (type))
3024 return align;
3025
3026 /* Find the first field, looking down into aggregates. */
3027 do {
3028 tree field = TYPE_FIELDS (type);
3029 /* Skip all non field decls */
3030 while (field != NULL && TREE_CODE (field) != FIELD_DECL)
3031 field = TREE_CHAIN (field);
3032 if (! field)
3033 break;
3034 type = TREE_TYPE (field);
3035 while (TREE_CODE (type) == ARRAY_TYPE)
3036 type = TREE_TYPE (type);
3037 } while (AGGREGATE_TYPE_P (type));
3038
3039 if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
3040 align = MAX (align, TYPE_ALIGN (type));
3041
3042 return align;
3043}
3044
a4f6c312 3045/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
3046
3047int
f676971a 3048small_data_operand (rtx op ATTRIBUTE_UNUSED,
a2369ed3 3049 enum machine_mode mode ATTRIBUTE_UNUSED)
7509c759 3050{
38c1f2d7 3051#if TARGET_ELF
5f59ecb7 3052 rtx sym_ref;
7509c759 3053
d9407988 3054 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 3055 return 0;
a54d04b7 3056
f607bc57 3057 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
3058 return 0;
3059
88228c4b
MM
3060 if (GET_CODE (op) == SYMBOL_REF)
3061 sym_ref = op;
3062
3063 else if (GET_CODE (op) != CONST
3064 || GET_CODE (XEXP (op, 0)) != PLUS
3065 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
3066 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
3067 return 0;
3068
88228c4b 3069 else
dbf55e53
MM
3070 {
3071 rtx sum = XEXP (op, 0);
3072 HOST_WIDE_INT summand;
3073
3074 /* We have to be careful here, because it is the referenced address
c4ad648e 3075 that must be 32k from _SDA_BASE_, not just the symbol. */
dbf55e53 3076 summand = INTVAL (XEXP (sum, 1));
307b599c 3077 if (summand < 0 || (unsigned HOST_WIDE_INT) summand > g_switch_value)
9390387d 3078 return 0;
dbf55e53
MM
3079
3080 sym_ref = XEXP (sum, 0);
3081 }
88228c4b 3082
20bfcd69 3083 return SYMBOL_REF_SMALL_P (sym_ref);
d9407988
MM
3084#else
3085 return 0;
3086#endif
7509c759 3087}
46c07df8 3088
3a1f863f 3089/* Return true if either operand is a general purpose register. */
46c07df8 3090
3a1f863f
DE
3091bool
3092gpr_or_gpr_p (rtx op0, rtx op1)
46c07df8 3093{
3a1f863f
DE
3094 return ((REG_P (op0) && INT_REGNO_P (REGNO (op0)))
3095 || (REG_P (op1) && INT_REGNO_P (REGNO (op1))));
46c07df8
HP
3096}
3097
9ebbca7d 3098\f
4d588c14
RH
3099/* Subroutines of rs6000_legitimize_address and rs6000_legitimate_address. */
3100
f676971a
EC
3101static int
3102constant_pool_expr_1 (rtx op, int *have_sym, int *have_toc)
9ebbca7d 3103{
9390387d 3104 switch (GET_CODE (op))
9ebbca7d
GK
3105 {
3106 case SYMBOL_REF:
c4501e62
JJ
3107 if (RS6000_SYMBOL_REF_TLS_P (op))
3108 return 0;
3109 else if (CONSTANT_POOL_ADDRESS_P (op))
a4f6c312
SS
3110 {
3111 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
3112 {
3113 *have_sym = 1;
3114 return 1;
3115 }
3116 else
3117 return 0;
3118 }
3119 else if (! strcmp (XSTR (op, 0), toc_label_name))
3120 {
3121 *have_toc = 1;
3122 return 1;
3123 }
3124 else
3125 return 0;
9ebbca7d
GK
3126 case PLUS:
3127 case MINUS:
c1f11548
DE
3128 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
3129 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 3130 case CONST:
a4f6c312 3131 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 3132 case CONST_INT:
a4f6c312 3133 return 1;
9ebbca7d 3134 default:
a4f6c312 3135 return 0;
9ebbca7d
GK
3136 }
3137}
3138
4d588c14 3139static bool
a2369ed3 3140constant_pool_expr_p (rtx op)
9ebbca7d
GK
3141{
3142 int have_sym = 0;
3143 int have_toc = 0;
3144 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
3145}
3146
48d72335 3147bool
a2369ed3 3148toc_relative_expr_p (rtx op)
9ebbca7d 3149{
4d588c14
RH
3150 int have_sym = 0;
3151 int have_toc = 0;
3152 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
3153}
3154
4d588c14 3155bool
a2369ed3 3156legitimate_constant_pool_address_p (rtx x)
4d588c14
RH
3157{
3158 return (TARGET_TOC
3159 && GET_CODE (x) == PLUS
3160 && GET_CODE (XEXP (x, 0)) == REG
3161 && (TARGET_MINIMAL_TOC || REGNO (XEXP (x, 0)) == TOC_REGISTER)
3162 && constant_pool_expr_p (XEXP (x, 1)));
3163}
3164
d04b6e6e
EB
3165static bool
3166legitimate_small_data_p (enum machine_mode mode, rtx x)
4d588c14
RH
3167{
3168 return (DEFAULT_ABI == ABI_V4
3169 && !flag_pic && !TARGET_TOC
3170 && (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST)
3171 && small_data_operand (x, mode));
3172}
3173
60cdabab
DE
3174/* SPE offset addressing is limited to 5-bits worth of double words. */
3175#define SPE_CONST_OFFSET_OK(x) (((x) & ~0xf8) == 0)
3176
76d2b81d
DJ
3177bool
3178rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
4d588c14
RH
3179{
3180 unsigned HOST_WIDE_INT offset, extra;
3181
3182 if (GET_CODE (x) != PLUS)
3183 return false;
3184 if (GET_CODE (XEXP (x, 0)) != REG)
3185 return false;
3186 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
3187 return false;
60cdabab
DE
3188 if (legitimate_constant_pool_address_p (x))
3189 return true;
4d588c14
RH
3190 if (GET_CODE (XEXP (x, 1)) != CONST_INT)
3191 return false;
3192
3193 offset = INTVAL (XEXP (x, 1));
3194 extra = 0;
3195 switch (mode)
3196 {
3197 case V16QImode:
3198 case V8HImode:
3199 case V4SFmode:
3200 case V4SImode:
7a4eca66
DE
3201 /* AltiVec vector modes. Only reg+reg addressing is valid and
3202 constant offset zero should not occur due to canonicalization.
3203 Allow any offset when not strict before reload. */
3204 return !strict;
4d588c14
RH
3205
3206 case V4HImode:
3207 case V2SImode:
3208 case V1DImode:
3209 case V2SFmode:
d42a3bae
RE
3210 /* Paired vector modes. Only reg+reg addressing is valid and
3211 constant offset zero should not occur due to canonicalization.
3212 Allow any offset when not strict before reload. */
3213 if (TARGET_PAIRED_FLOAT)
3214 return !strict;
4d588c14
RH
3215 /* SPE vector modes. */
3216 return SPE_CONST_OFFSET_OK (offset);
3217
3218 case DFmode:
7393f7f8 3219 case DDmode:
4d4cbc0e
AH
3220 if (TARGET_E500_DOUBLE)
3221 return SPE_CONST_OFFSET_OK (offset);
3222
4d588c14 3223 case DImode:
54b695e7
AH
3224 /* On e500v2, we may have:
3225
3226 (subreg:DF (mem:DI (plus (reg) (const_int))) 0).
3227
3228 Which gets addressed with evldd instructions. */
3229 if (TARGET_E500_DOUBLE)
3230 return SPE_CONST_OFFSET_OK (offset);
3231
7393f7f8 3232 if (mode == DFmode || mode == DDmode || !TARGET_POWERPC64)
4d588c14
RH
3233 extra = 4;
3234 else if (offset & 3)
3235 return false;
3236 break;
3237
3238 case TFmode:
17caeff2
JM
3239 if (TARGET_E500_DOUBLE)
3240 return (SPE_CONST_OFFSET_OK (offset)
3241 && SPE_CONST_OFFSET_OK (offset + 8));
3242
4d588c14 3243 case TImode:
7393f7f8
BE
3244 case TDmode:
3245 if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
4d588c14
RH
3246 extra = 12;
3247 else if (offset & 3)
3248 return false;
3249 else
3250 extra = 8;
3251 break;
3252
3253 default:
3254 break;
3255 }
3256
b1917422
AM
3257 offset += 0x8000;
3258 return (offset < 0x10000) && (offset + extra < 0x10000);
4d588c14
RH
3259}
3260
6fb5fa3c 3261bool
a2369ed3 3262legitimate_indexed_address_p (rtx x, int strict)
4d588c14
RH
3263{
3264 rtx op0, op1;
3265
3266 if (GET_CODE (x) != PLUS)
3267 return false;
850e8d3d 3268
4d588c14
RH
3269 op0 = XEXP (x, 0);
3270 op1 = XEXP (x, 1);
3271
bf00cc0f 3272 /* Recognize the rtl generated by reload which we know will later be
9024f4b8
AM
3273 replaced with proper base and index regs. */
3274 if (!strict
3275 && reload_in_progress
3276 && (REG_P (op0) || GET_CODE (op0) == PLUS)
3277 && REG_P (op1))
3278 return true;
3279
3280 return (REG_P (op0) && REG_P (op1)
3281 && ((INT_REG_OK_FOR_BASE_P (op0, strict)
3282 && INT_REG_OK_FOR_INDEX_P (op1, strict))
3283 || (INT_REG_OK_FOR_BASE_P (op1, strict)
3284 && INT_REG_OK_FOR_INDEX_P (op0, strict))));
9ebbca7d
GK
3285}
3286
48d72335 3287inline bool
a2369ed3 3288legitimate_indirect_address_p (rtx x, int strict)
4d588c14
RH
3289{
3290 return GET_CODE (x) == REG && INT_REG_OK_FOR_BASE_P (x, strict);
3291}
3292
48d72335 3293bool
4c81e946
FJ
3294macho_lo_sum_memory_operand (rtx x, enum machine_mode mode)
3295{
c4ad648e 3296 if (!TARGET_MACHO || !flag_pic
9390387d 3297 || mode != SImode || GET_CODE (x) != MEM)
c4ad648e
AM
3298 return false;
3299 x = XEXP (x, 0);
4c81e946
FJ
3300
3301 if (GET_CODE (x) != LO_SUM)
3302 return false;
3303 if (GET_CODE (XEXP (x, 0)) != REG)
3304 return false;
3305 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), 0))
3306 return false;
3307 x = XEXP (x, 1);
3308
3309 return CONSTANT_P (x);
3310}
3311
4d588c14 3312static bool
a2369ed3 3313legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
4d588c14
RH
3314{
3315 if (GET_CODE (x) != LO_SUM)
3316 return false;
3317 if (GET_CODE (XEXP (x, 0)) != REG)
3318 return false;
3319 if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
3320 return false;
54b695e7 3321 /* Restrict addressing for DI because of our SUBREG hackery. */
17caeff2
JM
3322 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3323 || mode == DImode))
f82f556d 3324 return false;
4d588c14
RH
3325 x = XEXP (x, 1);
3326
8622e235 3327 if (TARGET_ELF || TARGET_MACHO)
4d588c14 3328 {
a29077da 3329 if (DEFAULT_ABI != ABI_AIX && DEFAULT_ABI != ABI_DARWIN && flag_pic)
4d588c14
RH
3330 return false;
3331 if (TARGET_TOC)
3332 return false;
3333 if (GET_MODE_NUNITS (mode) != 1)
3334 return false;
5e5f01b9 3335 if (GET_MODE_BITSIZE (mode) > 64
3c028f65
AM
3336 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
3337 && !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode)))
4d588c14
RH
3338 return false;
3339
3340 return CONSTANT_P (x);
3341 }
3342
3343 return false;
3344}
3345
3346
9ebbca7d
GK
3347/* Try machine-dependent ways of modifying an illegitimate address
3348 to be legitimate. If we find one, return the new, valid address.
3349 This is used from only one place: `memory_address' in explow.c.
3350
a4f6c312
SS
3351 OLDX is the address as it was before break_out_memory_refs was
3352 called. In some cases it is useful to look at this to decide what
3353 needs to be done.
9ebbca7d 3354
a4f6c312 3355 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 3356
a4f6c312
SS
3357 It is always safe for this function to do nothing. It exists to
3358 recognize opportunities to optimize the output.
9ebbca7d
GK
3359
3360 On RS/6000, first check for the sum of a register with a constant
3361 integer that is out of range. If so, generate code to add the
3362 constant with the low-order 16 bits masked to the register and force
3363 this result into another register (this can be done with `cau').
3364 Then generate an address of REG+(CONST&0xffff), allowing for the
3365 possibility of bit 16 being a one.
3366
3367 Then check for the sum of a register and something not constant, try to
3368 load the other things into a register and return the sum. */
4d588c14 3369
9ebbca7d 3370rtx
a2369ed3
DJ
3371rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3372 enum machine_mode mode)
0ac081f6 3373{
c4501e62
JJ
3374 if (GET_CODE (x) == SYMBOL_REF)
3375 {
3376 enum tls_model model = SYMBOL_REF_TLS_MODEL (x);
3377 if (model != 0)
3378 return rs6000_legitimize_tls_address (x, model);
3379 }
3380
f676971a 3381 if (GET_CODE (x) == PLUS
9ebbca7d
GK
3382 && GET_CODE (XEXP (x, 0)) == REG
3383 && GET_CODE (XEXP (x, 1)) == CONST_INT
3c1eb9eb
JM
3384 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000
3385 && !(SPE_VECTOR_MODE (mode)
3386 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3387 || mode == DImode))))
f676971a 3388 {
9ebbca7d
GK
3389 HOST_WIDE_INT high_int, low_int;
3390 rtx sum;
a65c591c
DE
3391 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
3392 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
3393 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
3394 GEN_INT (high_int)), 0);
3395 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
3396 }
f676971a 3397 else if (GET_CODE (x) == PLUS
9ebbca7d
GK
3398 && GET_CODE (XEXP (x, 0)) == REG
3399 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 3400 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
3401 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3402 || TARGET_POWERPC64
7393f7f8
BE
3403 || (((mode != DImode && mode != DFmode && mode != DDmode)
3404 || TARGET_E500_DOUBLE)
3405 && mode != TFmode && mode != TDmode))
9ebbca7d
GK
3406 && (TARGET_POWERPC64 || mode != DImode)
3407 && mode != TImode)
3408 {
3409 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
3410 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
3411 }
0ac081f6
AH
3412 else if (ALTIVEC_VECTOR_MODE (mode))
3413 {
3414 rtx reg;
3415
3416 /* Make sure both operands are registers. */
3417 if (GET_CODE (x) == PLUS)
9f85ed45 3418 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
3419 force_reg (Pmode, XEXP (x, 1)));
3420
3421 reg = force_reg (Pmode, x);
3422 return reg;
3423 }
4d4cbc0e 3424 else if (SPE_VECTOR_MODE (mode)
17caeff2 3425 || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
7393f7f8 3426 || mode == DDmode || mode == TDmode
54b695e7 3427 || mode == DImode)))
a3170dc6 3428 {
54b695e7
AH
3429 if (mode == DImode)
3430 return NULL_RTX;
a3170dc6
AH
3431 /* We accept [reg + reg] and [reg + OFFSET]. */
3432
3433 if (GET_CODE (x) == PLUS)
c4ad648e
AM
3434 {
3435 rtx op1 = XEXP (x, 0);
3436 rtx op2 = XEXP (x, 1);
a3170dc6 3437
c4ad648e 3438 op1 = force_reg (Pmode, op1);
a3170dc6 3439
c4ad648e
AM
3440 if (GET_CODE (op2) != REG
3441 && (GET_CODE (op2) != CONST_INT
3442 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
3443 op2 = force_reg (Pmode, op2);
a3170dc6 3444
c4ad648e
AM
3445 return gen_rtx_PLUS (Pmode, op1, op2);
3446 }
a3170dc6
AH
3447
3448 return force_reg (Pmode, x);
3449 }
f1384257
AM
3450 else if (TARGET_ELF
3451 && TARGET_32BIT
3452 && TARGET_NO_TOC
3453 && ! flag_pic
9ebbca7d 3454 && GET_CODE (x) != CONST_INT
f676971a 3455 && GET_CODE (x) != CONST_DOUBLE
9ebbca7d 3456 && CONSTANT_P (x)
6ac7bf2c
GK
3457 && GET_MODE_NUNITS (mode) == 1
3458 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 3459 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
3460 {
3461 rtx reg = gen_reg_rtx (Pmode);
8a1977f3
GK
3462 emit_insn (gen_elf_high (reg, x));
3463 return gen_rtx_LO_SUM (Pmode, reg, x);
9ebbca7d 3464 }
ee890fe2
SS
3465 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
3466 && ! flag_pic
ab82a49f
AP
3467#if TARGET_MACHO
3468 && ! MACHO_DYNAMIC_NO_PIC_P
3469#endif
ee890fe2 3470 && GET_CODE (x) != CONST_INT
f676971a 3471 && GET_CODE (x) != CONST_DOUBLE
ee890fe2 3472 && CONSTANT_P (x)
f82f556d 3473 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
f676971a 3474 && mode != DImode
ee890fe2
SS
3475 && mode != TImode)
3476 {
3477 rtx reg = gen_reg_rtx (Pmode);
8a1977f3
GK
3478 emit_insn (gen_macho_high (reg, x));
3479 return gen_rtx_LO_SUM (Pmode, reg, x);
ee890fe2 3480 }
f676971a 3481 else if (TARGET_TOC
4d588c14 3482 && constant_pool_expr_p (x)
a9098fd0 3483 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
3484 {
3485 return create_TOC_reference (x);
3486 }
3487 else
3488 return NULL_RTX;
3489}
258bfae2 3490
fdbe66f2 3491/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
c973d557
JJ
3492 We need to emit DTP-relative relocations. */
3493
fdbe66f2 3494static void
c973d557
JJ
3495rs6000_output_dwarf_dtprel (FILE *file, int size, rtx x)
3496{
3497 switch (size)
3498 {
3499 case 4:
3500 fputs ("\t.long\t", file);
3501 break;
3502 case 8:
3503 fputs (DOUBLE_INT_ASM_OP, file);
3504 break;
3505 default:
37409796 3506 gcc_unreachable ();
c973d557
JJ
3507 }
3508 output_addr_const (file, x);
3509 fputs ("@dtprel+0x8000", file);
3510}
3511
c4501e62
JJ
3512/* Construct the SYMBOL_REF for the tls_get_addr function. */
3513
3514static GTY(()) rtx rs6000_tls_symbol;
3515static rtx
863d938c 3516rs6000_tls_get_addr (void)
c4501e62
JJ
3517{
3518 if (!rs6000_tls_symbol)
3519 rs6000_tls_symbol = init_one_libfunc ("__tls_get_addr");
3520
3521 return rs6000_tls_symbol;
3522}
3523
3524/* Construct the SYMBOL_REF for TLS GOT references. */
3525
3526static GTY(()) rtx rs6000_got_symbol;
3527static rtx
863d938c 3528rs6000_got_sym (void)
c4501e62
JJ
3529{
3530 if (!rs6000_got_symbol)
3531 {
3532 rs6000_got_symbol = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3533 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_LOCAL;
3534 SYMBOL_REF_FLAGS (rs6000_got_symbol) |= SYMBOL_FLAG_EXTERNAL;
f676971a 3535 }
c4501e62
JJ
3536
3537 return rs6000_got_symbol;
3538}
3539
3540/* ADDR contains a thread-local SYMBOL_REF. Generate code to compute
3541 this (thread-local) address. */
3542
3543static rtx
a2369ed3 3544rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
c4501e62
JJ
3545{
3546 rtx dest, insn;
3547
3548 dest = gen_reg_rtx (Pmode);
3549 if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 16)
3550 {
3551 rtx tlsreg;
3552
3553 if (TARGET_64BIT)
3554 {
3555 tlsreg = gen_rtx_REG (Pmode, 13);
3556 insn = gen_tls_tprel_64 (dest, tlsreg, addr);
3557 }
3558 else
3559 {
3560 tlsreg = gen_rtx_REG (Pmode, 2);
3561 insn = gen_tls_tprel_32 (dest, tlsreg, addr);
3562 }
3563 emit_insn (insn);
3564 }
3565 else if (model == TLS_MODEL_LOCAL_EXEC && rs6000_tls_size == 32)
3566 {
3567 rtx tlsreg, tmp;
3568
3569 tmp = gen_reg_rtx (Pmode);
3570 if (TARGET_64BIT)
3571 {
3572 tlsreg = gen_rtx_REG (Pmode, 13);
3573 insn = gen_tls_tprel_ha_64 (tmp, tlsreg, addr);
3574 }
3575 else
3576 {
3577 tlsreg = gen_rtx_REG (Pmode, 2);
3578 insn = gen_tls_tprel_ha_32 (tmp, tlsreg, addr);
3579 }
3580 emit_insn (insn);
3581 if (TARGET_64BIT)
3582 insn = gen_tls_tprel_lo_64 (dest, tmp, addr);
3583 else
3584 insn = gen_tls_tprel_lo_32 (dest, tmp, addr);
3585 emit_insn (insn);
3586 }
3587 else
3588 {
3589 rtx r3, got, tga, tmp1, tmp2, eqv;
3590
4fed8f8f
AM
3591 /* We currently use relocations like @got@tlsgd for tls, which
3592 means the linker will handle allocation of tls entries, placing
3593 them in the .got section. So use a pointer to the .got section,
3594 not one to secondary TOC sections used by 64-bit -mminimal-toc,
3595 or to secondary GOT sections used by 32-bit -fPIC. */
c4501e62 3596 if (TARGET_64BIT)
972f427b 3597 got = gen_rtx_REG (Pmode, 2);
c4501e62
JJ
3598 else
3599 {
3600 if (flag_pic == 1)
3601 got = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
3602 else
3603 {
3604 rtx gsym = rs6000_got_sym ();
3605 got = gen_reg_rtx (Pmode);
3606 if (flag_pic == 0)
3607 rs6000_emit_move (got, gsym, Pmode);
3608 else
3609 {
e65a3857 3610 rtx tmp3, mem;
c4501e62
JJ
3611 rtx first, last;
3612
c4501e62
JJ
3613 tmp1 = gen_reg_rtx (Pmode);
3614 tmp2 = gen_reg_rtx (Pmode);
3615 tmp3 = gen_reg_rtx (Pmode);
542a8afa 3616 mem = gen_const_mem (Pmode, tmp1);
c4501e62 3617
e65a3857
DE
3618 first = emit_insn (gen_load_toc_v4_PIC_1b (gsym));
3619 emit_move_insn (tmp1,
1de43f85 3620 gen_rtx_REG (Pmode, LR_REGNO));
c4501e62
JJ
3621 emit_move_insn (tmp2, mem);
3622 emit_insn (gen_addsi3 (tmp3, tmp1, tmp2));
3623 last = emit_move_insn (got, tmp3);
bd94cb6e 3624 set_unique_reg_note (last, REG_EQUAL, gsym);
6fb5fa3c 3625 maybe_encapsulate_block (first, last, gsym);
c4501e62
JJ
3626 }
3627 }
3628 }
3629
3630 if (model == TLS_MODEL_GLOBAL_DYNAMIC)
3631 {
3632 r3 = gen_rtx_REG (Pmode, 3);
3633 if (TARGET_64BIT)
3634 insn = gen_tls_gd_64 (r3, got, addr);
3635 else
3636 insn = gen_tls_gd_32 (r3, got, addr);
3637 start_sequence ();
3638 emit_insn (insn);
3639 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3640 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3641 insn = emit_call_insn (insn);
3642 CONST_OR_PURE_CALL_P (insn) = 1;
3643 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3644 insn = get_insns ();
3645 end_sequence ();
3646 emit_libcall_block (insn, dest, r3, addr);
3647 }
3648 else if (model == TLS_MODEL_LOCAL_DYNAMIC)
3649 {
3650 r3 = gen_rtx_REG (Pmode, 3);
3651 if (TARGET_64BIT)
3652 insn = gen_tls_ld_64 (r3, got);
3653 else
3654 insn = gen_tls_ld_32 (r3, got);
3655 start_sequence ();
3656 emit_insn (insn);
3657 tga = gen_rtx_MEM (Pmode, rs6000_tls_get_addr ());
3658 insn = gen_call_value (r3, tga, const0_rtx, const0_rtx);
3659 insn = emit_call_insn (insn);
3660 CONST_OR_PURE_CALL_P (insn) = 1;
3661 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), r3);
3662 insn = get_insns ();
3663 end_sequence ();
3664 tmp1 = gen_reg_rtx (Pmode);
3665 eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
3666 UNSPEC_TLSLD);
3667 emit_libcall_block (insn, tmp1, r3, eqv);
3668 if (rs6000_tls_size == 16)
3669 {
3670 if (TARGET_64BIT)
3671 insn = gen_tls_dtprel_64 (dest, tmp1, addr);
3672 else
3673 insn = gen_tls_dtprel_32 (dest, tmp1, addr);
3674 }
3675 else if (rs6000_tls_size == 32)
3676 {
3677 tmp2 = gen_reg_rtx (Pmode);
3678 if (TARGET_64BIT)
3679 insn = gen_tls_dtprel_ha_64 (tmp2, tmp1, addr);
3680 else
3681 insn = gen_tls_dtprel_ha_32 (tmp2, tmp1, addr);
3682 emit_insn (insn);
3683 if (TARGET_64BIT)
3684 insn = gen_tls_dtprel_lo_64 (dest, tmp2, addr);
3685 else
3686 insn = gen_tls_dtprel_lo_32 (dest, tmp2, addr);
3687 }
3688 else
3689 {
3690 tmp2 = gen_reg_rtx (Pmode);
3691 if (TARGET_64BIT)
3692 insn = gen_tls_got_dtprel_64 (tmp2, got, addr);
3693 else
3694 insn = gen_tls_got_dtprel_32 (tmp2, got, addr);
3695 emit_insn (insn);
3696 insn = gen_rtx_SET (Pmode, dest,
3697 gen_rtx_PLUS (Pmode, tmp2, tmp1));
3698 }
3699 emit_insn (insn);
3700 }
3701 else
3702 {
a7b376ee 3703 /* IE, or 64-bit offset LE. */
c4501e62
JJ
3704 tmp2 = gen_reg_rtx (Pmode);
3705 if (TARGET_64BIT)
3706 insn = gen_tls_got_tprel_64 (tmp2, got, addr);
3707 else
3708 insn = gen_tls_got_tprel_32 (tmp2, got, addr);
3709 emit_insn (insn);
3710 if (TARGET_64BIT)
3711 insn = gen_tls_tls_64 (dest, tmp2, addr);
3712 else
3713 insn = gen_tls_tls_32 (dest, tmp2, addr);
3714 emit_insn (insn);
3715 }
3716 }
3717
3718 return dest;
3719}
3720
c4501e62
JJ
3721/* Return 1 if X contains a thread-local symbol. */
3722
3723bool
a2369ed3 3724rs6000_tls_referenced_p (rtx x)
c4501e62 3725{
cd413cab
AP
3726 if (! TARGET_HAVE_TLS)
3727 return false;
3728
c4501e62
JJ
3729 return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
3730}
3731
3732/* Return 1 if *X is a thread-local symbol. This is the same as
3733 rs6000_tls_symbol_ref except for the type of the unused argument. */
3734
9390387d 3735static int
a2369ed3 3736rs6000_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
c4501e62
JJ
3737{
3738 return RS6000_SYMBOL_REF_TLS_P (*x);
3739}
3740
24ea750e
DJ
3741/* The convention appears to be to define this wherever it is used.
3742 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
3743 is now used here. */
3744#ifndef REG_MODE_OK_FOR_BASE_P
3745#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
3746#endif
3747
3748/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
3749 replace the input X, or the original X if no replacement is called for.
3750 The output parameter *WIN is 1 if the calling macro should goto WIN,
3751 0 if it should not.
3752
3753 For RS/6000, we wish to handle large displacements off a base
3754 register by splitting the addend across an addiu/addis and the mem insn.
3755 This cuts number of extra insns needed from 3 to 1.
3756
3757 On Darwin, we use this to generate code for floating point constants.
3758 A movsf_low is generated so we wind up with 2 instructions rather than 3.
3759 The Darwin code is inside #if TARGET_MACHO because only then is
3760 machopic_function_base_name() defined. */
3761rtx
f676971a 3762rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
c4ad648e
AM
3763 int opnum, int type,
3764 int ind_levels ATTRIBUTE_UNUSED, int *win)
24ea750e 3765{
f676971a 3766 /* We must recognize output that we have already generated ourselves. */
24ea750e
DJ
3767 if (GET_CODE (x) == PLUS
3768 && GET_CODE (XEXP (x, 0)) == PLUS
3769 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3770 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3771 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3772 {
3773 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
c4ad648e
AM
3774 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3775 opnum, (enum reload_type)type);
24ea750e
DJ
3776 *win = 1;
3777 return x;
3778 }
3deb2758 3779
24ea750e
DJ
3780#if TARGET_MACHO
3781 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
3782 && GET_CODE (x) == LO_SUM
3783 && GET_CODE (XEXP (x, 0)) == PLUS
3784 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
3785 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
3786 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
3787 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
3788 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
3789 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
3790 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
3791 {
3792 /* Result of previous invocation of this function on Darwin
6f317ef3 3793 floating point constant. */
24ea750e 3794 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
c4ad648e
AM
3795 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3796 opnum, (enum reload_type)type);
24ea750e
DJ
3797 *win = 1;
3798 return x;
3799 }
3800#endif
4937d02d
DE
3801
3802 /* Force ld/std non-word aligned offset into base register by wrapping
3803 in offset 0. */
3804 if (GET_CODE (x) == PLUS
3805 && GET_CODE (XEXP (x, 0)) == REG
3806 && REGNO (XEXP (x, 0)) < 32
3807 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
3808 && GET_CODE (XEXP (x, 1)) == CONST_INT
3809 && (INTVAL (XEXP (x, 1)) & 3) != 0
78796ad5 3810 && !ALTIVEC_VECTOR_MODE (mode)
4937d02d
DE
3811 && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
3812 && TARGET_POWERPC64)
3813 {
3814 x = gen_rtx_PLUS (GET_MODE (x), x, GEN_INT (0));
3815 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
3816 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3817 opnum, (enum reload_type) type);
3818 *win = 1;
3819 return x;
3820 }
3821
24ea750e
DJ
3822 if (GET_CODE (x) == PLUS
3823 && GET_CODE (XEXP (x, 0)) == REG
3824 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
3825 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 3826 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 3827 && !SPE_VECTOR_MODE (mode)
17caeff2 3828 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
54b695e7 3829 || mode == DImode))
78c875e8 3830 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
3831 {
3832 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3833 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
3834 HOST_WIDE_INT high
c4ad648e 3835 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
24ea750e
DJ
3836
3837 /* Check for 32-bit overflow. */
3838 if (high + low != val)
c4ad648e 3839 {
24ea750e
DJ
3840 *win = 0;
3841 return x;
3842 }
3843
3844 /* Reload the high part into a base reg; leave the low part
c4ad648e 3845 in the mem directly. */
24ea750e
DJ
3846
3847 x = gen_rtx_PLUS (GET_MODE (x),
c4ad648e
AM
3848 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
3849 GEN_INT (high)),
3850 GEN_INT (low));
24ea750e
DJ
3851
3852 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
c4ad648e
AM
3853 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
3854 opnum, (enum reload_type)type);
24ea750e
DJ
3855 *win = 1;
3856 return x;
3857 }
4937d02d 3858
24ea750e 3859 if (GET_CODE (x) == SYMBOL_REF
69ef87e2 3860 && !ALTIVEC_VECTOR_MODE (mode)
1650e3f5 3861 && !SPE_VECTOR_MODE (mode)
8308679f
DE
3862#if TARGET_MACHO
3863 && DEFAULT_ABI == ABI_DARWIN
a29077da 3864 && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
8308679f
DE
3865#else
3866 && DEFAULT_ABI == ABI_V4
3867 && !flag_pic
3868#endif
7393f7f8 3869 /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
7b5d92b2
AM
3870 The same goes for DImode without 64-bit gprs and DFmode
3871 without fprs. */
0d8c1c97 3872 && mode != TFmode
7393f7f8 3873 && mode != TDmode
7b5d92b2
AM
3874 && (mode != DImode || TARGET_POWERPC64)
3875 && (mode != DFmode || TARGET_POWERPC64
3876 || (TARGET_FPRS && TARGET_HARD_FLOAT)))
24ea750e 3877 {
8308679f 3878#if TARGET_MACHO
a29077da
GK
3879 if (flag_pic)
3880 {
3881 rtx offset = gen_rtx_CONST (Pmode,
3882 gen_rtx_MINUS (Pmode, x,
11abc112 3883 machopic_function_base_sym ()));
a29077da
GK
3884 x = gen_rtx_LO_SUM (GET_MODE (x),
3885 gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
3886 gen_rtx_HIGH (Pmode, offset)), offset);
3887 }
3888 else
8308679f 3889#endif
a29077da 3890 x = gen_rtx_LO_SUM (GET_MODE (x),
c4ad648e 3891 gen_rtx_HIGH (Pmode, x), x);
a29077da 3892
24ea750e 3893 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
a29077da
GK
3894 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3895 opnum, (enum reload_type)type);
24ea750e
DJ
3896 *win = 1;
3897 return x;
3898 }
4937d02d 3899
dec1f3aa
DE
3900 /* Reload an offset address wrapped by an AND that represents the
3901 masking of the lower bits. Strip the outer AND and let reload
3902 convert the offset address into an indirect address. */
3903 if (TARGET_ALTIVEC
3904 && ALTIVEC_VECTOR_MODE (mode)
3905 && GET_CODE (x) == AND
3906 && GET_CODE (XEXP (x, 0)) == PLUS
3907 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
3908 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
3909 && GET_CODE (XEXP (x, 1)) == CONST_INT
3910 && INTVAL (XEXP (x, 1)) == -16)
3911 {
3912 x = XEXP (x, 0);
3913 *win = 1;
3914 return x;
3915 }
3916
24ea750e 3917 if (TARGET_TOC
4d588c14 3918 && constant_pool_expr_p (x)
c1f11548 3919 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e 3920 {
194c524a 3921 x = create_TOC_reference (x);
24ea750e
DJ
3922 *win = 1;
3923 return x;
3924 }
3925 *win = 0;
3926 return x;
f676971a 3927}
24ea750e 3928
258bfae2
FS
3929/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
3930 that is a valid memory address for an instruction.
3931 The MODE argument is the machine mode for the MEM expression
3932 that wants to use this address.
3933
3934 On the RS/6000, there are four valid address: a SYMBOL_REF that
3935 refers to a constant pool entry of an address (or the sum of it
3936 plus a constant), a short (16-bit signed) constant plus a register,
3937 the sum of two registers, or a register indirect, possibly with an
5bdc5878 3938 auto-increment. For DFmode and DImode with a constant plus register,
258bfae2
FS
3939 we must ensure that both words are addressable or PowerPC64 with offset
3940 word aligned.
3941
3942 For modes spanning multiple registers (DFmode in 32-bit GPRs,
7393f7f8
BE
3943 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
3944 because adjacent memory cells are accessed by adding word-sized offsets
258bfae2
FS
3945 during assembly output. */
3946int
a2369ed3 3947rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
258bfae2 3948{
850e8d3d
DN
3949 /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
3950 if (TARGET_ALTIVEC
3951 && ALTIVEC_VECTOR_MODE (mode)
3952 && GET_CODE (x) == AND
3953 && GET_CODE (XEXP (x, 1)) == CONST_INT
3954 && INTVAL (XEXP (x, 1)) == -16)
3955 x = XEXP (x, 0);
3956
c4501e62
JJ
3957 if (RS6000_SYMBOL_REF_TLS_P (x))
3958 return 0;
4d588c14 3959 if (legitimate_indirect_address_p (x, reg_ok_strict))
258bfae2
FS
3960 return 1;
3961 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 3962 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 3963 && !SPE_VECTOR_MODE (mode)
429ec7dc 3964 && mode != TFmode
7393f7f8 3965 && mode != TDmode
54b695e7 3966 /* Restrict addressing for DI because of our SUBREG hackery. */
17caeff2
JM
3967 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
3968 || mode == DImode))
258bfae2 3969 && TARGET_UPDATE
4d588c14 3970 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
258bfae2 3971 return 1;
d04b6e6e 3972 if (legitimate_small_data_p (mode, x))
258bfae2 3973 return 1;
4d588c14 3974 if (legitimate_constant_pool_address_p (x))
258bfae2
FS
3975 return 1;
3976 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
3977 if (! reg_ok_strict
3978 && GET_CODE (x) == PLUS
3979 && GET_CODE (XEXP (x, 0)) == REG
708d2456 3980 && (XEXP (x, 0) == virtual_stack_vars_rtx
c4ad648e 3981 || XEXP (x, 0) == arg_pointer_rtx)
258bfae2
FS
3982 && GET_CODE (XEXP (x, 1)) == CONST_INT)
3983 return 1;
76d2b81d 3984 if (rs6000_legitimate_offset_address_p (mode, x, reg_ok_strict))
258bfae2
FS
3985 return 1;
3986 if (mode != TImode
76d2b81d 3987 && mode != TFmode
7393f7f8 3988 && mode != TDmode
a3170dc6
AH
3989 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
3990 || TARGET_POWERPC64
4d4cbc0e 3991 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
258bfae2 3992 && (TARGET_POWERPC64 || mode != DImode)
4d588c14 3993 && legitimate_indexed_address_p (x, reg_ok_strict))
258bfae2 3994 return 1;
6fb5fa3c
DB
3995 if (GET_CODE (x) == PRE_MODIFY
3996 && mode != TImode
3997 && mode != TFmode
3998 && mode != TDmode
3999 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
4000 || TARGET_POWERPC64
4001 || ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode))
4002 && (TARGET_POWERPC64 || mode != DImode)
4003 && !ALTIVEC_VECTOR_MODE (mode)
4004 && !SPE_VECTOR_MODE (mode)
4005 /* Restrict addressing for DI because of our SUBREG hackery. */
4006 && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode))
4007 && TARGET_UPDATE
4008 && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
4009 && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
4010 || legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict))
4011 && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
4012 return 1;
4d588c14 4013 if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
258bfae2
FS
4014 return 1;
4015 return 0;
4016}
4d588c14
RH
4017
4018/* Go to LABEL if ADDR (a legitimate address expression)
4019 has an effect that depends on the machine mode it is used for.
4020
4021 On the RS/6000 this is true of all integral offsets (since AltiVec
4022 modes don't allow them) or is a pre-increment or decrement.
4023
4024 ??? Except that due to conceptual problems in offsettable_address_p
4025 we can't really report the problems of integral offsets. So leave
f676971a 4026 this assuming that the adjustable offset must be valid for the
4d588c14
RH
4027 sub-words of a TFmode operand, which is what we had before. */
4028
4029bool
a2369ed3 4030rs6000_mode_dependent_address (rtx addr)
4d588c14
RH
4031{
4032 switch (GET_CODE (addr))
4033 {
4034 case PLUS:
4035 if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
4036 {
4037 unsigned HOST_WIDE_INT val = INTVAL (XEXP (addr, 1));
4038 return val + 12 + 0x8000 >= 0x10000;
4039 }
4040 break;
4041
4042 case LO_SUM:
4043 return true;
4044
6fb5fa3c
DB
4045 case PRE_INC:
4046 case PRE_DEC:
4047 case PRE_MODIFY:
4048 return TARGET_UPDATE;
4d588c14
RH
4049
4050 default:
4051 break;
4052 }
4053
4054 return false;
4055}
d8ecbcdb 4056
d04b6e6e
EB
4057/* More elaborate version of recog's offsettable_memref_p predicate
4058 that works around the ??? note of rs6000_mode_dependent_address.
4059 In particular it accepts
4060
4061 (mem:DI (plus:SI (reg/f:SI 31 31) (const_int 32760 [0x7ff8])))
4062
4063 in 32-bit mode, that the recog predicate rejects. */
4064
4065bool
4066rs6000_offsettable_memref_p (rtx op)
4067{
4068 if (!MEM_P (op))
4069 return false;
4070
4071 /* First mimic offsettable_memref_p. */
4072 if (offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)))
4073 return true;
4074
4075 /* offsettable_address_p invokes rs6000_mode_dependent_address, but
4076 the latter predicate knows nothing about the mode of the memory
4077 reference and, therefore, assumes that it is the largest supported
4078 mode (TFmode). As a consequence, legitimate offsettable memory
4079 references are rejected. rs6000_legitimate_offset_address_p contains
4080 the correct logic for the PLUS case of rs6000_mode_dependent_address. */
4081 return rs6000_legitimate_offset_address_p (GET_MODE (op), XEXP (op, 0), 1);
4082}
4083
d8ecbcdb
AH
4084/* Return number of consecutive hard regs needed starting at reg REGNO
4085 to hold something of mode MODE.
4086 This is ordinarily the length in words of a value of mode MODE
4087 but can be less for certain modes in special long registers.
4088
4089 For the SPE, GPRs are 64 bits but only 32 bits are visible in
4090 scalar instructions. The upper 32 bits are only available to the
4091 SIMD instructions.
4092
4093 POWER and PowerPC GPRs hold 32 bits worth;
4094 PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
4095
4096int
4097rs6000_hard_regno_nregs (int regno, enum machine_mode mode)
4098{
4099 if (FP_REGNO_P (regno))
4100 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
4101
4102 if (SPE_SIMD_REGNO_P (regno) && TARGET_SPE && SPE_VECTOR_MODE (mode))
4103 return (GET_MODE_SIZE (mode) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD;
4104
4105 if (ALTIVEC_REGNO_P (regno))
4106 return
4107 (GET_MODE_SIZE (mode) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD;
4108
8521c414
JM
4109 /* The value returned for SCmode in the E500 double case is 2 for
4110 ABI compatibility; storing an SCmode value in a single register
4111 would require function_arg and rs6000_spe_function_arg to handle
4112 SCmode so as to pass the value correctly in a pair of
4113 registers. */
4114 if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode)
4115 return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD;
4116
d8ecbcdb
AH
4117 return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4118}
2aa4498c
AH
4119
4120/* Change register usage conditional on target flags. */
4121void
4122rs6000_conditional_register_usage (void)
4123{
4124 int i;
4125
4126 /* Set MQ register fixed (already call_used) if not POWER
4127 architecture (RIOS1, RIOS2, RSC, and PPC601) so that it will not
4128 be allocated. */
4129 if (! TARGET_POWER)
4130 fixed_regs[64] = 1;
4131
7c9ac5c0 4132 /* 64-bit AIX and Linux reserve GPR13 for thread-private data. */
2aa4498c
AH
4133 if (TARGET_64BIT)
4134 fixed_regs[13] = call_used_regs[13]
4135 = call_really_used_regs[13] = 1;
4136
4137 /* Conditionally disable FPRs. */
4138 if (TARGET_SOFT_FLOAT || !TARGET_FPRS)
4139 for (i = 32; i < 64; i++)
4140 fixed_regs[i] = call_used_regs[i]
c4ad648e 4141 = call_really_used_regs[i] = 1;
2aa4498c 4142
7c9ac5c0
PH
4143 /* The TOC register is not killed across calls in a way that is
4144 visible to the compiler. */
4145 if (DEFAULT_ABI == ABI_AIX)
4146 call_really_used_regs[2] = 0;
4147
2aa4498c
AH
4148 if (DEFAULT_ABI == ABI_V4
4149 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
4150 && flag_pic == 2)
4151 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4152
4153 if (DEFAULT_ABI == ABI_V4
4154 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
4155 && flag_pic == 1)
4156 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4157 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4158 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4159
4160 if (DEFAULT_ABI == ABI_DARWIN
4161 && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
6d0a8091 4162 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
2aa4498c
AH
4163 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4164 = call_really_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4165
b4db40bf
JJ
4166 if (TARGET_TOC && TARGET_MINIMAL_TOC)
4167 fixed_regs[RS6000_PIC_OFFSET_TABLE_REGNUM]
4168 = call_used_regs[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
4169
2aa4498c
AH
4170 if (TARGET_ALTIVEC)
4171 global_regs[VSCR_REGNO] = 1;
4172
4173 if (TARGET_SPE)
4174 {
4175 global_regs[SPEFSCR_REGNO] = 1;
52ff33d0
NF
4176 /* We used to use r14 as FIXED_SCRATCH to address SPE 64-bit
4177 registers in prologues and epilogues. We no longer use r14
4178 for FIXED_SCRATCH, but we're keeping r14 out of the allocation
4179 pool for link-compatibility with older versions of GCC. Once
4180 "old" code has died out, we can return r14 to the allocation
4181 pool. */
4182 fixed_regs[14]
4183 = call_used_regs[14]
4184 = call_really_used_regs[14] = 1;
2aa4498c
AH
4185 }
4186
4187 if (! TARGET_ALTIVEC)
4188 {
4189 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
4190 fixed_regs[i] = call_used_regs[i] = call_really_used_regs[i] = 1;
4191 call_really_used_regs[VRSAVE_REGNO] = 1;
4192 }
4193
4194 if (TARGET_ALTIVEC_ABI)
4195 for (i = FIRST_ALTIVEC_REGNO; i < FIRST_ALTIVEC_REGNO + 20; ++i)
4196 call_used_regs[i] = call_really_used_regs[i] = 1;
4197}
fb4d4348 4198\f
a4f6c312
SS
4199/* Try to output insns to set TARGET equal to the constant C if it can
4200 be done in less than N insns. Do all computations in MODE.
4201 Returns the place where the output has been placed if it can be
4202 done and the insns have been emitted. If it would take more than N
4203 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
4204
4205rtx
f676971a 4206rs6000_emit_set_const (rtx dest, enum machine_mode mode,
a2369ed3 4207 rtx source, int n ATTRIBUTE_UNUSED)
2bfcf297 4208{
af8cb5c5 4209 rtx result, insn, set;
2bfcf297
DB
4210 HOST_WIDE_INT c0, c1;
4211
37409796 4212 switch (mode)
2bfcf297 4213 {
37409796
NS
4214 case QImode:
4215 case HImode:
2bfcf297 4216 if (dest == NULL)
c4ad648e 4217 dest = gen_reg_rtx (mode);
2bfcf297
DB
4218 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
4219 return dest;
bb8df8a6 4220
37409796 4221 case SImode:
b3a13419 4222 result = !can_create_pseudo_p () ? dest : gen_reg_rtx (SImode);
bb8df8a6 4223
d448860e 4224 emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (result),
af8cb5c5
DE
4225 GEN_INT (INTVAL (source)
4226 & (~ (HOST_WIDE_INT) 0xffff))));
4227 emit_insn (gen_rtx_SET (VOIDmode, dest,
d448860e 4228 gen_rtx_IOR (SImode, copy_rtx (result),
af8cb5c5
DE
4229 GEN_INT (INTVAL (source) & 0xffff))));
4230 result = dest;
37409796
NS
4231 break;
4232
4233 case DImode:
4234 switch (GET_CODE (source))
af8cb5c5 4235 {
37409796 4236 case CONST_INT:
af8cb5c5
DE
4237 c0 = INTVAL (source);
4238 c1 = -(c0 < 0);
37409796 4239 break;
bb8df8a6 4240
37409796 4241 case CONST_DOUBLE:
2bfcf297 4242#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
4243 c0 = CONST_DOUBLE_LOW (source);
4244 c1 = -(c0 < 0);
2bfcf297 4245#else
af8cb5c5
DE
4246 c0 = CONST_DOUBLE_LOW (source);
4247 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 4248#endif
37409796
NS
4249 break;
4250
4251 default:
4252 gcc_unreachable ();
af8cb5c5 4253 }
af8cb5c5
DE
4254
4255 result = rs6000_emit_set_long_const (dest, c0, c1);
37409796
NS
4256 break;
4257
4258 default:
4259 gcc_unreachable ();
2bfcf297 4260 }
2bfcf297 4261
af8cb5c5
DE
4262 insn = get_last_insn ();
4263 set = single_set (insn);
4264 if (! CONSTANT_P (SET_SRC (set)))
4265 set_unique_reg_note (insn, REG_EQUAL, source);
4266
4267 return result;
2bfcf297
DB
4268}
4269
4270/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
4271 fall back to a straight forward decomposition. We do this to avoid
4272 exponential run times encountered when looking for longer sequences
4273 with rs6000_emit_set_const. */
4274static rtx
a2369ed3 4275rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
2bfcf297
DB
4276{
4277 if (!TARGET_POWERPC64)
4278 {
4279 rtx operand1, operand2;
4280
4281 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
4282 DImode);
d448860e 4283 operand2 = operand_subword_force (copy_rtx (dest), WORDS_BIG_ENDIAN != 0,
2bfcf297
DB
4284 DImode);
4285 emit_move_insn (operand1, GEN_INT (c1));
4286 emit_move_insn (operand2, GEN_INT (c2));
4287 }
4288 else
4289 {
bc06712d 4290 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 4291
bc06712d 4292 ud1 = c1 & 0xffff;
f921c9c9 4293 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 4294#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 4295 c2 = c1 >> 32;
2bfcf297 4296#endif
bc06712d 4297 ud3 = c2 & 0xffff;
f921c9c9 4298 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 4299
f676971a 4300 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
bc06712d 4301 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 4302 {
bc06712d 4303 if (ud1 & 0x8000)
b78d48dd 4304 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
bc06712d
TR
4305 else
4306 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 4307 }
2bfcf297 4308
f676971a 4309 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
bc06712d 4310 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 4311 {
bc06712d 4312 if (ud2 & 0x8000)
f676971a 4313 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
bc06712d 4314 - 0x80000000));
252b88f7 4315 else
bc06712d
TR
4316 emit_move_insn (dest, GEN_INT (ud2 << 16));
4317 if (ud1 != 0)
d448860e
JH
4318 emit_move_insn (copy_rtx (dest),
4319 gen_rtx_IOR (DImode, copy_rtx (dest),
4320 GEN_INT (ud1)));
252b88f7 4321 }
f676971a 4322 else if ((ud4 == 0xffff && (ud3 & 0x8000))
bc06712d
TR
4323 || (ud4 == 0 && ! (ud3 & 0x8000)))
4324 {
4325 if (ud3 & 0x8000)
f676971a 4326 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
bc06712d
TR
4327 - 0x80000000));
4328 else
4329 emit_move_insn (dest, GEN_INT (ud3 << 16));
4330
4331 if (ud2 != 0)
d448860e
JH
4332 emit_move_insn (copy_rtx (dest),
4333 gen_rtx_IOR (DImode, copy_rtx (dest),
4334 GEN_INT (ud2)));
4335 emit_move_insn (copy_rtx (dest),
4336 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4337 GEN_INT (16)));
bc06712d 4338 if (ud1 != 0)
d448860e
JH
4339 emit_move_insn (copy_rtx (dest),
4340 gen_rtx_IOR (DImode, copy_rtx (dest),
4341 GEN_INT (ud1)));
bc06712d 4342 }
f676971a 4343 else
bc06712d
TR
4344 {
4345 if (ud4 & 0x8000)
f676971a 4346 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
bc06712d
TR
4347 - 0x80000000));
4348 else
4349 emit_move_insn (dest, GEN_INT (ud4 << 16));
4350
4351 if (ud3 != 0)
d448860e
JH
4352 emit_move_insn (copy_rtx (dest),
4353 gen_rtx_IOR (DImode, copy_rtx (dest),
4354 GEN_INT (ud3)));
2bfcf297 4355
d448860e
JH
4356 emit_move_insn (copy_rtx (dest),
4357 gen_rtx_ASHIFT (DImode, copy_rtx (dest),
4358 GEN_INT (32)));
bc06712d 4359 if (ud2 != 0)
d448860e
JH
4360 emit_move_insn (copy_rtx (dest),
4361 gen_rtx_IOR (DImode, copy_rtx (dest),
4362 GEN_INT (ud2 << 16)));
bc06712d 4363 if (ud1 != 0)
d448860e
JH
4364 emit_move_insn (copy_rtx (dest),
4365 gen_rtx_IOR (DImode, copy_rtx (dest), GEN_INT (ud1)));
bc06712d
TR
4366 }
4367 }
2bfcf297
DB
4368 return dest;
4369}
4370
76d2b81d 4371/* Helper for the following. Get rid of [r+r] memory refs
7393f7f8 4372 in cases where it won't work (TImode, TFmode, TDmode). */
76d2b81d
DJ
4373
4374static void
4375rs6000_eliminate_indexed_memrefs (rtx operands[2])
4376{
4377 if (GET_CODE (operands[0]) == MEM
4378 && GET_CODE (XEXP (operands[0], 0)) != REG
55aa0757 4379 && ! legitimate_constant_pool_address_p (XEXP (operands[0], 0))
76d2b81d
DJ
4380 && ! reload_in_progress)
4381 operands[0]
4382 = replace_equiv_address (operands[0],
4383 copy_addr_to_reg (XEXP (operands[0], 0)));
4384
4385 if (GET_CODE (operands[1]) == MEM
4386 && GET_CODE (XEXP (operands[1], 0)) != REG
55aa0757 4387 && ! legitimate_constant_pool_address_p (XEXP (operands[1], 0))
76d2b81d
DJ
4388 && ! reload_in_progress)
4389 operands[1]
4390 = replace_equiv_address (operands[1],
4391 copy_addr_to_reg (XEXP (operands[1], 0)));
4392}
4393
fb4d4348
GK
4394/* Emit a move from SOURCE to DEST in mode MODE. */
4395void
a2369ed3 4396rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
fb4d4348
GK
4397{
4398 rtx operands[2];
4399 operands[0] = dest;
4400 operands[1] = source;
f676971a 4401
fb4d4348
GK
4402 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
4403 if (GET_CODE (operands[1]) == CONST_DOUBLE
4404 && ! FLOAT_MODE_P (mode)
4405 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
4406 {
4407 /* FIXME. This should never happen. */
4408 /* Since it seems that it does, do the safe thing and convert
4409 to a CONST_INT. */
2496c7bd 4410 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348 4411 }
37409796
NS
4412 gcc_assert (GET_CODE (operands[1]) != CONST_DOUBLE
4413 || FLOAT_MODE_P (mode)
4414 || ((CONST_DOUBLE_HIGH (operands[1]) != 0
4415 || CONST_DOUBLE_LOW (operands[1]) < 0)
4416 && (CONST_DOUBLE_HIGH (operands[1]) != -1
4417 || CONST_DOUBLE_LOW (operands[1]) >= 0)));
bb8df8a6 4418
c9e8cb32
DD
4419 /* Check if GCC is setting up a block move that will end up using FP
4420 registers as temporaries. We must make sure this is acceptable. */
4421 if (GET_CODE (operands[0]) == MEM
4422 && GET_CODE (operands[1]) == MEM
4423 && mode == DImode
41543739
GK
4424 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
4425 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
4426 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
4427 ? 32 : MEM_ALIGN (operands[0])))
4428 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
f676971a 4429 ? 32
41543739
GK
4430 : MEM_ALIGN (operands[1]))))
4431 && ! MEM_VOLATILE_P (operands [0])
4432 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 4433 {
41543739
GK
4434 emit_move_insn (adjust_address (operands[0], SImode, 0),
4435 adjust_address (operands[1], SImode, 0));
d448860e
JH
4436 emit_move_insn (adjust_address (copy_rtx (operands[0]), SImode, 4),
4437 adjust_address (copy_rtx (operands[1]), SImode, 4));
c9e8cb32
DD
4438 return;
4439 }
630d42a0 4440
b3a13419 4441 if (can_create_pseudo_p () && GET_CODE (operands[0]) == MEM
c9dbf840 4442 && !gpc_reg_operand (operands[1], mode))
f6219a5e 4443 operands[1] = force_reg (mode, operands[1]);
a9098fd0 4444
a3170dc6
AH
4445 if (mode == SFmode && ! TARGET_POWERPC
4446 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 4447 && GET_CODE (operands[0]) == MEM)
fb4d4348 4448 {
ffc14f31
GK
4449 int regnum;
4450
4451 if (reload_in_progress || reload_completed)
4452 regnum = true_regnum (operands[1]);
4453 else if (GET_CODE (operands[1]) == REG)
4454 regnum = REGNO (operands[1]);
4455 else
4456 regnum = -1;
f676971a 4457
fb4d4348
GK
4458 /* If operands[1] is a register, on POWER it may have
4459 double-precision data in it, so truncate it to single
4460 precision. */
4461 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
4462 {
4463 rtx newreg;
b3a13419 4464 newreg = (!can_create_pseudo_p () ? copy_rtx (operands[1])
d448860e 4465 : gen_reg_rtx (mode));
fb4d4348
GK
4466 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
4467 operands[1] = newreg;
4468 }
4469 }
4470
c4501e62
JJ
4471 /* Recognize the case where operand[1] is a reference to thread-local
4472 data and load its address to a register. */
84f52ebd 4473 if (rs6000_tls_referenced_p (operands[1]))
c4501e62 4474 {
84f52ebd
RH
4475 enum tls_model model;
4476 rtx tmp = operands[1];
4477 rtx addend = NULL;
4478
4479 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS)
4480 {
4481 addend = XEXP (XEXP (tmp, 0), 1);
4482 tmp = XEXP (XEXP (tmp, 0), 0);
4483 }
4484
4485 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
4486 model = SYMBOL_REF_TLS_MODEL (tmp);
4487 gcc_assert (model != 0);
4488
4489 tmp = rs6000_legitimize_tls_address (tmp, model);
4490 if (addend)
4491 {
4492 tmp = gen_rtx_PLUS (mode, tmp, addend);
4493 tmp = force_operand (tmp, operands[0]);
4494 }
4495 operands[1] = tmp;
c4501e62
JJ
4496 }
4497
8f4e6caf
RH
4498 /* Handle the case where reload calls us with an invalid address. */
4499 if (reload_in_progress && mode == Pmode
69ef87e2 4500 && (! general_operand (operands[1], mode)
8f4e6caf
RH
4501 || ! nonimmediate_operand (operands[0], mode)))
4502 goto emit_set;
4503
a9baceb1
GK
4504 /* 128-bit constant floating-point values on Darwin should really be
4505 loaded as two parts. */
8521c414 4506 if (!TARGET_IEEEQUAD && TARGET_LONG_DOUBLE_128
a9baceb1
GK
4507 && mode == TFmode && GET_CODE (operands[1]) == CONST_DOUBLE)
4508 {
4509 /* DImode is used, not DFmode, because simplify_gen_subreg doesn't
4510 know how to get a DFmode SUBREG of a TFmode. */
17caeff2
JM
4511 enum machine_mode imode = (TARGET_E500_DOUBLE ? DFmode : DImode);
4512 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode, 0),
4513 simplify_gen_subreg (imode, operands[1], mode, 0),
4514 imode);
4515 rs6000_emit_move (simplify_gen_subreg (imode, operands[0], mode,
4516 GET_MODE_SIZE (imode)),
4517 simplify_gen_subreg (imode, operands[1], mode,
4518 GET_MODE_SIZE (imode)),
4519 imode);
a9baceb1
GK
4520 return;
4521 }
4522
fb4d4348
GK
4523 /* FIXME: In the long term, this switch statement should go away
4524 and be replaced by a sequence of tests based on things like
4525 mode == Pmode. */
4526 switch (mode)
4527 {
4528 case HImode:
4529 case QImode:
4530 if (CONSTANT_P (operands[1])
4531 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 4532 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
4533 break;
4534
06f4e019 4535 case TFmode:
7393f7f8 4536 case TDmode:
76d2b81d
DJ
4537 rs6000_eliminate_indexed_memrefs (operands);
4538 /* fall through */
4539
fb4d4348 4540 case DFmode:
7393f7f8 4541 case DDmode:
fb4d4348 4542 case SFmode:
f676971a 4543 if (CONSTANT_P (operands[1])
fb4d4348 4544 && ! easy_fp_constant (operands[1], mode))
a9098fd0 4545 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348 4546 break;
f676971a 4547
0ac081f6
AH
4548 case V16QImode:
4549 case V8HImode:
4550 case V4SFmode:
4551 case V4SImode:
a3170dc6
AH
4552 case V4HImode:
4553 case V2SFmode:
4554 case V2SImode:
00a892b8 4555 case V1DImode:
69ef87e2 4556 if (CONSTANT_P (operands[1])
d744e06e 4557 && !easy_vector_constant (operands[1], mode))
0ac081f6
AH
4558 operands[1] = force_const_mem (mode, operands[1]);
4559 break;
f676971a 4560
fb4d4348 4561 case SImode:
a9098fd0 4562 case DImode:
fb4d4348
GK
4563 /* Use default pattern for address of ELF small data */
4564 if (TARGET_ELF
a9098fd0 4565 && mode == Pmode
f607bc57 4566 && DEFAULT_ABI == ABI_V4
f676971a 4567 && (GET_CODE (operands[1]) == SYMBOL_REF
a9098fd0
GK
4568 || GET_CODE (operands[1]) == CONST)
4569 && small_data_operand (operands[1], mode))
fb4d4348
GK
4570 {
4571 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4572 return;
4573 }
4574
f607bc57 4575 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
4576 && mode == Pmode && mode == SImode
4577 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
4578 {
4579 emit_insn (gen_movsi_got (operands[0], operands[1]));
4580 return;
4581 }
4582
ee890fe2 4583 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
f1384257
AM
4584 && TARGET_NO_TOC
4585 && ! flag_pic
a9098fd0 4586 && mode == Pmode
fb4d4348
GK
4587 && CONSTANT_P (operands[1])
4588 && GET_CODE (operands[1]) != HIGH
4589 && GET_CODE (operands[1]) != CONST_INT)
4590 {
b3a13419
ILT
4591 rtx target = (!can_create_pseudo_p ()
4592 ? operands[0]
4593 : gen_reg_rtx (mode));
fb4d4348
GK
4594
4595 /* If this is a function address on -mcall-aixdesc,
4596 convert it to the address of the descriptor. */
4597 if (DEFAULT_ABI == ABI_AIX
4598 && GET_CODE (operands[1]) == SYMBOL_REF
4599 && XSTR (operands[1], 0)[0] == '.')
4600 {
4601 const char *name = XSTR (operands[1], 0);
4602 rtx new_ref;
4603 while (*name == '.')
4604 name++;
4605 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
4606 CONSTANT_POOL_ADDRESS_P (new_ref)
4607 = CONSTANT_POOL_ADDRESS_P (operands[1]);
d1908feb 4608 SYMBOL_REF_FLAGS (new_ref) = SYMBOL_REF_FLAGS (operands[1]);
fb4d4348 4609 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
c185c797 4610 SYMBOL_REF_DATA (new_ref) = SYMBOL_REF_DATA (operands[1]);
fb4d4348
GK
4611 operands[1] = new_ref;
4612 }
7509c759 4613
ee890fe2
SS
4614 if (DEFAULT_ABI == ABI_DARWIN)
4615 {
ab82a49f
AP
4616#if TARGET_MACHO
4617 if (MACHO_DYNAMIC_NO_PIC_P)
4618 {
4619 /* Take care of any required data indirection. */
4620 operands[1] = rs6000_machopic_legitimize_pic_address (
4621 operands[1], mode, operands[0]);
4622 if (operands[0] != operands[1])
4623 emit_insn (gen_rtx_SET (VOIDmode,
c4ad648e 4624 operands[0], operands[1]));
ab82a49f
AP
4625 return;
4626 }
4627#endif
b8a55285
AP
4628 emit_insn (gen_macho_high (target, operands[1]));
4629 emit_insn (gen_macho_low (operands[0], target, operands[1]));
ee890fe2
SS
4630 return;
4631 }
4632
fb4d4348
GK
4633 emit_insn (gen_elf_high (target, operands[1]));
4634 emit_insn (gen_elf_low (operands[0], target, operands[1]));
4635 return;
4636 }
4637
a9098fd0
GK
4638 /* If this is a SYMBOL_REF that refers to a constant pool entry,
4639 and we have put it in the TOC, we just need to make a TOC-relative
4640 reference to it. */
4641 if (TARGET_TOC
4642 && GET_CODE (operands[1]) == SYMBOL_REF
4d588c14 4643 && constant_pool_expr_p (operands[1])
a9098fd0
GK
4644 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
4645 get_pool_mode (operands[1])))
fb4d4348 4646 {
a9098fd0 4647 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 4648 }
a9098fd0
GK
4649 else if (mode == Pmode
4650 && CONSTANT_P (operands[1])
38886f37
AO
4651 && ((GET_CODE (operands[1]) != CONST_INT
4652 && ! easy_fp_constant (operands[1], mode))
4653 || (GET_CODE (operands[1]) == CONST_INT
4654 && num_insns_constant (operands[1], mode) > 2)
4655 || (GET_CODE (operands[0]) == REG
4656 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0 4657 && GET_CODE (operands[1]) != HIGH
4d588c14
RH
4658 && ! legitimate_constant_pool_address_p (operands[1])
4659 && ! toc_relative_expr_p (operands[1]))
fb4d4348
GK
4660 {
4661 /* Emit a USE operation so that the constant isn't deleted if
4662 expensive optimizations are turned on because nobody
4663 references it. This should only be done for operands that
4664 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
4665 This should not be done for operands that contain LABEL_REFs.
4666 For now, we just handle the obvious case. */
4667 if (GET_CODE (operands[1]) != LABEL_REF)
4668 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
4669
c859cda6 4670#if TARGET_MACHO
ee890fe2 4671 /* Darwin uses a special PIC legitimizer. */
ab82a49f 4672 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
ee890fe2 4673 {
ee890fe2
SS
4674 operands[1] =
4675 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
4676 operands[0]);
4677 if (operands[0] != operands[1])
4678 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
4679 return;
4680 }
c859cda6 4681#endif
ee890fe2 4682
fb4d4348
GK
4683 /* If we are to limit the number of things we put in the TOC and
4684 this is a symbol plus a constant we can add in one insn,
4685 just put the symbol in the TOC and add the constant. Don't do
4686 this if reload is in progress. */
4687 if (GET_CODE (operands[1]) == CONST
4688 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
4689 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 4690 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
4691 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
4692 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
4693 && ! side_effects_p (operands[0]))
4694 {
a4f6c312
SS
4695 rtx sym =
4696 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
4697 rtx other = XEXP (XEXP (operands[1], 0), 1);
4698
a9098fd0
GK
4699 sym = force_reg (mode, sym);
4700 if (mode == SImode)
4701 emit_insn (gen_addsi3 (operands[0], sym, other));
4702 else
4703 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
4704 return;
4705 }
4706
a9098fd0 4707 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348 4708
f676971a 4709 if (TARGET_TOC
4d588c14 4710 && constant_pool_expr_p (XEXP (operands[1], 0))
d34c5b80
DE
4711 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
4712 get_pool_constant (XEXP (operands[1], 0)),
4713 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 4714 {
ba4828e0 4715 operands[1]
542a8afa 4716 = gen_const_mem (mode,
c4ad648e 4717 create_TOC_reference (XEXP (operands[1], 0)));
ba4828e0 4718 set_mem_alias_set (operands[1], get_TOC_alias_set ());
a9098fd0 4719 }
fb4d4348
GK
4720 }
4721 break;
a9098fd0 4722
fb4d4348 4723 case TImode:
76d2b81d
DJ
4724 rs6000_eliminate_indexed_memrefs (operands);
4725
27dc0551
DE
4726 if (TARGET_POWER)
4727 {
4728 emit_insn (gen_rtx_PARALLEL (VOIDmode,
4729 gen_rtvec (2,
4730 gen_rtx_SET (VOIDmode,
4731 operands[0], operands[1]),
4732 gen_rtx_CLOBBER (VOIDmode,
4733 gen_rtx_SCRATCH (SImode)))));
4734 return;
4735 }
fb4d4348
GK
4736 break;
4737
4738 default:
37409796 4739 gcc_unreachable ();
fb4d4348
GK
4740 }
4741
a9098fd0
GK
4742 /* Above, we may have called force_const_mem which may have returned
4743 an invalid address. If we can, fix this up; otherwise, reload will
4744 have to deal with it. */
8f4e6caf
RH
4745 if (GET_CODE (operands[1]) == MEM && ! reload_in_progress)
4746 operands[1] = validize_mem (operands[1]);
a9098fd0 4747
8f4e6caf 4748 emit_set:
fb4d4348
GK
4749 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
4750}
4697a36c 4751\f
2858f73a
GK
4752/* Nonzero if we can use a floating-point register to pass this arg. */
4753#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
ebb109ad 4754 (SCALAR_FLOAT_MODE_P (MODE) \
7393f7f8 4755 && (MODE) != SDmode \
2858f73a
GK
4756 && (CUM)->fregno <= FP_ARG_MAX_REG \
4757 && TARGET_HARD_FLOAT && TARGET_FPRS)
4758
4759/* Nonzero if we can use an AltiVec register to pass this arg. */
4760#define USE_ALTIVEC_FOR_ARG_P(CUM,MODE,TYPE,NAMED) \
4761 (ALTIVEC_VECTOR_MODE (MODE) \
4762 && (CUM)->vregno <= ALTIVEC_ARG_MAX_REG \
4763 && TARGET_ALTIVEC_ABI \
83953138 4764 && (NAMED))
2858f73a 4765
c6e8c921
GK
4766/* Return a nonzero value to say to return the function value in
4767 memory, just as large structures are always returned. TYPE will be
4768 the data type of the value, and FNTYPE will be the type of the
4769 function doing the returning, or @code{NULL} for libcalls.
4770
4771 The AIX ABI for the RS/6000 specifies that all structures are
4772 returned in memory. The Darwin ABI does the same. The SVR4 ABI
4773 specifies that structures <= 8 bytes are returned in r3/r4, but a
4774 draft put them in memory, and GCC used to implement the draft
df01da37 4775 instead of the final standard. Therefore, aix_struct_return
c6e8c921
GK
4776 controls this instead of DEFAULT_ABI; V.4 targets needing backward
4777 compatibility can change DRAFT_V4_STRUCT_RET to override the
4778 default, and -m switches get the final word. See
4779 rs6000_override_options for more details.
4780
4781 The PPC32 SVR4 ABI uses IEEE double extended for long double, if 128-bit
4782 long double support is enabled. These values are returned in memory.
4783
4784 int_size_in_bytes returns -1 for variable size objects, which go in
4785 memory always. The cast to unsigned makes -1 > 8. */
4786
4787static bool
586de218 4788rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
c6e8c921 4789{
594a51fe
SS
4790 /* In the darwin64 abi, try to use registers for larger structs
4791 if possible. */
0b5383eb 4792 if (rs6000_darwin64_abi
594a51fe 4793 && TREE_CODE (type) == RECORD_TYPE
0b5383eb
DJ
4794 && int_size_in_bytes (type) > 0)
4795 {
4796 CUMULATIVE_ARGS valcum;
4797 rtx valret;
4798
4799 valcum.words = 0;
4800 valcum.fregno = FP_ARG_MIN_REG;
4801 valcum.vregno = ALTIVEC_ARG_MIN_REG;
4802 /* Do a trial code generation as if this were going to be passed
4803 as an argument; if any part goes in memory, we return NULL. */
4804 valret = rs6000_darwin64_record_arg (&valcum, type, 1, true);
4805 if (valret)
4806 return false;
4807 /* Otherwise fall through to more conventional ABI rules. */
4808 }
594a51fe 4809
c6e8c921 4810 if (AGGREGATE_TYPE_P (type)
df01da37 4811 && (aix_struct_return
c6e8c921
GK
4812 || (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
4813 return true;
b693336b 4814
bada2eb8
DE
4815 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
4816 modes only exist for GCC vector types if -maltivec. */
4817 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI
4818 && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
4819 return false;
4820
b693336b
PB
4821 /* Return synthetic vectors in memory. */
4822 if (TREE_CODE (type) == VECTOR_TYPE
ad630bef 4823 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
b693336b
PB
4824 {
4825 static bool warned_for_return_big_vectors = false;
4826 if (!warned_for_return_big_vectors)
4827 {
d4ee4d25 4828 warning (0, "GCC vector returned by reference: "
b693336b
PB
4829 "non-standard ABI extension with no compatibility guarantee");
4830 warned_for_return_big_vectors = true;
4831 }
4832 return true;
4833 }
4834
602ea4d3 4835 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && TYPE_MODE (type) == TFmode)
c6e8c921 4836 return true;
ad630bef 4837
c6e8c921
GK
4838 return false;
4839}
4840
4697a36c
MM
4841/* Initialize a variable CUM of type CUMULATIVE_ARGS
4842 for a call to a function whose data type is FNTYPE.
4843 For a library call, FNTYPE is 0.
4844
4845 For incoming args we set the number of arguments in the prototype large
1c20ae99 4846 so we never return a PARALLEL. */
4697a36c
MM
4847
4848void
f676971a 4849init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype,
0f6937fe
AM
4850 rtx libname ATTRIBUTE_UNUSED, int incoming,
4851 int libcall, int n_named_args)
4697a36c
MM
4852{
4853 static CUMULATIVE_ARGS zero_cumulative;
4854
4855 *cum = zero_cumulative;
4856 cum->words = 0;
4857 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 4858 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 4859 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
ddcc8263
DE
4860 cum->call_cookie = ((DEFAULT_ABI == ABI_V4 && libcall)
4861 ? CALL_LIBCALL : CALL_NORMAL);
4cc833b7 4862 cum->sysv_gregno = GP_ARG_MIN_REG;
a6c9bed4
AH
4863 cum->stdarg = fntype
4864 && (TYPE_ARG_TYPES (fntype) != 0
4865 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
4866 != void_type_node));
4697a36c 4867
0f6937fe
AM
4868 cum->nargs_prototype = 0;
4869 if (incoming || cum->prototype)
4870 cum->nargs_prototype = n_named_args;
4697a36c 4871
a5c76ee6 4872 /* Check for a longcall attribute. */
3eb4e360
AM
4873 if ((!fntype && rs6000_default_long_calls)
4874 || (fntype
4875 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
4876 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype))))
4877 cum->call_cookie |= CALL_LONG;
6a4cee5f 4878
4697a36c
MM
4879 if (TARGET_DEBUG_ARG)
4880 {
4881 fprintf (stderr, "\ninit_cumulative_args:");
4882 if (fntype)
4883 {
4884 tree ret_type = TREE_TYPE (fntype);
4885 fprintf (stderr, " ret code = %s,",
4886 tree_code_name[ (int)TREE_CODE (ret_type) ]);
4887 }
4888
6a4cee5f
MM
4889 if (cum->call_cookie & CALL_LONG)
4890 fprintf (stderr, " longcall,");
4891
4697a36c
MM
4892 fprintf (stderr, " proto = %d, nargs = %d\n",
4893 cum->prototype, cum->nargs_prototype);
4894 }
f676971a 4895
c4ad648e
AM
4896 if (fntype
4897 && !TARGET_ALTIVEC
4898 && TARGET_ALTIVEC_ABI
4899 && ALTIVEC_VECTOR_MODE (TYPE_MODE (TREE_TYPE (fntype))))
4900 {
c85ce869 4901 error ("cannot return value in vector register because"
c4ad648e 4902 " altivec instructions are disabled, use -maltivec"
c85ce869 4903 " to enable them");
c4ad648e 4904 }
4697a36c
MM
4905}
4906\f
fe984136
RH
4907/* Return true if TYPE must be passed on the stack and not in registers. */
4908
4909static bool
586de218 4910rs6000_must_pass_in_stack (enum machine_mode mode, const_tree type)
fe984136
RH
4911{
4912 if (DEFAULT_ABI == ABI_AIX || TARGET_64BIT)
4913 return must_pass_in_stack_var_size (mode, type);
4914 else
4915 return must_pass_in_stack_var_size_or_pad (mode, type);
4916}
4917
c229cba9
DE
4918/* If defined, a C expression which determines whether, and in which
4919 direction, to pad out an argument with extra space. The value
4920 should be of type `enum direction': either `upward' to pad above
4921 the argument, `downward' to pad below, or `none' to inhibit
4922 padding.
4923
4924 For the AIX ABI structs are always stored left shifted in their
4925 argument slot. */
4926
9ebbca7d 4927enum direction
586de218 4928function_arg_padding (enum machine_mode mode, const_tree type)
c229cba9 4929{
6e985040
AM
4930#ifndef AGGREGATE_PADDING_FIXED
4931#define AGGREGATE_PADDING_FIXED 0
4932#endif
4933#ifndef AGGREGATES_PAD_UPWARD_ALWAYS
4934#define AGGREGATES_PAD_UPWARD_ALWAYS 0
4935#endif
4936
4937 if (!AGGREGATE_PADDING_FIXED)
4938 {
4939 /* GCC used to pass structures of the same size as integer types as
4940 if they were in fact integers, ignoring FUNCTION_ARG_PADDING.
19525b57 4941 i.e. Structures of size 1 or 2 (or 4 when TARGET_64BIT) were
6e985040
AM
4942 passed padded downward, except that -mstrict-align further
4943 muddied the water in that multi-component structures of 2 and 4
4944 bytes in size were passed padded upward.
4945
4946 The following arranges for best compatibility with previous
4947 versions of gcc, but removes the -mstrict-align dependency. */
4948 if (BYTES_BIG_ENDIAN)
4949 {
4950 HOST_WIDE_INT size = 0;
4951
4952 if (mode == BLKmode)
4953 {
4954 if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
4955 size = int_size_in_bytes (type);
4956 }
4957 else
4958 size = GET_MODE_SIZE (mode);
4959
4960 if (size == 1 || size == 2 || size == 4)
4961 return downward;
4962 }
4963 return upward;
4964 }
4965
4966 if (AGGREGATES_PAD_UPWARD_ALWAYS)
4967 {
4968 if (type != 0 && AGGREGATE_TYPE_P (type))
4969 return upward;
4970 }
c229cba9 4971
d3704c46
KH
4972 /* Fall back to the default. */
4973 return DEFAULT_FUNCTION_ARG_PADDING (mode, type);
c229cba9
DE
4974}
4975
b6c9286a 4976/* If defined, a C expression that gives the alignment boundary, in bits,
f676971a 4977 of an argument with the specified mode and type. If it is not defined,
b6c9286a 4978 PARM_BOUNDARY is used for all arguments.
f676971a 4979
84e9ad15
AM
4980 V.4 wants long longs and doubles to be double word aligned. Just
4981 testing the mode size is a boneheaded way to do this as it means
4982 that other types such as complex int are also double word aligned.
4983 However, we're stuck with this because changing the ABI might break
4984 existing library interfaces.
4985
b693336b
PB
4986 Doubleword align SPE vectors.
4987 Quadword align Altivec vectors.
4988 Quadword align large synthetic vector types. */
b6c9286a
MM
4989
4990int
b693336b 4991function_arg_boundary (enum machine_mode mode, tree type)
b6c9286a 4992{
84e9ad15
AM
4993 if (DEFAULT_ABI == ABI_V4
4994 && (GET_MODE_SIZE (mode) == 8
4995 || (TARGET_HARD_FLOAT
4996 && TARGET_FPRS
7393f7f8 4997 && (mode == TFmode || mode == TDmode))))
4ed78545 4998 return 64;
ad630bef
DE
4999 else if (SPE_VECTOR_MODE (mode)
5000 || (type && TREE_CODE (type) == VECTOR_TYPE
5001 && int_size_in_bytes (type) >= 8
5002 && int_size_in_bytes (type) < 16))
e1f83b4d 5003 return 64;
ad630bef
DE
5004 else if (ALTIVEC_VECTOR_MODE (mode)
5005 || (type && TREE_CODE (type) == VECTOR_TYPE
5006 && int_size_in_bytes (type) >= 16))
0ac081f6 5007 return 128;
0b5383eb
DJ
5008 else if (rs6000_darwin64_abi && mode == BLKmode
5009 && type && TYPE_ALIGN (type) > 64)
5010 return 128;
9ebbca7d 5011 else
b6c9286a 5012 return PARM_BOUNDARY;
b6c9286a 5013}
c53bdcf5 5014
294bd182
AM
5015/* For a function parm of MODE and TYPE, return the starting word in
5016 the parameter area. NWORDS of the parameter area are already used. */
5017
5018static unsigned int
5019rs6000_parm_start (enum machine_mode mode, tree type, unsigned int nwords)
5020{
5021 unsigned int align;
5022 unsigned int parm_offset;
5023
5024 align = function_arg_boundary (mode, type) / PARM_BOUNDARY - 1;
5025 parm_offset = DEFAULT_ABI == ABI_V4 ? 2 : 6;
5026 return nwords + (-(parm_offset + nwords) & align);
5027}
5028
c53bdcf5
AM
5029/* Compute the size (in words) of a function argument. */
5030
5031static unsigned long
5032rs6000_arg_size (enum machine_mode mode, tree type)
5033{
5034 unsigned long size;
5035
5036 if (mode != BLKmode)
5037 size = GET_MODE_SIZE (mode);
5038 else
5039 size = int_size_in_bytes (type);
5040
5041 if (TARGET_32BIT)
5042 return (size + 3) >> 2;
5043 else
5044 return (size + 7) >> 3;
5045}
b6c9286a 5046\f
0b5383eb 5047/* Use this to flush pending int fields. */
594a51fe
SS
5048
5049static void
0b5383eb
DJ
5050rs6000_darwin64_record_arg_advance_flush (CUMULATIVE_ARGS *cum,
5051 HOST_WIDE_INT bitpos)
594a51fe 5052{
0b5383eb
DJ
5053 unsigned int startbit, endbit;
5054 int intregs, intoffset;
5055 enum machine_mode mode;
594a51fe 5056
0b5383eb
DJ
5057 if (cum->intoffset == -1)
5058 return;
594a51fe 5059
0b5383eb
DJ
5060 intoffset = cum->intoffset;
5061 cum->intoffset = -1;
5062
5063 if (intoffset % BITS_PER_WORD != 0)
5064 {
5065 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5066 MODE_INT, 0);
5067 if (mode == BLKmode)
594a51fe 5068 {
0b5383eb
DJ
5069 /* We couldn't find an appropriate mode, which happens,
5070 e.g., in packed structs when there are 3 bytes to load.
5071 Back intoffset back to the beginning of the word in this
5072 case. */
5073 intoffset = intoffset & -BITS_PER_WORD;
594a51fe 5074 }
594a51fe 5075 }
0b5383eb
DJ
5076
5077 startbit = intoffset & -BITS_PER_WORD;
5078 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5079 intregs = (endbit - startbit) / BITS_PER_WORD;
5080 cum->words += intregs;
5081}
5082
5083/* The darwin64 ABI calls for us to recurse down through structs,
5084 looking for elements passed in registers. Unfortunately, we have
5085 to track int register count here also because of misalignments
5086 in powerpc alignment mode. */
5087
5088static void
5089rs6000_darwin64_record_arg_advance_recurse (CUMULATIVE_ARGS *cum,
5090 tree type,
5091 HOST_WIDE_INT startbitpos)
5092{
5093 tree f;
5094
5095 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5096 if (TREE_CODE (f) == FIELD_DECL)
5097 {
5098 HOST_WIDE_INT bitpos = startbitpos;
5099 tree ftype = TREE_TYPE (f);
70fb00df
AP
5100 enum machine_mode mode;
5101 if (ftype == error_mark_node)
5102 continue;
5103 mode = TYPE_MODE (ftype);
0b5383eb
DJ
5104
5105 if (DECL_SIZE (f) != 0
5106 && host_integerp (bit_position (f), 1))
5107 bitpos += int_bit_position (f);
5108
5109 /* ??? FIXME: else assume zero offset. */
5110
5111 if (TREE_CODE (ftype) == RECORD_TYPE)
5112 rs6000_darwin64_record_arg_advance_recurse (cum, ftype, bitpos);
5113 else if (USE_FP_FOR_ARG_P (cum, mode, ftype))
5114 {
5115 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
5116 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5117 cum->words += (GET_MODE_SIZE (mode) + 7) >> 3;
5118 }
5119 else if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, 1))
5120 {
5121 rs6000_darwin64_record_arg_advance_flush (cum, bitpos);
5122 cum->vregno++;
5123 cum->words += 2;
5124 }
5125 else if (cum->intoffset == -1)
5126 cum->intoffset = bitpos;
5127 }
594a51fe
SS
5128}
5129
4697a36c
MM
5130/* Update the data in CUM to advance over an argument
5131 of mode MODE and data type TYPE.
b2d04ecf
AM
5132 (TYPE is null for libcalls where that information may not be available.)
5133
5134 Note that for args passed by reference, function_arg will be called
5135 with MODE and TYPE set to that of the pointer to the arg, not the arg
5136 itself. */
4697a36c
MM
5137
5138void
f676971a 5139function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
594a51fe 5140 tree type, int named, int depth)
4697a36c 5141{
0b5383eb
DJ
5142 int size;
5143
594a51fe
SS
5144 /* Only tick off an argument if we're not recursing. */
5145 if (depth == 0)
5146 cum->nargs_prototype--;
4697a36c 5147
ad630bef
DE
5148 if (TARGET_ALTIVEC_ABI
5149 && (ALTIVEC_VECTOR_MODE (mode)
5150 || (type && TREE_CODE (type) == VECTOR_TYPE
5151 && int_size_in_bytes (type) == 16)))
0ac081f6 5152 {
4ed78545
AM
5153 bool stack = false;
5154
2858f73a 5155 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
c4ad648e 5156 {
6d0ef01e
HP
5157 cum->vregno++;
5158 if (!TARGET_ALTIVEC)
c85ce869 5159 error ("cannot pass argument in vector register because"
6d0ef01e 5160 " altivec instructions are disabled, use -maltivec"
c85ce869 5161 " to enable them");
4ed78545
AM
5162
5163 /* PowerPC64 Linux and AIX allocate GPRs for a vector argument
f676971a 5164 even if it is going to be passed in a vector register.
4ed78545
AM
5165 Darwin does the same for variable-argument functions. */
5166 if ((DEFAULT_ABI == ABI_AIX && TARGET_64BIT)
5167 || (cum->stdarg && DEFAULT_ABI != ABI_V4))
5168 stack = true;
6d0ef01e 5169 }
4ed78545
AM
5170 else
5171 stack = true;
5172
5173 if (stack)
c4ad648e 5174 {
a594a19c 5175 int align;
f676971a 5176
2858f73a
GK
5177 /* Vector parameters must be 16-byte aligned. This places
5178 them at 2 mod 4 in terms of words in 32-bit mode, since
5179 the parameter save area starts at offset 24 from the
5180 stack. In 64-bit mode, they just have to start on an
5181 even word, since the parameter save area is 16-byte
5182 aligned. Space for GPRs is reserved even if the argument
5183 will be passed in memory. */
5184 if (TARGET_32BIT)
4ed78545 5185 align = (2 - cum->words) & 3;
2858f73a
GK
5186 else
5187 align = cum->words & 1;
c53bdcf5 5188 cum->words += align + rs6000_arg_size (mode, type);
f676971a 5189
a594a19c
GK
5190 if (TARGET_DEBUG_ARG)
5191 {
f676971a 5192 fprintf (stderr, "function_adv: words = %2d, align=%d, ",
a594a19c
GK
5193 cum->words, align);
5194 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s\n",
f676971a 5195 cum->nargs_prototype, cum->prototype,
2858f73a 5196 GET_MODE_NAME (mode));
a594a19c
GK
5197 }
5198 }
0ac081f6 5199 }
a4b0320c 5200 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
a6c9bed4
AH
5201 && !cum->stdarg
5202 && cum->sysv_gregno <= GP_ARG_MAX_REG)
a4b0320c 5203 cum->sysv_gregno++;
594a51fe
SS
5204
5205 else if (rs6000_darwin64_abi
5206 && mode == BLKmode
0b5383eb
DJ
5207 && TREE_CODE (type) == RECORD_TYPE
5208 && (size = int_size_in_bytes (type)) > 0)
5209 {
5210 /* Variable sized types have size == -1 and are
5211 treated as if consisting entirely of ints.
5212 Pad to 16 byte boundary if needed. */
5213 if (TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5214 && (cum->words % 2) != 0)
5215 cum->words++;
5216 /* For varargs, we can just go up by the size of the struct. */
5217 if (!named)
5218 cum->words += (size + 7) / 8;
5219 else
5220 {
5221 /* It is tempting to say int register count just goes up by
5222 sizeof(type)/8, but this is wrong in a case such as
5223 { int; double; int; } [powerpc alignment]. We have to
5224 grovel through the fields for these too. */
5225 cum->intoffset = 0;
5226 rs6000_darwin64_record_arg_advance_recurse (cum, type, 0);
bb8df8a6 5227 rs6000_darwin64_record_arg_advance_flush (cum,
0b5383eb
DJ
5228 size * BITS_PER_UNIT);
5229 }
5230 }
f607bc57 5231 else if (DEFAULT_ABI == ABI_V4)
4697a36c 5232 {
a3170dc6 5233 if (TARGET_HARD_FLOAT && TARGET_FPRS
602ea4d3 5234 && (mode == SFmode || mode == DFmode
7393f7f8 5235 || mode == DDmode || mode == TDmode
602ea4d3 5236 || (mode == TFmode && !TARGET_IEEEQUAD)))
4697a36c 5237 {
2d83f070
JJ
5238 /* _Decimal128 must use an even/odd register pair. This assumes
5239 that the register number is odd when fregno is odd. */
5240 if (mode == TDmode && (cum->fregno % 2) == 1)
7393f7f8
BE
5241 cum->fregno++;
5242
5243 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
5244 <= FP_ARG_V4_MAX_REG)
602ea4d3 5245 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
4cc833b7
RH
5246 else
5247 {
602ea4d3 5248 cum->fregno = FP_ARG_V4_MAX_REG + 1;
7393f7f8 5249 if (mode == DFmode || mode == TFmode || mode == DDmode || mode == TDmode)
c4ad648e 5250 cum->words += cum->words & 1;
c53bdcf5 5251 cum->words += rs6000_arg_size (mode, type);
4cc833b7 5252 }
4697a36c 5253 }
4cc833b7
RH
5254 else
5255 {
b2d04ecf 5256 int n_words = rs6000_arg_size (mode, type);
4cc833b7
RH
5257 int gregno = cum->sysv_gregno;
5258
4ed78545
AM
5259 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5260 (r7,r8) or (r9,r10). As does any other 2 word item such
5261 as complex int due to a historical mistake. */
5262 if (n_words == 2)
5263 gregno += (1 - gregno) & 1;
4cc833b7 5264
4ed78545 5265 /* Multi-reg args are not split between registers and stack. */
4cc833b7
RH
5266 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
5267 {
4ed78545
AM
5268 /* Long long and SPE vectors are aligned on the stack.
5269 So are other 2 word items such as complex int due to
5270 a historical mistake. */
4cc833b7
RH
5271 if (n_words == 2)
5272 cum->words += cum->words & 1;
5273 cum->words += n_words;
5274 }
4697a36c 5275
4cc833b7
RH
5276 /* Note: continuing to accumulate gregno past when we've started
5277 spilling to the stack indicates the fact that we've started
5278 spilling to the stack to expand_builtin_saveregs. */
5279 cum->sysv_gregno = gregno + n_words;
5280 }
4697a36c 5281
4cc833b7
RH
5282 if (TARGET_DEBUG_ARG)
5283 {
5284 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5285 cum->words, cum->fregno);
5286 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
5287 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
5288 fprintf (stderr, "mode = %4s, named = %d\n",
5289 GET_MODE_NAME (mode), named);
5290 }
4697a36c
MM
5291 }
5292 else
4cc833b7 5293 {
b2d04ecf 5294 int n_words = rs6000_arg_size (mode, type);
294bd182
AM
5295 int start_words = cum->words;
5296 int align_words = rs6000_parm_start (mode, type, start_words);
a4f6c312 5297
294bd182 5298 cum->words = align_words + n_words;
4697a36c 5299
ebb109ad 5300 if (SCALAR_FLOAT_MODE_P (mode)
7393f7f8 5301 && mode != SDmode
a3170dc6 5302 && TARGET_HARD_FLOAT && TARGET_FPRS)
2d83f070
JJ
5303 {
5304 /* _Decimal128 must be passed in an even/odd float register pair.
5305 This assumes that the register number is odd when fregno is
5306 odd. */
5307 if (mode == TDmode && (cum->fregno % 2) == 1)
5308 cum->fregno++;
5309 cum->fregno += (GET_MODE_SIZE (mode) + 7) >> 3;
5310 }
4cc833b7
RH
5311
5312 if (TARGET_DEBUG_ARG)
5313 {
5314 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
5315 cum->words, cum->fregno);
5316 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
5317 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
594a51fe 5318 fprintf (stderr, "named = %d, align = %d, depth = %d\n",
294bd182 5319 named, align_words - start_words, depth);
4cc833b7
RH
5320 }
5321 }
4697a36c 5322}
a6c9bed4 5323
f82f556d
AH
5324static rtx
5325spe_build_register_parallel (enum machine_mode mode, int gregno)
5326{
17caeff2 5327 rtx r1, r3, r5, r7;
f82f556d 5328
37409796 5329 switch (mode)
f82f556d 5330 {
37409796 5331 case DFmode:
54b695e7
AH
5332 r1 = gen_rtx_REG (DImode, gregno);
5333 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5334 return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
37409796
NS
5335
5336 case DCmode:
17caeff2 5337 case TFmode:
54b695e7
AH
5338 r1 = gen_rtx_REG (DImode, gregno);
5339 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5340 r3 = gen_rtx_REG (DImode, gregno + 2);
5341 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5342 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r3));
37409796 5343
17caeff2
JM
5344 case TCmode:
5345 r1 = gen_rtx_REG (DImode, gregno);
5346 r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
5347 r3 = gen_rtx_REG (DImode, gregno + 2);
5348 r3 = gen_rtx_EXPR_LIST (VOIDmode, r3, GEN_INT (8));
5349 r5 = gen_rtx_REG (DImode, gregno + 4);
5350 r5 = gen_rtx_EXPR_LIST (VOIDmode, r5, GEN_INT (16));
5351 r7 = gen_rtx_REG (DImode, gregno + 6);
5352 r7 = gen_rtx_EXPR_LIST (VOIDmode, r7, GEN_INT (24));
5353 return gen_rtx_PARALLEL (mode, gen_rtvec (4, r1, r3, r5, r7));
5354
37409796
NS
5355 default:
5356 gcc_unreachable ();
f82f556d 5357 }
f82f556d 5358}
b78d48dd 5359
f82f556d 5360/* Determine where to put a SIMD argument on the SPE. */
a6c9bed4 5361static rtx
f676971a 5362rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
a2369ed3 5363 tree type)
a6c9bed4 5364{
f82f556d
AH
5365 int gregno = cum->sysv_gregno;
5366
5367 /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but
600e1f95 5368 are passed and returned in a pair of GPRs for ABI compatibility. */
17caeff2
JM
5369 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode
5370 || mode == TFmode || mode == TCmode))
f82f556d 5371 {
b5870bee
AH
5372 int n_words = rs6000_arg_size (mode, type);
5373
f82f556d 5374 /* Doubles go in an odd/even register pair (r5/r6, etc). */
b5870bee
AH
5375 if (mode == DFmode)
5376 gregno += (1 - gregno) & 1;
f82f556d 5377
b5870bee
AH
5378 /* Multi-reg args are not split between registers and stack. */
5379 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
f82f556d
AH
5380 return NULL_RTX;
5381
5382 return spe_build_register_parallel (mode, gregno);
5383 }
a6c9bed4
AH
5384 if (cum->stdarg)
5385 {
c53bdcf5 5386 int n_words = rs6000_arg_size (mode, type);
a6c9bed4
AH
5387
5388 /* SPE vectors are put in odd registers. */
5389 if (n_words == 2 && (gregno & 1) == 0)
5390 gregno += 1;
5391
5392 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
5393 {
5394 rtx r1, r2;
5395 enum machine_mode m = SImode;
5396
5397 r1 = gen_rtx_REG (m, gregno);
5398 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
5399 r2 = gen_rtx_REG (m, gregno + 1);
5400 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
5401 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
5402 }
5403 else
b78d48dd 5404 return NULL_RTX;
a6c9bed4
AH
5405 }
5406 else
5407 {
f82f556d
AH
5408 if (gregno <= GP_ARG_MAX_REG)
5409 return gen_rtx_REG (mode, gregno);
a6c9bed4 5410 else
b78d48dd 5411 return NULL_RTX;
a6c9bed4
AH
5412 }
5413}
5414
0b5383eb
DJ
5415/* A subroutine of rs6000_darwin64_record_arg. Assign the bits of the
5416 structure between cum->intoffset and bitpos to integer registers. */
594a51fe 5417
0b5383eb 5418static void
bb8df8a6 5419rs6000_darwin64_record_arg_flush (CUMULATIVE_ARGS *cum,
0b5383eb 5420 HOST_WIDE_INT bitpos, rtx rvec[], int *k)
594a51fe 5421{
0b5383eb
DJ
5422 enum machine_mode mode;
5423 unsigned int regno;
5424 unsigned int startbit, endbit;
5425 int this_regno, intregs, intoffset;
5426 rtx reg;
594a51fe 5427
0b5383eb
DJ
5428 if (cum->intoffset == -1)
5429 return;
5430
5431 intoffset = cum->intoffset;
5432 cum->intoffset = -1;
5433
5434 /* If this is the trailing part of a word, try to only load that
5435 much into the register. Otherwise load the whole register. Note
5436 that in the latter case we may pick up unwanted bits. It's not a
5437 problem at the moment but may wish to revisit. */
5438
5439 if (intoffset % BITS_PER_WORD != 0)
594a51fe 5440 {
0b5383eb
DJ
5441 mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
5442 MODE_INT, 0);
5443 if (mode == BLKmode)
5444 {
5445 /* We couldn't find an appropriate mode, which happens,
5446 e.g., in packed structs when there are 3 bytes to load.
5447 Back intoffset back to the beginning of the word in this
5448 case. */
5449 intoffset = intoffset & -BITS_PER_WORD;
5450 mode = word_mode;
5451 }
5452 }
5453 else
5454 mode = word_mode;
5455
5456 startbit = intoffset & -BITS_PER_WORD;
5457 endbit = (bitpos + BITS_PER_WORD - 1) & -BITS_PER_WORD;
5458 intregs = (endbit - startbit) / BITS_PER_WORD;
5459 this_regno = cum->words + intoffset / BITS_PER_WORD;
5460
5461 if (intregs > 0 && intregs > GP_ARG_NUM_REG - this_regno)
5462 cum->use_stack = 1;
bb8df8a6 5463
0b5383eb
DJ
5464 intregs = MIN (intregs, GP_ARG_NUM_REG - this_regno);
5465 if (intregs <= 0)
5466 return;
5467
5468 intoffset /= BITS_PER_UNIT;
5469 do
5470 {
5471 regno = GP_ARG_MIN_REG + this_regno;
5472 reg = gen_rtx_REG (mode, regno);
5473 rvec[(*k)++] =
5474 gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (intoffset));
5475
5476 this_regno += 1;
5477 intoffset = (intoffset | (UNITS_PER_WORD-1)) + 1;
5478 mode = word_mode;
5479 intregs -= 1;
5480 }
5481 while (intregs > 0);
5482}
5483
5484/* Recursive workhorse for the following. */
5485
5486static void
586de218 5487rs6000_darwin64_record_arg_recurse (CUMULATIVE_ARGS *cum, const_tree type,
0b5383eb
DJ
5488 HOST_WIDE_INT startbitpos, rtx rvec[],
5489 int *k)
5490{
5491 tree f;
5492
5493 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
5494 if (TREE_CODE (f) == FIELD_DECL)
5495 {
5496 HOST_WIDE_INT bitpos = startbitpos;
5497 tree ftype = TREE_TYPE (f);
70fb00df
AP
5498 enum machine_mode mode;
5499 if (ftype == error_mark_node)
5500 continue;
5501 mode = TYPE_MODE (ftype);
0b5383eb
DJ
5502
5503 if (DECL_SIZE (f) != 0
5504 && host_integerp (bit_position (f), 1))
5505 bitpos += int_bit_position (f);
5506
5507 /* ??? FIXME: else assume zero offset. */
5508
5509 if (TREE_CODE (ftype) == RECORD_TYPE)
5510 rs6000_darwin64_record_arg_recurse (cum, ftype, bitpos, rvec, k);
5511 else if (cum->named && USE_FP_FOR_ARG_P (cum, mode, ftype))
594a51fe 5512 {
0b5383eb
DJ
5513#if 0
5514 switch (mode)
594a51fe 5515 {
0b5383eb
DJ
5516 case SCmode: mode = SFmode; break;
5517 case DCmode: mode = DFmode; break;
5518 case TCmode: mode = TFmode; break;
5519 default: break;
594a51fe 5520 }
0b5383eb
DJ
5521#endif
5522 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5523 rvec[(*k)++]
bb8df8a6 5524 = gen_rtx_EXPR_LIST (VOIDmode,
0b5383eb
DJ
5525 gen_rtx_REG (mode, cum->fregno++),
5526 GEN_INT (bitpos / BITS_PER_UNIT));
7393f7f8 5527 if (mode == TFmode || mode == TDmode)
0b5383eb 5528 cum->fregno++;
594a51fe 5529 }
0b5383eb
DJ
5530 else if (cum->named && USE_ALTIVEC_FOR_ARG_P (cum, mode, ftype, 1))
5531 {
5532 rs6000_darwin64_record_arg_flush (cum, bitpos, rvec, k);
5533 rvec[(*k)++]
bb8df8a6
EC
5534 = gen_rtx_EXPR_LIST (VOIDmode,
5535 gen_rtx_REG (mode, cum->vregno++),
0b5383eb
DJ
5536 GEN_INT (bitpos / BITS_PER_UNIT));
5537 }
5538 else if (cum->intoffset == -1)
5539 cum->intoffset = bitpos;
5540 }
5541}
594a51fe 5542
0b5383eb
DJ
5543/* For the darwin64 ABI, we want to construct a PARALLEL consisting of
5544 the register(s) to be used for each field and subfield of a struct
5545 being passed by value, along with the offset of where the
5546 register's value may be found in the block. FP fields go in FP
5547 register, vector fields go in vector registers, and everything
bb8df8a6 5548 else goes in int registers, packed as in memory.
8ff40a74 5549
0b5383eb
DJ
5550 This code is also used for function return values. RETVAL indicates
5551 whether this is the case.
8ff40a74 5552
a4d05547 5553 Much of this is taken from the SPARC V9 port, which has a similar
0b5383eb 5554 calling convention. */
594a51fe 5555
0b5383eb 5556static rtx
586de218 5557rs6000_darwin64_record_arg (CUMULATIVE_ARGS *orig_cum, const_tree type,
0b5383eb
DJ
5558 int named, bool retval)
5559{
5560 rtx rvec[FIRST_PSEUDO_REGISTER];
5561 int k = 1, kbase = 1;
5562 HOST_WIDE_INT typesize = int_size_in_bytes (type);
5563 /* This is a copy; modifications are not visible to our caller. */
5564 CUMULATIVE_ARGS copy_cum = *orig_cum;
5565 CUMULATIVE_ARGS *cum = &copy_cum;
5566
5567 /* Pad to 16 byte boundary if needed. */
5568 if (!retval && TYPE_ALIGN (type) >= 2 * BITS_PER_WORD
5569 && (cum->words % 2) != 0)
5570 cum->words++;
5571
5572 cum->intoffset = 0;
5573 cum->use_stack = 0;
5574 cum->named = named;
5575
5576 /* Put entries into rvec[] for individual FP and vector fields, and
5577 for the chunks of memory that go in int regs. Note we start at
5578 element 1; 0 is reserved for an indication of using memory, and
5579 may or may not be filled in below. */
5580 rs6000_darwin64_record_arg_recurse (cum, type, 0, rvec, &k);
5581 rs6000_darwin64_record_arg_flush (cum, typesize * BITS_PER_UNIT, rvec, &k);
5582
5583 /* If any part of the struct went on the stack put all of it there.
5584 This hack is because the generic code for
5585 FUNCTION_ARG_PARTIAL_NREGS cannot handle cases where the register
5586 parts of the struct are not at the beginning. */
5587 if (cum->use_stack)
5588 {
5589 if (retval)
5590 return NULL_RTX; /* doesn't go in registers at all */
5591 kbase = 0;
5592 rvec[0] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5593 }
5594 if (k > 1 || cum->use_stack)
5595 return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k - kbase, &rvec[kbase]));
594a51fe
SS
5596 else
5597 return NULL_RTX;
5598}
5599
b78d48dd
FJ
5600/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
5601
5602static rtx
ec6376ab 5603rs6000_mixed_function_arg (enum machine_mode mode, tree type, int align_words)
b78d48dd 5604{
ec6376ab
AM
5605 int n_units;
5606 int i, k;
5607 rtx rvec[GP_ARG_NUM_REG + 1];
5608
5609 if (align_words >= GP_ARG_NUM_REG)
5610 return NULL_RTX;
5611
5612 n_units = rs6000_arg_size (mode, type);
5613
5614 /* Optimize the simple case where the arg fits in one gpr, except in
5615 the case of BLKmode due to assign_parms assuming that registers are
5616 BITS_PER_WORD wide. */
5617 if (n_units == 0
5618 || (n_units == 1 && mode != BLKmode))
5619 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5620
5621 k = 0;
5622 if (align_words + n_units > GP_ARG_NUM_REG)
5623 /* Not all of the arg fits in gprs. Say that it goes in memory too,
5624 using a magic NULL_RTX component.
79773478
AM
5625 This is not strictly correct. Only some of the arg belongs in
5626 memory, not all of it. However, the normal scheme using
5627 function_arg_partial_nregs can result in unusual subregs, eg.
5628 (subreg:SI (reg:DF) 4), which are not handled well. The code to
5629 store the whole arg to memory is often more efficient than code
5630 to store pieces, and we know that space is available in the right
5631 place for the whole arg. */
ec6376ab
AM
5632 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
5633
5634 i = 0;
5635 do
36a454e1 5636 {
ec6376ab
AM
5637 rtx r = gen_rtx_REG (SImode, GP_ARG_MIN_REG + align_words);
5638 rtx off = GEN_INT (i++ * 4);
5639 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
36a454e1 5640 }
ec6376ab
AM
5641 while (++align_words < GP_ARG_NUM_REG && --n_units != 0);
5642
5643 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
b78d48dd
FJ
5644}
5645
4697a36c
MM
5646/* Determine where to put an argument to a function.
5647 Value is zero to push the argument on the stack,
5648 or a hard register in which to store the argument.
5649
5650 MODE is the argument's machine mode.
5651 TYPE is the data type of the argument (as a tree).
5652 This is null for libcalls where that information may
5653 not be available.
5654 CUM is a variable of type CUMULATIVE_ARGS which gives info about
0b5383eb
DJ
5655 the preceding args and about the function being called. It is
5656 not modified in this routine.
4697a36c
MM
5657 NAMED is nonzero if this argument is a named parameter
5658 (otherwise it is an extra parameter matching an ellipsis).
5659
5660 On RS/6000 the first eight words of non-FP are normally in registers
5661 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
5662 Under V.4, the first 8 FP args are in registers.
5663
5664 If this is floating-point and no prototype is specified, we use
5665 both an FP and integer register (or possibly FP reg and stack). Library
b9599e46 5666 functions (when CALL_LIBCALL is set) always have the proper types for args,
4697a36c 5667 so we can pass the FP value just in one register. emit_library_function
b2d04ecf
AM
5668 doesn't support PARALLEL anyway.
5669
5670 Note that for args passed by reference, function_arg will be called
5671 with MODE and TYPE set to that of the pointer to the arg, not the arg
5672 itself. */
4697a36c 5673
9390387d 5674rtx
f676971a 5675function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
a2369ed3 5676 tree type, int named)
4697a36c 5677{
4cc833b7 5678 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 5679
a4f6c312
SS
5680 /* Return a marker to indicate whether CR1 needs to set or clear the
5681 bit that V.4 uses to say fp args were passed in registers.
5682 Assume that we don't need the marker for software floating point,
5683 or compiler generated library calls. */
4697a36c
MM
5684 if (mode == VOIDmode)
5685 {
f607bc57 5686 if (abi == ABI_V4
b9599e46 5687 && (cum->call_cookie & CALL_LIBCALL) == 0
c1fa753e
AM
5688 && (cum->stdarg
5689 || (cum->nargs_prototype < 0
5690 && (cum->prototype || TARGET_NO_PROTOTYPE))))
7509c759 5691 {
a3170dc6
AH
5692 /* For the SPE, we need to crxor CR6 always. */
5693 if (TARGET_SPE_ABI)
5694 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
5695 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
5696 return GEN_INT (cum->call_cookie
5697 | ((cum->fregno == FP_ARG_MIN_REG)
5698 ? CALL_V4_SET_FP_ARGS
5699 : CALL_V4_CLEAR_FP_ARGS));
7509c759 5700 }
4697a36c 5701
7509c759 5702 return GEN_INT (cum->call_cookie);
4697a36c
MM
5703 }
5704
0b5383eb
DJ
5705 if (rs6000_darwin64_abi && mode == BLKmode
5706 && TREE_CODE (type) == RECORD_TYPE)
8ff40a74 5707 {
0b5383eb 5708 rtx rslt = rs6000_darwin64_record_arg (cum, type, named, false);
8ff40a74
SS
5709 if (rslt != NULL_RTX)
5710 return rslt;
5711 /* Else fall through to usual handling. */
5712 }
5713
2858f73a 5714 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named))
c72d6c26
HP
5715 if (TARGET_64BIT && ! cum->prototype)
5716 {
c4ad648e
AM
5717 /* Vector parameters get passed in vector register
5718 and also in GPRs or memory, in absence of prototype. */
5719 int align_words;
5720 rtx slot;
5721 align_words = (cum->words + 1) & ~1;
5722
5723 if (align_words >= GP_ARG_NUM_REG)
5724 {
5725 slot = NULL_RTX;
5726 }
5727 else
5728 {
5729 slot = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5730 }
5731 return gen_rtx_PARALLEL (mode,
5732 gen_rtvec (2,
5733 gen_rtx_EXPR_LIST (VOIDmode,
5734 slot, const0_rtx),
5735 gen_rtx_EXPR_LIST (VOIDmode,
5736 gen_rtx_REG (mode, cum->vregno),
5737 const0_rtx)));
c72d6c26
HP
5738 }
5739 else
5740 return gen_rtx_REG (mode, cum->vregno);
ad630bef
DE
5741 else if (TARGET_ALTIVEC_ABI
5742 && (ALTIVEC_VECTOR_MODE (mode)
5743 || (type && TREE_CODE (type) == VECTOR_TYPE
5744 && int_size_in_bytes (type) == 16)))
0ac081f6 5745 {
2858f73a 5746 if (named || abi == ABI_V4)
a594a19c 5747 return NULL_RTX;
0ac081f6 5748 else
a594a19c
GK
5749 {
5750 /* Vector parameters to varargs functions under AIX or Darwin
5751 get passed in memory and possibly also in GPRs. */
ec6376ab
AM
5752 int align, align_words, n_words;
5753 enum machine_mode part_mode;
a594a19c
GK
5754
5755 /* Vector parameters must be 16-byte aligned. This places them at
2858f73a
GK
5756 2 mod 4 in terms of words in 32-bit mode, since the parameter
5757 save area starts at offset 24 from the stack. In 64-bit mode,
5758 they just have to start on an even word, since the parameter
5759 save area is 16-byte aligned. */
5760 if (TARGET_32BIT)
4ed78545 5761 align = (2 - cum->words) & 3;
2858f73a
GK
5762 else
5763 align = cum->words & 1;
a594a19c
GK
5764 align_words = cum->words + align;
5765
5766 /* Out of registers? Memory, then. */
5767 if (align_words >= GP_ARG_NUM_REG)
5768 return NULL_RTX;
ec6376ab
AM
5769
5770 if (TARGET_32BIT && TARGET_POWERPC64)
5771 return rs6000_mixed_function_arg (mode, type, align_words);
5772
2858f73a
GK
5773 /* The vector value goes in GPRs. Only the part of the
5774 value in GPRs is reported here. */
ec6376ab
AM
5775 part_mode = mode;
5776 n_words = rs6000_arg_size (mode, type);
5777 if (align_words + n_words > GP_ARG_NUM_REG)
839a4992 5778 /* Fortunately, there are only two possibilities, the value
2858f73a
GK
5779 is either wholly in GPRs or half in GPRs and half not. */
5780 part_mode = DImode;
ec6376ab
AM
5781
5782 return gen_rtx_REG (part_mode, GP_ARG_MIN_REG + align_words);
a594a19c 5783 }
0ac081f6 5784 }
f82f556d
AH
5785 else if (TARGET_SPE_ABI && TARGET_SPE
5786 && (SPE_VECTOR_MODE (mode)
18f63bfa 5787 || (TARGET_E500_DOUBLE && (mode == DFmode
7393f7f8 5788 || mode == DDmode
17caeff2
JM
5789 || mode == DCmode
5790 || mode == TFmode
7393f7f8 5791 || mode == TDmode
17caeff2 5792 || mode == TCmode))))
a6c9bed4 5793 return rs6000_spe_function_arg (cum, mode, type);
594a51fe 5794
f607bc57 5795 else if (abi == ABI_V4)
4697a36c 5796 {
a3170dc6 5797 if (TARGET_HARD_FLOAT && TARGET_FPRS
602ea4d3 5798 && (mode == SFmode || mode == DFmode
7393f7f8
BE
5799 || (mode == TFmode && !TARGET_IEEEQUAD)
5800 || mode == DDmode || mode == TDmode))
4cc833b7 5801 {
2d83f070
JJ
5802 /* _Decimal128 must use an even/odd register pair. This assumes
5803 that the register number is odd when fregno is odd. */
5804 if (mode == TDmode && (cum->fregno % 2) == 1)
7393f7f8
BE
5805 cum->fregno++;
5806
5807 if (cum->fregno + (mode == TFmode || mode == TDmode ? 1 : 0)
5808 <= FP_ARG_V4_MAX_REG)
4cc833b7
RH
5809 return gen_rtx_REG (mode, cum->fregno);
5810 else
b78d48dd 5811 return NULL_RTX;
4cc833b7
RH
5812 }
5813 else
5814 {
b2d04ecf 5815 int n_words = rs6000_arg_size (mode, type);
4cc833b7
RH
5816 int gregno = cum->sysv_gregno;
5817
4ed78545
AM
5818 /* Long long and SPE vectors are put in (r3,r4), (r5,r6),
5819 (r7,r8) or (r9,r10). As does any other 2 word item such
5820 as complex int due to a historical mistake. */
5821 if (n_words == 2)
5822 gregno += (1 - gregno) & 1;
4cc833b7 5823
4ed78545 5824 /* Multi-reg args are not split between registers and stack. */
ec6376ab 5825 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
b78d48dd 5826 return NULL_RTX;
ec6376ab
AM
5827
5828 if (TARGET_32BIT && TARGET_POWERPC64)
5829 return rs6000_mixed_function_arg (mode, type,
5830 gregno - GP_ARG_MIN_REG);
5831 return gen_rtx_REG (mode, gregno);
4cc833b7 5832 }
4697a36c 5833 }
4cc833b7
RH
5834 else
5835 {
294bd182 5836 int align_words = rs6000_parm_start (mode, type, cum->words);
b78d48dd 5837
2d83f070
JJ
5838 /* _Decimal128 must be passed in an even/odd float register pair.
5839 This assumes that the register number is odd when fregno is odd. */
5840 if (mode == TDmode && (cum->fregno % 2) == 1)
5841 cum->fregno++;
5842
2858f73a 5843 if (USE_FP_FOR_ARG_P (cum, mode, type))
4cc833b7 5844 {
ec6376ab
AM
5845 rtx rvec[GP_ARG_NUM_REG + 1];
5846 rtx r;
5847 int k;
c53bdcf5
AM
5848 bool needs_psave;
5849 enum machine_mode fmode = mode;
c53bdcf5
AM
5850 unsigned long n_fpreg = (GET_MODE_SIZE (mode) + 7) >> 3;
5851
5852 if (cum->fregno + n_fpreg > FP_ARG_MAX_REG + 1)
5853 {
c53bdcf5
AM
5854 /* Currently, we only ever need one reg here because complex
5855 doubles are split. */
7393f7f8
BE
5856 gcc_assert (cum->fregno == FP_ARG_MAX_REG
5857 && (fmode == TFmode || fmode == TDmode));
ec6376ab 5858
7393f7f8
BE
5859 /* Long double or _Decimal128 split over regs and memory. */
5860 fmode = DECIMAL_FLOAT_MODE_P (fmode) ? DDmode : DFmode;
c53bdcf5 5861 }
c53bdcf5
AM
5862
5863 /* Do we also need to pass this arg in the parameter save
5864 area? */
5865 needs_psave = (type
5866 && (cum->nargs_prototype <= 0
5867 || (DEFAULT_ABI == ABI_AIX
de17c25f 5868 && TARGET_XL_COMPAT
c53bdcf5
AM
5869 && align_words >= GP_ARG_NUM_REG)));
5870
5871 if (!needs_psave && mode == fmode)
ec6376ab 5872 return gen_rtx_REG (fmode, cum->fregno);
c53bdcf5 5873
ec6376ab 5874 k = 0;
c53bdcf5
AM
5875 if (needs_psave)
5876 {
ec6376ab 5877 /* Describe the part that goes in gprs or the stack.
c53bdcf5 5878 This piece must come first, before the fprs. */
c53bdcf5
AM
5879 if (align_words < GP_ARG_NUM_REG)
5880 {
5881 unsigned long n_words = rs6000_arg_size (mode, type);
ec6376ab
AM
5882
5883 if (align_words + n_words > GP_ARG_NUM_REG
5884 || (TARGET_32BIT && TARGET_POWERPC64))
5885 {
5886 /* If this is partially on the stack, then we only
5887 include the portion actually in registers here. */
5888 enum machine_mode rmode = TARGET_32BIT ? SImode : DImode;
5889 rtx off;
79773478
AM
5890 int i = 0;
5891 if (align_words + n_words > GP_ARG_NUM_REG)
c4ad648e
AM
5892 /* Not all of the arg fits in gprs. Say that it
5893 goes in memory too, using a magic NULL_RTX
5894 component. Also see comment in
5895 rs6000_mixed_function_arg for why the normal
5896 function_arg_partial_nregs scheme doesn't work
5897 in this case. */
5898 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX,
5899 const0_rtx);
ec6376ab
AM
5900 do
5901 {
5902 r = gen_rtx_REG (rmode,
5903 GP_ARG_MIN_REG + align_words);
2e6c9641 5904 off = GEN_INT (i++ * GET_MODE_SIZE (rmode));
ec6376ab
AM
5905 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
5906 }
5907 while (++align_words < GP_ARG_NUM_REG && --n_words != 0);
5908 }
5909 else
5910 {
5911 /* The whole arg fits in gprs. */
5912 r = gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5913 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5914 }
c53bdcf5 5915 }
ec6376ab
AM
5916 else
5917 /* It's entirely in memory. */
5918 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx);
c53bdcf5
AM
5919 }
5920
ec6376ab
AM
5921 /* Describe where this piece goes in the fprs. */
5922 r = gen_rtx_REG (fmode, cum->fregno);
5923 rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, const0_rtx);
5924
5925 return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
4cc833b7
RH
5926 }
5927 else if (align_words < GP_ARG_NUM_REG)
b2d04ecf 5928 {
ec6376ab
AM
5929 if (TARGET_32BIT && TARGET_POWERPC64)
5930 return rs6000_mixed_function_arg (mode, type, align_words);
b2d04ecf 5931
4eeca74f
AM
5932 if (mode == BLKmode)
5933 mode = Pmode;
5934
b2d04ecf
AM
5935 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
5936 }
4cc833b7
RH
5937 else
5938 return NULL_RTX;
4697a36c 5939 }
4697a36c
MM
5940}
5941\f
ec6376ab 5942/* For an arg passed partly in registers and partly in memory, this is
fb63c729
AM
5943 the number of bytes passed in registers. For args passed entirely in
5944 registers or entirely in memory, zero. When an arg is described by a
5945 PARALLEL, perhaps using more than one register type, this function
5946 returns the number of bytes used by the first element of the PARALLEL. */
4697a36c 5947
78a52f11
RH
5948static int
5949rs6000_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
5950 tree type, bool named)
4697a36c 5951{
c53bdcf5 5952 int ret = 0;
ec6376ab 5953 int align_words;
c53bdcf5 5954
f607bc57 5955 if (DEFAULT_ABI == ABI_V4)
4697a36c 5956 return 0;
4697a36c 5957
c53bdcf5
AM
5958 if (USE_ALTIVEC_FOR_ARG_P (cum, mode, type, named)
5959 && cum->nargs_prototype >= 0)
5960 return 0;
5961
0b5383eb
DJ
5962 /* In this complicated case we just disable the partial_nregs code. */
5963 if (rs6000_darwin64_abi && mode == BLKmode
5964 && TREE_CODE (type) == RECORD_TYPE
5965 && int_size_in_bytes (type) > 0)
5966 return 0;
5967
294bd182 5968 align_words = rs6000_parm_start (mode, type, cum->words);
ec6376ab 5969
79773478
AM
5970 if (USE_FP_FOR_ARG_P (cum, mode, type))
5971 {
fb63c729
AM
5972 /* If we are passing this arg in the fixed parameter save area
5973 (gprs or memory) as well as fprs, then this function should
79773478
AM
5974 return the number of partial bytes passed in the parameter
5975 save area rather than partial bytes passed in fprs. */
5976 if (type
5977 && (cum->nargs_prototype <= 0
5978 || (DEFAULT_ABI == ABI_AIX
5979 && TARGET_XL_COMPAT
5980 && align_words >= GP_ARG_NUM_REG)))
5981 return 0;
5982 else if (cum->fregno + ((GET_MODE_SIZE (mode) + 7) >> 3)
5983 > FP_ARG_MAX_REG + 1)
ac7e839c 5984 ret = (FP_ARG_MAX_REG + 1 - cum->fregno) * 8;
c53bdcf5 5985 else if (cum->nargs_prototype >= 0)
4697a36c
MM
5986 return 0;
5987 }
5988
ec6376ab
AM
5989 if (align_words < GP_ARG_NUM_REG
5990 && GP_ARG_NUM_REG < align_words + rs6000_arg_size (mode, type))
ac7e839c 5991 ret = (GP_ARG_NUM_REG - align_words) * (TARGET_32BIT ? 4 : 8);
78a52f11 5992
c53bdcf5 5993 if (ret != 0 && TARGET_DEBUG_ARG)
78a52f11 5994 fprintf (stderr, "rs6000_arg_partial_bytes: %d\n", ret);
4697a36c 5995
c53bdcf5 5996 return ret;
4697a36c
MM
5997}
5998\f
5999/* A C expression that indicates when an argument must be passed by
6000 reference. If nonzero for an argument, a copy of that argument is
6001 made in memory and a pointer to the argument is passed instead of
6002 the argument itself. The pointer is passed in whatever way is
6003 appropriate for passing a pointer to that type.
6004
b2d04ecf
AM
6005 Under V.4, aggregates and long double are passed by reference.
6006
6007 As an extension to all 32-bit ABIs, AltiVec vectors are passed by
6008 reference unless the AltiVec vector extension ABI is in force.
c8c99a68
DE
6009
6010 As an extension to all ABIs, variable sized types are passed by
6011 reference. */
4697a36c 6012
8cd5a4e0 6013static bool
f676971a 6014rs6000_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
586de218 6015 enum machine_mode mode, const_tree type,
bada2eb8 6016 bool named ATTRIBUTE_UNUSED)
4697a36c 6017{
602ea4d3 6018 if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD && mode == TFmode)
4697a36c
MM
6019 {
6020 if (TARGET_DEBUG_ARG)
bada2eb8
DE
6021 fprintf (stderr, "function_arg_pass_by_reference: V4 long double\n");
6022 return 1;
6023 }
6024
6025 if (!type)
6026 return 0;
4697a36c 6027
bada2eb8
DE
6028 if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type))
6029 {
6030 if (TARGET_DEBUG_ARG)
6031 fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n");
6032 return 1;
6033 }
6034
6035 if (int_size_in_bytes (type) < 0)
6036 {
6037 if (TARGET_DEBUG_ARG)
6038 fprintf (stderr, "function_arg_pass_by_reference: variable size\n");
6039 return 1;
6040 }
6041
6042 /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector
6043 modes only exist for GCC vector types if -maltivec. */
6044 if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
6045 {
6046 if (TARGET_DEBUG_ARG)
6047 fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n");
4697a36c
MM
6048 return 1;
6049 }
b693336b
PB
6050
6051 /* Pass synthetic vectors in memory. */
bada2eb8 6052 if (TREE_CODE (type) == VECTOR_TYPE
ad630bef 6053 && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8))
b693336b
PB
6054 {
6055 static bool warned_for_pass_big_vectors = false;
6056 if (TARGET_DEBUG_ARG)
6057 fprintf (stderr, "function_arg_pass_by_reference: synthetic vector\n");
6058 if (!warned_for_pass_big_vectors)
6059 {
d4ee4d25 6060 warning (0, "GCC vector passed by reference: "
b693336b
PB
6061 "non-standard ABI extension with no compatibility guarantee");
6062 warned_for_pass_big_vectors = true;
6063 }
6064 return 1;
6065 }
6066
b2d04ecf 6067 return 0;
4697a36c 6068}
5985c7a6
FJ
6069
6070static void
2d9db8eb 6071rs6000_move_block_from_reg (int regno, rtx x, int nregs)
5985c7a6
FJ
6072{
6073 int i;
6074 enum machine_mode reg_mode = TARGET_32BIT ? SImode : DImode;
6075
6076 if (nregs == 0)
6077 return;
6078
c4ad648e 6079 for (i = 0; i < nregs; i++)
5985c7a6 6080 {
9390387d 6081 rtx tem = adjust_address_nv (x, reg_mode, i * GET_MODE_SIZE (reg_mode));
5985c7a6 6082 if (reload_completed)
c4ad648e
AM
6083 {
6084 if (! strict_memory_address_p (reg_mode, XEXP (tem, 0)))
6085 tem = NULL_RTX;
6086 else
6087 tem = simplify_gen_subreg (reg_mode, x, BLKmode,
9390387d 6088 i * GET_MODE_SIZE (reg_mode));
c4ad648e 6089 }
5985c7a6
FJ
6090 else
6091 tem = replace_equiv_address (tem, XEXP (tem, 0));
6092
37409796 6093 gcc_assert (tem);
5985c7a6
FJ
6094
6095 emit_move_insn (tem, gen_rtx_REG (reg_mode, regno + i));
6096 }
6097}
4697a36c
MM
6098\f
6099/* Perform any needed actions needed for a function that is receiving a
f676971a 6100 variable number of arguments.
4697a36c
MM
6101
6102 CUM is as above.
6103
6104 MODE and TYPE are the mode and type of the current parameter.
6105
6106 PRETEND_SIZE is a variable that should be set to the amount of stack
6107 that must be pushed by the prolog to pretend that our caller pushed
6108 it.
6109
6110 Normally, this macro will push all remaining incoming registers on the
6111 stack and set PRETEND_SIZE to the length of the registers pushed. */
6112
c6e8c921 6113static void
f676971a 6114setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
c4ad648e
AM
6115 tree type, int *pretend_size ATTRIBUTE_UNUSED,
6116 int no_rtl)
4697a36c 6117{
4cc833b7
RH
6118 CUMULATIVE_ARGS next_cum;
6119 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 6120 rtx save_area = NULL_RTX, mem;
4862826d
ILT
6121 int first_reg_offset;
6122 alias_set_type set;
4697a36c 6123
f31bf321 6124 /* Skip the last named argument. */
d34c5b80 6125 next_cum = *cum;
594a51fe 6126 function_arg_advance (&next_cum, mode, type, 1, 0);
4cc833b7 6127
f607bc57 6128 if (DEFAULT_ABI == ABI_V4)
d34c5b80 6129 {
5b667039
JJ
6130 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
6131
60e2d0ca 6132 if (! no_rtl)
5b667039
JJ
6133 {
6134 int gpr_reg_num = 0, gpr_size = 0, fpr_size = 0;
6135 HOST_WIDE_INT offset = 0;
6136
6137 /* Try to optimize the size of the varargs save area.
6138 The ABI requires that ap.reg_save_area is doubleword
6139 aligned, but we don't need to allocate space for all
6140 the bytes, only those to which we actually will save
6141 anything. */
6142 if (cfun->va_list_gpr_size && first_reg_offset < GP_ARG_NUM_REG)
6143 gpr_reg_num = GP_ARG_NUM_REG - first_reg_offset;
6144 if (TARGET_HARD_FLOAT && TARGET_FPRS
6145 && next_cum.fregno <= FP_ARG_V4_MAX_REG
6146 && cfun->va_list_fpr_size)
6147 {
6148 if (gpr_reg_num)
6149 fpr_size = (next_cum.fregno - FP_ARG_MIN_REG)
6150 * UNITS_PER_FP_WORD;
6151 if (cfun->va_list_fpr_size
6152 < FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
6153 fpr_size += cfun->va_list_fpr_size * UNITS_PER_FP_WORD;
6154 else
6155 fpr_size += (FP_ARG_V4_MAX_REG + 1 - next_cum.fregno)
6156 * UNITS_PER_FP_WORD;
6157 }
6158 if (gpr_reg_num)
6159 {
6160 offset = -((first_reg_offset * reg_size) & ~7);
6161 if (!fpr_size && gpr_reg_num > cfun->va_list_gpr_size)
6162 {
6163 gpr_reg_num = cfun->va_list_gpr_size;
6164 if (reg_size == 4 && (first_reg_offset & 1))
6165 gpr_reg_num++;
6166 }
6167 gpr_size = (gpr_reg_num * reg_size + 7) & ~7;
6168 }
6169 else if (fpr_size)
6170 offset = - (int) (next_cum.fregno - FP_ARG_MIN_REG)
6171 * UNITS_PER_FP_WORD
6172 - (int) (GP_ARG_NUM_REG * reg_size);
4cc833b7 6173
5b667039
JJ
6174 if (gpr_size + fpr_size)
6175 {
6176 rtx reg_save_area
6177 = assign_stack_local (BLKmode, gpr_size + fpr_size, 64);
6178 gcc_assert (GET_CODE (reg_save_area) == MEM);
6179 reg_save_area = XEXP (reg_save_area, 0);
6180 if (GET_CODE (reg_save_area) == PLUS)
6181 {
6182 gcc_assert (XEXP (reg_save_area, 0)
6183 == virtual_stack_vars_rtx);
6184 gcc_assert (GET_CODE (XEXP (reg_save_area, 1)) == CONST_INT);
6185 offset += INTVAL (XEXP (reg_save_area, 1));
6186 }
6187 else
6188 gcc_assert (reg_save_area == virtual_stack_vars_rtx);
6189 }
6190
6191 cfun->machine->varargs_save_offset = offset;
6192 save_area = plus_constant (virtual_stack_vars_rtx, offset);
6193 }
4697a36c 6194 }
60e2d0ca 6195 else
4697a36c 6196 {
d34c5b80 6197 first_reg_offset = next_cum.words;
4cc833b7 6198 save_area = virtual_incoming_args_rtx;
4697a36c 6199
fe984136 6200 if (targetm.calls.must_pass_in_stack (mode, type))
c53bdcf5 6201 first_reg_offset += rs6000_arg_size (TYPE_MODE (type), type);
4cc833b7 6202 }
4697a36c 6203
dfafc897 6204 set = get_varargs_alias_set ();
9d30f3c1
JJ
6205 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG
6206 && cfun->va_list_gpr_size)
4cc833b7 6207 {
9d30f3c1
JJ
6208 int nregs = GP_ARG_NUM_REG - first_reg_offset;
6209
6210 if (va_list_gpr_counter_field)
6211 {
6212 /* V4 va_list_gpr_size counts number of registers needed. */
6213 if (nregs > cfun->va_list_gpr_size)
6214 nregs = cfun->va_list_gpr_size;
6215 }
6216 else
6217 {
6218 /* char * va_list instead counts number of bytes needed. */
6219 if (nregs > cfun->va_list_gpr_size / reg_size)
6220 nregs = cfun->va_list_gpr_size / reg_size;
6221 }
6222
dfafc897 6223 mem = gen_rtx_MEM (BLKmode,
c4ad648e 6224 plus_constant (save_area,
13e2e16e
DE
6225 first_reg_offset * reg_size));
6226 MEM_NOTRAP_P (mem) = 1;
ba4828e0 6227 set_mem_alias_set (mem, set);
8ac61af7 6228 set_mem_align (mem, BITS_PER_WORD);
dfafc897 6229
f676971a 6230 rs6000_move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem,
9d30f3c1 6231 nregs);
4697a36c
MM
6232 }
6233
4697a36c 6234 /* Save FP registers if needed. */
f607bc57 6235 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
6236 && TARGET_HARD_FLOAT && TARGET_FPRS
6237 && ! no_rtl
9d30f3c1
JJ
6238 && next_cum.fregno <= FP_ARG_V4_MAX_REG
6239 && cfun->va_list_fpr_size)
4697a36c 6240 {
9d30f3c1 6241 int fregno = next_cum.fregno, nregs;
9ebbca7d 6242 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7 6243 rtx lab = gen_label_rtx ();
5b667039
JJ
6244 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG)
6245 * UNITS_PER_FP_WORD);
4697a36c 6246
c4ad648e
AM
6247 emit_jump_insn
6248 (gen_rtx_SET (VOIDmode,
6249 pc_rtx,
6250 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7 6251 gen_rtx_NE (VOIDmode, cr1,
c4ad648e 6252 const0_rtx),
39403d82 6253 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
6254 pc_rtx)));
6255
9d30f3c1
JJ
6256 for (nregs = 0;
6257 fregno <= FP_ARG_V4_MAX_REG && nregs < cfun->va_list_fpr_size;
5b667039 6258 fregno++, off += UNITS_PER_FP_WORD, nregs++)
4cc833b7 6259 {
5496b36f 6260 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
13e2e16e 6261 MEM_NOTRAP_P (mem) = 1;
c4ad648e 6262 set_mem_alias_set (mem, set);
94ff898d 6263 set_mem_align (mem, GET_MODE_ALIGNMENT (DFmode));
dfafc897 6264 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4697a36c 6265 }
4cc833b7
RH
6266
6267 emit_label (lab);
4697a36c 6268 }
4697a36c 6269}
4697a36c 6270
dfafc897 6271/* Create the va_list data type. */
2c4974b7 6272
c35d187f
RH
6273static tree
6274rs6000_build_builtin_va_list (void)
dfafc897 6275{
64c2816f 6276 tree f_gpr, f_fpr, f_res, f_ovf, f_sav, record, type_decl;
4697a36c 6277
9ebbca7d
GK
6278 /* For AIX, prefer 'char *' because that's what the system
6279 header files like. */
f607bc57 6280 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 6281 return build_pointer_type (char_type_node);
dfafc897 6282
f1e639b1 6283 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 6284 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 6285
f676971a 6286 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
9ebbca7d 6287 unsigned_char_type_node);
f676971a 6288 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
9ebbca7d 6289 unsigned_char_type_node);
64c2816f
DT
6290 /* Give the two bytes of padding a name, so that -Wpadded won't warn on
6291 every user file. */
6292 f_res = build_decl (FIELD_DECL, get_identifier ("reserved"),
6293 short_unsigned_type_node);
dfafc897
FS
6294 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
6295 ptr_type_node);
6296 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
6297 ptr_type_node);
6298
9d30f3c1
JJ
6299 va_list_gpr_counter_field = f_gpr;
6300 va_list_fpr_counter_field = f_fpr;
6301
dfafc897
FS
6302 DECL_FIELD_CONTEXT (f_gpr) = record;
6303 DECL_FIELD_CONTEXT (f_fpr) = record;
64c2816f 6304 DECL_FIELD_CONTEXT (f_res) = record;
dfafc897
FS
6305 DECL_FIELD_CONTEXT (f_ovf) = record;
6306 DECL_FIELD_CONTEXT (f_sav) = record;
6307
bab45a51
FS
6308 TREE_CHAIN (record) = type_decl;
6309 TYPE_NAME (record) = type_decl;
dfafc897
FS
6310 TYPE_FIELDS (record) = f_gpr;
6311 TREE_CHAIN (f_gpr) = f_fpr;
64c2816f
DT
6312 TREE_CHAIN (f_fpr) = f_res;
6313 TREE_CHAIN (f_res) = f_ovf;
dfafc897
FS
6314 TREE_CHAIN (f_ovf) = f_sav;
6315
6316 layout_type (record);
6317
6318 /* The correct type is an array type of one element. */
6319 return build_array_type (record, build_index_type (size_zero_node));
6320}
6321
6322/* Implement va_start. */
6323
6324void
a2369ed3 6325rs6000_va_start (tree valist, rtx nextarg)
4697a36c 6326{
dfafc897 6327 HOST_WIDE_INT words, n_gpr, n_fpr;
c566f9bd 6328 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
dfafc897 6329 tree gpr, fpr, ovf, sav, t;
2c4974b7 6330
dfafc897 6331 /* Only SVR4 needs something special. */
f607bc57 6332 if (DEFAULT_ABI != ABI_V4)
dfafc897 6333 {
e5faf155 6334 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
6335 return;
6336 }
6337
973a648b 6338 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897 6339 f_fpr = TREE_CHAIN (f_gpr);
c566f9bd
DT
6340 f_res = TREE_CHAIN (f_fpr);
6341 f_ovf = TREE_CHAIN (f_res);
dfafc897
FS
6342 f_sav = TREE_CHAIN (f_ovf);
6343
872a65b5 6344 valist = build_va_arg_indirect_ref (valist);
47a25a46
RG
6345 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6346 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6347 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6348 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
dfafc897
FS
6349
6350 /* Count number of gp and fp argument registers used. */
4cc833b7 6351 words = current_function_args_info.words;
987732e0
DE
6352 n_gpr = MIN (current_function_args_info.sysv_gregno - GP_ARG_MIN_REG,
6353 GP_ARG_NUM_REG);
6354 n_fpr = MIN (current_function_args_info.fregno - FP_ARG_MIN_REG,
6355 FP_ARG_NUM_REG);
dfafc897
FS
6356
6357 if (TARGET_DEBUG_ARG)
4a0a75dd
KG
6358 fprintf (stderr, "va_start: words = "HOST_WIDE_INT_PRINT_DEC", n_gpr = "
6359 HOST_WIDE_INT_PRINT_DEC", n_fpr = "HOST_WIDE_INT_PRINT_DEC"\n",
6360 words, n_gpr, n_fpr);
dfafc897 6361
9d30f3c1
JJ
6362 if (cfun->va_list_gpr_size)
6363 {
07beea0d 6364 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (gpr), gpr,
47a25a46 6365 build_int_cst (NULL_TREE, n_gpr));
9d30f3c1
JJ
6366 TREE_SIDE_EFFECTS (t) = 1;
6367 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6368 }
58c8adc1 6369
9d30f3c1
JJ
6370 if (cfun->va_list_fpr_size)
6371 {
07beea0d 6372 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (fpr), fpr,
47a25a46 6373 build_int_cst (NULL_TREE, n_fpr));
9d30f3c1
JJ
6374 TREE_SIDE_EFFECTS (t) = 1;
6375 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6376 }
dfafc897
FS
6377
6378 /* Find the overflow area. */
6379 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
6380 if (words != 0)
5be014d5
AP
6381 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ovf), t,
6382 size_int (words * UNITS_PER_WORD));
07beea0d 6383 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
dfafc897
FS
6384 TREE_SIDE_EFFECTS (t) = 1;
6385 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6386
9d30f3c1
JJ
6387 /* If there were no va_arg invocations, don't set up the register
6388 save area. */
6389 if (!cfun->va_list_gpr_size
6390 && !cfun->va_list_fpr_size
6391 && n_gpr < GP_ARG_NUM_REG
6392 && n_fpr < FP_ARG_V4_MAX_REG)
6393 return;
6394
dfafc897
FS
6395 /* Find the register save area. */
6396 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
5b667039 6397 if (cfun->machine->varargs_save_offset)
5be014d5
AP
6398 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (sav), t,
6399 size_int (cfun->machine->varargs_save_offset));
07beea0d 6400 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (sav), sav, t);
dfafc897
FS
6401 TREE_SIDE_EFFECTS (t) = 1;
6402 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
6403}
6404
6405/* Implement va_arg. */
6406
23a60a04
JM
6407tree
6408rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
cd3ce9b4 6409{
cd3ce9b4
JM
6410 tree f_gpr, f_fpr, f_res, f_ovf, f_sav;
6411 tree gpr, fpr, ovf, sav, reg, t, u;
08b0dc1b 6412 int size, rsize, n_reg, sav_ofs, sav_scale;
cd3ce9b4
JM
6413 tree lab_false, lab_over, addr;
6414 int align;
6415 tree ptrtype = build_pointer_type (type);
7393f7f8 6416 int regalign = 0;
cd3ce9b4 6417
08b0dc1b
RH
6418 if (pass_by_reference (NULL, TYPE_MODE (type), type, false))
6419 {
6420 t = rs6000_gimplify_va_arg (valist, ptrtype, pre_p, post_p);
872a65b5 6421 return build_va_arg_indirect_ref (t);
08b0dc1b
RH
6422 }
6423
cd3ce9b4
JM
6424 if (DEFAULT_ABI != ABI_V4)
6425 {
08b0dc1b 6426 if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE)
cd3ce9b4
JM
6427 {
6428 tree elem_type = TREE_TYPE (type);
6429 enum machine_mode elem_mode = TYPE_MODE (elem_type);
6430 int elem_size = GET_MODE_SIZE (elem_mode);
6431
6432 if (elem_size < UNITS_PER_WORD)
6433 {
23a60a04 6434 tree real_part, imag_part;
cd3ce9b4
JM
6435 tree post = NULL_TREE;
6436
23a60a04
JM
6437 real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6438 &post);
6439 /* Copy the value into a temporary, lest the formal temporary
6440 be reused out from under us. */
6441 real_part = get_initialized_tmp_var (real_part, pre_p, &post);
cd3ce9b4
JM
6442 append_to_statement_list (post, pre_p);
6443
23a60a04
JM
6444 imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p,
6445 post_p);
cd3ce9b4 6446
47a25a46 6447 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
cd3ce9b4
JM
6448 }
6449 }
6450
23a60a04 6451 return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
cd3ce9b4
JM
6452 }
6453
6454 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
6455 f_fpr = TREE_CHAIN (f_gpr);
6456 f_res = TREE_CHAIN (f_fpr);
6457 f_ovf = TREE_CHAIN (f_res);
6458 f_sav = TREE_CHAIN (f_ovf);
6459
872a65b5 6460 valist = build_va_arg_indirect_ref (valist);
47a25a46
RG
6461 gpr = build3 (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr, NULL_TREE);
6462 fpr = build3 (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr, NULL_TREE);
6463 ovf = build3 (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf, NULL_TREE);
6464 sav = build3 (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav, NULL_TREE);
cd3ce9b4
JM
6465
6466 size = int_size_in_bytes (type);
6467 rsize = (size + 3) / 4;
6468 align = 1;
6469
08b0dc1b 6470 if (TARGET_HARD_FLOAT && TARGET_FPRS
602ea4d3
JJ
6471 && (TYPE_MODE (type) == SFmode
6472 || TYPE_MODE (type) == DFmode
7393f7f8
BE
6473 || TYPE_MODE (type) == TFmode
6474 || TYPE_MODE (type) == DDmode
6475 || TYPE_MODE (type) == TDmode))
cd3ce9b4
JM
6476 {
6477 /* FP args go in FP registers, if present. */
cd3ce9b4 6478 reg = fpr;
602ea4d3 6479 n_reg = (size + 7) / 8;
cd3ce9b4
JM
6480 sav_ofs = 8*4;
6481 sav_scale = 8;
602ea4d3 6482 if (TYPE_MODE (type) != SFmode)
cd3ce9b4
JM
6483 align = 8;
6484 }
6485 else
6486 {
6487 /* Otherwise into GP registers. */
cd3ce9b4
JM
6488 reg = gpr;
6489 n_reg = rsize;
6490 sav_ofs = 0;
6491 sav_scale = 4;
6492 if (n_reg == 2)
6493 align = 8;
6494 }
6495
6496 /* Pull the value out of the saved registers.... */
6497
6498 lab_over = NULL;
6499 addr = create_tmp_var (ptr_type_node, "addr");
6500 DECL_POINTER_ALIAS_SET (addr) = get_varargs_alias_set ();
6501
6502 /* AltiVec vectors never go in registers when -mabi=altivec. */
6503 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
6504 align = 16;
6505 else
6506 {
6507 lab_false = create_artificial_label ();
6508 lab_over = create_artificial_label ();
6509
6510 /* Long long and SPE vectors are aligned in the registers.
6511 As are any other 2 gpr item such as complex int due to a
6512 historical mistake. */
6513 u = reg;
602ea4d3 6514 if (n_reg == 2 && reg == gpr)
cd3ce9b4 6515 {
7393f7f8 6516 regalign = 1;
cd3ce9b4 6517 u = build2 (BIT_AND_EXPR, TREE_TYPE (reg), reg,
8fb632eb 6518 build_int_cst (TREE_TYPE (reg), n_reg - 1));
cd3ce9b4
JM
6519 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg, u);
6520 }
7393f7f8
BE
6521 /* _Decimal128 is passed in even/odd fpr pairs; the stored
6522 reg number is 0 for f1, so we want to make it odd. */
6523 else if (reg == fpr && TYPE_MODE (type) == TDmode)
6524 {
6525 regalign = 1;
6526 t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), reg, size_int (1));
6527 u = build2 (MODIFY_EXPR, void_type_node, reg, t);
6528 }
cd3ce9b4 6529
95674810 6530 t = fold_convert (TREE_TYPE (reg), size_int (8 - n_reg + 1));
cd3ce9b4
JM
6531 t = build2 (GE_EXPR, boolean_type_node, u, t);
6532 u = build1 (GOTO_EXPR, void_type_node, lab_false);
6533 t = build3 (COND_EXPR, void_type_node, t, u, NULL_TREE);
6534 gimplify_and_add (t, pre_p);
6535
6536 t = sav;
6537 if (sav_ofs)
5be014d5 6538 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, sav, size_int (sav_ofs));
cd3ce9b4 6539
8fb632eb
ZD
6540 u = build2 (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
6541 build_int_cst (TREE_TYPE (reg), n_reg));
5be014d5
AP
6542 u = fold_convert (sizetype, u);
6543 u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
6544 t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
cd3ce9b4 6545
07beea0d 6546 t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
cd3ce9b4
JM
6547 gimplify_and_add (t, pre_p);
6548
6549 t = build1 (GOTO_EXPR, void_type_node, lab_over);
6550 gimplify_and_add (t, pre_p);
6551
6552 t = build1 (LABEL_EXPR, void_type_node, lab_false);
6553 append_to_statement_list (t, pre_p);
6554
7393f7f8 6555 if ((n_reg == 2 && !regalign) || n_reg > 2)
cd3ce9b4
JM
6556 {
6557 /* Ensure that we don't find any more args in regs.
7393f7f8 6558 Alignment has taken care of for special cases. */
07beea0d 6559 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (reg), reg, size_int (8));
cd3ce9b4
JM
6560 gimplify_and_add (t, pre_p);
6561 }
6562 }
6563
6564 /* ... otherwise out of the overflow area. */
6565
6566 /* Care for on-stack alignment if needed. */
6567 t = ovf;
6568 if (align != 1)
6569 {
5be014d5
AP
6570 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (align - 1));
6571 t = fold_convert (sizetype, t);
4a90aeeb 6572 t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
5be014d5
AP
6573 size_int (-align));
6574 t = fold_convert (TREE_TYPE (ovf), t);
cd3ce9b4
JM
6575 }
6576 gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
6577
07beea0d 6578 u = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
cd3ce9b4
JM
6579 gimplify_and_add (u, pre_p);
6580
5be014d5 6581 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
07beea0d 6582 t = build2 (GIMPLE_MODIFY_STMT, TREE_TYPE (ovf), ovf, t);
cd3ce9b4
JM
6583 gimplify_and_add (t, pre_p);
6584
6585 if (lab_over)
6586 {
6587 t = build1 (LABEL_EXPR, void_type_node, lab_over);
6588 append_to_statement_list (t, pre_p);
6589 }
6590
0cfbc62b
JM
6591 if (STRICT_ALIGNMENT
6592 && (TYPE_ALIGN (type)
6593 > (unsigned) BITS_PER_UNIT * (align < 4 ? 4 : align)))
6594 {
6595 /* The value (of type complex double, for example) may not be
6596 aligned in memory in the saved registers, so copy via a
6597 temporary. (This is the same code as used for SPARC.) */
6598 tree tmp = create_tmp_var (type, "va_arg_tmp");
6599 tree dest_addr = build_fold_addr_expr (tmp);
6600
5039610b
SL
6601 tree copy = build_call_expr (implicit_built_in_decls[BUILT_IN_MEMCPY],
6602 3, dest_addr, addr, size_int (rsize * 4));
0cfbc62b
JM
6603
6604 gimplify_and_add (copy, pre_p);
6605 addr = dest_addr;
6606 }
6607
08b0dc1b 6608 addr = fold_convert (ptrtype, addr);
872a65b5 6609 return build_va_arg_indirect_ref (addr);
cd3ce9b4
JM
6610}
6611
0ac081f6
AH
6612/* Builtins. */
6613
58646b77
PB
6614static void
6615def_builtin (int mask, const char *name, tree type, int code)
6616{
96038623 6617 if ((mask & target_flags) || TARGET_PAIRED_FLOAT)
58646b77
PB
6618 {
6619 if (rs6000_builtin_decls[code])
6620 abort ();
6621
6622 rs6000_builtin_decls[code] =
c79efc4d
RÁE
6623 add_builtin_function (name, type, code, BUILT_IN_MD,
6624 NULL, NULL_TREE);
58646b77
PB
6625 }
6626}
0ac081f6 6627
24408032
AH
6628/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
6629
2212663f 6630static const struct builtin_description bdesc_3arg[] =
24408032
AH
6631{
6632 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
6633 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
6634 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
6635 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
6636 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
6637 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
6638 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
6639 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
6640 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
6641 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
f676971a 6642 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
aba5fb01
NS
6643 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
6644 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
6645 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
6646 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_v16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
6647 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
6648 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
6649 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
6650 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_v16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
6651 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
6652 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
6653 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
6654 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_v4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
58646b77
PB
6655
6656 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madd", ALTIVEC_BUILTIN_VEC_MADD },
6657 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_madds", ALTIVEC_BUILTIN_VEC_MADDS },
6658 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mladd", ALTIVEC_BUILTIN_VEC_MLADD },
6659 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mradds", ALTIVEC_BUILTIN_VEC_MRADDS },
6660 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msum", ALTIVEC_BUILTIN_VEC_MSUM },
6661 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshm", ALTIVEC_BUILTIN_VEC_VMSUMSHM },
6662 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhm", ALTIVEC_BUILTIN_VEC_VMSUMUHM },
6663 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsummbm", ALTIVEC_BUILTIN_VEC_VMSUMMBM },
6664 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumubm", ALTIVEC_BUILTIN_VEC_VMSUMUBM },
6665 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_msums", ALTIVEC_BUILTIN_VEC_MSUMS },
6666 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumshs", ALTIVEC_BUILTIN_VEC_VMSUMSHS },
6667 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmsumuhs", ALTIVEC_BUILTIN_VEC_VMSUMUHS },
6668 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nmsub", ALTIVEC_BUILTIN_VEC_NMSUB },
6669 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_perm", ALTIVEC_BUILTIN_VEC_PERM },
6670 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sel", ALTIVEC_BUILTIN_VEC_SEL },
96038623
DE
6671
6672 { 0, CODE_FOR_paired_msub, "__builtin_paired_msub", PAIRED_BUILTIN_MSUB },
6673 { 0, CODE_FOR_paired_madd, "__builtin_paired_madd", PAIRED_BUILTIN_MADD },
6674 { 0, CODE_FOR_paired_madds0, "__builtin_paired_madds0", PAIRED_BUILTIN_MADDS0 },
6675 { 0, CODE_FOR_paired_madds1, "__builtin_paired_madds1", PAIRED_BUILTIN_MADDS1 },
6676 { 0, CODE_FOR_paired_nmsub, "__builtin_paired_nmsub", PAIRED_BUILTIN_NMSUB },
6677 { 0, CODE_FOR_paired_nmadd, "__builtin_paired_nmadd", PAIRED_BUILTIN_NMADD },
6678 { 0, CODE_FOR_paired_sum0, "__builtin_paired_sum0", PAIRED_BUILTIN_SUM0 },
6679 { 0, CODE_FOR_paired_sum1, "__builtin_paired_sum1", PAIRED_BUILTIN_SUM1 },
49e39588 6680 { 0, CODE_FOR_selv2sf4, "__builtin_paired_selv2sf4", PAIRED_BUILTIN_SELV2SF4 },
24408032 6681};
2212663f 6682
95385cbb
AH
6683/* DST operations: void foo (void *, const int, const char). */
6684
6685static const struct builtin_description bdesc_dst[] =
6686{
6687 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
6688 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
6689 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
58646b77
PB
6690 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT },
6691
6692 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dst", ALTIVEC_BUILTIN_VEC_DST },
6693 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstt", ALTIVEC_BUILTIN_VEC_DSTT },
6694 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dstst", ALTIVEC_BUILTIN_VEC_DSTST },
6695 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_dststt", ALTIVEC_BUILTIN_VEC_DSTSTT }
95385cbb
AH
6696};
6697
2212663f 6698/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 6699
a3170dc6 6700static struct builtin_description bdesc_2arg[] =
0ac081f6 6701{
f18c054f
DB
6702 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
6703 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
6704 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
6705 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
6706 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
6707 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
6708 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
6709 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
6710 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
6711 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
6712 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 6713 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
aba5fb01 6714 { MASK_ALTIVEC, CODE_FOR_andcv4si3, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
0ac081f6
AH
6715 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
6716 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
6717 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
6718 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
6719 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
6720 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
6721 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
6722 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
6723 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
6724 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
6725 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
6726 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
6727 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
6728 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
6729 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
6730 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
6731 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
6732 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
6733 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
6734 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
6735 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
6736 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
6737 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
6738 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
6739 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
6740 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
6741 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
6742 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
6743 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
6744 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
6745 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
6746 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
6747 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
6748 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
6749 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
6750 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
6751 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
6752 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
6753 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
6754 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
6755 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
6756 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
6757 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
6758 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
6759 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
6760 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
6761 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
6762 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
6763 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
6764 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
6765 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
f96bc213 6766 { MASK_ALTIVEC, CODE_FOR_altivec_norv4si3, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 6767 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
6768 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
6769 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
6770 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
0ac081f6 6771 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
0ac081f6
AH
6772 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
6773 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
6774 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
6775 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
6776 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
6777 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
6778 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
6779 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
6780 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
6781 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
6782 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
6783 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
6784 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
6785 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
6786 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
6787 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
3e0de9d1
DP
6788 { MASK_ALTIVEC, CODE_FOR_lshrv16qi3, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
6789 { MASK_ALTIVEC, CODE_FOR_lshrv8hi3, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
6790 { MASK_ALTIVEC, CODE_FOR_lshrv4si3, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
6791 { MASK_ALTIVEC, CODE_FOR_ashrv16qi3, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
6792 { MASK_ALTIVEC, CODE_FOR_ashrv8hi3, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
6793 { MASK_ALTIVEC, CODE_FOR_ashrv4si3, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
0ac081f6
AH
6794 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
6795 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
6796 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
6797 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
6798 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
6799 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
6800 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
6801 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
6802 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
6803 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
6804 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
6805 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
6806 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
6807 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
6808 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
6809 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
6810 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
6811 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 6812 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6 6813
58646b77
PB
6814 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_add", ALTIVEC_BUILTIN_VEC_ADD },
6815 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddfp", ALTIVEC_BUILTIN_VEC_VADDFP },
6816 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduwm", ALTIVEC_BUILTIN_VEC_VADDUWM },
6817 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhm", ALTIVEC_BUILTIN_VEC_VADDUHM },
6818 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubm", ALTIVEC_BUILTIN_VEC_VADDUBM },
6819 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_addc", ALTIVEC_BUILTIN_VEC_ADDC },
6820 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_adds", ALTIVEC_BUILTIN_VEC_ADDS },
6821 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsws", ALTIVEC_BUILTIN_VEC_VADDSWS },
6822 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduws", ALTIVEC_BUILTIN_VEC_VADDUWS },
6823 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddshs", ALTIVEC_BUILTIN_VEC_VADDSHS },
6824 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vadduhs", ALTIVEC_BUILTIN_VEC_VADDUHS },
6825 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddsbs", ALTIVEC_BUILTIN_VEC_VADDSBS },
6826 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vaddubs", ALTIVEC_BUILTIN_VEC_VADDUBS },
6827 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_and", ALTIVEC_BUILTIN_VEC_AND },
6828 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_andc", ALTIVEC_BUILTIN_VEC_ANDC },
6829 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_avg", ALTIVEC_BUILTIN_VEC_AVG },
6830 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsw", ALTIVEC_BUILTIN_VEC_VAVGSW },
6831 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguw", ALTIVEC_BUILTIN_VEC_VAVGUW },
6832 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsh", ALTIVEC_BUILTIN_VEC_VAVGSH },
6833 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavguh", ALTIVEC_BUILTIN_VEC_VAVGUH },
6834 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgsb", ALTIVEC_BUILTIN_VEC_VAVGSB },
6835 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vavgub", ALTIVEC_BUILTIN_VEC_VAVGUB },
6836 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpb", ALTIVEC_BUILTIN_VEC_CMPB },
6837 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpeq", ALTIVEC_BUILTIN_VEC_CMPEQ },
6838 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpeqfp", ALTIVEC_BUILTIN_VEC_VCMPEQFP },
6839 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequw", ALTIVEC_BUILTIN_VEC_VCMPEQUW },
6840 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequh", ALTIVEC_BUILTIN_VEC_VCMPEQUH },
6841 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpequb", ALTIVEC_BUILTIN_VEC_VCMPEQUB },
6842 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpge", ALTIVEC_BUILTIN_VEC_CMPGE },
6843 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmpgt", ALTIVEC_BUILTIN_VEC_CMPGT },
6844 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtfp", ALTIVEC_BUILTIN_VEC_VCMPGTFP },
6845 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsw", ALTIVEC_BUILTIN_VEC_VCMPGTSW },
6846 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuw", ALTIVEC_BUILTIN_VEC_VCMPGTUW },
6847 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsh", ALTIVEC_BUILTIN_VEC_VCMPGTSH },
6848 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtuh", ALTIVEC_BUILTIN_VEC_VCMPGTUH },
6849 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtsb", ALTIVEC_BUILTIN_VEC_VCMPGTSB },
6850 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vcmpgtub", ALTIVEC_BUILTIN_VEC_VCMPGTUB },
6851 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmple", ALTIVEC_BUILTIN_VEC_CMPLE },
6852 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_cmplt", ALTIVEC_BUILTIN_VEC_CMPLT },
6853 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_max", ALTIVEC_BUILTIN_VEC_MAX },
6854 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxfp", ALTIVEC_BUILTIN_VEC_VMAXFP },
6855 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsw", ALTIVEC_BUILTIN_VEC_VMAXSW },
6856 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuw", ALTIVEC_BUILTIN_VEC_VMAXUW },
6857 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsh", ALTIVEC_BUILTIN_VEC_VMAXSH },
6858 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxuh", ALTIVEC_BUILTIN_VEC_VMAXUH },
6859 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxsb", ALTIVEC_BUILTIN_VEC_VMAXSB },
6860 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmaxub", ALTIVEC_BUILTIN_VEC_VMAXUB },
6861 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergeh", ALTIVEC_BUILTIN_VEC_MERGEH },
6862 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghw", ALTIVEC_BUILTIN_VEC_VMRGHW },
6863 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghh", ALTIVEC_BUILTIN_VEC_VMRGHH },
6864 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrghb", ALTIVEC_BUILTIN_VEC_VMRGHB },
6865 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mergel", ALTIVEC_BUILTIN_VEC_MERGEL },
6866 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglw", ALTIVEC_BUILTIN_VEC_VMRGLW },
6867 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglh", ALTIVEC_BUILTIN_VEC_VMRGLH },
6868 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmrglb", ALTIVEC_BUILTIN_VEC_VMRGLB },
6869 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_min", ALTIVEC_BUILTIN_VEC_MIN },
6870 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminfp", ALTIVEC_BUILTIN_VEC_VMINFP },
6871 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsw", ALTIVEC_BUILTIN_VEC_VMINSW },
6872 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuw", ALTIVEC_BUILTIN_VEC_VMINUW },
6873 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsh", ALTIVEC_BUILTIN_VEC_VMINSH },
6874 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminuh", ALTIVEC_BUILTIN_VEC_VMINUH },
6875 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminsb", ALTIVEC_BUILTIN_VEC_VMINSB },
6876 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vminub", ALTIVEC_BUILTIN_VEC_VMINUB },
6877 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mule", ALTIVEC_BUILTIN_VEC_MULE },
6878 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleub", ALTIVEC_BUILTIN_VEC_VMULEUB },
6879 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesb", ALTIVEC_BUILTIN_VEC_VMULESB },
6880 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuleuh", ALTIVEC_BUILTIN_VEC_VMULEUH },
6881 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulesh", ALTIVEC_BUILTIN_VEC_VMULESH },
6882 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mulo", ALTIVEC_BUILTIN_VEC_MULO },
6883 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosh", ALTIVEC_BUILTIN_VEC_VMULOSH },
6884 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulouh", ALTIVEC_BUILTIN_VEC_VMULOUH },
6885 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmulosb", ALTIVEC_BUILTIN_VEC_VMULOSB },
6886 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vmuloub", ALTIVEC_BUILTIN_VEC_VMULOUB },
6887 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_nor", ALTIVEC_BUILTIN_VEC_NOR },
6888 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_or", ALTIVEC_BUILTIN_VEC_OR },
6889 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_pack", ALTIVEC_BUILTIN_VEC_PACK },
6890 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwum", ALTIVEC_BUILTIN_VEC_VPKUWUM },
6891 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhum", ALTIVEC_BUILTIN_VEC_VPKUHUM },
6892 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packpx", ALTIVEC_BUILTIN_VEC_PACKPX },
6893 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packs", ALTIVEC_BUILTIN_VEC_PACKS },
6894 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswss", ALTIVEC_BUILTIN_VEC_VPKSWSS },
6895 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuwus", ALTIVEC_BUILTIN_VEC_VPKUWUS },
6896 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshss", ALTIVEC_BUILTIN_VEC_VPKSHSS },
6897 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkuhus", ALTIVEC_BUILTIN_VEC_VPKUHUS },
6898 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_packsu", ALTIVEC_BUILTIN_VEC_PACKSU },
6899 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkswus", ALTIVEC_BUILTIN_VEC_VPKSWUS },
6900 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vpkshus", ALTIVEC_BUILTIN_VEC_VPKSHUS },
6901 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rl", ALTIVEC_BUILTIN_VEC_RL },
6902 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlw", ALTIVEC_BUILTIN_VEC_VRLW },
6903 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlh", ALTIVEC_BUILTIN_VEC_VRLH },
6904 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vrlb", ALTIVEC_BUILTIN_VEC_VRLB },
6905 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sl", ALTIVEC_BUILTIN_VEC_SL },
6906 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslw", ALTIVEC_BUILTIN_VEC_VSLW },
6907 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslh", ALTIVEC_BUILTIN_VEC_VSLH },
6908 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vslb", ALTIVEC_BUILTIN_VEC_VSLB },
6909 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sll", ALTIVEC_BUILTIN_VEC_SLL },
6910 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_slo", ALTIVEC_BUILTIN_VEC_SLO },
6911 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sr", ALTIVEC_BUILTIN_VEC_SR },
6912 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrw", ALTIVEC_BUILTIN_VEC_VSRW },
6913 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrh", ALTIVEC_BUILTIN_VEC_VSRH },
6914 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrb", ALTIVEC_BUILTIN_VEC_VSRB },
6915 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sra", ALTIVEC_BUILTIN_VEC_SRA },
6916 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsraw", ALTIVEC_BUILTIN_VEC_VSRAW },
6917 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrah", ALTIVEC_BUILTIN_VEC_VSRAH },
6918 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsrab", ALTIVEC_BUILTIN_VEC_VSRAB },
6919 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_srl", ALTIVEC_BUILTIN_VEC_SRL },
6920 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sro", ALTIVEC_BUILTIN_VEC_SRO },
6921 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sub", ALTIVEC_BUILTIN_VEC_SUB },
6922 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubfp", ALTIVEC_BUILTIN_VEC_VSUBFP },
6923 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuwm", ALTIVEC_BUILTIN_VEC_VSUBUWM },
6924 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhm", ALTIVEC_BUILTIN_VEC_VSUBUHM },
6925 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububm", ALTIVEC_BUILTIN_VEC_VSUBUBM },
6926 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subc", ALTIVEC_BUILTIN_VEC_SUBC },
6927 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_subs", ALTIVEC_BUILTIN_VEC_SUBS },
6928 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsws", ALTIVEC_BUILTIN_VEC_VSUBSWS },
6929 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuws", ALTIVEC_BUILTIN_VEC_VSUBUWS },
6930 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubshs", ALTIVEC_BUILTIN_VEC_VSUBSHS },
6931 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubuhs", ALTIVEC_BUILTIN_VEC_VSUBUHS },
6932 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsubsbs", ALTIVEC_BUILTIN_VEC_VSUBSBS },
6933 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsububs", ALTIVEC_BUILTIN_VEC_VSUBUBS },
6934 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum4s", ALTIVEC_BUILTIN_VEC_SUM4S },
6935 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4shs", ALTIVEC_BUILTIN_VEC_VSUM4SHS },
6936 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4sbs", ALTIVEC_BUILTIN_VEC_VSUM4SBS },
6937 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vsum4ubs", ALTIVEC_BUILTIN_VEC_VSUM4UBS },
6938 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sum2s", ALTIVEC_BUILTIN_VEC_SUM2S },
6939 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_sums", ALTIVEC_BUILTIN_VEC_SUMS },
6940 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_xor", ALTIVEC_BUILTIN_VEC_XOR },
6941
96038623
DE
6942 { 0, CODE_FOR_divv2sf3, "__builtin_paired_divv2sf3", PAIRED_BUILTIN_DIVV2SF3 },
6943 { 0, CODE_FOR_addv2sf3, "__builtin_paired_addv2sf3", PAIRED_BUILTIN_ADDV2SF3 },
6944 { 0, CODE_FOR_subv2sf3, "__builtin_paired_subv2sf3", PAIRED_BUILTIN_SUBV2SF3 },
6945 { 0, CODE_FOR_mulv2sf3, "__builtin_paired_mulv2sf3", PAIRED_BUILTIN_MULV2SF3 },
6946 { 0, CODE_FOR_paired_muls0, "__builtin_paired_muls0", PAIRED_BUILTIN_MULS0 },
6947 { 0, CODE_FOR_paired_muls1, "__builtin_paired_muls1", PAIRED_BUILTIN_MULS1 },
6948 { 0, CODE_FOR_paired_merge00, "__builtin_paired_merge00", PAIRED_BUILTIN_MERGE00 },
6949 { 0, CODE_FOR_paired_merge01, "__builtin_paired_merge01", PAIRED_BUILTIN_MERGE01 },
6950 { 0, CODE_FOR_paired_merge10, "__builtin_paired_merge10", PAIRED_BUILTIN_MERGE10 },
6951 { 0, CODE_FOR_paired_merge11, "__builtin_paired_merge11", PAIRED_BUILTIN_MERGE11 },
6952
a3170dc6
AH
6953 /* Place holder, leave as first spe builtin. */
6954 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
6955 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
6956 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
6957 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
6958 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
6959 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
6960 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
6961 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
6962 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
6963 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
6964 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
6965 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
6966 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
6967 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
6968 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
6969 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
6970 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
6971 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
6972 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
6973 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
6974 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
6975 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
6976 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
6977 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
6978 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
6979 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
6980 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
6981 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
6982 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
6983 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
6984 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
6985 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
6986 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
6987 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
6988 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
6989 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
6990 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
6991 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
6992 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
6993 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
6994 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
6995 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
6996 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
6997 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
6998 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
6999 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
7000 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
7001 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
7002 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
7003 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
7004 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
7005 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
7006 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
7007 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
7008 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
7009 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
7010 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
7011 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
7012 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
7013 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
7014 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
7015 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
7016 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
7017 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
7018 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
7019 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
7020 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
7021 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
7022 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
7023 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
7024 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
7025 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
7026 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
7027 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
a3170dc6
AH
7028 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
7029 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
a3170dc6
AH
7030 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
7031 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
7032 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
7033 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
7034 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
7035 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
7036 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
7037 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
7038 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
7039 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
7040 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
7041 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
7042 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
7043 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
7044 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
7045 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
7046 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
7047 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
7048 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
7049 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
7050 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
7051 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
7052 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
7053 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
7054 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
7055 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
7056 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
7057 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
7058 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
7059 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
7060 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
7061 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
7062 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
7063
7064 /* SPE binary operations expecting a 5-bit unsigned literal. */
7065 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
7066
7067 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
7068 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
7069 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
7070 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
7071 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
7072 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
7073 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
7074 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
7075 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
7076 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
7077 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
7078 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
7079 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
7080 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
7081 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
7082 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
7083 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
7084 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
7085 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
7086 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
7087 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
7088 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
7089 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
7090 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
7091 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
7092 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
7093
7094 /* Place-holder. Leave as last binary SPE builtin. */
58646b77 7095 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR }
ae4b4a02
AH
7096};
7097
7098/* AltiVec predicates. */
7099
7100struct builtin_description_predicates
7101{
7102 const unsigned int mask;
7103 const enum insn_code icode;
7104 const char *opcode;
7105 const char *const name;
7106 const enum rs6000_builtins code;
7107};
7108
7109static const struct builtin_description_predicates bdesc_altivec_preds[] =
7110{
7111 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
7112 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
7113 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
7114 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
7115 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
7116 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
7117 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
7118 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
7119 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
7120 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
7121 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
7122 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
58646b77
PB
7123 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P },
7124
7125 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpeq_p", ALTIVEC_BUILTIN_VCMPEQ_P },
7126 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpgt_p", ALTIVEC_BUILTIN_VCMPGT_P },
7127 { MASK_ALTIVEC, 0, NULL, "__builtin_vec_vcmpge_p", ALTIVEC_BUILTIN_VCMPGE_P }
0ac081f6 7128};
24408032 7129
a3170dc6
AH
7130/* SPE predicates. */
7131static struct builtin_description bdesc_spe_predicates[] =
7132{
7133 /* Place-holder. Leave as first. */
7134 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
7135 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
7136 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
7137 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
7138 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
7139 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
7140 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
7141 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
7142 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
7143 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
7144 /* Place-holder. Leave as last. */
7145 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
7146};
7147
7148/* SPE evsel predicates. */
7149static struct builtin_description bdesc_spe_evsel[] =
7150{
7151 /* Place-holder. Leave as first. */
7152 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
7153 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
7154 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
7155 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
7156 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
7157 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
7158 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
7159 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
7160 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
7161 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
7162 /* Place-holder. Leave as last. */
7163 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
7164};
7165
96038623
DE
7166/* PAIRED predicates. */
7167static const struct builtin_description bdesc_paired_preds[] =
7168{
7169 /* Place-holder. Leave as first. */
7170 { 0, CODE_FOR_paired_cmpu0, "__builtin_paired_cmpu0", PAIRED_BUILTIN_CMPU0 },
7171 /* Place-holder. Leave as last. */
7172 { 0, CODE_FOR_paired_cmpu1, "__builtin_paired_cmpu1", PAIRED_BUILTIN_CMPU1 },
7173};
7174
b6d08ca1 7175/* ABS* operations. */
100c4561
AH
7176
7177static const struct builtin_description bdesc_abs[] =
7178{
7179 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
7180 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
7181 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
7182 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
7183 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
7184 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
7185 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
7186};
7187
617e0e1d
DB
7188/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
7189 foo (VECa). */
24408032 7190
a3170dc6 7191static struct builtin_description bdesc_1arg[] =
2212663f 7192{
617e0e1d
DB
7193 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
7194 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
7195 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
7196 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
7197 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
7198 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
7199 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
7200 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
7201 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
7202 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
7203 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
7204 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
7205 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
7206 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
7207 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
7208 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
7209 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6 7210
58646b77
PB
7211 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abs", ALTIVEC_BUILTIN_VEC_ABS },
7212 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_abss", ALTIVEC_BUILTIN_VEC_ABSS },
7213 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_ceil", ALTIVEC_BUILTIN_VEC_CEIL },
7214 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_expte", ALTIVEC_BUILTIN_VEC_EXPTE },
7215 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_floor", ALTIVEC_BUILTIN_VEC_FLOOR },
7216 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_loge", ALTIVEC_BUILTIN_VEC_LOGE },
7217 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_mtvscr", ALTIVEC_BUILTIN_VEC_MTVSCR },
7218 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_re", ALTIVEC_BUILTIN_VEC_RE },
7219 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_round", ALTIVEC_BUILTIN_VEC_ROUND },
7220 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_rsqrte", ALTIVEC_BUILTIN_VEC_RSQRTE },
7221 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_trunc", ALTIVEC_BUILTIN_VEC_TRUNC },
7222 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackh", ALTIVEC_BUILTIN_VEC_UNPACKH },
7223 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsh", ALTIVEC_BUILTIN_VEC_VUPKHSH },
7224 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhpx", ALTIVEC_BUILTIN_VEC_VUPKHPX },
7225 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupkhsb", ALTIVEC_BUILTIN_VEC_VUPKHSB },
7226 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_unpackl", ALTIVEC_BUILTIN_VEC_UNPACKL },
7227 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklpx", ALTIVEC_BUILTIN_VEC_VUPKLPX },
7228 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsh", ALTIVEC_BUILTIN_VEC_VUPKLSH },
7229 { MASK_ALTIVEC, CODE_FOR_nothing, "__builtin_vec_vupklsb", ALTIVEC_BUILTIN_VEC_VUPKLSB },
7230
a3170dc6
AH
7231 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
7232 end with SPE_BUILTIN_EVSUBFUSIAAW. */
7233 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
7234 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
7235 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
7236 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
7237 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
7238 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
7239 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
7240 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
7241 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
7242 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
7243 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
7244 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
7245 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
7246 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
7247 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
7248 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
7249 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
7250 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
7251 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
7252 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
7253 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
7254 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
7255 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
6a599451 7256 { 0, CODE_FOR_negv2si2, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
a3170dc6
AH
7257 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
7258 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
7259 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
7260 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
a3170dc6
AH
7261
7262 /* Place-holder. Leave as last unary SPE builtin. */
96038623
DE
7263 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
7264
7265 { 0, CODE_FOR_absv2sf2, "__builtin_paired_absv2sf2", PAIRED_BUILTIN_ABSV2SF2 },
7266 { 0, CODE_FOR_nabsv2sf2, "__builtin_paired_nabsv2sf2", PAIRED_BUILTIN_NABSV2SF2 },
7267 { 0, CODE_FOR_negv2sf2, "__builtin_paired_negv2sf2", PAIRED_BUILTIN_NEGV2SF2 },
7268 { 0, CODE_FOR_sqrtv2sf2, "__builtin_paired_sqrtv2sf2", PAIRED_BUILTIN_SQRTV2SF2 },
7269 { 0, CODE_FOR_resv2sf2, "__builtin_paired_resv2sf2", PAIRED_BUILTIN_RESV2SF2 }
2212663f
DB
7270};
7271
7272static rtx
5039610b 7273rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
2212663f
DB
7274{
7275 rtx pat;
5039610b 7276 tree arg0 = CALL_EXPR_ARG (exp, 0);
84217346 7277 rtx op0 = expand_normal (arg0);
2212663f
DB
7278 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7279 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7280
0559cc77
DE
7281 if (icode == CODE_FOR_nothing)
7282 /* Builtin not supported on this processor. */
7283 return 0;
7284
20e26713
AH
7285 /* If we got invalid arguments bail out before generating bad rtl. */
7286 if (arg0 == error_mark_node)
9a171fcd 7287 return const0_rtx;
20e26713 7288
0559cc77
DE
7289 if (icode == CODE_FOR_altivec_vspltisb
7290 || icode == CODE_FOR_altivec_vspltish
7291 || icode == CODE_FOR_altivec_vspltisw
7292 || icode == CODE_FOR_spe_evsplatfi
7293 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
7294 {
7295 /* Only allow 5-bit *signed* literals. */
b44140e7 7296 if (GET_CODE (op0) != CONST_INT
afca671b
DP
7297 || INTVAL (op0) > 15
7298 || INTVAL (op0) < -16)
b44140e7
AH
7299 {
7300 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 7301 return const0_rtx;
b44140e7 7302 }
b44140e7
AH
7303 }
7304
c62f2db5 7305 if (target == 0
2212663f
DB
7306 || GET_MODE (target) != tmode
7307 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7308 target = gen_reg_rtx (tmode);
7309
7310 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7311 op0 = copy_to_mode_reg (mode0, op0);
7312
7313 pat = GEN_FCN (icode) (target, op0);
7314 if (! pat)
7315 return 0;
7316 emit_insn (pat);
0ac081f6 7317
2212663f
DB
7318 return target;
7319}
ae4b4a02 7320
100c4561 7321static rtx
5039610b 7322altivec_expand_abs_builtin (enum insn_code icode, tree exp, rtx target)
100c4561
AH
7323{
7324 rtx pat, scratch1, scratch2;
5039610b 7325 tree arg0 = CALL_EXPR_ARG (exp, 0);
84217346 7326 rtx op0 = expand_normal (arg0);
100c4561
AH
7327 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7328 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7329
7330 /* If we have invalid arguments, bail out before generating bad rtl. */
7331 if (arg0 == error_mark_node)
9a171fcd 7332 return const0_rtx;
100c4561
AH
7333
7334 if (target == 0
7335 || GET_MODE (target) != tmode
7336 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7337 target = gen_reg_rtx (tmode);
7338
7339 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7340 op0 = copy_to_mode_reg (mode0, op0);
7341
7342 scratch1 = gen_reg_rtx (mode0);
7343 scratch2 = gen_reg_rtx (mode0);
7344
7345 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
7346 if (! pat)
7347 return 0;
7348 emit_insn (pat);
7349
7350 return target;
7351}
7352
0ac081f6 7353static rtx
5039610b 7354rs6000_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
0ac081f6
AH
7355{
7356 rtx pat;
5039610b
SL
7357 tree arg0 = CALL_EXPR_ARG (exp, 0);
7358 tree arg1 = CALL_EXPR_ARG (exp, 1);
84217346
MD
7359 rtx op0 = expand_normal (arg0);
7360 rtx op1 = expand_normal (arg1);
0ac081f6
AH
7361 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7362 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7363 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7364
0559cc77
DE
7365 if (icode == CODE_FOR_nothing)
7366 /* Builtin not supported on this processor. */
7367 return 0;
7368
20e26713
AH
7369 /* If we got invalid arguments bail out before generating bad rtl. */
7370 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 7371 return const0_rtx;
20e26713 7372
0559cc77
DE
7373 if (icode == CODE_FOR_altivec_vcfux
7374 || icode == CODE_FOR_altivec_vcfsx
7375 || icode == CODE_FOR_altivec_vctsxs
7376 || icode == CODE_FOR_altivec_vctuxs
7377 || icode == CODE_FOR_altivec_vspltb
7378 || icode == CODE_FOR_altivec_vsplth
7379 || icode == CODE_FOR_altivec_vspltw
7380 || icode == CODE_FOR_spe_evaddiw
7381 || icode == CODE_FOR_spe_evldd
7382 || icode == CODE_FOR_spe_evldh
7383 || icode == CODE_FOR_spe_evldw
7384 || icode == CODE_FOR_spe_evlhhesplat
7385 || icode == CODE_FOR_spe_evlhhossplat
7386 || icode == CODE_FOR_spe_evlhhousplat
7387 || icode == CODE_FOR_spe_evlwhe
7388 || icode == CODE_FOR_spe_evlwhos
7389 || icode == CODE_FOR_spe_evlwhou
7390 || icode == CODE_FOR_spe_evlwhsplat
7391 || icode == CODE_FOR_spe_evlwwsplat
7392 || icode == CODE_FOR_spe_evrlwi
7393 || icode == CODE_FOR_spe_evslwi
7394 || icode == CODE_FOR_spe_evsrwis
f5119d10 7395 || icode == CODE_FOR_spe_evsubifw
0559cc77 7396 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
7397 {
7398 /* Only allow 5-bit unsigned literals. */
8bb418a3 7399 STRIP_NOPS (arg1);
b44140e7
AH
7400 if (TREE_CODE (arg1) != INTEGER_CST
7401 || TREE_INT_CST_LOW (arg1) & ~0x1f)
7402 {
7403 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 7404 return const0_rtx;
b44140e7 7405 }
b44140e7
AH
7406 }
7407
c62f2db5 7408 if (target == 0
0ac081f6
AH
7409 || GET_MODE (target) != tmode
7410 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7411 target = gen_reg_rtx (tmode);
7412
7413 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7414 op0 = copy_to_mode_reg (mode0, op0);
7415 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7416 op1 = copy_to_mode_reg (mode1, op1);
7417
7418 pat = GEN_FCN (icode) (target, op0, op1);
7419 if (! pat)
7420 return 0;
7421 emit_insn (pat);
7422
7423 return target;
7424}
6525c0e7 7425
ae4b4a02 7426static rtx
f676971a 7427altivec_expand_predicate_builtin (enum insn_code icode, const char *opcode,
5039610b 7428 tree exp, rtx target)
ae4b4a02
AH
7429{
7430 rtx pat, scratch;
5039610b
SL
7431 tree cr6_form = CALL_EXPR_ARG (exp, 0);
7432 tree arg0 = CALL_EXPR_ARG (exp, 1);
7433 tree arg1 = CALL_EXPR_ARG (exp, 2);
84217346
MD
7434 rtx op0 = expand_normal (arg0);
7435 rtx op1 = expand_normal (arg1);
ae4b4a02
AH
7436 enum machine_mode tmode = SImode;
7437 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7438 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7439 int cr6_form_int;
7440
7441 if (TREE_CODE (cr6_form) != INTEGER_CST)
7442 {
7443 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 7444 return const0_rtx;
ae4b4a02
AH
7445 }
7446 else
7447 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
7448
37409796 7449 gcc_assert (mode0 == mode1);
ae4b4a02
AH
7450
7451 /* If we have invalid arguments, bail out before generating bad rtl. */
7452 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 7453 return const0_rtx;
ae4b4a02
AH
7454
7455 if (target == 0
7456 || GET_MODE (target) != tmode
7457 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7458 target = gen_reg_rtx (tmode);
7459
7460 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7461 op0 = copy_to_mode_reg (mode0, op0);
7462 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7463 op1 = copy_to_mode_reg (mode1, op1);
7464
7465 scratch = gen_reg_rtx (mode0);
7466
7467 pat = GEN_FCN (icode) (scratch, op0, op1,
f1c25d3b 7468 gen_rtx_SYMBOL_REF (Pmode, opcode));
ae4b4a02
AH
7469 if (! pat)
7470 return 0;
7471 emit_insn (pat);
7472
7473 /* The vec_any* and vec_all* predicates use the same opcodes for two
7474 different operations, but the bits in CR6 will be different
7475 depending on what information we want. So we have to play tricks
7476 with CR6 to get the right bits out.
7477
7478 If you think this is disgusting, look at the specs for the
7479 AltiVec predicates. */
7480
c4ad648e
AM
7481 switch (cr6_form_int)
7482 {
7483 case 0:
7484 emit_insn (gen_cr6_test_for_zero (target));
7485 break;
7486 case 1:
7487 emit_insn (gen_cr6_test_for_zero_reverse (target));
7488 break;
7489 case 2:
7490 emit_insn (gen_cr6_test_for_lt (target));
7491 break;
7492 case 3:
7493 emit_insn (gen_cr6_test_for_lt_reverse (target));
7494 break;
7495 default:
7496 error ("argument 1 of __builtin_altivec_predicate is out of range");
7497 break;
7498 }
ae4b4a02
AH
7499
7500 return target;
7501}
7502
96038623
DE
7503static rtx
7504paired_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
7505{
7506 rtx pat, addr;
7507 tree arg0 = CALL_EXPR_ARG (exp, 0);
7508 tree arg1 = CALL_EXPR_ARG (exp, 1);
7509 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7510 enum machine_mode mode0 = Pmode;
7511 enum machine_mode mode1 = Pmode;
7512 rtx op0 = expand_normal (arg0);
7513 rtx op1 = expand_normal (arg1);
7514
7515 if (icode == CODE_FOR_nothing)
7516 /* Builtin not supported on this processor. */
7517 return 0;
7518
7519 /* If we got invalid arguments bail out before generating bad rtl. */
7520 if (arg0 == error_mark_node || arg1 == error_mark_node)
7521 return const0_rtx;
7522
7523 if (target == 0
7524 || GET_MODE (target) != tmode
7525 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7526 target = gen_reg_rtx (tmode);
7527
7528 op1 = copy_to_mode_reg (mode1, op1);
7529
7530 if (op0 == const0_rtx)
7531 {
7532 addr = gen_rtx_MEM (tmode, op1);
7533 }
7534 else
7535 {
7536 op0 = copy_to_mode_reg (mode0, op0);
7537 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7538 }
7539
7540 pat = GEN_FCN (icode) (target, addr);
7541
7542 if (! pat)
7543 return 0;
7544 emit_insn (pat);
7545
7546 return target;
7547}
7548
b4a62fa0 7549static rtx
5039610b 7550altivec_expand_lv_builtin (enum insn_code icode, tree exp, rtx target)
b4a62fa0
SB
7551{
7552 rtx pat, addr;
5039610b
SL
7553 tree arg0 = CALL_EXPR_ARG (exp, 0);
7554 tree arg1 = CALL_EXPR_ARG (exp, 1);
b4a62fa0
SB
7555 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7556 enum machine_mode mode0 = Pmode;
7557 enum machine_mode mode1 = Pmode;
84217346
MD
7558 rtx op0 = expand_normal (arg0);
7559 rtx op1 = expand_normal (arg1);
b4a62fa0
SB
7560
7561 if (icode == CODE_FOR_nothing)
7562 /* Builtin not supported on this processor. */
7563 return 0;
7564
7565 /* If we got invalid arguments bail out before generating bad rtl. */
7566 if (arg0 == error_mark_node || arg1 == error_mark_node)
7567 return const0_rtx;
7568
7569 if (target == 0
7570 || GET_MODE (target) != tmode
7571 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7572 target = gen_reg_rtx (tmode);
7573
f676971a 7574 op1 = copy_to_mode_reg (mode1, op1);
b4a62fa0
SB
7575
7576 if (op0 == const0_rtx)
7577 {
7578 addr = gen_rtx_MEM (tmode, op1);
7579 }
7580 else
7581 {
7582 op0 = copy_to_mode_reg (mode0, op0);
7583 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op0, op1));
7584 }
7585
7586 pat = GEN_FCN (icode) (target, addr);
7587
7588 if (! pat)
7589 return 0;
7590 emit_insn (pat);
7591
7592 return target;
7593}
7594
61bea3b0 7595static rtx
5039610b 7596spe_expand_stv_builtin (enum insn_code icode, tree exp)
61bea3b0 7597{
5039610b
SL
7598 tree arg0 = CALL_EXPR_ARG (exp, 0);
7599 tree arg1 = CALL_EXPR_ARG (exp, 1);
7600 tree arg2 = CALL_EXPR_ARG (exp, 2);
84217346
MD
7601 rtx op0 = expand_normal (arg0);
7602 rtx op1 = expand_normal (arg1);
7603 rtx op2 = expand_normal (arg2);
61bea3b0
AH
7604 rtx pat;
7605 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
7606 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
7607 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
7608
7609 /* Invalid arguments. Bail before doing anything stoopid! */
7610 if (arg0 == error_mark_node
7611 || arg1 == error_mark_node
7612 || arg2 == error_mark_node)
7613 return const0_rtx;
7614
7615 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
7616 op0 = copy_to_mode_reg (mode2, op0);
7617 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
7618 op1 = copy_to_mode_reg (mode0, op1);
7619 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
7620 op2 = copy_to_mode_reg (mode1, op2);
7621
7622 pat = GEN_FCN (icode) (op1, op2, op0);
7623 if (pat)
7624 emit_insn (pat);
7625 return NULL_RTX;
7626}
7627
96038623
DE
7628static rtx
7629paired_expand_stv_builtin (enum insn_code icode, tree exp)
7630{
7631 tree arg0 = CALL_EXPR_ARG (exp, 0);
7632 tree arg1 = CALL_EXPR_ARG (exp, 1);
7633 tree arg2 = CALL_EXPR_ARG (exp, 2);
7634 rtx op0 = expand_normal (arg0);
7635 rtx op1 = expand_normal (arg1);
7636 rtx op2 = expand_normal (arg2);
7637 rtx pat, addr;
7638 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7639 enum machine_mode mode1 = Pmode;
7640 enum machine_mode mode2 = Pmode;
7641
7642 /* Invalid arguments. Bail before doing anything stoopid! */
7643 if (arg0 == error_mark_node
7644 || arg1 == error_mark_node
7645 || arg2 == error_mark_node)
7646 return const0_rtx;
7647
7648 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
7649 op0 = copy_to_mode_reg (tmode, op0);
7650
7651 op2 = copy_to_mode_reg (mode2, op2);
7652
7653 if (op1 == const0_rtx)
7654 {
7655 addr = gen_rtx_MEM (tmode, op2);
7656 }
7657 else
7658 {
7659 op1 = copy_to_mode_reg (mode1, op1);
7660 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
7661 }
7662
7663 pat = GEN_FCN (icode) (addr, op0);
7664 if (pat)
7665 emit_insn (pat);
7666 return NULL_RTX;
7667}
7668
6525c0e7 7669static rtx
5039610b 7670altivec_expand_stv_builtin (enum insn_code icode, tree exp)
6525c0e7 7671{
5039610b
SL
7672 tree arg0 = CALL_EXPR_ARG (exp, 0);
7673 tree arg1 = CALL_EXPR_ARG (exp, 1);
7674 tree arg2 = CALL_EXPR_ARG (exp, 2);
84217346
MD
7675 rtx op0 = expand_normal (arg0);
7676 rtx op1 = expand_normal (arg1);
7677 rtx op2 = expand_normal (arg2);
b4a62fa0
SB
7678 rtx pat, addr;
7679 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7680 enum machine_mode mode1 = Pmode;
7681 enum machine_mode mode2 = Pmode;
6525c0e7
AH
7682
7683 /* Invalid arguments. Bail before doing anything stoopid! */
7684 if (arg0 == error_mark_node
7685 || arg1 == error_mark_node
7686 || arg2 == error_mark_node)
9a171fcd 7687 return const0_rtx;
6525c0e7 7688
b4a62fa0
SB
7689 if (! (*insn_data[icode].operand[1].predicate) (op0, tmode))
7690 op0 = copy_to_mode_reg (tmode, op0);
7691
f676971a 7692 op2 = copy_to_mode_reg (mode2, op2);
b4a62fa0
SB
7693
7694 if (op1 == const0_rtx)
7695 {
7696 addr = gen_rtx_MEM (tmode, op2);
7697 }
7698 else
7699 {
7700 op1 = copy_to_mode_reg (mode1, op1);
7701 addr = gen_rtx_MEM (tmode, gen_rtx_PLUS (Pmode, op1, op2));
7702 }
6525c0e7 7703
b4a62fa0 7704 pat = GEN_FCN (icode) (addr, op0);
6525c0e7
AH
7705 if (pat)
7706 emit_insn (pat);
7707 return NULL_RTX;
7708}
7709
2212663f 7710static rtx
5039610b 7711rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
2212663f
DB
7712{
7713 rtx pat;
5039610b
SL
7714 tree arg0 = CALL_EXPR_ARG (exp, 0);
7715 tree arg1 = CALL_EXPR_ARG (exp, 1);
7716 tree arg2 = CALL_EXPR_ARG (exp, 2);
84217346
MD
7717 rtx op0 = expand_normal (arg0);
7718 rtx op1 = expand_normal (arg1);
7719 rtx op2 = expand_normal (arg2);
2212663f
DB
7720 enum machine_mode tmode = insn_data[icode].operand[0].mode;
7721 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7722 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7723 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 7724
774b5662
DE
7725 if (icode == CODE_FOR_nothing)
7726 /* Builtin not supported on this processor. */
7727 return 0;
7728
20e26713
AH
7729 /* If we got invalid arguments bail out before generating bad rtl. */
7730 if (arg0 == error_mark_node
7731 || arg1 == error_mark_node
7732 || arg2 == error_mark_node)
9a171fcd 7733 return const0_rtx;
20e26713 7734
aba5fb01
NS
7735 if (icode == CODE_FOR_altivec_vsldoi_v4sf
7736 || icode == CODE_FOR_altivec_vsldoi_v4si
7737 || icode == CODE_FOR_altivec_vsldoi_v8hi
7738 || icode == CODE_FOR_altivec_vsldoi_v16qi)
b44140e7
AH
7739 {
7740 /* Only allow 4-bit unsigned literals. */
8bb418a3 7741 STRIP_NOPS (arg2);
b44140e7
AH
7742 if (TREE_CODE (arg2) != INTEGER_CST
7743 || TREE_INT_CST_LOW (arg2) & ~0xf)
7744 {
7745 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 7746 return const0_rtx;
b44140e7 7747 }
b44140e7
AH
7748 }
7749
c62f2db5 7750 if (target == 0
2212663f
DB
7751 || GET_MODE (target) != tmode
7752 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7753 target = gen_reg_rtx (tmode);
7754
7755 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7756 op0 = copy_to_mode_reg (mode0, op0);
7757 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7758 op1 = copy_to_mode_reg (mode1, op1);
7759 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
7760 op2 = copy_to_mode_reg (mode2, op2);
7761
49e39588
RE
7762 if (TARGET_PAIRED_FLOAT && icode == CODE_FOR_selv2sf4)
7763 pat = GEN_FCN (icode) (target, op0, op1, op2, CONST0_RTX (SFmode));
7764 else
7765 pat = GEN_FCN (icode) (target, op0, op1, op2);
2212663f
DB
7766 if (! pat)
7767 return 0;
7768 emit_insn (pat);
7769
7770 return target;
7771}
92898235 7772
3a9b8c7e 7773/* Expand the lvx builtins. */
0ac081f6 7774static rtx
a2369ed3 7775altivec_expand_ld_builtin (tree exp, rtx target, bool *expandedp)
0ac081f6 7776{
5039610b 7777 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
0ac081f6 7778 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
7779 tree arg0;
7780 enum machine_mode tmode, mode0;
7c3abc73 7781 rtx pat, op0;
3a9b8c7e 7782 enum insn_code icode;
92898235 7783
0ac081f6
AH
7784 switch (fcode)
7785 {
f18c054f 7786 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
81466555 7787 icode = CODE_FOR_altivec_lvx_v16qi;
3a9b8c7e 7788 break;
f18c054f 7789 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
81466555 7790 icode = CODE_FOR_altivec_lvx_v8hi;
3a9b8c7e
AH
7791 break;
7792 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
81466555 7793 icode = CODE_FOR_altivec_lvx_v4si;
3a9b8c7e
AH
7794 break;
7795 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
81466555 7796 icode = CODE_FOR_altivec_lvx_v4sf;
3a9b8c7e
AH
7797 break;
7798 default:
7799 *expandedp = false;
7800 return NULL_RTX;
7801 }
0ac081f6 7802
3a9b8c7e 7803 *expandedp = true;
f18c054f 7804
5039610b 7805 arg0 = CALL_EXPR_ARG (exp, 0);
84217346 7806 op0 = expand_normal (arg0);
3a9b8c7e
AH
7807 tmode = insn_data[icode].operand[0].mode;
7808 mode0 = insn_data[icode].operand[1].mode;
f18c054f 7809
3a9b8c7e
AH
7810 if (target == 0
7811 || GET_MODE (target) != tmode
7812 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7813 target = gen_reg_rtx (tmode);
24408032 7814
3a9b8c7e
AH
7815 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7816 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 7817
3a9b8c7e
AH
7818 pat = GEN_FCN (icode) (target, op0);
7819 if (! pat)
7820 return 0;
7821 emit_insn (pat);
7822 return target;
7823}
f18c054f 7824
3a9b8c7e
AH
7825/* Expand the stvx builtins. */
7826static rtx
f676971a 7827altivec_expand_st_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
a2369ed3 7828 bool *expandedp)
3a9b8c7e 7829{
5039610b 7830 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3a9b8c7e
AH
7831 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7832 tree arg0, arg1;
7833 enum machine_mode mode0, mode1;
7c3abc73 7834 rtx pat, op0, op1;
3a9b8c7e 7835 enum insn_code icode;
f18c054f 7836
3a9b8c7e
AH
7837 switch (fcode)
7838 {
7839 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
81466555 7840 icode = CODE_FOR_altivec_stvx_v16qi;
3a9b8c7e
AH
7841 break;
7842 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
81466555 7843 icode = CODE_FOR_altivec_stvx_v8hi;
3a9b8c7e
AH
7844 break;
7845 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
81466555 7846 icode = CODE_FOR_altivec_stvx_v4si;
3a9b8c7e
AH
7847 break;
7848 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
81466555 7849 icode = CODE_FOR_altivec_stvx_v4sf;
3a9b8c7e
AH
7850 break;
7851 default:
7852 *expandedp = false;
7853 return NULL_RTX;
7854 }
24408032 7855
5039610b
SL
7856 arg0 = CALL_EXPR_ARG (exp, 0);
7857 arg1 = CALL_EXPR_ARG (exp, 1);
84217346
MD
7858 op0 = expand_normal (arg0);
7859 op1 = expand_normal (arg1);
3a9b8c7e
AH
7860 mode0 = insn_data[icode].operand[0].mode;
7861 mode1 = insn_data[icode].operand[1].mode;
f18c054f 7862
3a9b8c7e
AH
7863 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
7864 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
7865 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
7866 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 7867
3a9b8c7e
AH
7868 pat = GEN_FCN (icode) (op0, op1);
7869 if (pat)
7870 emit_insn (pat);
f18c054f 7871
3a9b8c7e
AH
7872 *expandedp = true;
7873 return NULL_RTX;
7874}
f18c054f 7875
3a9b8c7e
AH
7876/* Expand the dst builtins. */
7877static rtx
f676971a 7878altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
a2369ed3 7879 bool *expandedp)
3a9b8c7e 7880{
5039610b 7881 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3a9b8c7e
AH
7882 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
7883 tree arg0, arg1, arg2;
7884 enum machine_mode mode0, mode1, mode2;
7c3abc73 7885 rtx pat, op0, op1, op2;
586de218 7886 const struct builtin_description *d;
a3170dc6 7887 size_t i;
f18c054f 7888
3a9b8c7e 7889 *expandedp = false;
f18c054f 7890
3a9b8c7e 7891 /* Handle DST variants. */
586de218 7892 d = bdesc_dst;
3a9b8c7e
AH
7893 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
7894 if (d->code == fcode)
7895 {
5039610b
SL
7896 arg0 = CALL_EXPR_ARG (exp, 0);
7897 arg1 = CALL_EXPR_ARG (exp, 1);
7898 arg2 = CALL_EXPR_ARG (exp, 2);
84217346
MD
7899 op0 = expand_normal (arg0);
7900 op1 = expand_normal (arg1);
7901 op2 = expand_normal (arg2);
3a9b8c7e
AH
7902 mode0 = insn_data[d->icode].operand[0].mode;
7903 mode1 = insn_data[d->icode].operand[1].mode;
7904 mode2 = insn_data[d->icode].operand[2].mode;
24408032 7905
3a9b8c7e
AH
7906 /* Invalid arguments, bail out before generating bad rtl. */
7907 if (arg0 == error_mark_node
7908 || arg1 == error_mark_node
7909 || arg2 == error_mark_node)
7910 return const0_rtx;
f18c054f 7911
86e7df90 7912 *expandedp = true;
8bb418a3 7913 STRIP_NOPS (arg2);
3a9b8c7e
AH
7914 if (TREE_CODE (arg2) != INTEGER_CST
7915 || TREE_INT_CST_LOW (arg2) & ~0x3)
7916 {
9e637a26 7917 error ("argument to %qs must be a 2-bit unsigned literal", d->name);
3a9b8c7e
AH
7918 return const0_rtx;
7919 }
f18c054f 7920
3a9b8c7e 7921 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
666158b9 7922 op0 = copy_to_mode_reg (Pmode, op0);
3a9b8c7e
AH
7923 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
7924 op1 = copy_to_mode_reg (mode1, op1);
24408032 7925
3a9b8c7e
AH
7926 pat = GEN_FCN (d->icode) (op0, op1, op2);
7927 if (pat != 0)
7928 emit_insn (pat);
f18c054f 7929
3a9b8c7e
AH
7930 return NULL_RTX;
7931 }
f18c054f 7932
3a9b8c7e
AH
7933 return NULL_RTX;
7934}
24408032 7935
7a4eca66
DE
7936/* Expand vec_init builtin. */
7937static rtx
5039610b 7938altivec_expand_vec_init_builtin (tree type, tree exp, rtx target)
7a4eca66
DE
7939{
7940 enum machine_mode tmode = TYPE_MODE (type);
7941 enum machine_mode inner_mode = GET_MODE_INNER (tmode);
7942 int i, n_elt = GET_MODE_NUNITS (tmode);
7943 rtvec v = rtvec_alloc (n_elt);
7944
7945 gcc_assert (VECTOR_MODE_P (tmode));
5039610b 7946 gcc_assert (n_elt == call_expr_nargs (exp));
982afe02 7947
5039610b 7948 for (i = 0; i < n_elt; ++i)
7a4eca66 7949 {
5039610b 7950 rtx x = expand_normal (CALL_EXPR_ARG (exp, i));
7a4eca66
DE
7951 RTVEC_ELT (v, i) = gen_lowpart (inner_mode, x);
7952 }
7953
7a4eca66
DE
7954 if (!target || !register_operand (target, tmode))
7955 target = gen_reg_rtx (tmode);
7956
7957 rs6000_expand_vector_init (target, gen_rtx_PARALLEL (tmode, v));
7958 return target;
7959}
7960
7961/* Return the integer constant in ARG. Constrain it to be in the range
7962 of the subparts of VEC_TYPE; issue an error if not. */
7963
7964static int
7965get_element_number (tree vec_type, tree arg)
7966{
7967 unsigned HOST_WIDE_INT elt, max = TYPE_VECTOR_SUBPARTS (vec_type) - 1;
7968
7969 if (!host_integerp (arg, 1)
7970 || (elt = tree_low_cst (arg, 1), elt > max))
7971 {
7972 error ("selector must be an integer constant in the range 0..%wi", max);
7973 return 0;
7974 }
7975
7976 return elt;
7977}
7978
7979/* Expand vec_set builtin. */
7980static rtx
5039610b 7981altivec_expand_vec_set_builtin (tree exp)
7a4eca66
DE
7982{
7983 enum machine_mode tmode, mode1;
7984 tree arg0, arg1, arg2;
7985 int elt;
7986 rtx op0, op1;
7987
5039610b
SL
7988 arg0 = CALL_EXPR_ARG (exp, 0);
7989 arg1 = CALL_EXPR_ARG (exp, 1);
7990 arg2 = CALL_EXPR_ARG (exp, 2);
7a4eca66
DE
7991
7992 tmode = TYPE_MODE (TREE_TYPE (arg0));
7993 mode1 = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
7994 gcc_assert (VECTOR_MODE_P (tmode));
7995
7996 op0 = expand_expr (arg0, NULL_RTX, tmode, 0);
7997 op1 = expand_expr (arg1, NULL_RTX, mode1, 0);
7998 elt = get_element_number (TREE_TYPE (arg0), arg2);
7999
8000 if (GET_MODE (op1) != mode1 && GET_MODE (op1) != VOIDmode)
8001 op1 = convert_modes (mode1, GET_MODE (op1), op1, true);
8002
8003 op0 = force_reg (tmode, op0);
8004 op1 = force_reg (mode1, op1);
8005
8006 rs6000_expand_vector_set (op0, op1, elt);
8007
8008 return op0;
8009}
8010
8011/* Expand vec_ext builtin. */
8012static rtx
5039610b 8013altivec_expand_vec_ext_builtin (tree exp, rtx target)
7a4eca66
DE
8014{
8015 enum machine_mode tmode, mode0;
8016 tree arg0, arg1;
8017 int elt;
8018 rtx op0;
8019
5039610b
SL
8020 arg0 = CALL_EXPR_ARG (exp, 0);
8021 arg1 = CALL_EXPR_ARG (exp, 1);
7a4eca66 8022
84217346 8023 op0 = expand_normal (arg0);
7a4eca66
DE
8024 elt = get_element_number (TREE_TYPE (arg0), arg1);
8025
8026 tmode = TYPE_MODE (TREE_TYPE (TREE_TYPE (arg0)));
8027 mode0 = TYPE_MODE (TREE_TYPE (arg0));
8028 gcc_assert (VECTOR_MODE_P (mode0));
8029
8030 op0 = force_reg (mode0, op0);
8031
8032 if (optimize || !target || !register_operand (target, tmode))
8033 target = gen_reg_rtx (tmode);
8034
8035 rs6000_expand_vector_extract (target, op0, elt);
8036
8037 return target;
8038}
8039
3a9b8c7e
AH
8040/* Expand the builtin in EXP and store the result in TARGET. Store
8041 true in *EXPANDEDP if we found a builtin to expand. */
8042static rtx
a2369ed3 8043altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
3a9b8c7e 8044{
586de218
KG
8045 const struct builtin_description *d;
8046 const struct builtin_description_predicates *dp;
3a9b8c7e
AH
8047 size_t i;
8048 enum insn_code icode;
5039610b 8049 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7c3abc73
AH
8050 tree arg0;
8051 rtx op0, pat;
8052 enum machine_mode tmode, mode0;
3a9b8c7e 8053 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 8054
58646b77
PB
8055 if (fcode >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
8056 && fcode <= ALTIVEC_BUILTIN_OVERLOADED_LAST)
8057 {
8058 *expandedp = true;
ea40ba9c 8059 error ("unresolved overload for Altivec builtin %qF", fndecl);
58646b77
PB
8060 return const0_rtx;
8061 }
8062
3a9b8c7e
AH
8063 target = altivec_expand_ld_builtin (exp, target, expandedp);
8064 if (*expandedp)
8065 return target;
0ac081f6 8066
3a9b8c7e
AH
8067 target = altivec_expand_st_builtin (exp, target, expandedp);
8068 if (*expandedp)
8069 return target;
8070
8071 target = altivec_expand_dst_builtin (exp, target, expandedp);
8072 if (*expandedp)
8073 return target;
8074
8075 *expandedp = true;
95385cbb 8076
3a9b8c7e
AH
8077 switch (fcode)
8078 {
6525c0e7 8079 case ALTIVEC_BUILTIN_STVX:
5039610b 8080 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, exp);
6525c0e7 8081 case ALTIVEC_BUILTIN_STVEBX:
5039610b 8082 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, exp);
6525c0e7 8083 case ALTIVEC_BUILTIN_STVEHX:
5039610b 8084 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, exp);
6525c0e7 8085 case ALTIVEC_BUILTIN_STVEWX:
5039610b 8086 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, exp);
6525c0e7 8087 case ALTIVEC_BUILTIN_STVXL:
5039610b 8088 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, exp);
3a9b8c7e 8089
95385cbb
AH
8090 case ALTIVEC_BUILTIN_MFVSCR:
8091 icode = CODE_FOR_altivec_mfvscr;
8092 tmode = insn_data[icode].operand[0].mode;
8093
8094 if (target == 0
8095 || GET_MODE (target) != tmode
8096 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8097 target = gen_reg_rtx (tmode);
f676971a 8098
95385cbb 8099 pat = GEN_FCN (icode) (target);
0ac081f6
AH
8100 if (! pat)
8101 return 0;
8102 emit_insn (pat);
95385cbb
AH
8103 return target;
8104
8105 case ALTIVEC_BUILTIN_MTVSCR:
8106 icode = CODE_FOR_altivec_mtvscr;
5039610b 8107 arg0 = CALL_EXPR_ARG (exp, 0);
84217346 8108 op0 = expand_normal (arg0);
95385cbb
AH
8109 mode0 = insn_data[icode].operand[0].mode;
8110
8111 /* If we got invalid arguments bail out before generating bad rtl. */
8112 if (arg0 == error_mark_node)
9a171fcd 8113 return const0_rtx;
95385cbb
AH
8114
8115 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8116 op0 = copy_to_mode_reg (mode0, op0);
8117
8118 pat = GEN_FCN (icode) (op0);
8119 if (pat)
8120 emit_insn (pat);
8121 return NULL_RTX;
3a9b8c7e 8122
95385cbb
AH
8123 case ALTIVEC_BUILTIN_DSSALL:
8124 emit_insn (gen_altivec_dssall ());
8125 return NULL_RTX;
8126
8127 case ALTIVEC_BUILTIN_DSS:
8128 icode = CODE_FOR_altivec_dss;
5039610b 8129 arg0 = CALL_EXPR_ARG (exp, 0);
8bb418a3 8130 STRIP_NOPS (arg0);
84217346 8131 op0 = expand_normal (arg0);
95385cbb
AH
8132 mode0 = insn_data[icode].operand[0].mode;
8133
8134 /* If we got invalid arguments bail out before generating bad rtl. */
8135 if (arg0 == error_mark_node)
9a171fcd 8136 return const0_rtx;
95385cbb 8137
b44140e7
AH
8138 if (TREE_CODE (arg0) != INTEGER_CST
8139 || TREE_INT_CST_LOW (arg0) & ~0x3)
8140 {
8141 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 8142 return const0_rtx;
b44140e7
AH
8143 }
8144
95385cbb
AH
8145 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8146 op0 = copy_to_mode_reg (mode0, op0);
8147
8148 emit_insn (gen_altivec_dss (op0));
0ac081f6 8149 return NULL_RTX;
7a4eca66
DE
8150
8151 case ALTIVEC_BUILTIN_VEC_INIT_V4SI:
8152 case ALTIVEC_BUILTIN_VEC_INIT_V8HI:
8153 case ALTIVEC_BUILTIN_VEC_INIT_V16QI:
8154 case ALTIVEC_BUILTIN_VEC_INIT_V4SF:
5039610b 8155 return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target);
7a4eca66
DE
8156
8157 case ALTIVEC_BUILTIN_VEC_SET_V4SI:
8158 case ALTIVEC_BUILTIN_VEC_SET_V8HI:
8159 case ALTIVEC_BUILTIN_VEC_SET_V16QI:
8160 case ALTIVEC_BUILTIN_VEC_SET_V4SF:
5039610b 8161 return altivec_expand_vec_set_builtin (exp);
7a4eca66
DE
8162
8163 case ALTIVEC_BUILTIN_VEC_EXT_V4SI:
8164 case ALTIVEC_BUILTIN_VEC_EXT_V8HI:
8165 case ALTIVEC_BUILTIN_VEC_EXT_V16QI:
8166 case ALTIVEC_BUILTIN_VEC_EXT_V4SF:
5039610b 8167 return altivec_expand_vec_ext_builtin (exp, target);
7a4eca66
DE
8168
8169 default:
8170 break;
8171 /* Fall through. */
0ac081f6 8172 }
24408032 8173
100c4561 8174 /* Expand abs* operations. */
586de218 8175 d = bdesc_abs;
ca7558fc 8176 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561 8177 if (d->code == fcode)
5039610b 8178 return altivec_expand_abs_builtin (d->icode, exp, target);
100c4561 8179
ae4b4a02 8180 /* Expand the AltiVec predicates. */
586de218 8181 dp = bdesc_altivec_preds;
ca7558fc 8182 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02 8183 if (dp->code == fcode)
c4ad648e 8184 return altivec_expand_predicate_builtin (dp->icode, dp->opcode,
5039610b 8185 exp, target);
ae4b4a02 8186
6525c0e7
AH
8187 /* LV* are funky. We initialized them differently. */
8188 switch (fcode)
8189 {
8190 case ALTIVEC_BUILTIN_LVSL:
b4a62fa0 8191 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsl,
5039610b 8192 exp, target);
6525c0e7 8193 case ALTIVEC_BUILTIN_LVSR:
b4a62fa0 8194 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvsr,
5039610b 8195 exp, target);
6525c0e7 8196 case ALTIVEC_BUILTIN_LVEBX:
b4a62fa0 8197 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvebx,
5039610b 8198 exp, target);
6525c0e7 8199 case ALTIVEC_BUILTIN_LVEHX:
b4a62fa0 8200 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvehx,
5039610b 8201 exp, target);
6525c0e7 8202 case ALTIVEC_BUILTIN_LVEWX:
b4a62fa0 8203 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvewx,
5039610b 8204 exp, target);
6525c0e7 8205 case ALTIVEC_BUILTIN_LVXL:
b4a62fa0 8206 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvxl,
5039610b 8207 exp, target);
6525c0e7 8208 case ALTIVEC_BUILTIN_LVX:
b4a62fa0 8209 return altivec_expand_lv_builtin (CODE_FOR_altivec_lvx,
5039610b 8210 exp, target);
6525c0e7
AH
8211 default:
8212 break;
8213 /* Fall through. */
8214 }
95385cbb 8215
92898235 8216 *expandedp = false;
0ac081f6
AH
8217 return NULL_RTX;
8218}
8219
96038623
DE
8220/* Expand the builtin in EXP and store the result in TARGET. Store
8221 true in *EXPANDEDP if we found a builtin to expand. */
8222static rtx
8223paired_expand_builtin (tree exp, rtx target, bool * expandedp)
8224{
8225 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
8226 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
23a651fc 8227 const struct builtin_description *d;
96038623
DE
8228 size_t i;
8229
8230 *expandedp = true;
8231
8232 switch (fcode)
8233 {
8234 case PAIRED_BUILTIN_STX:
8235 return paired_expand_stv_builtin (CODE_FOR_paired_stx, exp);
8236 case PAIRED_BUILTIN_LX:
8237 return paired_expand_lv_builtin (CODE_FOR_paired_lx, exp, target);
8238 default:
8239 break;
8240 /* Fall through. */
8241 }
8242
8243 /* Expand the paired predicates. */
23a651fc 8244 d = bdesc_paired_preds;
96038623
DE
8245 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); i++, d++)
8246 if (d->code == fcode)
8247 return paired_expand_predicate_builtin (d->icode, exp, target);
8248
8249 *expandedp = false;
8250 return NULL_RTX;
8251}
8252
a3170dc6
AH
8253/* Binops that need to be initialized manually, but can be expanded
8254 automagically by rs6000_expand_binop_builtin. */
8255static struct builtin_description bdesc_2arg_spe[] =
8256{
8257 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
8258 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
8259 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
8260 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
8261 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
8262 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
8263 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
8264 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
8265 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
8266 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
8267 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
8268 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
8269 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
8270 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
8271 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
8272 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
8273 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
8274 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
8275 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
8276 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
8277 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
8278 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
8279};
8280
8281/* Expand the builtin in EXP and store the result in TARGET. Store
8282 true in *EXPANDEDP if we found a builtin to expand.
8283
8284 This expands the SPE builtins that are not simple unary and binary
8285 operations. */
8286static rtx
a2369ed3 8287spe_expand_builtin (tree exp, rtx target, bool *expandedp)
a3170dc6 8288{
5039610b 8289 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
a3170dc6
AH
8290 tree arg1, arg0;
8291 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
8292 enum insn_code icode;
8293 enum machine_mode tmode, mode0;
8294 rtx pat, op0;
8295 struct builtin_description *d;
8296 size_t i;
8297
8298 *expandedp = true;
8299
8300 /* Syntax check for a 5-bit unsigned immediate. */
8301 switch (fcode)
8302 {
8303 case SPE_BUILTIN_EVSTDD:
8304 case SPE_BUILTIN_EVSTDH:
8305 case SPE_BUILTIN_EVSTDW:
8306 case SPE_BUILTIN_EVSTWHE:
8307 case SPE_BUILTIN_EVSTWHO:
8308 case SPE_BUILTIN_EVSTWWE:
8309 case SPE_BUILTIN_EVSTWWO:
5039610b 8310 arg1 = CALL_EXPR_ARG (exp, 2);
a3170dc6
AH
8311 if (TREE_CODE (arg1) != INTEGER_CST
8312 || TREE_INT_CST_LOW (arg1) & ~0x1f)
8313 {
8314 error ("argument 2 must be a 5-bit unsigned literal");
8315 return const0_rtx;
8316 }
8317 break;
8318 default:
8319 break;
8320 }
8321
00332c9f
AH
8322 /* The evsplat*i instructions are not quite generic. */
8323 switch (fcode)
8324 {
8325 case SPE_BUILTIN_EVSPLATFI:
8326 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplatfi,
5039610b 8327 exp, target);
00332c9f
AH
8328 case SPE_BUILTIN_EVSPLATI:
8329 return rs6000_expand_unop_builtin (CODE_FOR_spe_evsplati,
5039610b 8330 exp, target);
00332c9f
AH
8331 default:
8332 break;
8333 }
8334
a3170dc6
AH
8335 d = (struct builtin_description *) bdesc_2arg_spe;
8336 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
8337 if (d->code == fcode)
5039610b 8338 return rs6000_expand_binop_builtin (d->icode, exp, target);
a3170dc6
AH
8339
8340 d = (struct builtin_description *) bdesc_spe_predicates;
8341 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
8342 if (d->code == fcode)
5039610b 8343 return spe_expand_predicate_builtin (d->icode, exp, target);
a3170dc6
AH
8344
8345 d = (struct builtin_description *) bdesc_spe_evsel;
8346 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
8347 if (d->code == fcode)
5039610b 8348 return spe_expand_evsel_builtin (d->icode, exp, target);
a3170dc6
AH
8349
8350 switch (fcode)
8351 {
8352 case SPE_BUILTIN_EVSTDDX:
5039610b 8353 return spe_expand_stv_builtin (CODE_FOR_spe_evstddx, exp);
a3170dc6 8354 case SPE_BUILTIN_EVSTDHX:
5039610b 8355 return spe_expand_stv_builtin (CODE_FOR_spe_evstdhx, exp);
a3170dc6 8356 case SPE_BUILTIN_EVSTDWX:
5039610b 8357 return spe_expand_stv_builtin (CODE_FOR_spe_evstdwx, exp);
a3170dc6 8358 case SPE_BUILTIN_EVSTWHEX:
5039610b 8359 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhex, exp);
a3170dc6 8360 case SPE_BUILTIN_EVSTWHOX:
5039610b 8361 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhox, exp);
a3170dc6 8362 case SPE_BUILTIN_EVSTWWEX:
5039610b 8363 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwex, exp);
a3170dc6 8364 case SPE_BUILTIN_EVSTWWOX:
5039610b 8365 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwox, exp);
a3170dc6 8366 case SPE_BUILTIN_EVSTDD:
5039610b 8367 return spe_expand_stv_builtin (CODE_FOR_spe_evstdd, exp);
a3170dc6 8368 case SPE_BUILTIN_EVSTDH:
5039610b 8369 return spe_expand_stv_builtin (CODE_FOR_spe_evstdh, exp);
a3170dc6 8370 case SPE_BUILTIN_EVSTDW:
5039610b 8371 return spe_expand_stv_builtin (CODE_FOR_spe_evstdw, exp);
a3170dc6 8372 case SPE_BUILTIN_EVSTWHE:
5039610b 8373 return spe_expand_stv_builtin (CODE_FOR_spe_evstwhe, exp);
a3170dc6 8374 case SPE_BUILTIN_EVSTWHO:
5039610b 8375 return spe_expand_stv_builtin (CODE_FOR_spe_evstwho, exp);
a3170dc6 8376 case SPE_BUILTIN_EVSTWWE:
5039610b 8377 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwe, exp);
a3170dc6 8378 case SPE_BUILTIN_EVSTWWO:
5039610b 8379 return spe_expand_stv_builtin (CODE_FOR_spe_evstwwo, exp);
a3170dc6
AH
8380 case SPE_BUILTIN_MFSPEFSCR:
8381 icode = CODE_FOR_spe_mfspefscr;
8382 tmode = insn_data[icode].operand[0].mode;
8383
8384 if (target == 0
8385 || GET_MODE (target) != tmode
8386 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8387 target = gen_reg_rtx (tmode);
f676971a 8388
a3170dc6
AH
8389 pat = GEN_FCN (icode) (target);
8390 if (! pat)
8391 return 0;
8392 emit_insn (pat);
8393 return target;
8394 case SPE_BUILTIN_MTSPEFSCR:
8395 icode = CODE_FOR_spe_mtspefscr;
5039610b 8396 arg0 = CALL_EXPR_ARG (exp, 0);
84217346 8397 op0 = expand_normal (arg0);
a3170dc6
AH
8398 mode0 = insn_data[icode].operand[0].mode;
8399
8400 if (arg0 == error_mark_node)
8401 return const0_rtx;
8402
8403 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
8404 op0 = copy_to_mode_reg (mode0, op0);
8405
8406 pat = GEN_FCN (icode) (op0);
8407 if (pat)
8408 emit_insn (pat);
8409 return NULL_RTX;
8410 default:
8411 break;
8412 }
8413
8414 *expandedp = false;
8415 return NULL_RTX;
8416}
8417
96038623
DE
8418static rtx
8419paired_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
8420{
8421 rtx pat, scratch, tmp;
8422 tree form = CALL_EXPR_ARG (exp, 0);
8423 tree arg0 = CALL_EXPR_ARG (exp, 1);
8424 tree arg1 = CALL_EXPR_ARG (exp, 2);
8425 rtx op0 = expand_normal (arg0);
8426 rtx op1 = expand_normal (arg1);
8427 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8428 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8429 int form_int;
8430 enum rtx_code code;
8431
8432 if (TREE_CODE (form) != INTEGER_CST)
8433 {
8434 error ("argument 1 of __builtin_paired_predicate must be a constant");
8435 return const0_rtx;
8436 }
8437 else
8438 form_int = TREE_INT_CST_LOW (form);
8439
8440 gcc_assert (mode0 == mode1);
8441
8442 if (arg0 == error_mark_node || arg1 == error_mark_node)
8443 return const0_rtx;
8444
8445 if (target == 0
8446 || GET_MODE (target) != SImode
8447 || !(*insn_data[icode].operand[0].predicate) (target, SImode))
8448 target = gen_reg_rtx (SImode);
8449 if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
8450 op0 = copy_to_mode_reg (mode0, op0);
8451 if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
8452 op1 = copy_to_mode_reg (mode1, op1);
8453
8454 scratch = gen_reg_rtx (CCFPmode);
8455
8456 pat = GEN_FCN (icode) (scratch, op0, op1);
8457 if (!pat)
8458 return const0_rtx;
8459
8460 emit_insn (pat);
8461
8462 switch (form_int)
8463 {
8464 /* LT bit. */
8465 case 0:
8466 code = LT;
8467 break;
8468 /* GT bit. */
8469 case 1:
8470 code = GT;
8471 break;
8472 /* EQ bit. */
8473 case 2:
8474 code = EQ;
8475 break;
8476 /* UN bit. */
8477 case 3:
8478 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8479 return target;
8480 default:
8481 error ("argument 1 of __builtin_paired_predicate is out of range");
8482 return const0_rtx;
8483 }
8484
8485 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8486 emit_move_insn (target, tmp);
8487 return target;
8488}
8489
a3170dc6 8490static rtx
5039610b 8491spe_expand_predicate_builtin (enum insn_code icode, tree exp, rtx target)
a3170dc6
AH
8492{
8493 rtx pat, scratch, tmp;
5039610b
SL
8494 tree form = CALL_EXPR_ARG (exp, 0);
8495 tree arg0 = CALL_EXPR_ARG (exp, 1);
8496 tree arg1 = CALL_EXPR_ARG (exp, 2);
84217346
MD
8497 rtx op0 = expand_normal (arg0);
8498 rtx op1 = expand_normal (arg1);
a3170dc6
AH
8499 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8500 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8501 int form_int;
8502 enum rtx_code code;
8503
8504 if (TREE_CODE (form) != INTEGER_CST)
8505 {
8506 error ("argument 1 of __builtin_spe_predicate must be a constant");
8507 return const0_rtx;
8508 }
8509 else
8510 form_int = TREE_INT_CST_LOW (form);
8511
37409796 8512 gcc_assert (mode0 == mode1);
a3170dc6
AH
8513
8514 if (arg0 == error_mark_node || arg1 == error_mark_node)
8515 return const0_rtx;
8516
8517 if (target == 0
8518 || GET_MODE (target) != SImode
8519 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
8520 target = gen_reg_rtx (SImode);
8521
8522 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8523 op0 = copy_to_mode_reg (mode0, op0);
8524 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
8525 op1 = copy_to_mode_reg (mode1, op1);
8526
8527 scratch = gen_reg_rtx (CCmode);
8528
8529 pat = GEN_FCN (icode) (scratch, op0, op1);
8530 if (! pat)
8531 return const0_rtx;
8532 emit_insn (pat);
8533
8534 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
8535 _lower_. We use one compare, but look in different bits of the
8536 CR for each variant.
8537
8538 There are 2 elements in each SPE simd type (upper/lower). The CR
8539 bits are set as follows:
8540
8541 BIT0 | BIT 1 | BIT 2 | BIT 3
8542 U | L | (U | L) | (U & L)
8543
8544 So, for an "all" relationship, BIT 3 would be set.
8545 For an "any" relationship, BIT 2 would be set. Etc.
8546
8547 Following traditional nomenclature, these bits map to:
8548
8549 BIT0 | BIT 1 | BIT 2 | BIT 3
8550 LT | GT | EQ | OV
8551
8552 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
8553 */
8554
8555 switch (form_int)
8556 {
8557 /* All variant. OV bit. */
8558 case 0:
8559 /* We need to get to the OV bit, which is the ORDERED bit. We
8560 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
992d08b1 8561 that's ugly and will make validate_condition_mode die.
a3170dc6
AH
8562 So let's just use another pattern. */
8563 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
8564 return target;
8565 /* Any variant. EQ bit. */
8566 case 1:
8567 code = EQ;
8568 break;
8569 /* Upper variant. LT bit. */
8570 case 2:
8571 code = LT;
8572 break;
8573 /* Lower variant. GT bit. */
8574 case 3:
8575 code = GT;
8576 break;
8577 default:
8578 error ("argument 1 of __builtin_spe_predicate is out of range");
8579 return const0_rtx;
8580 }
8581
8582 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
8583 emit_move_insn (target, tmp);
8584
8585 return target;
8586}
8587
8588/* The evsel builtins look like this:
8589
8590 e = __builtin_spe_evsel_OP (a, b, c, d);
8591
8592 and work like this:
8593
8594 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
8595 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
8596*/
8597
8598static rtx
5039610b 8599spe_expand_evsel_builtin (enum insn_code icode, tree exp, rtx target)
a3170dc6
AH
8600{
8601 rtx pat, scratch;
5039610b
SL
8602 tree arg0 = CALL_EXPR_ARG (exp, 0);
8603 tree arg1 = CALL_EXPR_ARG (exp, 1);
8604 tree arg2 = CALL_EXPR_ARG (exp, 2);
8605 tree arg3 = CALL_EXPR_ARG (exp, 3);
84217346
MD
8606 rtx op0 = expand_normal (arg0);
8607 rtx op1 = expand_normal (arg1);
8608 rtx op2 = expand_normal (arg2);
8609 rtx op3 = expand_normal (arg3);
a3170dc6
AH
8610 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
8611 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
8612
37409796 8613 gcc_assert (mode0 == mode1);
a3170dc6
AH
8614
8615 if (arg0 == error_mark_node || arg1 == error_mark_node
8616 || arg2 == error_mark_node || arg3 == error_mark_node)
8617 return const0_rtx;
8618
8619 if (target == 0
8620 || GET_MODE (target) != mode0
8621 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
8622 target = gen_reg_rtx (mode0);
8623
8624 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
8625 op0 = copy_to_mode_reg (mode0, op0);
8626 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
8627 op1 = copy_to_mode_reg (mode0, op1);
8628 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
8629 op2 = copy_to_mode_reg (mode0, op2);
8630 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
8631 op3 = copy_to_mode_reg (mode0, op3);
8632
8633 /* Generate the compare. */
8634 scratch = gen_reg_rtx (CCmode);
8635 pat = GEN_FCN (icode) (scratch, op0, op1);
8636 if (! pat)
8637 return const0_rtx;
8638 emit_insn (pat);
8639
8640 if (mode0 == V2SImode)
8641 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
8642 else
8643 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
8644
8645 return target;
8646}
8647
0ac081f6
AH
8648/* Expand an expression EXP that calls a built-in function,
8649 with result going to TARGET if that's convenient
8650 (and in mode MODE if that's convenient).
8651 SUBTARGET may be used as the target for computing one of EXP's operands.
8652 IGNORE is nonzero if the value is to be ignored. */
8653
8654static rtx
a2369ed3 8655rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
c4ad648e
AM
8656 enum machine_mode mode ATTRIBUTE_UNUSED,
8657 int ignore ATTRIBUTE_UNUSED)
0ac081f6 8658{
5039610b 8659 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
92898235 8660 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
586de218 8661 const struct builtin_description *d;
92898235
AH
8662 size_t i;
8663 rtx ret;
8664 bool success;
f676971a 8665
9c78b944
DE
8666 if (fcode == RS6000_BUILTIN_RECIP)
8667 return rs6000_expand_binop_builtin (CODE_FOR_recipdf3, exp, target);
8668
8669 if (fcode == RS6000_BUILTIN_RECIPF)
8670 return rs6000_expand_binop_builtin (CODE_FOR_recipsf3, exp, target);
8671
8672 if (fcode == RS6000_BUILTIN_RSQRTF)
8673 return rs6000_expand_unop_builtin (CODE_FOR_rsqrtsf2, exp, target);
8674
7ccf35ed
DN
8675 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_LOAD
8676 || fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8677 {
8678 int icode = (int) CODE_FOR_altivec_lvsr;
8679 enum machine_mode tmode = insn_data[icode].operand[0].mode;
8680 enum machine_mode mode = insn_data[icode].operand[1].mode;
8681 tree arg;
8682 rtx op, addr, pat;
8683
37409796 8684 gcc_assert (TARGET_ALTIVEC);
7ccf35ed 8685
5039610b 8686 arg = CALL_EXPR_ARG (exp, 0);
37409796 8687 gcc_assert (TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE);
7ccf35ed
DN
8688 op = expand_expr (arg, NULL_RTX, Pmode, EXPAND_NORMAL);
8689 addr = memory_address (mode, op);
8690 if (fcode == ALTIVEC_BUILTIN_MASK_FOR_STORE)
8691 op = addr;
8692 else
8693 {
8694 /* For the load case need to negate the address. */
8695 op = gen_reg_rtx (GET_MODE (addr));
8696 emit_insn (gen_rtx_SET (VOIDmode, op,
8697 gen_rtx_NEG (GET_MODE (addr), addr)));
c4ad648e 8698 }
7ccf35ed
DN
8699 op = gen_rtx_MEM (mode, op);
8700
8701 if (target == 0
8702 || GET_MODE (target) != tmode
8703 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
8704 target = gen_reg_rtx (tmode);
8705
8706 /*pat = gen_altivec_lvsr (target, op);*/
8707 pat = GEN_FCN (icode) (target, op);
8708 if (!pat)
8709 return 0;
8710 emit_insn (pat);
8711
8712 return target;
8713 }
5039610b
SL
8714
8715 /* FIXME: There's got to be a nicer way to handle this case than
8716 constructing a new CALL_EXPR. */
f57d17f1
TM
8717 if (fcode == ALTIVEC_BUILTIN_VCFUX
8718 || fcode == ALTIVEC_BUILTIN_VCFSX)
8719 {
5039610b
SL
8720 if (call_expr_nargs (exp) == 1)
8721 exp = build_call_nary (TREE_TYPE (exp), CALL_EXPR_FN (exp),
8722 2, CALL_EXPR_ARG (exp, 0), integer_zero_node);
982afe02 8723 }
7ccf35ed 8724
0ac081f6 8725 if (TARGET_ALTIVEC)
92898235
AH
8726 {
8727 ret = altivec_expand_builtin (exp, target, &success);
8728
a3170dc6
AH
8729 if (success)
8730 return ret;
8731 }
8732 if (TARGET_SPE)
8733 {
8734 ret = spe_expand_builtin (exp, target, &success);
8735
92898235
AH
8736 if (success)
8737 return ret;
8738 }
96038623
DE
8739 if (TARGET_PAIRED_FLOAT)
8740 {
8741 ret = paired_expand_builtin (exp, target, &success);
8742
8743 if (success)
8744 return ret;
8745 }
92898235 8746
96038623 8747 gcc_assert (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT);
bb8df8a6 8748
37409796
NS
8749 /* Handle simple unary operations. */
8750 d = (struct builtin_description *) bdesc_1arg;
8751 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
8752 if (d->code == fcode)
5039610b 8753 return rs6000_expand_unop_builtin (d->icode, exp, target);
bb8df8a6 8754
37409796
NS
8755 /* Handle simple binary operations. */
8756 d = (struct builtin_description *) bdesc_2arg;
8757 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
8758 if (d->code == fcode)
5039610b 8759 return rs6000_expand_binop_builtin (d->icode, exp, target);
0ac081f6 8760
37409796 8761 /* Handle simple ternary operations. */
586de218 8762 d = bdesc_3arg;
37409796
NS
8763 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
8764 if (d->code == fcode)
5039610b 8765 return rs6000_expand_ternop_builtin (d->icode, exp, target);
bb8df8a6 8766
37409796 8767 gcc_unreachable ();
0ac081f6
AH
8768}
8769
7c62e993
PB
8770static tree
8771build_opaque_vector_type (tree node, int nunits)
8772{
8773 node = copy_node (node);
8774 TYPE_MAIN_VARIANT (node) = node;
8775 return build_vector_type (node, nunits);
8776}
8777
0ac081f6 8778static void
863d938c 8779rs6000_init_builtins (void)
0ac081f6 8780{
4a5eab38
PB
8781 V2SI_type_node = build_vector_type (intSI_type_node, 2);
8782 V2SF_type_node = build_vector_type (float_type_node, 2);
8783 V4HI_type_node = build_vector_type (intHI_type_node, 4);
8784 V4SI_type_node = build_vector_type (intSI_type_node, 4);
8785 V4SF_type_node = build_vector_type (float_type_node, 4);
7e463bda 8786 V8HI_type_node = build_vector_type (intHI_type_node, 8);
4a5eab38
PB
8787 V16QI_type_node = build_vector_type (intQI_type_node, 16);
8788
8789 unsigned_V16QI_type_node = build_vector_type (unsigned_intQI_type_node, 16);
8790 unsigned_V8HI_type_node = build_vector_type (unsigned_intHI_type_node, 8);
8791 unsigned_V4SI_type_node = build_vector_type (unsigned_intSI_type_node, 4);
8792
7c62e993
PB
8793 opaque_V2SF_type_node = build_opaque_vector_type (float_type_node, 2);
8794 opaque_V2SI_type_node = build_opaque_vector_type (intSI_type_node, 2);
6035d635 8795 opaque_p_V2SI_type_node = build_pointer_type (opaque_V2SI_type_node);
58646b77 8796 opaque_V4SI_type_node = copy_node (V4SI_type_node);
3fdaa45a 8797
8bb418a3
ZL
8798 /* The 'vector bool ...' types must be kept distinct from 'vector unsigned ...'
8799 types, especially in C++ land. Similarly, 'vector pixel' is distinct from
8800 'vector unsigned short'. */
8801
8dd16ecc
NS
8802 bool_char_type_node = build_distinct_type_copy (unsigned_intQI_type_node);
8803 bool_short_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8804 bool_int_type_node = build_distinct_type_copy (unsigned_intSI_type_node);
8805 pixel_type_node = build_distinct_type_copy (unsigned_intHI_type_node);
8bb418a3 8806
58646b77
PB
8807 long_integer_type_internal_node = long_integer_type_node;
8808 long_unsigned_type_internal_node = long_unsigned_type_node;
8809 intQI_type_internal_node = intQI_type_node;
8810 uintQI_type_internal_node = unsigned_intQI_type_node;
8811 intHI_type_internal_node = intHI_type_node;
8812 uintHI_type_internal_node = unsigned_intHI_type_node;
8813 intSI_type_internal_node = intSI_type_node;
8814 uintSI_type_internal_node = unsigned_intSI_type_node;
8815 float_type_internal_node = float_type_node;
8816 void_type_internal_node = void_type_node;
8817
8bb418a3
ZL
8818 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8819 get_identifier ("__bool char"),
8820 bool_char_type_node));
8821 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8822 get_identifier ("__bool short"),
8823 bool_short_type_node));
8824 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8825 get_identifier ("__bool int"),
8826 bool_int_type_node));
8827 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8828 get_identifier ("__pixel"),
8829 pixel_type_node));
8830
4a5eab38
PB
8831 bool_V16QI_type_node = build_vector_type (bool_char_type_node, 16);
8832 bool_V8HI_type_node = build_vector_type (bool_short_type_node, 8);
8833 bool_V4SI_type_node = build_vector_type (bool_int_type_node, 4);
8834 pixel_V8HI_type_node = build_vector_type (pixel_type_node, 8);
8bb418a3
ZL
8835
8836 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8837 get_identifier ("__vector unsigned char"),
8838 unsigned_V16QI_type_node));
8839 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8840 get_identifier ("__vector signed char"),
8841 V16QI_type_node));
8842 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8843 get_identifier ("__vector __bool char"),
8844 bool_V16QI_type_node));
8845
8846 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8847 get_identifier ("__vector unsigned short"),
8848 unsigned_V8HI_type_node));
8849 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8850 get_identifier ("__vector signed short"),
8851 V8HI_type_node));
8852 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8853 get_identifier ("__vector __bool short"),
8854 bool_V8HI_type_node));
8855
8856 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8857 get_identifier ("__vector unsigned int"),
8858 unsigned_V4SI_type_node));
8859 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8860 get_identifier ("__vector signed int"),
8861 V4SI_type_node));
8862 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8863 get_identifier ("__vector __bool int"),
8864 bool_V4SI_type_node));
8865
8866 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8867 get_identifier ("__vector float"),
8868 V4SF_type_node));
8869 (*lang_hooks.decls.pushdecl) (build_decl (TYPE_DECL,
8870 get_identifier ("__vector __pixel"),
8871 pixel_V8HI_type_node));
8872
96038623
DE
8873 if (TARGET_PAIRED_FLOAT)
8874 paired_init_builtins ();
a3170dc6 8875 if (TARGET_SPE)
3fdaa45a 8876 spe_init_builtins ();
0ac081f6
AH
8877 if (TARGET_ALTIVEC)
8878 altivec_init_builtins ();
96038623 8879 if (TARGET_ALTIVEC || TARGET_SPE || TARGET_PAIRED_FLOAT)
0559cc77 8880 rs6000_common_init_builtins ();
9c78b944
DE
8881 if (TARGET_PPC_GFXOPT)
8882 {
8883 tree ftype = build_function_type_list (float_type_node,
8884 float_type_node,
8885 float_type_node,
8886 NULL_TREE);
8887 def_builtin (MASK_PPC_GFXOPT, "__builtin_recipdivf", ftype,
8888 RS6000_BUILTIN_RECIPF);
8889
8890 ftype = build_function_type_list (float_type_node,
8891 float_type_node,
8892 NULL_TREE);
8893 def_builtin (MASK_PPC_GFXOPT, "__builtin_rsqrtf", ftype,
8894 RS6000_BUILTIN_RSQRTF);
8895 }
8896 if (TARGET_POPCNTB)
8897 {
8898 tree ftype = build_function_type_list (double_type_node,
8899 double_type_node,
8900 double_type_node,
8901 NULL_TREE);
8902 def_builtin (MASK_POPCNTB, "__builtin_recipdiv", ftype,
8903 RS6000_BUILTIN_RECIP);
8904
8905 }
69ca3549
DE
8906
8907#if TARGET_XCOFF
8908 /* AIX libm provides clog as __clog. */
8909 if (built_in_decls [BUILT_IN_CLOG])
8910 set_user_assembler_name (built_in_decls [BUILT_IN_CLOG], "__clog");
8911#endif
0ac081f6
AH
8912}
8913
a3170dc6
AH
8914/* Search through a set of builtins and enable the mask bits.
8915 DESC is an array of builtins.
b6d08ca1 8916 SIZE is the total number of builtins.
a3170dc6
AH
8917 START is the builtin enum at which to start.
8918 END is the builtin enum at which to end. */
0ac081f6 8919static void
a2369ed3 8920enable_mask_for_builtins (struct builtin_description *desc, int size,
f676971a 8921 enum rs6000_builtins start,
a2369ed3 8922 enum rs6000_builtins end)
a3170dc6
AH
8923{
8924 int i;
8925
8926 for (i = 0; i < size; ++i)
8927 if (desc[i].code == start)
8928 break;
8929
8930 if (i == size)
8931 return;
8932
8933 for (; i < size; ++i)
8934 {
8935 /* Flip all the bits on. */
8936 desc[i].mask = target_flags;
8937 if (desc[i].code == end)
8938 break;
8939 }
8940}
8941
8942static void
863d938c 8943spe_init_builtins (void)
0ac081f6 8944{
a3170dc6
AH
8945 tree endlink = void_list_node;
8946 tree puint_type_node = build_pointer_type (unsigned_type_node);
8947 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
ae4b4a02 8948 struct builtin_description *d;
0ac081f6
AH
8949 size_t i;
8950
a3170dc6
AH
8951 tree v2si_ftype_4_v2si
8952 = build_function_type
3fdaa45a
AH
8953 (opaque_V2SI_type_node,
8954 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8955 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8956 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8957 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8958 endlink)))));
8959
8960 tree v2sf_ftype_4_v2sf
8961 = build_function_type
3fdaa45a
AH
8962 (opaque_V2SF_type_node,
8963 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8964 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8965 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8966 tree_cons (NULL_TREE, opaque_V2SF_type_node,
a3170dc6
AH
8967 endlink)))));
8968
8969 tree int_ftype_int_v2si_v2si
8970 = build_function_type
8971 (integer_type_node,
8972 tree_cons (NULL_TREE, integer_type_node,
3fdaa45a
AH
8973 tree_cons (NULL_TREE, opaque_V2SI_type_node,
8974 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8975 endlink))));
8976
8977 tree int_ftype_int_v2sf_v2sf
8978 = build_function_type
8979 (integer_type_node,
8980 tree_cons (NULL_TREE, integer_type_node,
3fdaa45a
AH
8981 tree_cons (NULL_TREE, opaque_V2SF_type_node,
8982 tree_cons (NULL_TREE, opaque_V2SF_type_node,
a3170dc6
AH
8983 endlink))));
8984
8985 tree void_ftype_v2si_puint_int
8986 = build_function_type (void_type_node,
3fdaa45a 8987 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8988 tree_cons (NULL_TREE, puint_type_node,
8989 tree_cons (NULL_TREE,
8990 integer_type_node,
8991 endlink))));
8992
8993 tree void_ftype_v2si_puint_char
8994 = build_function_type (void_type_node,
3fdaa45a 8995 tree_cons (NULL_TREE, opaque_V2SI_type_node,
a3170dc6
AH
8996 tree_cons (NULL_TREE, puint_type_node,
8997 tree_cons (NULL_TREE,
8998 char_type_node,
8999 endlink))));
9000
9001 tree void_ftype_v2si_pv2si_int
9002 = build_function_type (void_type_node,
3fdaa45a 9003 tree_cons (NULL_TREE, opaque_V2SI_type_node,
6035d635 9004 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
a3170dc6
AH
9005 tree_cons (NULL_TREE,
9006 integer_type_node,
9007 endlink))));
9008
9009 tree void_ftype_v2si_pv2si_char
9010 = build_function_type (void_type_node,
3fdaa45a 9011 tree_cons (NULL_TREE, opaque_V2SI_type_node,
6035d635 9012 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
a3170dc6
AH
9013 tree_cons (NULL_TREE,
9014 char_type_node,
9015 endlink))));
9016
9017 tree void_ftype_int
9018 = build_function_type (void_type_node,
9019 tree_cons (NULL_TREE, integer_type_node, endlink));
9020
9021 tree int_ftype_void
36e8d515 9022 = build_function_type (integer_type_node, endlink);
a3170dc6
AH
9023
9024 tree v2si_ftype_pv2si_int
3fdaa45a 9025 = build_function_type (opaque_V2SI_type_node,
6035d635 9026 tree_cons (NULL_TREE, opaque_p_V2SI_type_node,
a3170dc6
AH
9027 tree_cons (NULL_TREE, integer_type_node,
9028 endlink)));
9029
9030 tree v2si_ftype_puint_int
3fdaa45a 9031 = build_function_type (opaque_V2SI_type_node,
a3170dc6
AH
9032 tree_cons (NULL_TREE, puint_type_node,
9033 tree_cons (NULL_TREE, integer_type_node,
9034 endlink)));
9035
9036 tree v2si_ftype_pushort_int
3fdaa45a 9037 = build_function_type (opaque_V2SI_type_node,
a3170dc6
AH
9038 tree_cons (NULL_TREE, pushort_type_node,
9039 tree_cons (NULL_TREE, integer_type_node,
9040 endlink)));
9041
00332c9f
AH
9042 tree v2si_ftype_signed_char
9043 = build_function_type (opaque_V2SI_type_node,
9044 tree_cons (NULL_TREE, signed_char_type_node,
9045 endlink));
9046
a3170dc6
AH
9047 /* The initialization of the simple binary and unary builtins is
9048 done in rs6000_common_init_builtins, but we have to enable the
9049 mask bits here manually because we have run out of `target_flags'
9050 bits. We really need to redesign this mask business. */
9051
9052 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
9053 ARRAY_SIZE (bdesc_2arg),
9054 SPE_BUILTIN_EVADDW,
9055 SPE_BUILTIN_EVXOR);
9056 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
9057 ARRAY_SIZE (bdesc_1arg),
9058 SPE_BUILTIN_EVABS,
9059 SPE_BUILTIN_EVSUBFUSIAAW);
9060 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
9061 ARRAY_SIZE (bdesc_spe_predicates),
9062 SPE_BUILTIN_EVCMPEQ,
9063 SPE_BUILTIN_EVFSTSTLT);
9064 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
9065 ARRAY_SIZE (bdesc_spe_evsel),
9066 SPE_BUILTIN_EVSEL_CMPGTS,
9067 SPE_BUILTIN_EVSEL_FSTSTEQ);
9068
36252949
AH
9069 (*lang_hooks.decls.pushdecl)
9070 (build_decl (TYPE_DECL, get_identifier ("__ev64_opaque__"),
9071 opaque_V2SI_type_node));
9072
a3170dc6 9073 /* Initialize irregular SPE builtins. */
f676971a 9074
a3170dc6
AH
9075 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
9076 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
9077 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
9078 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
9079 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
9080 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
9081 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
9082 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
9083 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
9084 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
9085 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
9086 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
9087 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
9088 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
9089 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
9090 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
00332c9f
AH
9091 def_builtin (target_flags, "__builtin_spe_evsplatfi", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATFI);
9092 def_builtin (target_flags, "__builtin_spe_evsplati", v2si_ftype_signed_char, SPE_BUILTIN_EVSPLATI);
a3170dc6
AH
9093
9094 /* Loads. */
9095 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
9096 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
9097 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
9098 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
9099 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
9100 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
9101 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
9102 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
9103 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
9104 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
9105 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
9106 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
9107 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
9108 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
9109 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
9110 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
9111 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
9112 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
9113 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
9114 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
9115 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
9116 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
9117
9118 /* Predicates. */
9119 d = (struct builtin_description *) bdesc_spe_predicates;
9120 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
9121 {
9122 tree type;
9123
9124 switch (insn_data[d->icode].operand[1].mode)
9125 {
9126 case V2SImode:
9127 type = int_ftype_int_v2si_v2si;
9128 break;
9129 case V2SFmode:
9130 type = int_ftype_int_v2sf_v2sf;
9131 break;
9132 default:
37409796 9133 gcc_unreachable ();
a3170dc6
AH
9134 }
9135
9136 def_builtin (d->mask, d->name, type, d->code);
9137 }
9138
9139 /* Evsel predicates. */
9140 d = (struct builtin_description *) bdesc_spe_evsel;
9141 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
9142 {
9143 tree type;
9144
9145 switch (insn_data[d->icode].operand[1].mode)
9146 {
9147 case V2SImode:
9148 type = v2si_ftype_4_v2si;
9149 break;
9150 case V2SFmode:
9151 type = v2sf_ftype_4_v2sf;
9152 break;
9153 default:
37409796 9154 gcc_unreachable ();
a3170dc6
AH
9155 }
9156
9157 def_builtin (d->mask, d->name, type, d->code);
9158 }
9159}
9160
96038623
DE
9161static void
9162paired_init_builtins (void)
9163{
23a651fc 9164 const struct builtin_description *d;
96038623
DE
9165 size_t i;
9166 tree endlink = void_list_node;
9167
9168 tree int_ftype_int_v2sf_v2sf
9169 = build_function_type
9170 (integer_type_node,
9171 tree_cons (NULL_TREE, integer_type_node,
9172 tree_cons (NULL_TREE, V2SF_type_node,
9173 tree_cons (NULL_TREE, V2SF_type_node,
9174 endlink))));
9175 tree pcfloat_type_node =
9176 build_pointer_type (build_qualified_type
9177 (float_type_node, TYPE_QUAL_CONST));
9178
9179 tree v2sf_ftype_long_pcfloat = build_function_type_list (V2SF_type_node,
9180 long_integer_type_node,
9181 pcfloat_type_node,
9182 NULL_TREE);
9183 tree void_ftype_v2sf_long_pcfloat =
9184 build_function_type_list (void_type_node,
9185 V2SF_type_node,
9186 long_integer_type_node,
9187 pcfloat_type_node,
9188 NULL_TREE);
9189
9190
9191 def_builtin (0, "__builtin_paired_lx", v2sf_ftype_long_pcfloat,
9192 PAIRED_BUILTIN_LX);
9193
9194
9195 def_builtin (0, "__builtin_paired_stx", void_ftype_v2sf_long_pcfloat,
9196 PAIRED_BUILTIN_STX);
9197
9198 /* Predicates. */
23a651fc 9199 d = bdesc_paired_preds;
96038623
DE
9200 for (i = 0; i < ARRAY_SIZE (bdesc_paired_preds); ++i, d++)
9201 {
9202 tree type;
9203
9204 switch (insn_data[d->icode].operand[1].mode)
9205 {
9206 case V2SFmode:
9207 type = int_ftype_int_v2sf_v2sf;
9208 break;
9209 default:
9210 gcc_unreachable ();
9211 }
9212
9213 def_builtin (d->mask, d->name, type, d->code);
9214 }
9215}
9216
a3170dc6 9217static void
863d938c 9218altivec_init_builtins (void)
a3170dc6 9219{
586de218
KG
9220 const struct builtin_description *d;
9221 const struct builtin_description_predicates *dp;
a3170dc6 9222 size_t i;
7a4eca66
DE
9223 tree ftype;
9224
a3170dc6
AH
9225 tree pfloat_type_node = build_pointer_type (float_type_node);
9226 tree pint_type_node = build_pointer_type (integer_type_node);
9227 tree pshort_type_node = build_pointer_type (short_integer_type_node);
9228 tree pchar_type_node = build_pointer_type (char_type_node);
9229
9230 tree pvoid_type_node = build_pointer_type (void_type_node);
9231
0dbc3651
ZW
9232 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
9233 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
9234 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
9235 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
9236
9237 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
9238
58646b77
PB
9239 tree int_ftype_opaque
9240 = build_function_type_list (integer_type_node,
9241 opaque_V4SI_type_node, NULL_TREE);
9242
9243 tree opaque_ftype_opaque_int
9244 = build_function_type_list (opaque_V4SI_type_node,
9245 opaque_V4SI_type_node, integer_type_node, NULL_TREE);
9246 tree opaque_ftype_opaque_opaque_int
9247 = build_function_type_list (opaque_V4SI_type_node,
9248 opaque_V4SI_type_node, opaque_V4SI_type_node,
9249 integer_type_node, NULL_TREE);
9250 tree int_ftype_int_opaque_opaque
9251 = build_function_type_list (integer_type_node,
9252 integer_type_node, opaque_V4SI_type_node,
9253 opaque_V4SI_type_node, NULL_TREE);
a3170dc6
AH
9254 tree int_ftype_int_v4si_v4si
9255 = build_function_type_list (integer_type_node,
9256 integer_type_node, V4SI_type_node,
9257 V4SI_type_node, NULL_TREE);
0dbc3651
ZW
9258 tree v4sf_ftype_pcfloat
9259 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
a3170dc6 9260 tree void_ftype_pfloat_v4sf
b4de2f7d 9261 = build_function_type_list (void_type_node,
a3170dc6 9262 pfloat_type_node, V4SF_type_node, NULL_TREE);
0dbc3651
ZW
9263 tree v4si_ftype_pcint
9264 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
9265 tree void_ftype_pint_v4si
b4de2f7d
AH
9266 = build_function_type_list (void_type_node,
9267 pint_type_node, V4SI_type_node, NULL_TREE);
0dbc3651
ZW
9268 tree v8hi_ftype_pcshort
9269 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
f18c054f 9270 tree void_ftype_pshort_v8hi
b4de2f7d
AH
9271 = build_function_type_list (void_type_node,
9272 pshort_type_node, V8HI_type_node, NULL_TREE);
0dbc3651
ZW
9273 tree v16qi_ftype_pcchar
9274 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
f18c054f 9275 tree void_ftype_pchar_v16qi
b4de2f7d
AH
9276 = build_function_type_list (void_type_node,
9277 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 9278 tree void_ftype_v4si
b4de2f7d 9279 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
9280 tree v8hi_ftype_void
9281 = build_function_type (V8HI_type_node, void_list_node);
9282 tree void_ftype_void
9283 = build_function_type (void_type_node, void_list_node);
e34b6648
JJ
9284 tree void_ftype_int
9285 = build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
0dbc3651 9286
58646b77
PB
9287 tree opaque_ftype_long_pcvoid
9288 = build_function_type_list (opaque_V4SI_type_node,
9289 long_integer_type_node, pcvoid_type_node, NULL_TREE);
b4a62fa0 9290 tree v16qi_ftype_long_pcvoid
a3170dc6 9291 = build_function_type_list (V16QI_type_node,
b4a62fa0
SB
9292 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9293 tree v8hi_ftype_long_pcvoid
a3170dc6 9294 = build_function_type_list (V8HI_type_node,
b4a62fa0
SB
9295 long_integer_type_node, pcvoid_type_node, NULL_TREE);
9296 tree v4si_ftype_long_pcvoid
a3170dc6 9297 = build_function_type_list (V4SI_type_node,
b4a62fa0 9298 long_integer_type_node, pcvoid_type_node, NULL_TREE);
0dbc3651 9299
58646b77
PB
9300 tree void_ftype_opaque_long_pvoid
9301 = build_function_type_list (void_type_node,
9302 opaque_V4SI_type_node, long_integer_type_node,
9303 pvoid_type_node, NULL_TREE);
b4a62fa0 9304 tree void_ftype_v4si_long_pvoid
b4de2f7d 9305 = build_function_type_list (void_type_node,
b4a62fa0 9306 V4SI_type_node, long_integer_type_node,
b4de2f7d 9307 pvoid_type_node, NULL_TREE);
b4a62fa0 9308 tree void_ftype_v16qi_long_pvoid
b4de2f7d 9309 = build_function_type_list (void_type_node,
b4a62fa0 9310 V16QI_type_node, long_integer_type_node,
b4de2f7d 9311 pvoid_type_node, NULL_TREE);
b4a62fa0 9312 tree void_ftype_v8hi_long_pvoid
b4de2f7d 9313 = build_function_type_list (void_type_node,
b4a62fa0 9314 V8HI_type_node, long_integer_type_node,
b4de2f7d 9315 pvoid_type_node, NULL_TREE);
a3170dc6
AH
9316 tree int_ftype_int_v8hi_v8hi
9317 = build_function_type_list (integer_type_node,
9318 integer_type_node, V8HI_type_node,
9319 V8HI_type_node, NULL_TREE);
9320 tree int_ftype_int_v16qi_v16qi
9321 = build_function_type_list (integer_type_node,
9322 integer_type_node, V16QI_type_node,
9323 V16QI_type_node, NULL_TREE);
9324 tree int_ftype_int_v4sf_v4sf
9325 = build_function_type_list (integer_type_node,
9326 integer_type_node, V4SF_type_node,
9327 V4SF_type_node, NULL_TREE);
9328 tree v4si_ftype_v4si
9329 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
9330 tree v8hi_ftype_v8hi
9331 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
9332 tree v16qi_ftype_v16qi
9333 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
9334 tree v4sf_ftype_v4sf
9335 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
8bb418a3 9336 tree void_ftype_pcvoid_int_int
a3170dc6 9337 = build_function_type_list (void_type_node,
0dbc3651 9338 pcvoid_type_node, integer_type_node,
8bb418a3 9339 integer_type_node, NULL_TREE);
8bb418a3 9340
0dbc3651
ZW
9341 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
9342 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
9343 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
9344 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
9345 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
9346 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
9347 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
9348 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
9349 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
9350 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
9351 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
9352 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
9353 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
9354 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
9355 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
9356 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
a3170dc6
AH
9357 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
9358 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
9359 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
e34b6648 9360 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_int, ALTIVEC_BUILTIN_DSS);
b4a62fa0
SB
9361 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSL);
9362 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVSR);
9363 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEBX);
9364 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEHX);
9365 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVEWX);
9366 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVXL);
9367 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVX);
9368 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVX);
9369 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVEWX);
9370 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_long_pvoid, ALTIVEC_BUILTIN_STVXL);
9371 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_long_pvoid, ALTIVEC_BUILTIN_STVEBX);
9372 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_long_pvoid, ALTIVEC_BUILTIN_STVEHX);
58646b77
PB
9373 def_builtin (MASK_ALTIVEC, "__builtin_vec_ld", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LD);
9374 def_builtin (MASK_ALTIVEC, "__builtin_vec_lde", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDE);
9375 def_builtin (MASK_ALTIVEC, "__builtin_vec_ldl", opaque_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LDL);
9376 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsl", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSL);
9377 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvsr", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVSR);
9378 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvebx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEBX);
9379 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvehx", v8hi_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEHX);
9380 def_builtin (MASK_ALTIVEC, "__builtin_vec_lvewx", v4si_ftype_long_pcvoid, ALTIVEC_BUILTIN_VEC_LVEWX);
9381 def_builtin (MASK_ALTIVEC, "__builtin_vec_st", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_ST);
9382 def_builtin (MASK_ALTIVEC, "__builtin_vec_ste", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STE);
9383 def_builtin (MASK_ALTIVEC, "__builtin_vec_stl", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STL);
9384 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvewx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEWX);
9385 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvebx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEBX);
9386 def_builtin (MASK_ALTIVEC, "__builtin_vec_stvehx", void_ftype_opaque_long_pvoid, ALTIVEC_BUILTIN_VEC_STVEHX);
9387
9388 def_builtin (MASK_ALTIVEC, "__builtin_vec_step", int_ftype_opaque, ALTIVEC_BUILTIN_VEC_STEP);
9389
9390 def_builtin (MASK_ALTIVEC, "__builtin_vec_sld", opaque_ftype_opaque_opaque_int, ALTIVEC_BUILTIN_VEC_SLD);
9391 def_builtin (MASK_ALTIVEC, "__builtin_vec_splat", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_SPLAT);
9392 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltw", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTW);
9393 def_builtin (MASK_ALTIVEC, "__builtin_vec_vsplth", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTH);
9394 def_builtin (MASK_ALTIVEC, "__builtin_vec_vspltb", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VSPLTB);
9395 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctf", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTF);
9396 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfsx", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFSX);
9397 def_builtin (MASK_ALTIVEC, "__builtin_vec_vcfux", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_VCFUX);
9398 def_builtin (MASK_ALTIVEC, "__builtin_vec_cts", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTS);
9399 def_builtin (MASK_ALTIVEC, "__builtin_vec_ctu", opaque_ftype_opaque_int, ALTIVEC_BUILTIN_VEC_CTU);
8bb418a3 9400
a3170dc6 9401 /* Add the DST variants. */
586de218 9402 d = bdesc_dst;
a3170dc6 9403 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
8bb418a3 9404 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_int, d->code);
a3170dc6
AH
9405
9406 /* Initialize the predicates. */
586de218 9407 dp = bdesc_altivec_preds;
a3170dc6
AH
9408 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
9409 {
9410 enum machine_mode mode1;
9411 tree type;
58646b77
PB
9412 bool is_overloaded = dp->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9413 && dp->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
a3170dc6 9414
58646b77
PB
9415 if (is_overloaded)
9416 mode1 = VOIDmode;
9417 else
9418 mode1 = insn_data[dp->icode].operand[1].mode;
a3170dc6
AH
9419
9420 switch (mode1)
9421 {
58646b77
PB
9422 case VOIDmode:
9423 type = int_ftype_int_opaque_opaque;
9424 break;
a3170dc6
AH
9425 case V4SImode:
9426 type = int_ftype_int_v4si_v4si;
9427 break;
9428 case V8HImode:
9429 type = int_ftype_int_v8hi_v8hi;
9430 break;
9431 case V16QImode:
9432 type = int_ftype_int_v16qi_v16qi;
9433 break;
9434 case V4SFmode:
9435 type = int_ftype_int_v4sf_v4sf;
9436 break;
9437 default:
37409796 9438 gcc_unreachable ();
a3170dc6 9439 }
f676971a 9440
a3170dc6
AH
9441 def_builtin (dp->mask, dp->name, type, dp->code);
9442 }
9443
9444 /* Initialize the abs* operators. */
586de218 9445 d = bdesc_abs;
a3170dc6
AH
9446 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
9447 {
9448 enum machine_mode mode0;
9449 tree type;
9450
9451 mode0 = insn_data[d->icode].operand[0].mode;
9452
9453 switch (mode0)
9454 {
9455 case V4SImode:
9456 type = v4si_ftype_v4si;
9457 break;
9458 case V8HImode:
9459 type = v8hi_ftype_v8hi;
9460 break;
9461 case V16QImode:
9462 type = v16qi_ftype_v16qi;
9463 break;
9464 case V4SFmode:
9465 type = v4sf_ftype_v4sf;
9466 break;
9467 default:
37409796 9468 gcc_unreachable ();
a3170dc6 9469 }
f676971a 9470
a3170dc6
AH
9471 def_builtin (d->mask, d->name, type, d->code);
9472 }
7ccf35ed 9473
13c62176
DN
9474 if (TARGET_ALTIVEC)
9475 {
9476 tree decl;
9477
9478 /* Initialize target builtin that implements
9479 targetm.vectorize.builtin_mask_for_load. */
9480
c79efc4d
RÁE
9481 decl = add_builtin_function ("__builtin_altivec_mask_for_load",
9482 v16qi_ftype_long_pcvoid,
9483 ALTIVEC_BUILTIN_MASK_FOR_LOAD,
61210b72
AP
9484 BUILT_IN_MD, NULL, NULL_TREE);
9485 TREE_READONLY (decl) = 1;
13c62176
DN
9486 /* Record the decl. Will be used by rs6000_builtin_mask_for_load. */
9487 altivec_builtin_mask_for_load = decl;
13c62176 9488 }
7a4eca66
DE
9489
9490 /* Access to the vec_init patterns. */
9491 ftype = build_function_type_list (V4SI_type_node, integer_type_node,
9492 integer_type_node, integer_type_node,
9493 integer_type_node, NULL_TREE);
9494 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4si", ftype,
9495 ALTIVEC_BUILTIN_VEC_INIT_V4SI);
9496
9497 ftype = build_function_type_list (V8HI_type_node, short_integer_type_node,
9498 short_integer_type_node,
9499 short_integer_type_node,
9500 short_integer_type_node,
9501 short_integer_type_node,
9502 short_integer_type_node,
9503 short_integer_type_node,
9504 short_integer_type_node, NULL_TREE);
9505 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v8hi", ftype,
9506 ALTIVEC_BUILTIN_VEC_INIT_V8HI);
9507
9508 ftype = build_function_type_list (V16QI_type_node, char_type_node,
9509 char_type_node, char_type_node,
9510 char_type_node, char_type_node,
9511 char_type_node, char_type_node,
9512 char_type_node, char_type_node,
9513 char_type_node, char_type_node,
9514 char_type_node, char_type_node,
9515 char_type_node, char_type_node,
9516 char_type_node, NULL_TREE);
9517 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v16qi", ftype,
9518 ALTIVEC_BUILTIN_VEC_INIT_V16QI);
9519
9520 ftype = build_function_type_list (V4SF_type_node, float_type_node,
9521 float_type_node, float_type_node,
9522 float_type_node, NULL_TREE);
9523 def_builtin (MASK_ALTIVEC, "__builtin_vec_init_v4sf", ftype,
9524 ALTIVEC_BUILTIN_VEC_INIT_V4SF);
9525
9526 /* Access to the vec_set patterns. */
9527 ftype = build_function_type_list (V4SI_type_node, V4SI_type_node,
9528 intSI_type_node,
9529 integer_type_node, NULL_TREE);
9530 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4si", ftype,
9531 ALTIVEC_BUILTIN_VEC_SET_V4SI);
9532
9533 ftype = build_function_type_list (V8HI_type_node, V8HI_type_node,
9534 intHI_type_node,
9535 integer_type_node, NULL_TREE);
9536 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v8hi", ftype,
9537 ALTIVEC_BUILTIN_VEC_SET_V8HI);
9538
9539 ftype = build_function_type_list (V8HI_type_node, V16QI_type_node,
9540 intQI_type_node,
9541 integer_type_node, NULL_TREE);
9542 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v16qi", ftype,
9543 ALTIVEC_BUILTIN_VEC_SET_V16QI);
9544
9545 ftype = build_function_type_list (V4SF_type_node, V4SF_type_node,
9546 float_type_node,
9547 integer_type_node, NULL_TREE);
9548 def_builtin (MASK_ALTIVEC, "__builtin_vec_set_v4sf", ftype,
9549 ALTIVEC_BUILTIN_VEC_SET_V4SF);
9550
9551 /* Access to the vec_extract patterns. */
9552 ftype = build_function_type_list (intSI_type_node, V4SI_type_node,
9553 integer_type_node, NULL_TREE);
9554 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4si", ftype,
9555 ALTIVEC_BUILTIN_VEC_EXT_V4SI);
9556
9557 ftype = build_function_type_list (intHI_type_node, V8HI_type_node,
9558 integer_type_node, NULL_TREE);
9559 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v8hi", ftype,
9560 ALTIVEC_BUILTIN_VEC_EXT_V8HI);
9561
9562 ftype = build_function_type_list (intQI_type_node, V16QI_type_node,
9563 integer_type_node, NULL_TREE);
9564 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v16qi", ftype,
9565 ALTIVEC_BUILTIN_VEC_EXT_V16QI);
9566
9567 ftype = build_function_type_list (float_type_node, V4SF_type_node,
9568 integer_type_node, NULL_TREE);
9569 def_builtin (MASK_ALTIVEC, "__builtin_vec_ext_v4sf", ftype,
9570 ALTIVEC_BUILTIN_VEC_EXT_V4SF);
a3170dc6
AH
9571}
9572
9573static void
863d938c 9574rs6000_common_init_builtins (void)
a3170dc6 9575{
586de218 9576 const struct builtin_description *d;
a3170dc6
AH
9577 size_t i;
9578
96038623
DE
9579 tree v2sf_ftype_v2sf_v2sf_v2sf
9580 = build_function_type_list (V2SF_type_node,
9581 V2SF_type_node, V2SF_type_node,
9582 V2SF_type_node, NULL_TREE);
9583
a3170dc6
AH
9584 tree v4sf_ftype_v4sf_v4sf_v16qi
9585 = build_function_type_list (V4SF_type_node,
9586 V4SF_type_node, V4SF_type_node,
9587 V16QI_type_node, NULL_TREE);
9588 tree v4si_ftype_v4si_v4si_v16qi
9589 = build_function_type_list (V4SI_type_node,
9590 V4SI_type_node, V4SI_type_node,
9591 V16QI_type_node, NULL_TREE);
9592 tree v8hi_ftype_v8hi_v8hi_v16qi
9593 = build_function_type_list (V8HI_type_node,
9594 V8HI_type_node, V8HI_type_node,
9595 V16QI_type_node, NULL_TREE);
9596 tree v16qi_ftype_v16qi_v16qi_v16qi
9597 = build_function_type_list (V16QI_type_node,
9598 V16QI_type_node, V16QI_type_node,
9599 V16QI_type_node, NULL_TREE);
b9e4e5d1
ZL
9600 tree v4si_ftype_int
9601 = build_function_type_list (V4SI_type_node, integer_type_node, NULL_TREE);
9602 tree v8hi_ftype_int
9603 = build_function_type_list (V8HI_type_node, integer_type_node, NULL_TREE);
9604 tree v16qi_ftype_int
9605 = build_function_type_list (V16QI_type_node, integer_type_node, NULL_TREE);
a3170dc6
AH
9606 tree v8hi_ftype_v16qi
9607 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
9608 tree v4sf_ftype_v4sf
9609 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
9610
9611 tree v2si_ftype_v2si_v2si
2abe3e28
AH
9612 = build_function_type_list (opaque_V2SI_type_node,
9613 opaque_V2SI_type_node,
9614 opaque_V2SI_type_node, NULL_TREE);
a3170dc6 9615
96038623 9616 tree v2sf_ftype_v2sf_v2sf_spe
2abe3e28
AH
9617 = build_function_type_list (opaque_V2SF_type_node,
9618 opaque_V2SF_type_node,
9619 opaque_V2SF_type_node, NULL_TREE);
a3170dc6 9620
96038623
DE
9621 tree v2sf_ftype_v2sf_v2sf
9622 = build_function_type_list (V2SF_type_node,
9623 V2SF_type_node,
9624 V2SF_type_node, NULL_TREE);
9625
9626
a3170dc6 9627 tree v2si_ftype_int_int
2abe3e28 9628 = build_function_type_list (opaque_V2SI_type_node,
a3170dc6
AH
9629 integer_type_node, integer_type_node,
9630 NULL_TREE);
9631
58646b77
PB
9632 tree opaque_ftype_opaque
9633 = build_function_type_list (opaque_V4SI_type_node,
9634 opaque_V4SI_type_node, NULL_TREE);
9635
a3170dc6 9636 tree v2si_ftype_v2si
2abe3e28
AH
9637 = build_function_type_list (opaque_V2SI_type_node,
9638 opaque_V2SI_type_node, NULL_TREE);
a3170dc6 9639
96038623 9640 tree v2sf_ftype_v2sf_spe
2abe3e28
AH
9641 = build_function_type_list (opaque_V2SF_type_node,
9642 opaque_V2SF_type_node, NULL_TREE);
f676971a 9643
96038623
DE
9644 tree v2sf_ftype_v2sf
9645 = build_function_type_list (V2SF_type_node,
9646 V2SF_type_node, NULL_TREE);
9647
a3170dc6 9648 tree v2sf_ftype_v2si
2abe3e28
AH
9649 = build_function_type_list (opaque_V2SF_type_node,
9650 opaque_V2SI_type_node, NULL_TREE);
a3170dc6
AH
9651
9652 tree v2si_ftype_v2sf
2abe3e28
AH
9653 = build_function_type_list (opaque_V2SI_type_node,
9654 opaque_V2SF_type_node, NULL_TREE);
a3170dc6
AH
9655
9656 tree v2si_ftype_v2si_char
2abe3e28
AH
9657 = build_function_type_list (opaque_V2SI_type_node,
9658 opaque_V2SI_type_node,
9659 char_type_node, NULL_TREE);
a3170dc6
AH
9660
9661 tree v2si_ftype_int_char
2abe3e28 9662 = build_function_type_list (opaque_V2SI_type_node,
a3170dc6
AH
9663 integer_type_node, char_type_node, NULL_TREE);
9664
9665 tree v2si_ftype_char
2abe3e28
AH
9666 = build_function_type_list (opaque_V2SI_type_node,
9667 char_type_node, NULL_TREE);
a3170dc6
AH
9668
9669 tree int_ftype_int_int
9670 = build_function_type_list (integer_type_node,
9671 integer_type_node, integer_type_node,
9672 NULL_TREE);
95385cbb 9673
58646b77
PB
9674 tree opaque_ftype_opaque_opaque
9675 = build_function_type_list (opaque_V4SI_type_node,
9676 opaque_V4SI_type_node, opaque_V4SI_type_node, NULL_TREE);
0ac081f6 9677 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
9678 = build_function_type_list (V4SI_type_node,
9679 V4SI_type_node, V4SI_type_node, NULL_TREE);
b9e4e5d1 9680 tree v4sf_ftype_v4si_int
b4de2f7d 9681 = build_function_type_list (V4SF_type_node,
b9e4e5d1
ZL
9682 V4SI_type_node, integer_type_node, NULL_TREE);
9683 tree v4si_ftype_v4sf_int
b4de2f7d 9684 = build_function_type_list (V4SI_type_node,
b9e4e5d1
ZL
9685 V4SF_type_node, integer_type_node, NULL_TREE);
9686 tree v4si_ftype_v4si_int
b4de2f7d 9687 = build_function_type_list (V4SI_type_node,
b9e4e5d1
ZL
9688 V4SI_type_node, integer_type_node, NULL_TREE);
9689 tree v8hi_ftype_v8hi_int
b4de2f7d 9690 = build_function_type_list (V8HI_type_node,
b9e4e5d1
ZL
9691 V8HI_type_node, integer_type_node, NULL_TREE);
9692 tree v16qi_ftype_v16qi_int
b4de2f7d 9693 = build_function_type_list (V16QI_type_node,
b9e4e5d1
ZL
9694 V16QI_type_node, integer_type_node, NULL_TREE);
9695 tree v16qi_ftype_v16qi_v16qi_int
b4de2f7d
AH
9696 = build_function_type_list (V16QI_type_node,
9697 V16QI_type_node, V16QI_type_node,
b9e4e5d1
ZL
9698 integer_type_node, NULL_TREE);
9699 tree v8hi_ftype_v8hi_v8hi_int
b4de2f7d
AH
9700 = build_function_type_list (V8HI_type_node,
9701 V8HI_type_node, V8HI_type_node,
b9e4e5d1
ZL
9702 integer_type_node, NULL_TREE);
9703 tree v4si_ftype_v4si_v4si_int
b4de2f7d
AH
9704 = build_function_type_list (V4SI_type_node,
9705 V4SI_type_node, V4SI_type_node,
b9e4e5d1
ZL
9706 integer_type_node, NULL_TREE);
9707 tree v4sf_ftype_v4sf_v4sf_int
b4de2f7d
AH
9708 = build_function_type_list (V4SF_type_node,
9709 V4SF_type_node, V4SF_type_node,
b9e4e5d1 9710 integer_type_node, NULL_TREE);
0ac081f6 9711 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
9712 = build_function_type_list (V4SF_type_node,
9713 V4SF_type_node, V4SF_type_node, NULL_TREE);
58646b77
PB
9714 tree opaque_ftype_opaque_opaque_opaque
9715 = build_function_type_list (opaque_V4SI_type_node,
9716 opaque_V4SI_type_node, opaque_V4SI_type_node,
9717 opaque_V4SI_type_node, NULL_TREE);
617e0e1d 9718 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
9719 = build_function_type_list (V4SF_type_node,
9720 V4SF_type_node, V4SF_type_node,
9721 V4SI_type_node, NULL_TREE);
2212663f 9722 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
9723 = build_function_type_list (V4SF_type_node,
9724 V4SF_type_node, V4SF_type_node,
9725 V4SF_type_node, NULL_TREE);
f676971a 9726 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
9727 = build_function_type_list (V4SI_type_node,
9728 V4SI_type_node, V4SI_type_node,
9729 V4SI_type_node, NULL_TREE);
0ac081f6 9730 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
9731 = build_function_type_list (V8HI_type_node,
9732 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 9733 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
9734 = build_function_type_list (V8HI_type_node,
9735 V8HI_type_node, V8HI_type_node,
9736 V8HI_type_node, NULL_TREE);
c4ad648e 9737 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
9738 = build_function_type_list (V4SI_type_node,
9739 V8HI_type_node, V8HI_type_node,
9740 V4SI_type_node, NULL_TREE);
c4ad648e 9741 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
9742 = build_function_type_list (V4SI_type_node,
9743 V16QI_type_node, V16QI_type_node,
9744 V4SI_type_node, NULL_TREE);
0ac081f6 9745 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
9746 = build_function_type_list (V16QI_type_node,
9747 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 9748 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
9749 = build_function_type_list (V4SI_type_node,
9750 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 9751 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
9752 = build_function_type_list (V8HI_type_node,
9753 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 9754 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
9755 = build_function_type_list (V4SI_type_node,
9756 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 9757 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
9758 = build_function_type_list (V8HI_type_node,
9759 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 9760 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
9761 = build_function_type_list (V16QI_type_node,
9762 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 9763 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
9764 = build_function_type_list (V4SI_type_node,
9765 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 9766 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
9767 = build_function_type_list (V4SI_type_node,
9768 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 9769 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
9770 = build_function_type_list (V4SI_type_node,
9771 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
9772 tree v4si_ftype_v8hi
9773 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
9774 tree int_ftype_v4si_v4si
9775 = build_function_type_list (integer_type_node,
9776 V4SI_type_node, V4SI_type_node, NULL_TREE);
9777 tree int_ftype_v4sf_v4sf
9778 = build_function_type_list (integer_type_node,
9779 V4SF_type_node, V4SF_type_node, NULL_TREE);
9780 tree int_ftype_v16qi_v16qi
9781 = build_function_type_list (integer_type_node,
9782 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 9783 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
9784 = build_function_type_list (integer_type_node,
9785 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 9786
6f317ef3 9787 /* Add the simple ternary operators. */
586de218 9788 d = bdesc_3arg;
ca7558fc 9789 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f 9790 {
2212663f
DB
9791 enum machine_mode mode0, mode1, mode2, mode3;
9792 tree type;
58646b77
PB
9793 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9794 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
2212663f 9795
58646b77
PB
9796 if (is_overloaded)
9797 {
9798 mode0 = VOIDmode;
9799 mode1 = VOIDmode;
9800 mode2 = VOIDmode;
9801 mode3 = VOIDmode;
9802 }
9803 else
9804 {
9805 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9806 continue;
f676971a 9807
58646b77
PB
9808 mode0 = insn_data[d->icode].operand[0].mode;
9809 mode1 = insn_data[d->icode].operand[1].mode;
9810 mode2 = insn_data[d->icode].operand[2].mode;
9811 mode3 = insn_data[d->icode].operand[3].mode;
9812 }
bb8df8a6 9813
2212663f
DB
9814 /* When all four are of the same mode. */
9815 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
9816 {
9817 switch (mode0)
9818 {
58646b77
PB
9819 case VOIDmode:
9820 type = opaque_ftype_opaque_opaque_opaque;
9821 break;
617e0e1d
DB
9822 case V4SImode:
9823 type = v4si_ftype_v4si_v4si_v4si;
9824 break;
2212663f
DB
9825 case V4SFmode:
9826 type = v4sf_ftype_v4sf_v4sf_v4sf;
9827 break;
9828 case V8HImode:
9829 type = v8hi_ftype_v8hi_v8hi_v8hi;
f676971a 9830 break;
2212663f
DB
9831 case V16QImode:
9832 type = v16qi_ftype_v16qi_v16qi_v16qi;
f676971a 9833 break;
96038623
DE
9834 case V2SFmode:
9835 type = v2sf_ftype_v2sf_v2sf_v2sf;
9836 break;
2212663f 9837 default:
37409796 9838 gcc_unreachable ();
2212663f
DB
9839 }
9840 }
9841 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
c4ad648e 9842 {
2212663f
DB
9843 switch (mode0)
9844 {
9845 case V4SImode:
9846 type = v4si_ftype_v4si_v4si_v16qi;
9847 break;
9848 case V4SFmode:
9849 type = v4sf_ftype_v4sf_v4sf_v16qi;
9850 break;
9851 case V8HImode:
9852 type = v8hi_ftype_v8hi_v8hi_v16qi;
f676971a 9853 break;
2212663f
DB
9854 case V16QImode:
9855 type = v16qi_ftype_v16qi_v16qi_v16qi;
f676971a 9856 break;
2212663f 9857 default:
37409796 9858 gcc_unreachable ();
2212663f
DB
9859 }
9860 }
f676971a 9861 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
2212663f 9862 && mode3 == V4SImode)
24408032 9863 type = v4si_ftype_v16qi_v16qi_v4si;
f676971a 9864 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
2212663f 9865 && mode3 == V4SImode)
24408032 9866 type = v4si_ftype_v8hi_v8hi_v4si;
f676971a 9867 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
617e0e1d 9868 && mode3 == V4SImode)
24408032
AH
9869 type = v4sf_ftype_v4sf_v4sf_v4si;
9870
a7b376ee 9871 /* vchar, vchar, vchar, 4-bit literal. */
24408032
AH
9872 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
9873 && mode3 == QImode)
b9e4e5d1 9874 type = v16qi_ftype_v16qi_v16qi_int;
24408032 9875
a7b376ee 9876 /* vshort, vshort, vshort, 4-bit literal. */
24408032
AH
9877 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
9878 && mode3 == QImode)
b9e4e5d1 9879 type = v8hi_ftype_v8hi_v8hi_int;
24408032 9880
a7b376ee 9881 /* vint, vint, vint, 4-bit literal. */
24408032
AH
9882 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
9883 && mode3 == QImode)
b9e4e5d1 9884 type = v4si_ftype_v4si_v4si_int;
24408032 9885
a7b376ee 9886 /* vfloat, vfloat, vfloat, 4-bit literal. */
24408032
AH
9887 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
9888 && mode3 == QImode)
b9e4e5d1 9889 type = v4sf_ftype_v4sf_v4sf_int;
24408032 9890
2212663f 9891 else
37409796 9892 gcc_unreachable ();
2212663f
DB
9893
9894 def_builtin (d->mask, d->name, type, d->code);
9895 }
9896
0ac081f6 9897 /* Add the simple binary operators. */
00b960c7 9898 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 9899 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
9900 {
9901 enum machine_mode mode0, mode1, mode2;
9902 tree type;
58646b77
PB
9903 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
9904 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
0ac081f6 9905
58646b77
PB
9906 if (is_overloaded)
9907 {
9908 mode0 = VOIDmode;
9909 mode1 = VOIDmode;
9910 mode2 = VOIDmode;
9911 }
9912 else
bb8df8a6 9913 {
58646b77
PB
9914 if (d->name == 0 || d->icode == CODE_FOR_nothing)
9915 continue;
f676971a 9916
58646b77
PB
9917 mode0 = insn_data[d->icode].operand[0].mode;
9918 mode1 = insn_data[d->icode].operand[1].mode;
9919 mode2 = insn_data[d->icode].operand[2].mode;
9920 }
0ac081f6
AH
9921
9922 /* When all three operands are of the same mode. */
9923 if (mode0 == mode1 && mode1 == mode2)
9924 {
9925 switch (mode0)
9926 {
58646b77
PB
9927 case VOIDmode:
9928 type = opaque_ftype_opaque_opaque;
9929 break;
0ac081f6
AH
9930 case V4SFmode:
9931 type = v4sf_ftype_v4sf_v4sf;
9932 break;
9933 case V4SImode:
9934 type = v4si_ftype_v4si_v4si;
9935 break;
9936 case V16QImode:
9937 type = v16qi_ftype_v16qi_v16qi;
9938 break;
9939 case V8HImode:
9940 type = v8hi_ftype_v8hi_v8hi;
9941 break;
a3170dc6
AH
9942 case V2SImode:
9943 type = v2si_ftype_v2si_v2si;
9944 break;
96038623
DE
9945 case V2SFmode:
9946 if (TARGET_PAIRED_FLOAT)
9947 type = v2sf_ftype_v2sf_v2sf;
9948 else
9949 type = v2sf_ftype_v2sf_v2sf_spe;
a3170dc6
AH
9950 break;
9951 case SImode:
9952 type = int_ftype_int_int;
9953 break;
0ac081f6 9954 default:
37409796 9955 gcc_unreachable ();
0ac081f6
AH
9956 }
9957 }
9958
9959 /* A few other combos we really don't want to do manually. */
9960
9961 /* vint, vfloat, vfloat. */
9962 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
9963 type = v4si_ftype_v4sf_v4sf;
9964
9965 /* vshort, vchar, vchar. */
9966 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
9967 type = v8hi_ftype_v16qi_v16qi;
9968
9969 /* vint, vshort, vshort. */
9970 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
9971 type = v4si_ftype_v8hi_v8hi;
9972
9973 /* vshort, vint, vint. */
9974 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
9975 type = v8hi_ftype_v4si_v4si;
9976
9977 /* vchar, vshort, vshort. */
9978 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
9979 type = v16qi_ftype_v8hi_v8hi;
9980
9981 /* vint, vchar, vint. */
9982 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
9983 type = v4si_ftype_v16qi_v4si;
9984
fa066a23
AH
9985 /* vint, vchar, vchar. */
9986 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
9987 type = v4si_ftype_v16qi_v16qi;
9988
0ac081f6
AH
9989 /* vint, vshort, vint. */
9990 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
9991 type = v4si_ftype_v8hi_v4si;
f676971a 9992
a7b376ee 9993 /* vint, vint, 5-bit literal. */
2212663f 9994 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
b9e4e5d1 9995 type = v4si_ftype_v4si_int;
f676971a 9996
a7b376ee 9997 /* vshort, vshort, 5-bit literal. */
2212663f 9998 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
b9e4e5d1 9999 type = v8hi_ftype_v8hi_int;
f676971a 10000
a7b376ee 10001 /* vchar, vchar, 5-bit literal. */
2212663f 10002 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
b9e4e5d1 10003 type = v16qi_ftype_v16qi_int;
0ac081f6 10004
a7b376ee 10005 /* vfloat, vint, 5-bit literal. */
617e0e1d 10006 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
b9e4e5d1 10007 type = v4sf_ftype_v4si_int;
f676971a 10008
a7b376ee 10009 /* vint, vfloat, 5-bit literal. */
617e0e1d 10010 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
b9e4e5d1 10011 type = v4si_ftype_v4sf_int;
617e0e1d 10012
a3170dc6
AH
10013 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
10014 type = v2si_ftype_int_int;
10015
10016 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
10017 type = v2si_ftype_v2si_char;
10018
10019 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
10020 type = v2si_ftype_int_char;
10021
37409796 10022 else
0ac081f6 10023 {
37409796
NS
10024 /* int, x, x. */
10025 gcc_assert (mode0 == SImode);
0ac081f6
AH
10026 switch (mode1)
10027 {
10028 case V4SImode:
10029 type = int_ftype_v4si_v4si;
10030 break;
10031 case V4SFmode:
10032 type = int_ftype_v4sf_v4sf;
10033 break;
10034 case V16QImode:
10035 type = int_ftype_v16qi_v16qi;
10036 break;
10037 case V8HImode:
10038 type = int_ftype_v8hi_v8hi;
10039 break;
10040 default:
37409796 10041 gcc_unreachable ();
0ac081f6
AH
10042 }
10043 }
10044
2212663f
DB
10045 def_builtin (d->mask, d->name, type, d->code);
10046 }
24408032 10047
2212663f
DB
10048 /* Add the simple unary operators. */
10049 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 10050 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
10051 {
10052 enum machine_mode mode0, mode1;
10053 tree type;
58646b77
PB
10054 bool is_overloaded = d->code >= ALTIVEC_BUILTIN_OVERLOADED_FIRST
10055 && d->code <= ALTIVEC_BUILTIN_OVERLOADED_LAST;
10056
10057 if (is_overloaded)
10058 {
10059 mode0 = VOIDmode;
10060 mode1 = VOIDmode;
10061 }
10062 else
10063 {
10064 if (d->name == 0 || d->icode == CODE_FOR_nothing)
10065 continue;
bb8df8a6 10066
58646b77
PB
10067 mode0 = insn_data[d->icode].operand[0].mode;
10068 mode1 = insn_data[d->icode].operand[1].mode;
10069 }
2212663f
DB
10070
10071 if (mode0 == V4SImode && mode1 == QImode)
c4ad648e 10072 type = v4si_ftype_int;
2212663f 10073 else if (mode0 == V8HImode && mode1 == QImode)
c4ad648e 10074 type = v8hi_ftype_int;
2212663f 10075 else if (mode0 == V16QImode && mode1 == QImode)
c4ad648e 10076 type = v16qi_ftype_int;
58646b77
PB
10077 else if (mode0 == VOIDmode && mode1 == VOIDmode)
10078 type = opaque_ftype_opaque;
617e0e1d
DB
10079 else if (mode0 == V4SFmode && mode1 == V4SFmode)
10080 type = v4sf_ftype_v4sf;
20e26713
AH
10081 else if (mode0 == V8HImode && mode1 == V16QImode)
10082 type = v8hi_ftype_v16qi;
10083 else if (mode0 == V4SImode && mode1 == V8HImode)
10084 type = v4si_ftype_v8hi;
a3170dc6
AH
10085 else if (mode0 == V2SImode && mode1 == V2SImode)
10086 type = v2si_ftype_v2si;
10087 else if (mode0 == V2SFmode && mode1 == V2SFmode)
96038623
DE
10088 {
10089 if (TARGET_PAIRED_FLOAT)
10090 type = v2sf_ftype_v2sf;
10091 else
10092 type = v2sf_ftype_v2sf_spe;
10093 }
a3170dc6
AH
10094 else if (mode0 == V2SFmode && mode1 == V2SImode)
10095 type = v2sf_ftype_v2si;
10096 else if (mode0 == V2SImode && mode1 == V2SFmode)
10097 type = v2si_ftype_v2sf;
10098 else if (mode0 == V2SImode && mode1 == QImode)
10099 type = v2si_ftype_char;
2212663f 10100 else
37409796 10101 gcc_unreachable ();
2212663f 10102
0ac081f6
AH
10103 def_builtin (d->mask, d->name, type, d->code);
10104 }
10105}
10106
c15c90bb
ZW
10107static void
10108rs6000_init_libfuncs (void)
10109{
602ea4d3
JJ
10110 if (DEFAULT_ABI != ABI_V4 && TARGET_XCOFF
10111 && !TARGET_POWER2 && !TARGET_POWERPC)
c15c90bb 10112 {
602ea4d3
JJ
10113 /* AIX library routines for float->int conversion. */
10114 set_conv_libfunc (sfix_optab, SImode, DFmode, "__itrunc");
10115 set_conv_libfunc (ufix_optab, SImode, DFmode, "__uitrunc");
10116 set_conv_libfunc (sfix_optab, SImode, TFmode, "_qitrunc");
10117 set_conv_libfunc (ufix_optab, SImode, TFmode, "_quitrunc");
10118 }
c15c90bb 10119
602ea4d3 10120 if (!TARGET_IEEEQUAD)
98c41d98 10121 /* AIX/Darwin/64-bit Linux quad floating point routines. */
602ea4d3
JJ
10122 if (!TARGET_XL_COMPAT)
10123 {
10124 set_optab_libfunc (add_optab, TFmode, "__gcc_qadd");
10125 set_optab_libfunc (sub_optab, TFmode, "__gcc_qsub");
10126 set_optab_libfunc (smul_optab, TFmode, "__gcc_qmul");
10127 set_optab_libfunc (sdiv_optab, TFmode, "__gcc_qdiv");
d0768f19 10128
17caeff2 10129 if (!(TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)))
d0768f19
DE
10130 {
10131 set_optab_libfunc (neg_optab, TFmode, "__gcc_qneg");
10132 set_optab_libfunc (eq_optab, TFmode, "__gcc_qeq");
10133 set_optab_libfunc (ne_optab, TFmode, "__gcc_qne");
10134 set_optab_libfunc (gt_optab, TFmode, "__gcc_qgt");
10135 set_optab_libfunc (ge_optab, TFmode, "__gcc_qge");
10136 set_optab_libfunc (lt_optab, TFmode, "__gcc_qlt");
10137 set_optab_libfunc (le_optab, TFmode, "__gcc_qle");
d0768f19
DE
10138
10139 set_conv_libfunc (sext_optab, TFmode, SFmode, "__gcc_stoq");
10140 set_conv_libfunc (sext_optab, TFmode, DFmode, "__gcc_dtoq");
10141 set_conv_libfunc (trunc_optab, SFmode, TFmode, "__gcc_qtos");
10142 set_conv_libfunc (trunc_optab, DFmode, TFmode, "__gcc_qtod");
10143 set_conv_libfunc (sfix_optab, SImode, TFmode, "__gcc_qtoi");
10144 set_conv_libfunc (ufix_optab, SImode, TFmode, "__gcc_qtou");
10145 set_conv_libfunc (sfloat_optab, TFmode, SImode, "__gcc_itoq");
10146 set_conv_libfunc (ufloat_optab, TFmode, SImode, "__gcc_utoq");
10147 }
b26941b4
JM
10148
10149 if (!(TARGET_HARD_FLOAT && TARGET_FPRS))
10150 set_optab_libfunc (unord_optab, TFmode, "__gcc_qunord");
602ea4d3
JJ
10151 }
10152 else
10153 {
10154 set_optab_libfunc (add_optab, TFmode, "_xlqadd");
10155 set_optab_libfunc (sub_optab, TFmode, "_xlqsub");
10156 set_optab_libfunc (smul_optab, TFmode, "_xlqmul");
10157 set_optab_libfunc (sdiv_optab, TFmode, "_xlqdiv");
10158 }
c9034561 10159 else
c15c90bb 10160 {
c9034561 10161 /* 32-bit SVR4 quad floating point routines. */
c15c90bb
ZW
10162
10163 set_optab_libfunc (add_optab, TFmode, "_q_add");
10164 set_optab_libfunc (sub_optab, TFmode, "_q_sub");
10165 set_optab_libfunc (neg_optab, TFmode, "_q_neg");
10166 set_optab_libfunc (smul_optab, TFmode, "_q_mul");
10167 set_optab_libfunc (sdiv_optab, TFmode, "_q_div");
10168 if (TARGET_PPC_GPOPT || TARGET_POWER2)
10169 set_optab_libfunc (sqrt_optab, TFmode, "_q_sqrt");
10170
c9034561
ZW
10171 set_optab_libfunc (eq_optab, TFmode, "_q_feq");
10172 set_optab_libfunc (ne_optab, TFmode, "_q_fne");
10173 set_optab_libfunc (gt_optab, TFmode, "_q_fgt");
10174 set_optab_libfunc (ge_optab, TFmode, "_q_fge");
10175 set_optab_libfunc (lt_optab, TFmode, "_q_flt");
10176 set_optab_libfunc (le_optab, TFmode, "_q_fle");
10177
85363ca0
ZW
10178 set_conv_libfunc (sext_optab, TFmode, SFmode, "_q_stoq");
10179 set_conv_libfunc (sext_optab, TFmode, DFmode, "_q_dtoq");
10180 set_conv_libfunc (trunc_optab, SFmode, TFmode, "_q_qtos");
10181 set_conv_libfunc (trunc_optab, DFmode, TFmode, "_q_qtod");
10182 set_conv_libfunc (sfix_optab, SImode, TFmode, "_q_qtoi");
10183 set_conv_libfunc (ufix_optab, SImode, TFmode, "_q_qtou");
10184 set_conv_libfunc (sfloat_optab, TFmode, SImode, "_q_itoq");
57904aa7 10185 set_conv_libfunc (ufloat_optab, TFmode, SImode, "_q_utoq");
c15c90bb
ZW
10186 }
10187}
fba73eb1
DE
10188
10189\f
10190/* Expand a block clear operation, and return 1 if successful. Return 0
10191 if we should let the compiler generate normal code.
10192
10193 operands[0] is the destination
10194 operands[1] is the length
57e84f18 10195 operands[3] is the alignment */
fba73eb1
DE
10196
10197int
10198expand_block_clear (rtx operands[])
10199{
10200 rtx orig_dest = operands[0];
10201 rtx bytes_rtx = operands[1];
57e84f18 10202 rtx align_rtx = operands[3];
5514620a
GK
10203 bool constp = (GET_CODE (bytes_rtx) == CONST_INT);
10204 HOST_WIDE_INT align;
10205 HOST_WIDE_INT bytes;
fba73eb1
DE
10206 int offset;
10207 int clear_bytes;
5514620a 10208 int clear_step;
fba73eb1
DE
10209
10210 /* If this is not a fixed size move, just call memcpy */
10211 if (! constp)
10212 return 0;
10213
37409796
NS
10214 /* This must be a fixed size alignment */
10215 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
fba73eb1
DE
10216 align = INTVAL (align_rtx) * BITS_PER_UNIT;
10217
10218 /* Anything to clear? */
10219 bytes = INTVAL (bytes_rtx);
10220 if (bytes <= 0)
10221 return 1;
10222
5514620a
GK
10223 /* Use the builtin memset after a point, to avoid huge code bloat.
10224 When optimize_size, avoid any significant code bloat; calling
10225 memset is about 4 instructions, so allow for one instruction to
10226 load zero and three to do clearing. */
10227 if (TARGET_ALTIVEC && align >= 128)
10228 clear_step = 16;
10229 else if (TARGET_POWERPC64 && align >= 32)
10230 clear_step = 8;
21d818ff
NF
10231 else if (TARGET_SPE && align >= 64)
10232 clear_step = 8;
5514620a
GK
10233 else
10234 clear_step = 4;
fba73eb1 10235
5514620a
GK
10236 if (optimize_size && bytes > 3 * clear_step)
10237 return 0;
10238 if (! optimize_size && bytes > 8 * clear_step)
fba73eb1
DE
10239 return 0;
10240
10241 for (offset = 0; bytes > 0; offset += clear_bytes, bytes -= clear_bytes)
10242 {
fba73eb1
DE
10243 enum machine_mode mode = BLKmode;
10244 rtx dest;
f676971a 10245
5514620a
GK
10246 if (bytes >= 16 && TARGET_ALTIVEC && align >= 128)
10247 {
10248 clear_bytes = 16;
10249 mode = V4SImode;
10250 }
21d818ff
NF
10251 else if (bytes >= 8 && TARGET_SPE && align >= 64)
10252 {
10253 clear_bytes = 8;
10254 mode = V2SImode;
10255 }
5514620a 10256 else if (bytes >= 8 && TARGET_POWERPC64
21d818ff
NF
10257 /* 64-bit loads and stores require word-aligned
10258 displacements. */
10259 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
fba73eb1
DE
10260 {
10261 clear_bytes = 8;
10262 mode = DImode;
fba73eb1 10263 }
5514620a 10264 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
fba73eb1
DE
10265 { /* move 4 bytes */
10266 clear_bytes = 4;
10267 mode = SImode;
fba73eb1 10268 }
ec53fc93 10269 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
fba73eb1
DE
10270 { /* move 2 bytes */
10271 clear_bytes = 2;
10272 mode = HImode;
fba73eb1
DE
10273 }
10274 else /* move 1 byte at a time */
10275 {
10276 clear_bytes = 1;
10277 mode = QImode;
fba73eb1 10278 }
f676971a 10279
fba73eb1 10280 dest = adjust_address (orig_dest, mode, offset);
f676971a 10281
5514620a 10282 emit_move_insn (dest, CONST0_RTX (mode));
fba73eb1
DE
10283 }
10284
10285 return 1;
10286}
10287
35aff10b 10288\f
7e69e155
MM
10289/* Expand a block move operation, and return 1 if successful. Return 0
10290 if we should let the compiler generate normal code.
10291
10292 operands[0] is the destination
10293 operands[1] is the source
10294 operands[2] is the length
10295 operands[3] is the alignment */
10296
3933e0e1
MM
10297#define MAX_MOVE_REG 4
10298
7e69e155 10299int
a2369ed3 10300expand_block_move (rtx operands[])
7e69e155 10301{
b6c9286a
MM
10302 rtx orig_dest = operands[0];
10303 rtx orig_src = operands[1];
7e69e155 10304 rtx bytes_rtx = operands[2];
7e69e155 10305 rtx align_rtx = operands[3];
3933e0e1 10306 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 10307 int align;
3933e0e1
MM
10308 int bytes;
10309 int offset;
7e69e155 10310 int move_bytes;
cabfd258
GK
10311 rtx stores[MAX_MOVE_REG];
10312 int num_reg = 0;
7e69e155 10313
3933e0e1 10314 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 10315 if (! constp)
3933e0e1
MM
10316 return 0;
10317
37409796
NS
10318 /* This must be a fixed size alignment */
10319 gcc_assert (GET_CODE (align_rtx) == CONST_INT);
fba73eb1 10320 align = INTVAL (align_rtx) * BITS_PER_UNIT;
5ee95df6 10321
7e69e155 10322 /* Anything to move? */
3933e0e1
MM
10323 bytes = INTVAL (bytes_rtx);
10324 if (bytes <= 0)
7e69e155
MM
10325 return 1;
10326
ea9982a8 10327 /* store_one_arg depends on expand_block_move to handle at least the size of
f676971a 10328 reg_parm_stack_space. */
ea9982a8 10329 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
10330 return 0;
10331
cabfd258 10332 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 10333 {
cabfd258 10334 union {
70128ad9 10335 rtx (*movmemsi) (rtx, rtx, rtx, rtx);
a2369ed3 10336 rtx (*mov) (rtx, rtx);
cabfd258
GK
10337 } gen_func;
10338 enum machine_mode mode = BLKmode;
10339 rtx src, dest;
f676971a 10340
5514620a
GK
10341 /* Altivec first, since it will be faster than a string move
10342 when it applies, and usually not significantly larger. */
10343 if (TARGET_ALTIVEC && bytes >= 16 && align >= 128)
10344 {
10345 move_bytes = 16;
10346 mode = V4SImode;
10347 gen_func.mov = gen_movv4si;
10348 }
21d818ff
NF
10349 else if (TARGET_SPE && bytes >= 8 && align >= 64)
10350 {
10351 move_bytes = 8;
10352 mode = V2SImode;
10353 gen_func.mov = gen_movv2si;
10354 }
5514620a 10355 else if (TARGET_STRING
cabfd258
GK
10356 && bytes > 24 /* move up to 32 bytes at a time */
10357 && ! fixed_regs[5]
10358 && ! fixed_regs[6]
10359 && ! fixed_regs[7]
10360 && ! fixed_regs[8]
10361 && ! fixed_regs[9]
10362 && ! fixed_regs[10]
10363 && ! fixed_regs[11]
10364 && ! fixed_regs[12])
7e69e155 10365 {
cabfd258 10366 move_bytes = (bytes > 32) ? 32 : bytes;
70128ad9 10367 gen_func.movmemsi = gen_movmemsi_8reg;
cabfd258
GK
10368 }
10369 else if (TARGET_STRING
10370 && bytes > 16 /* move up to 24 bytes at a time */
10371 && ! fixed_regs[5]
10372 && ! fixed_regs[6]
10373 && ! fixed_regs[7]
10374 && ! fixed_regs[8]
10375 && ! fixed_regs[9]
10376 && ! fixed_regs[10])
10377 {
10378 move_bytes = (bytes > 24) ? 24 : bytes;
70128ad9 10379 gen_func.movmemsi = gen_movmemsi_6reg;
cabfd258
GK
10380 }
10381 else if (TARGET_STRING
10382 && bytes > 8 /* move up to 16 bytes at a time */
10383 && ! fixed_regs[5]
10384 && ! fixed_regs[6]
10385 && ! fixed_regs[7]
10386 && ! fixed_regs[8])
10387 {
10388 move_bytes = (bytes > 16) ? 16 : bytes;
70128ad9 10389 gen_func.movmemsi = gen_movmemsi_4reg;
cabfd258
GK
10390 }
10391 else if (bytes >= 8 && TARGET_POWERPC64
10392 /* 64-bit loads and stores require word-aligned
10393 displacements. */
fba73eb1 10394 && (align >= 64 || (!STRICT_ALIGNMENT && align >= 32)))
cabfd258
GK
10395 {
10396 move_bytes = 8;
10397 mode = DImode;
10398 gen_func.mov = gen_movdi;
10399 }
10400 else if (TARGET_STRING && bytes > 4 && !TARGET_POWERPC64)
10401 { /* move up to 8 bytes at a time */
10402 move_bytes = (bytes > 8) ? 8 : bytes;
70128ad9 10403 gen_func.movmemsi = gen_movmemsi_2reg;
cabfd258 10404 }
cd7d9ca4 10405 else if (bytes >= 4 && (align >= 32 || !STRICT_ALIGNMENT))
cabfd258
GK
10406 { /* move 4 bytes */
10407 move_bytes = 4;
10408 mode = SImode;
10409 gen_func.mov = gen_movsi;
10410 }
ec53fc93 10411 else if (bytes >= 2 && (align >= 16 || !STRICT_ALIGNMENT))
cabfd258
GK
10412 { /* move 2 bytes */
10413 move_bytes = 2;
10414 mode = HImode;
10415 gen_func.mov = gen_movhi;
10416 }
10417 else if (TARGET_STRING && bytes > 1)
10418 { /* move up to 4 bytes at a time */
10419 move_bytes = (bytes > 4) ? 4 : bytes;
70128ad9 10420 gen_func.movmemsi = gen_movmemsi_1reg;
cabfd258
GK
10421 }
10422 else /* move 1 byte at a time */
10423 {
10424 move_bytes = 1;
10425 mode = QImode;
10426 gen_func.mov = gen_movqi;
10427 }
f676971a 10428
cabfd258
GK
10429 src = adjust_address (orig_src, mode, offset);
10430 dest = adjust_address (orig_dest, mode, offset);
f676971a
EC
10431
10432 if (mode != BLKmode)
cabfd258
GK
10433 {
10434 rtx tmp_reg = gen_reg_rtx (mode);
f676971a 10435
cabfd258
GK
10436 emit_insn ((*gen_func.mov) (tmp_reg, src));
10437 stores[num_reg++] = (*gen_func.mov) (dest, tmp_reg);
4c64a852 10438 }
3933e0e1 10439
cabfd258
GK
10440 if (mode == BLKmode || num_reg >= MAX_MOVE_REG || bytes == move_bytes)
10441 {
10442 int i;
10443 for (i = 0; i < num_reg; i++)
10444 emit_insn (stores[i]);
10445 num_reg = 0;
10446 }
35aff10b 10447
cabfd258 10448 if (mode == BLKmode)
7e69e155 10449 {
70128ad9 10450 /* Move the address into scratch registers. The movmemsi
cabfd258
GK
10451 patterns require zero offset. */
10452 if (!REG_P (XEXP (src, 0)))
b6c9286a 10453 {
cabfd258
GK
10454 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
10455 src = replace_equiv_address (src, src_reg);
b6c9286a 10456 }
cabfd258 10457 set_mem_size (src, GEN_INT (move_bytes));
f676971a 10458
cabfd258 10459 if (!REG_P (XEXP (dest, 0)))
3933e0e1 10460 {
cabfd258
GK
10461 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
10462 dest = replace_equiv_address (dest, dest_reg);
7e69e155 10463 }
cabfd258 10464 set_mem_size (dest, GEN_INT (move_bytes));
f676971a 10465
70128ad9 10466 emit_insn ((*gen_func.movmemsi) (dest, src,
cabfd258
GK
10467 GEN_INT (move_bytes & 31),
10468 align_rtx));
7e69e155 10469 }
7e69e155
MM
10470 }
10471
10472 return 1;
10473}
10474
d62294f5 10475\f
9caa3eb2
DE
10476/* Return a string to perform a load_multiple operation.
10477 operands[0] is the vector.
10478 operands[1] is the source address.
10479 operands[2] is the first destination register. */
10480
10481const char *
a2369ed3 10482rs6000_output_load_multiple (rtx operands[3])
9caa3eb2
DE
10483{
10484 /* We have to handle the case where the pseudo used to contain the address
10485 is assigned to one of the output registers. */
10486 int i, j;
10487 int words = XVECLEN (operands[0], 0);
10488 rtx xop[10];
10489
10490 if (XVECLEN (operands[0], 0) == 1)
10491 return "{l|lwz} %2,0(%1)";
10492
10493 for (i = 0; i < words; i++)
10494 if (refers_to_regno_p (REGNO (operands[2]) + i,
10495 REGNO (operands[2]) + i + 1, operands[1], 0))
10496 {
10497 if (i == words-1)
10498 {
10499 xop[0] = GEN_INT (4 * (words-1));
10500 xop[1] = operands[1];
10501 xop[2] = operands[2];
10502 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
10503 return "";
10504 }
10505 else if (i == 0)
10506 {
10507 xop[0] = GEN_INT (4 * (words-1));
10508 xop[1] = operands[1];
10509 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
10510 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);
10511 return "";
10512 }
10513 else
10514 {
10515 for (j = 0; j < words; j++)
10516 if (j != i)
10517 {
10518 xop[0] = GEN_INT (j * 4);
10519 xop[1] = operands[1];
10520 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
10521 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
10522 }
10523 xop[0] = GEN_INT (i * 4);
10524 xop[1] = operands[1];
10525 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
10526 return "";
10527 }
10528 }
10529
10530 return "{lsi|lswi} %2,%1,%N0";
10531}
10532
9878760c 10533\f
a4f6c312
SS
10534/* A validation routine: say whether CODE, a condition code, and MODE
10535 match. The other alternatives either don't make sense or should
10536 never be generated. */
39a10a29 10537
48d72335 10538void
a2369ed3 10539validate_condition_mode (enum rtx_code code, enum machine_mode mode)
39a10a29 10540{
37409796
NS
10541 gcc_assert ((GET_RTX_CLASS (code) == RTX_COMPARE
10542 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
10543 && GET_MODE_CLASS (mode) == MODE_CC);
39a10a29
GK
10544
10545 /* These don't make sense. */
37409796
NS
10546 gcc_assert ((code != GT && code != LT && code != GE && code != LE)
10547 || mode != CCUNSmode);
39a10a29 10548
37409796
NS
10549 gcc_assert ((code != GTU && code != LTU && code != GEU && code != LEU)
10550 || mode == CCUNSmode);
39a10a29 10551
37409796
NS
10552 gcc_assert (mode == CCFPmode
10553 || (code != ORDERED && code != UNORDERED
10554 && code != UNEQ && code != LTGT
10555 && code != UNGT && code != UNLT
10556 && code != UNGE && code != UNLE));
f676971a
EC
10557
10558 /* These should never be generated except for
bc9ec0e0 10559 flag_finite_math_only. */
37409796
NS
10560 gcc_assert (mode != CCFPmode
10561 || flag_finite_math_only
10562 || (code != LE && code != GE
10563 && code != UNEQ && code != LTGT
10564 && code != UNGT && code != UNLT));
39a10a29
GK
10565
10566 /* These are invalid; the information is not there. */
37409796 10567 gcc_assert (mode != CCEQmode || code == EQ || code == NE);
39a10a29
GK
10568}
10569
9878760c
RK
10570\f
10571/* Return 1 if ANDOP is a mask that has no bits on that are not in the
10572 mask required to convert the result of a rotate insn into a shift
b1765bde 10573 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
10574
10575int
a2369ed3 10576includes_lshift_p (rtx shiftop, rtx andop)
9878760c 10577{
e2c953b6
DE
10578 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
10579
10580 shift_mask <<= INTVAL (shiftop);
9878760c 10581
b1765bde 10582 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
10583}
10584
10585/* Similar, but for right shift. */
10586
10587int
a2369ed3 10588includes_rshift_p (rtx shiftop, rtx andop)
9878760c 10589{
a7653a2c 10590 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
10591
10592 shift_mask >>= INTVAL (shiftop);
10593
b1765bde 10594 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
10595}
10596
c5059423
AM
10597/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
10598 to perform a left shift. It must have exactly SHIFTOP least
b6d08ca1 10599 significant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
10600
10601int
a2369ed3 10602includes_rldic_lshift_p (rtx shiftop, rtx andop)
e2c953b6 10603{
c5059423
AM
10604 if (GET_CODE (andop) == CONST_INT)
10605 {
02071907 10606 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 10607
c5059423 10608 c = INTVAL (andop);
02071907 10609 if (c == 0 || c == ~0)
c5059423 10610 return 0;
e2c953b6 10611
02071907 10612 shift_mask = ~0;
c5059423
AM
10613 shift_mask <<= INTVAL (shiftop);
10614
b6d08ca1 10615 /* Find the least significant one bit. */
c5059423
AM
10616 lsb = c & -c;
10617
10618 /* It must coincide with the LSB of the shift mask. */
10619 if (-lsb != shift_mask)
10620 return 0;
e2c953b6 10621
c5059423
AM
10622 /* Invert to look for the next transition (if any). */
10623 c = ~c;
10624
10625 /* Remove the low group of ones (originally low group of zeros). */
10626 c &= -lsb;
10627
10628 /* Again find the lsb, and check we have all 1's above. */
10629 lsb = c & -c;
10630 return c == -lsb;
10631 }
10632 else if (GET_CODE (andop) == CONST_DOUBLE
10633 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
10634 {
02071907
AM
10635 HOST_WIDE_INT low, high, lsb;
10636 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
10637
10638 low = CONST_DOUBLE_LOW (andop);
10639 if (HOST_BITS_PER_WIDE_INT < 64)
10640 high = CONST_DOUBLE_HIGH (andop);
10641
10642 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 10643 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
10644 return 0;
10645
10646 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
10647 {
02071907 10648 shift_mask_high = ~0;
c5059423
AM
10649 if (INTVAL (shiftop) > 32)
10650 shift_mask_high <<= INTVAL (shiftop) - 32;
10651
10652 lsb = high & -high;
10653
10654 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
10655 return 0;
10656
10657 high = ~high;
10658 high &= -lsb;
10659
10660 lsb = high & -high;
10661 return high == -lsb;
10662 }
10663
02071907 10664 shift_mask_low = ~0;
c5059423
AM
10665 shift_mask_low <<= INTVAL (shiftop);
10666
10667 lsb = low & -low;
10668
10669 if (-lsb != shift_mask_low)
10670 return 0;
10671
10672 if (HOST_BITS_PER_WIDE_INT < 64)
10673 high = ~high;
10674 low = ~low;
10675 low &= -lsb;
10676
10677 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
10678 {
10679 lsb = high & -high;
10680 return high == -lsb;
10681 }
10682
10683 lsb = low & -low;
10684 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
10685 }
10686 else
10687 return 0;
10688}
e2c953b6 10689
c5059423
AM
10690/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
10691 to perform a left shift. It must have SHIFTOP or more least
c1207243 10692 significant 0's, with the remainder of the word 1's. */
e2c953b6 10693
c5059423 10694int
a2369ed3 10695includes_rldicr_lshift_p (rtx shiftop, rtx andop)
c5059423 10696{
e2c953b6 10697 if (GET_CODE (andop) == CONST_INT)
c5059423 10698 {
02071907 10699 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 10700
02071907 10701 shift_mask = ~0;
c5059423
AM
10702 shift_mask <<= INTVAL (shiftop);
10703 c = INTVAL (andop);
10704
c1207243 10705 /* Find the least significant one bit. */
c5059423
AM
10706 lsb = c & -c;
10707
10708 /* It must be covered by the shift mask.
a4f6c312 10709 This test also rejects c == 0. */
c5059423
AM
10710 if ((lsb & shift_mask) == 0)
10711 return 0;
10712
10713 /* Check we have all 1's above the transition, and reject all 1's. */
10714 return c == -lsb && lsb != 1;
10715 }
10716 else if (GET_CODE (andop) == CONST_DOUBLE
10717 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
10718 {
02071907 10719 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
10720
10721 low = CONST_DOUBLE_LOW (andop);
10722
10723 if (HOST_BITS_PER_WIDE_INT < 64)
10724 {
02071907 10725 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
10726
10727 high = CONST_DOUBLE_HIGH (andop);
10728
10729 if (low == 0)
10730 {
02071907 10731 shift_mask_high = ~0;
c5059423
AM
10732 if (INTVAL (shiftop) > 32)
10733 shift_mask_high <<= INTVAL (shiftop) - 32;
10734
10735 lsb = high & -high;
10736
10737 if ((lsb & shift_mask_high) == 0)
10738 return 0;
10739
10740 return high == -lsb;
10741 }
10742 if (high != ~0)
10743 return 0;
10744 }
10745
02071907 10746 shift_mask_low = ~0;
c5059423
AM
10747 shift_mask_low <<= INTVAL (shiftop);
10748
10749 lsb = low & -low;
10750
10751 if ((lsb & shift_mask_low) == 0)
10752 return 0;
10753
10754 return low == -lsb && lsb != 1;
10755 }
e2c953b6 10756 else
c5059423 10757 return 0;
9878760c 10758}
35068b43 10759
11ac38b2
DE
10760/* Return 1 if operands will generate a valid arguments to rlwimi
10761instruction for insert with right shift in 64-bit mode. The mask may
10762not start on the first bit or stop on the last bit because wrap-around
10763effects of instruction do not correspond to semantics of RTL insn. */
10764
10765int
10766insvdi_rshift_rlwimi_p (rtx sizeop, rtx startop, rtx shiftop)
10767{
429ec7dc
DE
10768 if (INTVAL (startop) > 32
10769 && INTVAL (startop) < 64
10770 && INTVAL (sizeop) > 1
10771 && INTVAL (sizeop) + INTVAL (startop) < 64
10772 && INTVAL (shiftop) > 0
10773 && INTVAL (sizeop) + INTVAL (shiftop) < 32
11ac38b2
DE
10774 && (64 - (INTVAL (shiftop) & 63)) >= INTVAL (sizeop))
10775 return 1;
10776
10777 return 0;
10778}
10779
35068b43 10780/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
90f81f99 10781 for lfq and stfq insns iff the registers are hard registers. */
35068b43
RK
10782
10783int
a2369ed3 10784registers_ok_for_quad_peep (rtx reg1, rtx reg2)
35068b43
RK
10785{
10786 /* We might have been passed a SUBREG. */
f676971a 10787 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
35068b43 10788 return 0;
f676971a 10789
90f81f99
AP
10790 /* We might have been passed non floating point registers. */
10791 if (!FP_REGNO_P (REGNO (reg1))
10792 || !FP_REGNO_P (REGNO (reg2)))
10793 return 0;
35068b43
RK
10794
10795 return (REGNO (reg1) == REGNO (reg2) - 1);
10796}
10797
a4f6c312
SS
10798/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
10799 addr1 and addr2 must be in consecutive memory locations
10800 (addr2 == addr1 + 8). */
35068b43
RK
10801
10802int
90f81f99 10803mems_ok_for_quad_peep (rtx mem1, rtx mem2)
35068b43 10804{
90f81f99 10805 rtx addr1, addr2;
bb8df8a6
EC
10806 unsigned int reg1, reg2;
10807 int offset1, offset2;
35068b43 10808
90f81f99
AP
10809 /* The mems cannot be volatile. */
10810 if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
10811 return 0;
f676971a 10812
90f81f99
AP
10813 addr1 = XEXP (mem1, 0);
10814 addr2 = XEXP (mem2, 0);
10815
35068b43
RK
10816 /* Extract an offset (if used) from the first addr. */
10817 if (GET_CODE (addr1) == PLUS)
10818 {
10819 /* If not a REG, return zero. */
10820 if (GET_CODE (XEXP (addr1, 0)) != REG)
10821 return 0;
10822 else
10823 {
c4ad648e 10824 reg1 = REGNO (XEXP (addr1, 0));
35068b43
RK
10825 /* The offset must be constant! */
10826 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
c4ad648e
AM
10827 return 0;
10828 offset1 = INTVAL (XEXP (addr1, 1));
35068b43
RK
10829 }
10830 }
10831 else if (GET_CODE (addr1) != REG)
10832 return 0;
10833 else
10834 {
10835 reg1 = REGNO (addr1);
10836 /* This was a simple (mem (reg)) expression. Offset is 0. */
10837 offset1 = 0;
10838 }
10839
bb8df8a6
EC
10840 /* And now for the second addr. */
10841 if (GET_CODE (addr2) == PLUS)
10842 {
10843 /* If not a REG, return zero. */
10844 if (GET_CODE (XEXP (addr2, 0)) != REG)
10845 return 0;
10846 else
10847 {
10848 reg2 = REGNO (XEXP (addr2, 0));
10849 /* The offset must be constant. */
10850 if (GET_CODE (XEXP (addr2, 1)) != CONST_INT)
10851 return 0;
10852 offset2 = INTVAL (XEXP (addr2, 1));
10853 }
10854 }
10855 else if (GET_CODE (addr2) != REG)
35068b43 10856 return 0;
bb8df8a6
EC
10857 else
10858 {
10859 reg2 = REGNO (addr2);
10860 /* This was a simple (mem (reg)) expression. Offset is 0. */
10861 offset2 = 0;
10862 }
35068b43 10863
bb8df8a6
EC
10864 /* Both of these must have the same base register. */
10865 if (reg1 != reg2)
35068b43
RK
10866 return 0;
10867
10868 /* The offset for the second addr must be 8 more than the first addr. */
bb8df8a6 10869 if (offset2 != offset1 + 8)
35068b43
RK
10870 return 0;
10871
10872 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
10873 instructions. */
10874 return 1;
10875}
9878760c
RK
10876\f
10877/* Return the register class of a scratch register needed to copy IN into
10878 or out of a register in CLASS in MODE. If it can be done directly,
10879 NO_REGS is returned. */
10880
10881enum reg_class
3c4774e0
R
10882rs6000_secondary_reload_class (enum reg_class class,
10883 enum machine_mode mode ATTRIBUTE_UNUSED,
10884 rtx in)
9878760c 10885{
5accd822 10886 int regno;
9878760c 10887
ab82a49f
AP
10888 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
10889#if TARGET_MACHO
c4ad648e 10890 && MACHOPIC_INDIRECT
ab82a49f 10891#endif
c4ad648e 10892 ))
46fad5b7
DJ
10893 {
10894 /* We cannot copy a symbolic operand directly into anything
c4ad648e
AM
10895 other than BASE_REGS for TARGET_ELF. So indicate that a
10896 register from BASE_REGS is needed as an intermediate
10897 register.
f676971a 10898
46fad5b7
DJ
10899 On Darwin, pic addresses require a load from memory, which
10900 needs a base register. */
10901 if (class != BASE_REGS
c4ad648e
AM
10902 && (GET_CODE (in) == SYMBOL_REF
10903 || GET_CODE (in) == HIGH
10904 || GET_CODE (in) == LABEL_REF
10905 || GET_CODE (in) == CONST))
10906 return BASE_REGS;
46fad5b7 10907 }
e7b7998a 10908
5accd822
DE
10909 if (GET_CODE (in) == REG)
10910 {
10911 regno = REGNO (in);
10912 if (regno >= FIRST_PSEUDO_REGISTER)
10913 {
10914 regno = true_regnum (in);
10915 if (regno >= FIRST_PSEUDO_REGISTER)
10916 regno = -1;
10917 }
10918 }
10919 else if (GET_CODE (in) == SUBREG)
10920 {
10921 regno = true_regnum (in);
10922 if (regno >= FIRST_PSEUDO_REGISTER)
10923 regno = -1;
10924 }
10925 else
10926 regno = -1;
10927
9878760c
RK
10928 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
10929 into anything. */
10930 if (class == GENERAL_REGS || class == BASE_REGS
10931 || (regno >= 0 && INT_REGNO_P (regno)))
10932 return NO_REGS;
10933
10934 /* Constants, memory, and FP registers can go into FP registers. */
10935 if ((regno == -1 || FP_REGNO_P (regno))
10936 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
10937 return NO_REGS;
10938
0ac081f6
AH
10939 /* Memory, and AltiVec registers can go into AltiVec registers. */
10940 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
10941 && class == ALTIVEC_REGS)
10942 return NO_REGS;
10943
9878760c
RK
10944 /* We can copy among the CR registers. */
10945 if ((class == CR_REGS || class == CR0_REGS)
10946 && regno >= 0 && CR_REGNO_P (regno))
10947 return NO_REGS;
10948
10949 /* Otherwise, we need GENERAL_REGS. */
10950 return GENERAL_REGS;
10951}
10952\f
10953/* Given a comparison operation, return the bit number in CCR to test. We
f676971a 10954 know this is a valid comparison.
9878760c
RK
10955
10956 SCC_P is 1 if this is for an scc. That means that %D will have been
10957 used instead of %C, so the bits will be in different places.
10958
b4ac57ab 10959 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
10960
10961int
a2369ed3 10962ccr_bit (rtx op, int scc_p)
9878760c
RK
10963{
10964 enum rtx_code code = GET_CODE (op);
10965 enum machine_mode cc_mode;
10966 int cc_regnum;
10967 int base_bit;
9ebbca7d 10968 rtx reg;
9878760c 10969
ec8e098d 10970 if (!COMPARISON_P (op))
9878760c
RK
10971 return -1;
10972
9ebbca7d
GK
10973 reg = XEXP (op, 0);
10974
37409796 10975 gcc_assert (GET_CODE (reg) == REG && CR_REGNO_P (REGNO (reg)));
9ebbca7d
GK
10976
10977 cc_mode = GET_MODE (reg);
10978 cc_regnum = REGNO (reg);
10979 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 10980
39a10a29 10981 validate_condition_mode (code, cc_mode);
c5defebb 10982
b7053a3f
GK
10983 /* When generating a sCOND operation, only positive conditions are
10984 allowed. */
37409796
NS
10985 gcc_assert (!scc_p
10986 || code == EQ || code == GT || code == LT || code == UNORDERED
10987 || code == GTU || code == LTU);
f676971a 10988
9878760c
RK
10989 switch (code)
10990 {
10991 case NE:
10992 return scc_p ? base_bit + 3 : base_bit + 2;
10993 case EQ:
10994 return base_bit + 2;
1c882ea4 10995 case GT: case GTU: case UNLE:
9878760c 10996 return base_bit + 1;
1c882ea4 10997 case LT: case LTU: case UNGE:
9878760c 10998 return base_bit;
1c882ea4
GK
10999 case ORDERED: case UNORDERED:
11000 return base_bit + 3;
9878760c
RK
11001
11002 case GE: case GEU:
39a10a29 11003 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
11004 unordered position. So test that bit. For integer, this is ! LT
11005 unless this is an scc insn. */
39a10a29 11006 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
11007
11008 case LE: case LEU:
39a10a29 11009 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 11010
9878760c 11011 default:
37409796 11012 gcc_unreachable ();
9878760c
RK
11013 }
11014}
1ff7789b 11015\f
8d30c4ee 11016/* Return the GOT register. */
1ff7789b 11017
9390387d 11018rtx
a2369ed3 11019rs6000_got_register (rtx value ATTRIBUTE_UNUSED)
1ff7789b 11020{
a4f6c312
SS
11021 /* The second flow pass currently (June 1999) can't update
11022 regs_ever_live without disturbing other parts of the compiler, so
11023 update it here to make the prolog/epilogue code happy. */
b3a13419
ILT
11024 if (!can_create_pseudo_p ()
11025 && !df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM))
6fb5fa3c 11026 df_set_regs_ever_live (RS6000_PIC_OFFSET_TABLE_REGNUM, true);
1ff7789b 11027
8d30c4ee 11028 current_function_uses_pic_offset_table = 1;
3cb999d8 11029
1ff7789b
MM
11030 return pic_offset_table_rtx;
11031}
a7df97e6 11032\f
e2500fed
GK
11033/* Function to init struct machine_function.
11034 This will be called, via a pointer variable,
11035 from push_function_context. */
a7df97e6 11036
e2500fed 11037static struct machine_function *
863d938c 11038rs6000_init_machine_status (void)
a7df97e6 11039{
e2500fed 11040 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 11041}
9878760c 11042\f
0ba1b2ff
AM
11043/* These macros test for integers and extract the low-order bits. */
11044#define INT_P(X) \
11045((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
11046 && GET_MODE (X) == VOIDmode)
11047
11048#define INT_LOWPART(X) \
11049 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
11050
11051int
a2369ed3 11052extract_MB (rtx op)
0ba1b2ff
AM
11053{
11054 int i;
11055 unsigned long val = INT_LOWPART (op);
11056
11057 /* If the high bit is zero, the value is the first 1 bit we find
11058 from the left. */
11059 if ((val & 0x80000000) == 0)
11060 {
37409796 11061 gcc_assert (val & 0xffffffff);
0ba1b2ff
AM
11062
11063 i = 1;
11064 while (((val <<= 1) & 0x80000000) == 0)
11065 ++i;
11066 return i;
11067 }
11068
11069 /* If the high bit is set and the low bit is not, or the mask is all
11070 1's, the value is zero. */
11071 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
11072 return 0;
11073
11074 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11075 from the right. */
11076 i = 31;
11077 while (((val >>= 1) & 1) != 0)
11078 --i;
11079
11080 return i;
11081}
11082
11083int
a2369ed3 11084extract_ME (rtx op)
0ba1b2ff
AM
11085{
11086 int i;
11087 unsigned long val = INT_LOWPART (op);
11088
11089 /* If the low bit is zero, the value is the first 1 bit we find from
11090 the right. */
11091 if ((val & 1) == 0)
11092 {
37409796 11093 gcc_assert (val & 0xffffffff);
0ba1b2ff
AM
11094
11095 i = 30;
11096 while (((val >>= 1) & 1) == 0)
11097 --i;
11098
11099 return i;
11100 }
11101
11102 /* If the low bit is set and the high bit is not, or the mask is all
11103 1's, the value is 31. */
11104 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
11105 return 31;
11106
11107 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
11108 from the left. */
11109 i = 0;
11110 while (((val <<= 1) & 0x80000000) != 0)
11111 ++i;
11112
11113 return i;
11114}
11115
c4501e62
JJ
11116/* Locate some local-dynamic symbol still in use by this function
11117 so that we can print its name in some tls_ld pattern. */
11118
11119static const char *
863d938c 11120rs6000_get_some_local_dynamic_name (void)
c4501e62
JJ
11121{
11122 rtx insn;
11123
11124 if (cfun->machine->some_ld_name)
11125 return cfun->machine->some_ld_name;
11126
11127 for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
11128 if (INSN_P (insn)
11129 && for_each_rtx (&PATTERN (insn),
11130 rs6000_get_some_local_dynamic_name_1, 0))
11131 return cfun->machine->some_ld_name;
11132
37409796 11133 gcc_unreachable ();
c4501e62
JJ
11134}
11135
11136/* Helper function for rs6000_get_some_local_dynamic_name. */
11137
11138static int
a2369ed3 11139rs6000_get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
c4501e62
JJ
11140{
11141 rtx x = *px;
11142
11143 if (GET_CODE (x) == SYMBOL_REF)
11144 {
11145 const char *str = XSTR (x, 0);
11146 if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
11147 {
11148 cfun->machine->some_ld_name = str;
11149 return 1;
11150 }
11151 }
11152
11153 return 0;
11154}
11155
85b776df
AM
11156/* Write out a function code label. */
11157
11158void
11159rs6000_output_function_entry (FILE *file, const char *fname)
11160{
11161 if (fname[0] != '.')
11162 {
11163 switch (DEFAULT_ABI)
11164 {
11165 default:
37409796 11166 gcc_unreachable ();
85b776df
AM
11167
11168 case ABI_AIX:
11169 if (DOT_SYMBOLS)
11170 putc ('.', file);
11171 else
11172 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "L.");
11173 break;
11174
11175 case ABI_V4:
11176 case ABI_DARWIN:
11177 break;
11178 }
11179 }
11180 if (TARGET_AIX)
11181 RS6000_OUTPUT_BASENAME (file, fname);
11182 else
11183 assemble_name (file, fname);
11184}
11185
9878760c
RK
11186/* Print an operand. Recognize special options, documented below. */
11187
38c1f2d7 11188#if TARGET_ELF
d9407988 11189#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 11190#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
11191#else
11192#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 11193#define SMALL_DATA_REG 0
ba5e43aa
MM
11194#endif
11195
9878760c 11196void
a2369ed3 11197print_operand (FILE *file, rtx x, int code)
9878760c
RK
11198{
11199 int i;
a260abc9 11200 HOST_WIDE_INT val;
0ba1b2ff 11201 unsigned HOST_WIDE_INT uval;
9878760c
RK
11202
11203 switch (code)
11204 {
a8b3aeda 11205 case '.':
a85d226b
RK
11206 /* Write out an instruction after the call which may be replaced
11207 with glue code by the loader. This depends on the AIX version. */
11208 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
11209 return;
11210
81eace42
GK
11211 /* %a is output_address. */
11212
9854d9ed
RK
11213 case 'A':
11214 /* If X is a constant integer whose low-order 5 bits are zero,
11215 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 11216 in the AIX assembler where "sri" with a zero shift count
20e26713 11217 writes a trash instruction. */
9854d9ed 11218 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 11219 putc ('l', file);
9854d9ed 11220 else
76229ac8 11221 putc ('r', file);
9854d9ed
RK
11222 return;
11223
11224 case 'b':
e2c953b6
DE
11225 /* If constant, low-order 16 bits of constant, unsigned.
11226 Otherwise, write normally. */
11227 if (INT_P (x))
11228 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
11229 else
11230 print_operand (file, x, 0);
cad12a8d
RK
11231 return;
11232
a260abc9
DE
11233 case 'B':
11234 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
11235 for 64-bit mask direction. */
9390387d 11236 putc (((INT_LOWPART (x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 11237 return;
a260abc9 11238
81eace42
GK
11239 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
11240 output_operand. */
11241
423c1189
AH
11242 case 'c':
11243 /* X is a CR register. Print the number of the GT bit of the CR. */
11244 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11245 output_operand_lossage ("invalid %%E value");
11246 else
11247 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 1);
11248 return;
11249
11250 case 'D':
cef6b86c 11251 /* Like 'J' but get to the GT bit only. */
37409796 11252 gcc_assert (GET_CODE (x) == REG);
423c1189 11253
cef6b86c
EB
11254 /* Bit 1 is GT bit. */
11255 i = 4 * (REGNO (x) - CR0_REGNO) + 1;
423c1189 11256
cef6b86c
EB
11257 /* Add one for shift count in rlinm for scc. */
11258 fprintf (file, "%d", i + 1);
423c1189
AH
11259 return;
11260
9854d9ed 11261 case 'E':
39a10a29 11262 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
11263 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11264 output_operand_lossage ("invalid %%E value");
78fbdbf7 11265 else
39a10a29 11266 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 11267 return;
9854d9ed
RK
11268
11269 case 'f':
11270 /* X is a CR register. Print the shift count needed to move it
11271 to the high-order four bits. */
11272 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11273 output_operand_lossage ("invalid %%f value");
11274 else
9ebbca7d 11275 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
11276 return;
11277
11278 case 'F':
11279 /* Similar, but print the count for the rotate in the opposite
11280 direction. */
11281 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11282 output_operand_lossage ("invalid %%F value");
11283 else
9ebbca7d 11284 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
11285 return;
11286
11287 case 'G':
11288 /* X is a constant integer. If it is negative, print "m",
43aa4e05 11289 otherwise print "z". This is to make an aze or ame insn. */
9854d9ed
RK
11290 if (GET_CODE (x) != CONST_INT)
11291 output_operand_lossage ("invalid %%G value");
11292 else if (INTVAL (x) >= 0)
76229ac8 11293 putc ('z', file);
9854d9ed 11294 else
76229ac8 11295 putc ('m', file);
9854d9ed 11296 return;
e2c953b6 11297
9878760c 11298 case 'h':
a4f6c312
SS
11299 /* If constant, output low-order five bits. Otherwise, write
11300 normally. */
9878760c 11301 if (INT_P (x))
5f59ecb7 11302 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
11303 else
11304 print_operand (file, x, 0);
11305 return;
11306
64305719 11307 case 'H':
a4f6c312
SS
11308 /* If constant, output low-order six bits. Otherwise, write
11309 normally. */
64305719 11310 if (INT_P (x))
5f59ecb7 11311 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
11312 else
11313 print_operand (file, x, 0);
11314 return;
11315
9854d9ed
RK
11316 case 'I':
11317 /* Print `i' if this is a constant, else nothing. */
9878760c 11318 if (INT_P (x))
76229ac8 11319 putc ('i', file);
9878760c
RK
11320 return;
11321
9854d9ed
RK
11322 case 'j':
11323 /* Write the bit number in CCR for jump. */
11324 i = ccr_bit (x, 0);
11325 if (i == -1)
11326 output_operand_lossage ("invalid %%j code");
9878760c 11327 else
9854d9ed 11328 fprintf (file, "%d", i);
9878760c
RK
11329 return;
11330
9854d9ed
RK
11331 case 'J':
11332 /* Similar, but add one for shift count in rlinm for scc and pass
11333 scc flag to `ccr_bit'. */
11334 i = ccr_bit (x, 1);
11335 if (i == -1)
11336 output_operand_lossage ("invalid %%J code");
11337 else
a0466a68
RK
11338 /* If we want bit 31, write a shift count of zero, not 32. */
11339 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
11340 return;
11341
9854d9ed
RK
11342 case 'k':
11343 /* X must be a constant. Write the 1's complement of the
11344 constant. */
9878760c 11345 if (! INT_P (x))
9854d9ed 11346 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
11347 else
11348 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
11349 return;
11350
81eace42 11351 case 'K':
9ebbca7d
GK
11352 /* X must be a symbolic constant on ELF. Write an
11353 expression suitable for an 'addi' that adds in the low 16
11354 bits of the MEM. */
11355 if (GET_CODE (x) != CONST)
11356 {
11357 print_operand_address (file, x);
11358 fputs ("@l", file);
11359 }
11360 else
11361 {
11362 if (GET_CODE (XEXP (x, 0)) != PLUS
11363 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
11364 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
11365 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 11366 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
11367 print_operand_address (file, XEXP (XEXP (x, 0), 0));
11368 fputs ("@l", file);
ed8d2920
MM
11369 /* For GNU as, there must be a non-alphanumeric character
11370 between 'l' and the number. The '-' is added by
11371 print_operand() already. */
11372 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
11373 fputs ("+", file);
9ebbca7d
GK
11374 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
11375 }
81eace42
GK
11376 return;
11377
11378 /* %l is output_asm_label. */
9ebbca7d 11379
9854d9ed
RK
11380 case 'L':
11381 /* Write second word of DImode or DFmode reference. Works on register
11382 or non-indexed memory only. */
11383 if (GET_CODE (x) == REG)
fb5c67a7 11384 fputs (reg_names[REGNO (x) + 1], file);
9854d9ed
RK
11385 else if (GET_CODE (x) == MEM)
11386 {
11387 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 11388 we have already done it, we can just use an offset of word. */
9854d9ed
RK
11389 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11390 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
11391 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
11392 UNITS_PER_WORD));
6fb5fa3c
DB
11393 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
11394 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
11395 UNITS_PER_WORD));
9854d9ed 11396 else
d7624dc0
RK
11397 output_address (XEXP (adjust_address_nv (x, SImode,
11398 UNITS_PER_WORD),
11399 0));
ed8908e7 11400
ba5e43aa 11401 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
11402 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11403 reg_names[SMALL_DATA_REG]);
9854d9ed 11404 }
9878760c 11405 return;
f676971a 11406
9878760c
RK
11407 case 'm':
11408 /* MB value for a mask operand. */
b1765bde 11409 if (! mask_operand (x, SImode))
9878760c
RK
11410 output_operand_lossage ("invalid %%m value");
11411
0ba1b2ff 11412 fprintf (file, "%d", extract_MB (x));
9878760c
RK
11413 return;
11414
11415 case 'M':
11416 /* ME value for a mask operand. */
b1765bde 11417 if (! mask_operand (x, SImode))
a260abc9 11418 output_operand_lossage ("invalid %%M value");
9878760c 11419
0ba1b2ff 11420 fprintf (file, "%d", extract_ME (x));
9878760c
RK
11421 return;
11422
81eace42
GK
11423 /* %n outputs the negative of its operand. */
11424
9878760c
RK
11425 case 'N':
11426 /* Write the number of elements in the vector times 4. */
11427 if (GET_CODE (x) != PARALLEL)
11428 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
11429 else
11430 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
11431 return;
11432
11433 case 'O':
11434 /* Similar, but subtract 1 first. */
11435 if (GET_CODE (x) != PARALLEL)
1427100a 11436 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
11437 else
11438 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
11439 return;
11440
9854d9ed
RK
11441 case 'p':
11442 /* X is a CONST_INT that is a power of two. Output the logarithm. */
11443 if (! INT_P (x)
2bfcf297 11444 || INT_LOWPART (x) < 0
9854d9ed
RK
11445 || (i = exact_log2 (INT_LOWPART (x))) < 0)
11446 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
11447 else
11448 fprintf (file, "%d", i);
9854d9ed
RK
11449 return;
11450
9878760c
RK
11451 case 'P':
11452 /* The operand must be an indirect memory reference. The result
8bb418a3 11453 is the register name. */
9878760c
RK
11454 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
11455 || REGNO (XEXP (x, 0)) >= 32)
11456 output_operand_lossage ("invalid %%P value");
e2c953b6 11457 else
fb5c67a7 11458 fputs (reg_names[REGNO (XEXP (x, 0))], file);
9878760c
RK
11459 return;
11460
dfbdccdb
GK
11461 case 'q':
11462 /* This outputs the logical code corresponding to a boolean
11463 expression. The expression may have one or both operands
39a10a29 11464 negated (if one, only the first one). For condition register
c4ad648e
AM
11465 logical operations, it will also treat the negated
11466 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 11467 {
63bc1d05 11468 const char *const *t = 0;
dfbdccdb
GK
11469 const char *s;
11470 enum rtx_code code = GET_CODE (x);
11471 static const char * const tbl[3][3] = {
11472 { "and", "andc", "nor" },
11473 { "or", "orc", "nand" },
11474 { "xor", "eqv", "xor" } };
11475
11476 if (code == AND)
11477 t = tbl[0];
11478 else if (code == IOR)
11479 t = tbl[1];
11480 else if (code == XOR)
11481 t = tbl[2];
11482 else
11483 output_operand_lossage ("invalid %%q value");
11484
11485 if (GET_CODE (XEXP (x, 0)) != NOT)
11486 s = t[0];
11487 else
11488 {
11489 if (GET_CODE (XEXP (x, 1)) == NOT)
11490 s = t[2];
11491 else
11492 s = t[1];
11493 }
f676971a 11494
dfbdccdb
GK
11495 fputs (s, file);
11496 }
11497 return;
11498
2c4a9cff
DE
11499 case 'Q':
11500 if (TARGET_MFCRF)
3b6ce0af 11501 fputc (',', file);
5efb1046 11502 /* FALLTHRU */
2c4a9cff
DE
11503 else
11504 return;
11505
9854d9ed
RK
11506 case 'R':
11507 /* X is a CR register. Print the mask for `mtcrf'. */
11508 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
11509 output_operand_lossage ("invalid %%R value");
11510 else
9ebbca7d 11511 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 11512 return;
9854d9ed
RK
11513
11514 case 's':
11515 /* Low 5 bits of 32 - value */
11516 if (! INT_P (x))
11517 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
11518 else
11519 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 11520 return;
9854d9ed 11521
a260abc9 11522 case 'S':
0ba1b2ff 11523 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
11524 CONST_INT 32-bit mask is considered sign-extended so any
11525 transition must occur within the CONST_INT, not on the boundary. */
1990cd79 11526 if (! mask64_operand (x, DImode))
a260abc9
DE
11527 output_operand_lossage ("invalid %%S value");
11528
0ba1b2ff 11529 uval = INT_LOWPART (x);
a260abc9 11530
0ba1b2ff 11531 if (uval & 1) /* Clear Left */
a260abc9 11532 {
f099d360
GK
11533#if HOST_BITS_PER_WIDE_INT > 64
11534 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
11535#endif
0ba1b2ff 11536 i = 64;
a260abc9 11537 }
0ba1b2ff 11538 else /* Clear Right */
a260abc9 11539 {
0ba1b2ff 11540 uval = ~uval;
f099d360
GK
11541#if HOST_BITS_PER_WIDE_INT > 64
11542 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
11543#endif
0ba1b2ff 11544 i = 63;
a260abc9 11545 }
0ba1b2ff
AM
11546 while (uval != 0)
11547 --i, uval >>= 1;
37409796 11548 gcc_assert (i >= 0);
0ba1b2ff
AM
11549 fprintf (file, "%d", i);
11550 return;
a260abc9 11551
a3170dc6
AH
11552 case 't':
11553 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
37409796 11554 gcc_assert (GET_CODE (x) == REG && GET_MODE (x) == CCmode);
a3170dc6
AH
11555
11556 /* Bit 3 is OV bit. */
11557 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
11558
11559 /* If we want bit 31, write a shift count of zero, not 32. */
11560 fprintf (file, "%d", i == 31 ? 0 : i + 1);
11561 return;
11562
cccf3bdc
DE
11563 case 'T':
11564 /* Print the symbolic name of a branch target register. */
1de43f85
DE
11565 if (GET_CODE (x) != REG || (REGNO (x) != LR_REGNO
11566 && REGNO (x) != CTR_REGNO))
cccf3bdc 11567 output_operand_lossage ("invalid %%T value");
1de43f85 11568 else if (REGNO (x) == LR_REGNO)
cccf3bdc
DE
11569 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
11570 else
11571 fputs ("ctr", file);
11572 return;
11573
9854d9ed 11574 case 'u':
802a0058 11575 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
11576 if (! INT_P (x))
11577 output_operand_lossage ("invalid %%u value");
e2c953b6 11578 else
f676971a 11579 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
e2c953b6 11580 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
11581 return;
11582
802a0058
MM
11583 case 'v':
11584 /* High-order 16 bits of constant for use in signed operand. */
11585 if (! INT_P (x))
11586 output_operand_lossage ("invalid %%v value");
e2c953b6 11587 else
134c32f6
DE
11588 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
11589 (INT_LOWPART (x) >> 16) & 0xffff);
11590 return;
802a0058 11591
9854d9ed
RK
11592 case 'U':
11593 /* Print `u' if this has an auto-increment or auto-decrement. */
11594 if (GET_CODE (x) == MEM
11595 && (GET_CODE (XEXP (x, 0)) == PRE_INC
6fb5fa3c
DB
11596 || GET_CODE (XEXP (x, 0)) == PRE_DEC
11597 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY))
76229ac8 11598 putc ('u', file);
9854d9ed 11599 return;
9878760c 11600
e0cd0770
JC
11601 case 'V':
11602 /* Print the trap code for this operand. */
11603 switch (GET_CODE (x))
11604 {
11605 case EQ:
11606 fputs ("eq", file); /* 4 */
11607 break;
11608 case NE:
11609 fputs ("ne", file); /* 24 */
11610 break;
11611 case LT:
11612 fputs ("lt", file); /* 16 */
11613 break;
11614 case LE:
11615 fputs ("le", file); /* 20 */
11616 break;
11617 case GT:
11618 fputs ("gt", file); /* 8 */
11619 break;
11620 case GE:
11621 fputs ("ge", file); /* 12 */
11622 break;
11623 case LTU:
11624 fputs ("llt", file); /* 2 */
11625 break;
11626 case LEU:
11627 fputs ("lle", file); /* 6 */
11628 break;
11629 case GTU:
11630 fputs ("lgt", file); /* 1 */
11631 break;
11632 case GEU:
11633 fputs ("lge", file); /* 5 */
11634 break;
11635 default:
37409796 11636 gcc_unreachable ();
e0cd0770
JC
11637 }
11638 break;
11639
9854d9ed
RK
11640 case 'w':
11641 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
11642 normally. */
11643 if (INT_P (x))
f676971a 11644 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
5f59ecb7 11645 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
11646 else
11647 print_operand (file, x, 0);
9878760c
RK
11648 return;
11649
9854d9ed 11650 case 'W':
e2c953b6 11651 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
11652 val = (GET_CODE (x) == CONST_INT
11653 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
11654
11655 if (val < 0)
11656 i = -1;
9854d9ed 11657 else
e2c953b6
DE
11658 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
11659 if ((val <<= 1) < 0)
11660 break;
11661
11662#if HOST_BITS_PER_WIDE_INT == 32
11663 if (GET_CODE (x) == CONST_INT && i >= 0)
11664 i += 32; /* zero-extend high-part was all 0's */
11665 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
11666 {
11667 val = CONST_DOUBLE_LOW (x);
11668
37409796
NS
11669 gcc_assert (val);
11670 if (val < 0)
e2c953b6
DE
11671 --i;
11672 else
11673 for ( ; i < 64; i++)
11674 if ((val <<= 1) < 0)
11675 break;
11676 }
11677#endif
11678
11679 fprintf (file, "%d", i + 1);
9854d9ed 11680 return;
9878760c 11681
9854d9ed
RK
11682 case 'X':
11683 if (GET_CODE (x) == MEM
6fb5fa3c
DB
11684 && (legitimate_indexed_address_p (XEXP (x, 0), 0)
11685 || (GET_CODE (XEXP (x, 0)) == PRE_MODIFY
11686 && legitimate_indexed_address_p (XEXP (XEXP (x, 0), 1), 0))))
76229ac8 11687 putc ('x', file);
9854d9ed 11688 return;
9878760c 11689
9854d9ed
RK
11690 case 'Y':
11691 /* Like 'L', for third word of TImode */
11692 if (GET_CODE (x) == REG)
fb5c67a7 11693 fputs (reg_names[REGNO (x) + 2], file);
9854d9ed 11694 else if (GET_CODE (x) == MEM)
9878760c 11695 {
9854d9ed
RK
11696 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11697 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 11698 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
6fb5fa3c
DB
11699 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
11700 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 11701 else
d7624dc0 11702 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 11703 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
11704 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11705 reg_names[SMALL_DATA_REG]);
9878760c
RK
11706 }
11707 return;
f676971a 11708
9878760c 11709 case 'z':
b4ac57ab
RS
11710 /* X is a SYMBOL_REF. Write out the name preceded by a
11711 period and without any trailing data in brackets. Used for function
4d30c363
MM
11712 names. If we are configured for System V (or the embedded ABI) on
11713 the PowerPC, do not emit the period, since those systems do not use
11714 TOCs and the like. */
37409796 11715 gcc_assert (GET_CODE (x) == SYMBOL_REF);
9878760c 11716
c4ad648e
AM
11717 /* Mark the decl as referenced so that cgraph will output the
11718 function. */
9bf6462a 11719 if (SYMBOL_REF_DECL (x))
c4ad648e 11720 mark_decl_referenced (SYMBOL_REF_DECL (x));
9bf6462a 11721
85b776df 11722 /* For macho, check to see if we need a stub. */
f9da97f0
AP
11723 if (TARGET_MACHO)
11724 {
11725 const char *name = XSTR (x, 0);
a031e781 11726#if TARGET_MACHO
3b48085e 11727 if (MACHOPIC_INDIRECT
11abc112
MM
11728 && machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
11729 name = machopic_indirection_name (x, /*stub_p=*/true);
f9da97f0
AP
11730#endif
11731 assemble_name (file, name);
11732 }
85b776df 11733 else if (!DOT_SYMBOLS)
9739c90c 11734 assemble_name (file, XSTR (x, 0));
85b776df
AM
11735 else
11736 rs6000_output_function_entry (file, XSTR (x, 0));
9878760c
RK
11737 return;
11738
9854d9ed
RK
11739 case 'Z':
11740 /* Like 'L', for last word of TImode. */
11741 if (GET_CODE (x) == REG)
fb5c67a7 11742 fputs (reg_names[REGNO (x) + 3], file);
9854d9ed
RK
11743 else if (GET_CODE (x) == MEM)
11744 {
11745 if (GET_CODE (XEXP (x, 0)) == PRE_INC
11746 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 11747 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
6fb5fa3c
DB
11748 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
11749 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 11750 else
d7624dc0 11751 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 11752 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
11753 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11754 reg_names[SMALL_DATA_REG]);
9854d9ed 11755 }
5c23c401 11756 return;
0ac081f6 11757
a3170dc6 11758 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
11759 case 'y':
11760 {
11761 rtx tmp;
11762
37409796 11763 gcc_assert (GET_CODE (x) == MEM);
0ac081f6
AH
11764
11765 tmp = XEXP (x, 0);
11766
90d3ff1c 11767 /* Ugly hack because %y is overloaded. */
8ef65e3d 11768 if ((TARGET_SPE || TARGET_E500_DOUBLE)
17caeff2
JM
11769 && (GET_MODE_SIZE (GET_MODE (x)) == 8
11770 || GET_MODE (x) == TFmode
11771 || GET_MODE (x) == TImode))
a3170dc6
AH
11772 {
11773 /* Handle [reg]. */
11774 if (GET_CODE (tmp) == REG)
11775 {
11776 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
11777 break;
11778 }
11779 /* Handle [reg+UIMM]. */
11780 else if (GET_CODE (tmp) == PLUS &&
11781 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
11782 {
11783 int x;
11784
37409796 11785 gcc_assert (GET_CODE (XEXP (tmp, 0)) == REG);
a3170dc6
AH
11786
11787 x = INTVAL (XEXP (tmp, 1));
11788 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
11789 break;
11790 }
11791
11792 /* Fall through. Must be [reg+reg]. */
11793 }
850e8d3d
DN
11794 if (TARGET_ALTIVEC
11795 && GET_CODE (tmp) == AND
11796 && GET_CODE (XEXP (tmp, 1)) == CONST_INT
11797 && INTVAL (XEXP (tmp, 1)) == -16)
11798 tmp = XEXP (tmp, 0);
0ac081f6 11799 if (GET_CODE (tmp) == REG)
c62f2db5 11800 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
37409796 11801 else
0ac081f6 11802 {
37409796 11803 gcc_assert (GET_CODE (tmp) == PLUS
9024f4b8
AM
11804 && REG_P (XEXP (tmp, 0))
11805 && REG_P (XEXP (tmp, 1)));
bb8df8a6 11806
0ac081f6
AH
11807 if (REGNO (XEXP (tmp, 0)) == 0)
11808 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
11809 reg_names[ REGNO (XEXP (tmp, 0)) ]);
11810 else
11811 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
11812 reg_names[ REGNO (XEXP (tmp, 1)) ]);
11813 }
0ac081f6
AH
11814 break;
11815 }
f676971a 11816
9878760c
RK
11817 case 0:
11818 if (GET_CODE (x) == REG)
11819 fprintf (file, "%s", reg_names[REGNO (x)]);
11820 else if (GET_CODE (x) == MEM)
11821 {
11822 /* We need to handle PRE_INC and PRE_DEC here, since we need to
11823 know the width from the mode. */
11824 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
11825 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
11826 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 11827 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
11828 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
11829 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
6fb5fa3c
DB
11830 else if (GET_CODE (XEXP (x, 0)) == PRE_MODIFY)
11831 output_address (XEXP (XEXP (x, 0), 1));
9878760c 11832 else
a54d04b7 11833 output_address (XEXP (x, 0));
9878760c
RK
11834 }
11835 else
a54d04b7 11836 output_addr_const (file, x);
a85d226b 11837 return;
9878760c 11838
c4501e62
JJ
11839 case '&':
11840 assemble_name (file, rs6000_get_some_local_dynamic_name ());
11841 return;
11842
9878760c
RK
11843 default:
11844 output_operand_lossage ("invalid %%xn code");
11845 }
11846}
11847\f
11848/* Print the address of an operand. */
11849
11850void
a2369ed3 11851print_operand_address (FILE *file, rtx x)
9878760c
RK
11852{
11853 if (GET_CODE (x) == REG)
4697a36c 11854 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
11855 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
11856 || GET_CODE (x) == LABEL_REF)
9878760c
RK
11857 {
11858 output_addr_const (file, x);
ba5e43aa 11859 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
11860 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
11861 reg_names[SMALL_DATA_REG]);
37409796
NS
11862 else
11863 gcc_assert (!TARGET_TOC);
9878760c
RK
11864 }
11865 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
11866 {
9024f4b8 11867 gcc_assert (REG_P (XEXP (x, 0)));
9878760c 11868 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
11869 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
11870 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 11871 else
4697a36c
MM
11872 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
11873 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
11874 }
11875 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
4a0a75dd
KG
11876 fprintf (file, HOST_WIDE_INT_PRINT_DEC "(%s)",
11877 INTVAL (XEXP (x, 1)), reg_names[ REGNO (XEXP (x, 0)) ]);
3cb999d8
DE
11878#if TARGET_ELF
11879 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
c4ad648e 11880 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
11881 {
11882 output_addr_const (file, XEXP (x, 1));
11883 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11884 }
c859cda6
DJ
11885#endif
11886#if TARGET_MACHO
11887 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
c4ad648e 11888 && CONSTANT_P (XEXP (x, 1)))
c859cda6
DJ
11889 {
11890 fprintf (file, "lo16(");
11891 output_addr_const (file, XEXP (x, 1));
11892 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
11893 }
3cb999d8 11894#endif
4d588c14 11895 else if (legitimate_constant_pool_address_p (x))
9ebbca7d 11896 {
2bfcf297 11897 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 11898 {
2bfcf297
DB
11899 rtx contains_minus = XEXP (x, 1);
11900 rtx minus, symref;
11901 const char *name;
f676971a 11902
9ebbca7d 11903 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 11904 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
11905 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
11906 contains_minus = XEXP (contains_minus, 0);
11907
2bfcf297
DB
11908 minus = XEXP (contains_minus, 0);
11909 symref = XEXP (minus, 0);
11910 XEXP (contains_minus, 0) = symref;
11911 if (TARGET_ELF)
11912 {
11913 char *newname;
11914
11915 name = XSTR (symref, 0);
11916 newname = alloca (strlen (name) + sizeof ("@toc"));
11917 strcpy (newname, name);
11918 strcat (newname, "@toc");
11919 XSTR (symref, 0) = newname;
11920 }
11921 output_addr_const (file, XEXP (x, 1));
11922 if (TARGET_ELF)
11923 XSTR (symref, 0) = name;
9ebbca7d
GK
11924 XEXP (contains_minus, 0) = minus;
11925 }
11926 else
11927 output_addr_const (file, XEXP (x, 1));
11928
11929 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
11930 }
9878760c 11931 else
37409796 11932 gcc_unreachable ();
9878760c
RK
11933}
11934\f
88cad84b 11935/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
11936 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
11937 is defined. It also needs to handle DI-mode objects on 64-bit
11938 targets. */
11939
11940static bool
a2369ed3 11941rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
301d03af 11942{
f4f4921e 11943#ifdef RELOCATABLE_NEEDS_FIXUP
301d03af 11944 /* Special handling for SI values. */
84dcde01 11945 if (RELOCATABLE_NEEDS_FIXUP && size == 4 && aligned_p)
301d03af 11946 {
301d03af 11947 static int recurse = 0;
f676971a 11948
301d03af
RS
11949 /* For -mrelocatable, we mark all addresses that need to be fixed up
11950 in the .fixup section. */
11951 if (TARGET_RELOCATABLE
d6b5193b
RS
11952 && in_section != toc_section
11953 && in_section != text_section
4325ca90 11954 && !unlikely_text_section_p (in_section)
301d03af
RS
11955 && !recurse
11956 && GET_CODE (x) != CONST_INT
11957 && GET_CODE (x) != CONST_DOUBLE
11958 && CONSTANT_P (x))
11959 {
11960 char buf[256];
11961
11962 recurse = 1;
11963 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
11964 fixuplabelno++;
11965 ASM_OUTPUT_LABEL (asm_out_file, buf);
11966 fprintf (asm_out_file, "\t.long\t(");
11967 output_addr_const (asm_out_file, x);
11968 fprintf (asm_out_file, ")@fixup\n");
11969 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
11970 ASM_OUTPUT_ALIGN (asm_out_file, 2);
11971 fprintf (asm_out_file, "\t.long\t");
11972 assemble_name (asm_out_file, buf);
11973 fprintf (asm_out_file, "\n\t.previous\n");
11974 recurse = 0;
11975 return true;
11976 }
11977 /* Remove initial .'s to turn a -mcall-aixdesc function
11978 address into the address of the descriptor, not the function
11979 itself. */
11980 else if (GET_CODE (x) == SYMBOL_REF
11981 && XSTR (x, 0)[0] == '.'
11982 && DEFAULT_ABI == ABI_AIX)
11983 {
11984 const char *name = XSTR (x, 0);
11985 while (*name == '.')
11986 name++;
11987
11988 fprintf (asm_out_file, "\t.long\t%s\n", name);
11989 return true;
11990 }
11991 }
f4f4921e 11992#endif /* RELOCATABLE_NEEDS_FIXUP */
301d03af
RS
11993 return default_assemble_integer (x, size, aligned_p);
11994}
93638d7a
AM
11995
11996#ifdef HAVE_GAS_HIDDEN
11997/* Emit an assembler directive to set symbol visibility for DECL to
11998 VISIBILITY_TYPE. */
11999
5add3202 12000static void
a2369ed3 12001rs6000_assemble_visibility (tree decl, int vis)
93638d7a 12002{
93638d7a
AM
12003 /* Functions need to have their entry point symbol visibility set as
12004 well as their descriptor symbol visibility. */
85b776df
AM
12005 if (DEFAULT_ABI == ABI_AIX
12006 && DOT_SYMBOLS
12007 && TREE_CODE (decl) == FUNCTION_DECL)
93638d7a 12008 {
25fdb4dc 12009 static const char * const visibility_types[] = {
c4ad648e 12010 NULL, "internal", "hidden", "protected"
25fdb4dc
RH
12011 };
12012
12013 const char *name, *type;
93638d7a
AM
12014
12015 name = ((* targetm.strip_name_encoding)
12016 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
25fdb4dc 12017 type = visibility_types[vis];
93638d7a 12018
25fdb4dc
RH
12019 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
12020 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
93638d7a 12021 }
25fdb4dc
RH
12022 else
12023 default_assemble_visibility (decl, vis);
93638d7a
AM
12024}
12025#endif
301d03af 12026\f
39a10a29 12027enum rtx_code
a2369ed3 12028rs6000_reverse_condition (enum machine_mode mode, enum rtx_code code)
39a10a29
GK
12029{
12030 /* Reversal of FP compares takes care -- an ordered compare
12031 becomes an unordered compare and vice versa. */
f676971a 12032 if (mode == CCFPmode
bc9ec0e0
GK
12033 && (!flag_finite_math_only
12034 || code == UNLT || code == UNLE || code == UNGT || code == UNGE
12035 || code == UNEQ || code == LTGT))
bab6226b 12036 return reverse_condition_maybe_unordered (code);
39a10a29 12037 else
bab6226b 12038 return reverse_condition (code);
39a10a29
GK
12039}
12040
39a10a29
GK
12041/* Generate a compare for CODE. Return a brand-new rtx that
12042 represents the result of the compare. */
a4f6c312 12043
39a10a29 12044static rtx
a2369ed3 12045rs6000_generate_compare (enum rtx_code code)
39a10a29
GK
12046{
12047 enum machine_mode comp_mode;
12048 rtx compare_result;
12049
12050 if (rs6000_compare_fp_p)
12051 comp_mode = CCFPmode;
12052 else if (code == GTU || code == LTU
c4ad648e 12053 || code == GEU || code == LEU)
39a10a29 12054 comp_mode = CCUNSmode;
60934f9c
NS
12055 else if ((code == EQ || code == NE)
12056 && GET_CODE (rs6000_compare_op0) == SUBREG
12057 && GET_CODE (rs6000_compare_op1) == SUBREG
12058 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op0)
12059 && SUBREG_PROMOTED_UNSIGNED_P (rs6000_compare_op1))
12060 /* These are unsigned values, perhaps there will be a later
12061 ordering compare that can be shared with this one.
12062 Unfortunately we cannot detect the signedness of the operands
12063 for non-subregs. */
12064 comp_mode = CCUNSmode;
39a10a29
GK
12065 else
12066 comp_mode = CCmode;
12067
12068 /* First, the compare. */
12069 compare_result = gen_reg_rtx (comp_mode);
a3170dc6 12070
cef6b86c 12071 /* E500 FP compare instructions on the GPRs. Yuck! */
8ef65e3d 12072 if ((!TARGET_FPRS && TARGET_HARD_FLOAT)
993f19a8 12073 && rs6000_compare_fp_p)
a3170dc6 12074 {
64022b5d 12075 rtx cmp, or_result, compare_result2;
4d4cbc0e
AH
12076 enum machine_mode op_mode = GET_MODE (rs6000_compare_op0);
12077
12078 if (op_mode == VOIDmode)
12079 op_mode = GET_MODE (rs6000_compare_op1);
a3170dc6 12080
cef6b86c
EB
12081 /* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
12082 This explains the following mess. */
423c1189 12083
a3170dc6
AH
12084 switch (code)
12085 {
423c1189 12086 case EQ: case UNEQ: case NE: case LTGT:
37409796
NS
12087 switch (op_mode)
12088 {
12089 case SFmode:
12090 cmp = flag_unsafe_math_optimizations
12091 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
12092 rs6000_compare_op1)
12093 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
12094 rs6000_compare_op1);
12095 break;
12096
12097 case DFmode:
12098 cmp = flag_unsafe_math_optimizations
12099 ? gen_tstdfeq_gpr (compare_result, rs6000_compare_op0,
12100 rs6000_compare_op1)
12101 : gen_cmpdfeq_gpr (compare_result, rs6000_compare_op0,
12102 rs6000_compare_op1);
12103 break;
12104
17caeff2
JM
12105 case TFmode:
12106 cmp = flag_unsafe_math_optimizations
12107 ? gen_tsttfeq_gpr (compare_result, rs6000_compare_op0,
12108 rs6000_compare_op1)
12109 : gen_cmptfeq_gpr (compare_result, rs6000_compare_op0,
12110 rs6000_compare_op1);
12111 break;
12112
37409796
NS
12113 default:
12114 gcc_unreachable ();
12115 }
a3170dc6 12116 break;
bb8df8a6 12117
423c1189 12118 case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
37409796
NS
12119 switch (op_mode)
12120 {
12121 case SFmode:
12122 cmp = flag_unsafe_math_optimizations
12123 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
12124 rs6000_compare_op1)
12125 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
12126 rs6000_compare_op1);
12127 break;
bb8df8a6 12128
37409796
NS
12129 case DFmode:
12130 cmp = flag_unsafe_math_optimizations
12131 ? gen_tstdfgt_gpr (compare_result, rs6000_compare_op0,
12132 rs6000_compare_op1)
12133 : gen_cmpdfgt_gpr (compare_result, rs6000_compare_op0,
12134 rs6000_compare_op1);
12135 break;
12136
17caeff2
JM
12137 case TFmode:
12138 cmp = flag_unsafe_math_optimizations
12139 ? gen_tsttfgt_gpr (compare_result, rs6000_compare_op0,
12140 rs6000_compare_op1)
12141 : gen_cmptfgt_gpr (compare_result, rs6000_compare_op0,
12142 rs6000_compare_op1);
12143 break;
12144
37409796
NS
12145 default:
12146 gcc_unreachable ();
12147 }
a3170dc6 12148 break;
bb8df8a6 12149
423c1189 12150 case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
37409796
NS
12151 switch (op_mode)
12152 {
12153 case SFmode:
12154 cmp = flag_unsafe_math_optimizations
12155 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
12156 rs6000_compare_op1)
12157 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
12158 rs6000_compare_op1);
12159 break;
bb8df8a6 12160
37409796
NS
12161 case DFmode:
12162 cmp = flag_unsafe_math_optimizations
12163 ? gen_tstdflt_gpr (compare_result, rs6000_compare_op0,
12164 rs6000_compare_op1)
12165 : gen_cmpdflt_gpr (compare_result, rs6000_compare_op0,
12166 rs6000_compare_op1);
12167 break;
12168
17caeff2
JM
12169 case TFmode:
12170 cmp = flag_unsafe_math_optimizations
12171 ? gen_tsttflt_gpr (compare_result, rs6000_compare_op0,
12172 rs6000_compare_op1)
12173 : gen_cmptflt_gpr (compare_result, rs6000_compare_op0,
12174 rs6000_compare_op1);
12175 break;
12176
37409796
NS
12177 default:
12178 gcc_unreachable ();
12179 }
a3170dc6 12180 break;
4d4cbc0e 12181 default:
37409796 12182 gcc_unreachable ();
a3170dc6
AH
12183 }
12184
12185 /* Synthesize LE and GE from LT/GT || EQ. */
12186 if (code == LE || code == GE || code == LEU || code == GEU)
12187 {
a3170dc6
AH
12188 emit_insn (cmp);
12189
12190 switch (code)
12191 {
12192 case LE: code = LT; break;
12193 case GE: code = GT; break;
12194 case LEU: code = LT; break;
12195 case GEU: code = GT; break;
37409796 12196 default: gcc_unreachable ();
a3170dc6
AH
12197 }
12198
a3170dc6
AH
12199 compare_result2 = gen_reg_rtx (CCFPmode);
12200
12201 /* Do the EQ. */
37409796
NS
12202 switch (op_mode)
12203 {
12204 case SFmode:
12205 cmp = flag_unsafe_math_optimizations
12206 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
12207 rs6000_compare_op1)
12208 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
12209 rs6000_compare_op1);
12210 break;
12211
12212 case DFmode:
12213 cmp = flag_unsafe_math_optimizations
12214 ? gen_tstdfeq_gpr (compare_result2, rs6000_compare_op0,
12215 rs6000_compare_op1)
12216 : gen_cmpdfeq_gpr (compare_result2, rs6000_compare_op0,
12217 rs6000_compare_op1);
12218 break;
12219
17caeff2
JM
12220 case TFmode:
12221 cmp = flag_unsafe_math_optimizations
12222 ? gen_tsttfeq_gpr (compare_result2, rs6000_compare_op0,
12223 rs6000_compare_op1)
12224 : gen_cmptfeq_gpr (compare_result2, rs6000_compare_op0,
12225 rs6000_compare_op1);
12226 break;
12227
37409796
NS
12228 default:
12229 gcc_unreachable ();
12230 }
a3170dc6
AH
12231 emit_insn (cmp);
12232
a3170dc6 12233 /* OR them together. */
64022b5d
AH
12234 or_result = gen_reg_rtx (CCFPmode);
12235 cmp = gen_e500_cr_ior_compare (or_result, compare_result,
12236 compare_result2);
a3170dc6
AH
12237 compare_result = or_result;
12238 code = EQ;
12239 }
12240 else
12241 {
a3170dc6 12242 if (code == NE || code == LTGT)
a3170dc6 12243 code = NE;
423c1189
AH
12244 else
12245 code = EQ;
a3170dc6
AH
12246 }
12247
12248 emit_insn (cmp);
12249 }
12250 else
de17c25f
DE
12251 {
12252 /* Generate XLC-compatible TFmode compare as PARALLEL with extra
12253 CLOBBERs to match cmptf_internal2 pattern. */
12254 if (comp_mode == CCFPmode && TARGET_XL_COMPAT
12255 && GET_MODE (rs6000_compare_op0) == TFmode
602ea4d3 12256 && !TARGET_IEEEQUAD
de17c25f
DE
12257 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128)
12258 emit_insn (gen_rtx_PARALLEL (VOIDmode,
12259 gen_rtvec (9,
12260 gen_rtx_SET (VOIDmode,
12261 compare_result,
12262 gen_rtx_COMPARE (comp_mode,
12263 rs6000_compare_op0,
12264 rs6000_compare_op1)),
12265 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12266 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12267 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12268 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12269 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12270 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12271 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)),
12272 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (DFmode)))));
3aebbe5f
JJ
12273 else if (GET_CODE (rs6000_compare_op1) == UNSPEC
12274 && XINT (rs6000_compare_op1, 1) == UNSPEC_SP_TEST)
12275 {
12276 rtx op1 = XVECEXP (rs6000_compare_op1, 0, 0);
12277 comp_mode = CCEQmode;
12278 compare_result = gen_reg_rtx (CCEQmode);
12279 if (TARGET_64BIT)
12280 emit_insn (gen_stack_protect_testdi (compare_result,
12281 rs6000_compare_op0, op1));
12282 else
12283 emit_insn (gen_stack_protect_testsi (compare_result,
12284 rs6000_compare_op0, op1));
12285 }
de17c25f
DE
12286 else
12287 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
12288 gen_rtx_COMPARE (comp_mode,
12289 rs6000_compare_op0,
12290 rs6000_compare_op1)));
12291 }
f676971a 12292
ca5adc63 12293 /* Some kinds of FP comparisons need an OR operation;
e7108df9 12294 under flag_finite_math_only we don't bother. */
39a10a29 12295 if (rs6000_compare_fp_p
e7108df9 12296 && !flag_finite_math_only
8ef65e3d 12297 && !(TARGET_HARD_FLOAT && !TARGET_FPRS)
39a10a29
GK
12298 && (code == LE || code == GE
12299 || code == UNEQ || code == LTGT
12300 || code == UNGT || code == UNLT))
12301 {
12302 enum rtx_code or1, or2;
12303 rtx or1_rtx, or2_rtx, compare2_rtx;
12304 rtx or_result = gen_reg_rtx (CCEQmode);
f676971a 12305
39a10a29
GK
12306 switch (code)
12307 {
12308 case LE: or1 = LT; or2 = EQ; break;
12309 case GE: or1 = GT; or2 = EQ; break;
12310 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
12311 case LTGT: or1 = LT; or2 = GT; break;
12312 case UNGT: or1 = UNORDERED; or2 = GT; break;
12313 case UNLT: or1 = UNORDERED; or2 = LT; break;
37409796 12314 default: gcc_unreachable ();
39a10a29
GK
12315 }
12316 validate_condition_mode (or1, comp_mode);
12317 validate_condition_mode (or2, comp_mode);
1c563bed
KH
12318 or1_rtx = gen_rtx_fmt_ee (or1, SImode, compare_result, const0_rtx);
12319 or2_rtx = gen_rtx_fmt_ee (or2, SImode, compare_result, const0_rtx);
39a10a29
GK
12320 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
12321 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
12322 const_true_rtx);
12323 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
12324
12325 compare_result = or_result;
12326 code = EQ;
12327 }
12328
12329 validate_condition_mode (code, GET_MODE (compare_result));
f676971a 12330
1c563bed 12331 return gen_rtx_fmt_ee (code, VOIDmode, compare_result, const0_rtx);
39a10a29
GK
12332}
12333
12334
12335/* Emit the RTL for an sCOND pattern. */
12336
12337void
a2369ed3 12338rs6000_emit_sCOND (enum rtx_code code, rtx result)
39a10a29
GK
12339{
12340 rtx condition_rtx;
12341 enum machine_mode op_mode;
b7053a3f 12342 enum rtx_code cond_code;
39a10a29
GK
12343
12344 condition_rtx = rs6000_generate_compare (code);
b7053a3f
GK
12345 cond_code = GET_CODE (condition_rtx);
12346
8ef65e3d 12347 if (rs6000_compare_fp_p
423c1189
AH
12348 && !TARGET_FPRS && TARGET_HARD_FLOAT)
12349 {
12350 rtx t;
12351
12352 PUT_MODE (condition_rtx, SImode);
12353 t = XEXP (condition_rtx, 0);
12354
37409796 12355 gcc_assert (cond_code == NE || cond_code == EQ);
423c1189
AH
12356
12357 if (cond_code == NE)
64022b5d 12358 emit_insn (gen_e500_flip_gt_bit (t, t));
423c1189 12359
64022b5d 12360 emit_insn (gen_move_from_CR_gt_bit (result, t));
423c1189
AH
12361 return;
12362 }
12363
b7053a3f
GK
12364 if (cond_code == NE
12365 || cond_code == GE || cond_code == LE
12366 || cond_code == GEU || cond_code == LEU
12367 || cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
12368 {
12369 rtx not_result = gen_reg_rtx (CCEQmode);
12370 rtx not_op, rev_cond_rtx;
12371 enum machine_mode cc_mode;
f676971a 12372
b7053a3f
GK
12373 cc_mode = GET_MODE (XEXP (condition_rtx, 0));
12374
1c563bed 12375 rev_cond_rtx = gen_rtx_fmt_ee (rs6000_reverse_condition (cc_mode, cond_code),
0f4c242b 12376 SImode, XEXP (condition_rtx, 0), const0_rtx);
b7053a3f
GK
12377 not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
12378 emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
12379 condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
12380 }
39a10a29
GK
12381
12382 op_mode = GET_MODE (rs6000_compare_op0);
12383 if (op_mode == VOIDmode)
12384 op_mode = GET_MODE (rs6000_compare_op1);
12385
12386 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
12387 {
12388 PUT_MODE (condition_rtx, DImode);
12389 convert_move (result, condition_rtx, 0);
12390 }
12391 else
12392 {
12393 PUT_MODE (condition_rtx, SImode);
12394 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
12395 }
12396}
12397
39a10a29
GK
12398/* Emit a branch of kind CODE to location LOC. */
12399
12400void
a2369ed3 12401rs6000_emit_cbranch (enum rtx_code code, rtx loc)
39a10a29
GK
12402{
12403 rtx condition_rtx, loc_ref;
12404
12405 condition_rtx = rs6000_generate_compare (code);
12406 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
12407 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
12408 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
12409 loc_ref, pc_rtx)));
12410}
12411
12a4e8c5
GK
12412/* Return the string to output a conditional branch to LABEL, which is
12413 the operand number of the label, or -1 if the branch is really a
f676971a 12414 conditional return.
12a4e8c5
GK
12415
12416 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
12417 condition code register and its mode specifies what kind of
12418 comparison we made.
12419
a0ab749a 12420 REVERSED is nonzero if we should reverse the sense of the comparison.
12a4e8c5
GK
12421
12422 INSN is the insn. */
12423
12424char *
a2369ed3 12425output_cbranch (rtx op, const char *label, int reversed, rtx insn)
12a4e8c5
GK
12426{
12427 static char string[64];
12428 enum rtx_code code = GET_CODE (op);
12429 rtx cc_reg = XEXP (op, 0);
12430 enum machine_mode mode = GET_MODE (cc_reg);
12431 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 12432 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
12433 int really_reversed = reversed ^ need_longbranch;
12434 char *s = string;
12435 const char *ccode;
12436 const char *pred;
12437 rtx note;
12438
39a10a29
GK
12439 validate_condition_mode (code, mode);
12440
12441 /* Work out which way this really branches. We could use
12442 reverse_condition_maybe_unordered here always but this
12443 makes the resulting assembler clearer. */
12a4e8c5 12444 if (really_reversed)
de40e1df
DJ
12445 {
12446 /* Reversal of FP compares takes care -- an ordered compare
12447 becomes an unordered compare and vice versa. */
12448 if (mode == CCFPmode)
12449 code = reverse_condition_maybe_unordered (code);
12450 else
12451 code = reverse_condition (code);
12452 }
12a4e8c5 12453
8ef65e3d 12454 if ((!TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
a3170dc6
AH
12455 {
12456 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
12457 to the GT bit. */
37409796
NS
12458 switch (code)
12459 {
12460 case EQ:
12461 /* Opposite of GT. */
12462 code = GT;
12463 break;
12464
12465 case NE:
12466 code = UNLE;
12467 break;
12468
12469 default:
12470 gcc_unreachable ();
12471 }
a3170dc6
AH
12472 }
12473
39a10a29 12474 switch (code)
12a4e8c5
GK
12475 {
12476 /* Not all of these are actually distinct opcodes, but
12477 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
12478 case NE: case LTGT:
12479 ccode = "ne"; break;
12480 case EQ: case UNEQ:
12481 ccode = "eq"; break;
f676971a 12482 case GE: case GEU:
50a0b056 12483 ccode = "ge"; break;
f676971a 12484 case GT: case GTU: case UNGT:
50a0b056 12485 ccode = "gt"; break;
f676971a 12486 case LE: case LEU:
50a0b056 12487 ccode = "le"; break;
f676971a 12488 case LT: case LTU: case UNLT:
50a0b056 12489 ccode = "lt"; break;
12a4e8c5
GK
12490 case UNORDERED: ccode = "un"; break;
12491 case ORDERED: ccode = "nu"; break;
12492 case UNGE: ccode = "nl"; break;
12493 case UNLE: ccode = "ng"; break;
12494 default:
37409796 12495 gcc_unreachable ();
12a4e8c5 12496 }
f676971a
EC
12497
12498 /* Maybe we have a guess as to how likely the branch is.
94a54f47 12499 The old mnemonics don't have a way to specify this information. */
f4857b9b 12500 pred = "";
12a4e8c5
GK
12501 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
12502 if (note != NULL_RTX)
12503 {
12504 /* PROB is the difference from 50%. */
12505 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
12506
12507 /* Only hint for highly probable/improbable branches on newer
12508 cpus as static prediction overrides processor dynamic
12509 prediction. For older cpus we may as well always hint, but
12510 assume not taken for branches that are very close to 50% as a
12511 mispredicted taken branch is more expensive than a
f676971a 12512 mispredicted not-taken branch. */
ec507f2d 12513 if (rs6000_always_hint
2c9e13f3
JH
12514 || (abs (prob) > REG_BR_PROB_BASE / 100 * 48
12515 && br_prob_note_reliable_p (note)))
f4857b9b
AM
12516 {
12517 if (abs (prob) > REG_BR_PROB_BASE / 20
12518 && ((prob > 0) ^ need_longbranch))
c4ad648e 12519 pred = "+";
f4857b9b
AM
12520 else
12521 pred = "-";
12522 }
12a4e8c5 12523 }
12a4e8c5
GK
12524
12525 if (label == NULL)
94a54f47 12526 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 12527 else
94a54f47 12528 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 12529
37c67319 12530 /* We need to escape any '%' characters in the reg_names string.
a3c9585f 12531 Assume they'd only be the first character.... */
37c67319
GK
12532 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
12533 *s++ = '%';
94a54f47 12534 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
12535
12536 if (label != NULL)
12537 {
12538 /* If the branch distance was too far, we may have to use an
12539 unconditional branch to go the distance. */
12540 if (need_longbranch)
44518ddd 12541 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
12542 else
12543 s += sprintf (s, ",%s", label);
12544 }
12545
12546 return string;
12547}
50a0b056 12548
64022b5d 12549/* Return the string to flip the GT bit on a CR. */
423c1189 12550char *
64022b5d 12551output_e500_flip_gt_bit (rtx dst, rtx src)
423c1189
AH
12552{
12553 static char string[64];
12554 int a, b;
12555
37409796
NS
12556 gcc_assert (GET_CODE (dst) == REG && CR_REGNO_P (REGNO (dst))
12557 && GET_CODE (src) == REG && CR_REGNO_P (REGNO (src)));
423c1189 12558
64022b5d
AH
12559 /* GT bit. */
12560 a = 4 * (REGNO (dst) - CR0_REGNO) + 1;
12561 b = 4 * (REGNO (src) - CR0_REGNO) + 1;
423c1189
AH
12562
12563 sprintf (string, "crnot %d,%d", a, b);
12564 return string;
12565}
12566
21213b4c
DP
12567/* Return insn index for the vector compare instruction for given CODE,
12568 and DEST_MODE, OP_MODE. Return INSN_NOT_AVAILABLE if valid insn is
12569 not available. */
12570
12571static int
94ff898d 12572get_vec_cmp_insn (enum rtx_code code,
21213b4c
DP
12573 enum machine_mode dest_mode,
12574 enum machine_mode op_mode)
12575{
12576 if (!TARGET_ALTIVEC)
12577 return INSN_NOT_AVAILABLE;
12578
12579 switch (code)
12580 {
12581 case EQ:
12582 if (dest_mode == V16QImode && op_mode == V16QImode)
12583 return UNSPEC_VCMPEQUB;
12584 if (dest_mode == V8HImode && op_mode == V8HImode)
12585 return UNSPEC_VCMPEQUH;
12586 if (dest_mode == V4SImode && op_mode == V4SImode)
12587 return UNSPEC_VCMPEQUW;
12588 if (dest_mode == V4SImode && op_mode == V4SFmode)
12589 return UNSPEC_VCMPEQFP;
12590 break;
12591 case GE:
12592 if (dest_mode == V4SImode && op_mode == V4SFmode)
12593 return UNSPEC_VCMPGEFP;
12594 case GT:
12595 if (dest_mode == V16QImode && op_mode == V16QImode)
12596 return UNSPEC_VCMPGTSB;
12597 if (dest_mode == V8HImode && op_mode == V8HImode)
12598 return UNSPEC_VCMPGTSH;
12599 if (dest_mode == V4SImode && op_mode == V4SImode)
12600 return UNSPEC_VCMPGTSW;
12601 if (dest_mode == V4SImode && op_mode == V4SFmode)
12602 return UNSPEC_VCMPGTFP;
12603 break;
12604 case GTU:
12605 if (dest_mode == V16QImode && op_mode == V16QImode)
12606 return UNSPEC_VCMPGTUB;
12607 if (dest_mode == V8HImode && op_mode == V8HImode)
12608 return UNSPEC_VCMPGTUH;
12609 if (dest_mode == V4SImode && op_mode == V4SImode)
12610 return UNSPEC_VCMPGTUW;
12611 break;
12612 default:
12613 break;
12614 }
12615 return INSN_NOT_AVAILABLE;
12616}
12617
12618/* Emit vector compare for operands OP0 and OP1 using code RCODE.
12619 DMODE is expected destination mode. This is a recursive function. */
12620
12621static rtx
12622rs6000_emit_vector_compare (enum rtx_code rcode,
12623 rtx op0, rtx op1,
12624 enum machine_mode dmode)
12625{
12626 int vec_cmp_insn;
12627 rtx mask;
12628 enum machine_mode dest_mode;
12629 enum machine_mode op_mode = GET_MODE (op1);
12630
37409796
NS
12631 gcc_assert (TARGET_ALTIVEC);
12632 gcc_assert (GET_MODE (op0) == GET_MODE (op1));
21213b4c
DP
12633
12634 /* Floating point vector compare instructions uses destination V4SImode.
12635 Move destination to appropriate mode later. */
12636 if (dmode == V4SFmode)
12637 dest_mode = V4SImode;
12638 else
12639 dest_mode = dmode;
12640
12641 mask = gen_reg_rtx (dest_mode);
12642 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
12643
12644 if (vec_cmp_insn == INSN_NOT_AVAILABLE)
12645 {
12646 bool swap_operands = false;
12647 bool try_again = false;
12648 switch (rcode)
12649 {
12650 case LT:
12651 rcode = GT;
12652 swap_operands = true;
12653 try_again = true;
12654 break;
12655 case LTU:
12656 rcode = GTU;
12657 swap_operands = true;
12658 try_again = true;
12659 break;
12660 case NE:
370df7db
JC
12661 case UNLE:
12662 case UNLT:
12663 case UNGE:
12664 case UNGT:
12665 /* Invert condition and try again.
12666 e.g., A != B becomes ~(A==B). */
21213b4c 12667 {
370df7db 12668 enum rtx_code rev_code;
21213b4c 12669 enum insn_code nor_code;
d1123cde 12670 rtx eq_rtx;
370df7db
JC
12671
12672 rev_code = reverse_condition_maybe_unordered (rcode);
d1123cde
MS
12673 eq_rtx = rs6000_emit_vector_compare (rev_code, op0, op1,
12674 dest_mode);
94ff898d 12675
166cdb08 12676 nor_code = optab_handler (one_cmpl_optab, (int)dest_mode)->insn_code;
37409796 12677 gcc_assert (nor_code != CODE_FOR_nothing);
21213b4c
DP
12678 emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
12679
12680 if (dmode != dest_mode)
12681 {
12682 rtx temp = gen_reg_rtx (dest_mode);
12683 convert_move (temp, mask, 0);
12684 return temp;
12685 }
12686 return mask;
12687 }
12688 break;
12689 case GE:
12690 case GEU:
12691 case LE:
12692 case LEU:
12693 /* Try GT/GTU/LT/LTU OR EQ */
12694 {
12695 rtx c_rtx, eq_rtx;
12696 enum insn_code ior_code;
12697 enum rtx_code new_code;
12698
37409796
NS
12699 switch (rcode)
12700 {
12701 case GE:
12702 new_code = GT;
12703 break;
12704
12705 case GEU:
12706 new_code = GTU;
12707 break;
12708
12709 case LE:
12710 new_code = LT;
12711 break;
12712
12713 case LEU:
12714 new_code = LTU;
12715 break;
12716
12717 default:
12718 gcc_unreachable ();
12719 }
21213b4c
DP
12720
12721 c_rtx = rs6000_emit_vector_compare (new_code,
12722 op0, op1, dest_mode);
12723 eq_rtx = rs6000_emit_vector_compare (EQ, op0, op1,
12724 dest_mode);
12725
166cdb08 12726 ior_code = optab_handler (ior_optab, (int)dest_mode)->insn_code;
37409796 12727 gcc_assert (ior_code != CODE_FOR_nothing);
21213b4c
DP
12728 emit_insn (GEN_FCN (ior_code) (mask, c_rtx, eq_rtx));
12729 if (dmode != dest_mode)
12730 {
12731 rtx temp = gen_reg_rtx (dest_mode);
12732 convert_move (temp, mask, 0);
12733 return temp;
12734 }
12735 return mask;
12736 }
12737 break;
12738 default:
37409796 12739 gcc_unreachable ();
21213b4c
DP
12740 }
12741
12742 if (try_again)
12743 {
12744 vec_cmp_insn = get_vec_cmp_insn (rcode, dest_mode, op_mode);
37409796
NS
12745 /* You only get two chances. */
12746 gcc_assert (vec_cmp_insn != INSN_NOT_AVAILABLE);
21213b4c
DP
12747 }
12748
12749 if (swap_operands)
12750 {
12751 rtx tmp;
12752 tmp = op0;
12753 op0 = op1;
12754 op1 = tmp;
12755 }
12756 }
12757
915167f5
GK
12758 emit_insn (gen_rtx_SET (VOIDmode, mask,
12759 gen_rtx_UNSPEC (dest_mode,
12760 gen_rtvec (2, op0, op1),
12761 vec_cmp_insn)));
21213b4c
DP
12762 if (dmode != dest_mode)
12763 {
12764 rtx temp = gen_reg_rtx (dest_mode);
12765 convert_move (temp, mask, 0);
12766 return temp;
12767 }
12768 return mask;
12769}
12770
12771/* Return vector select instruction for MODE. Return INSN_NOT_AVAILABLE, if
12772 valid insn doesn exist for given mode. */
12773
12774static int
12775get_vsel_insn (enum machine_mode mode)
12776{
12777 switch (mode)
12778 {
12779 case V4SImode:
12780 return UNSPEC_VSEL4SI;
12781 break;
12782 case V4SFmode:
12783 return UNSPEC_VSEL4SF;
12784 break;
12785 case V8HImode:
12786 return UNSPEC_VSEL8HI;
12787 break;
12788 case V16QImode:
12789 return UNSPEC_VSEL16QI;
12790 break;
12791 default:
12792 return INSN_NOT_AVAILABLE;
12793 break;
12794 }
12795 return INSN_NOT_AVAILABLE;
12796}
12797
12798/* Emit vector select insn where DEST is destination using
12799 operands OP1, OP2 and MASK. */
12800
12801static void
12802rs6000_emit_vector_select (rtx dest, rtx op1, rtx op2, rtx mask)
12803{
12804 rtx t, temp;
12805 enum machine_mode dest_mode = GET_MODE (dest);
12806 int vsel_insn_index = get_vsel_insn (GET_MODE (dest));
12807
12808 temp = gen_reg_rtx (dest_mode);
94ff898d 12809
bb8df8a6 12810 /* For each vector element, select op1 when mask is 1 otherwise
19f1ebc7 12811 select op2. */
915167f5
GK
12812 t = gen_rtx_SET (VOIDmode, temp,
12813 gen_rtx_UNSPEC (dest_mode,
12814 gen_rtvec (3, op2, op1, mask),
12815 vsel_insn_index));
21213b4c
DP
12816 emit_insn (t);
12817 emit_move_insn (dest, temp);
12818 return;
12819}
12820
94ff898d 12821/* Emit vector conditional expression.
21213b4c
DP
12822 DEST is destination. OP1 and OP2 are two VEC_COND_EXPR operands.
12823 CC_OP0 and CC_OP1 are the two operands for the relation operation COND. */
12824
12825int
12826rs6000_emit_vector_cond_expr (rtx dest, rtx op1, rtx op2,
12827 rtx cond, rtx cc_op0, rtx cc_op1)
12828{
12829 enum machine_mode dest_mode = GET_MODE (dest);
12830 enum rtx_code rcode = GET_CODE (cond);
12831 rtx mask;
12832
12833 if (!TARGET_ALTIVEC)
12834 return 0;
12835
12836 /* Get the vector mask for the given relational operations. */
12837 mask = rs6000_emit_vector_compare (rcode, cc_op0, cc_op1, dest_mode);
12838
12839 rs6000_emit_vector_select (dest, op1, op2, mask);
12840
12841 return 1;
12842}
12843
50a0b056
GK
12844/* Emit a conditional move: move TRUE_COND to DEST if OP of the
12845 operands of the last comparison is nonzero/true, FALSE_COND if it
12846 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 12847
50a0b056 12848int
a2369ed3 12849rs6000_emit_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
50a0b056
GK
12850{
12851 enum rtx_code code = GET_CODE (op);
12852 rtx op0 = rs6000_compare_op0;
12853 rtx op1 = rs6000_compare_op1;
12854 REAL_VALUE_TYPE c1;
3148ad6d
DJ
12855 enum machine_mode compare_mode = GET_MODE (op0);
12856 enum machine_mode result_mode = GET_MODE (dest);
50a0b056 12857 rtx temp;
add2402e 12858 bool is_against_zero;
50a0b056 12859
a3c9585f 12860 /* These modes should always match. */
a3170dc6
AH
12861 if (GET_MODE (op1) != compare_mode
12862 /* In the isel case however, we can use a compare immediate, so
12863 op1 may be a small constant. */
12864 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 12865 return 0;
178c3eff 12866 if (GET_MODE (true_cond) != result_mode)
3148ad6d 12867 return 0;
178c3eff 12868 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
12869 return 0;
12870
50a0b056 12871 /* First, work out if the hardware can do this at all, or
a3c9585f 12872 if it's too slow.... */
50a0b056 12873 if (! rs6000_compare_fp_p)
a3170dc6
AH
12874 {
12875 if (TARGET_ISEL)
12876 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
12877 return 0;
12878 }
8ef65e3d 12879 else if (TARGET_HARD_FLOAT && !TARGET_FPRS
ebb109ad 12880 && SCALAR_FLOAT_MODE_P (compare_mode))
fef98bf2 12881 return 0;
50a0b056 12882
add2402e 12883 is_against_zero = op1 == CONST0_RTX (compare_mode);
94ff898d 12884
add2402e
GK
12885 /* A floating-point subtract might overflow, underflow, or produce
12886 an inexact result, thus changing the floating-point flags, so it
12887 can't be generated if we care about that. It's safe if one side
12888 of the construct is zero, since then no subtract will be
12889 generated. */
ebb109ad 12890 if (SCALAR_FLOAT_MODE_P (compare_mode)
add2402e
GK
12891 && flag_trapping_math && ! is_against_zero)
12892 return 0;
12893
50a0b056
GK
12894 /* Eliminate half of the comparisons by switching operands, this
12895 makes the remaining code simpler. */
12896 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
bc9ec0e0 12897 || code == LTGT || code == LT || code == UNLE)
50a0b056
GK
12898 {
12899 code = reverse_condition_maybe_unordered (code);
12900 temp = true_cond;
12901 true_cond = false_cond;
12902 false_cond = temp;
12903 }
12904
12905 /* UNEQ and LTGT take four instructions for a comparison with zero,
12906 it'll probably be faster to use a branch here too. */
bc9ec0e0 12907 if (code == UNEQ && HONOR_NANS (compare_mode))
50a0b056 12908 return 0;
f676971a 12909
50a0b056
GK
12910 if (GET_CODE (op1) == CONST_DOUBLE)
12911 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
f676971a 12912
b6d08ca1 12913 /* We're going to try to implement comparisons by performing
50a0b056
GK
12914 a subtract, then comparing against zero. Unfortunately,
12915 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 12916 know that the operand is finite and the comparison
50a0b056 12917 would treat EQ different to UNORDERED, we can't do it. */
bc9ec0e0 12918 if (HONOR_INFINITIES (compare_mode)
50a0b056 12919 && code != GT && code != UNGE
045572c7 12920 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
12921 /* Constructs of the form (a OP b ? a : b) are safe. */
12922 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
f676971a 12923 || (! rtx_equal_p (op0, true_cond)
50a0b056
GK
12924 && ! rtx_equal_p (op1, true_cond))))
12925 return 0;
add2402e 12926
50a0b056
GK
12927 /* At this point we know we can use fsel. */
12928
12929 /* Reduce the comparison to a comparison against zero. */
add2402e
GK
12930 if (! is_against_zero)
12931 {
12932 temp = gen_reg_rtx (compare_mode);
12933 emit_insn (gen_rtx_SET (VOIDmode, temp,
12934 gen_rtx_MINUS (compare_mode, op0, op1)));
12935 op0 = temp;
12936 op1 = CONST0_RTX (compare_mode);
12937 }
50a0b056
GK
12938
12939 /* If we don't care about NaNs we can reduce some of the comparisons
12940 down to faster ones. */
bc9ec0e0 12941 if (! HONOR_NANS (compare_mode))
50a0b056
GK
12942 switch (code)
12943 {
12944 case GT:
12945 code = LE;
12946 temp = true_cond;
12947 true_cond = false_cond;
12948 false_cond = temp;
12949 break;
12950 case UNGE:
12951 code = GE;
12952 break;
12953 case UNEQ:
12954 code = EQ;
12955 break;
12956 default:
12957 break;
12958 }
12959
12960 /* Now, reduce everything down to a GE. */
12961 switch (code)
12962 {
12963 case GE:
12964 break;
12965
12966 case LE:
3148ad6d
DJ
12967 temp = gen_reg_rtx (compare_mode);
12968 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
12969 op0 = temp;
12970 break;
12971
12972 case ORDERED:
3148ad6d
DJ
12973 temp = gen_reg_rtx (compare_mode);
12974 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
12975 op0 = temp;
12976 break;
12977
12978 case EQ:
3148ad6d 12979 temp = gen_reg_rtx (compare_mode);
f676971a 12980 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
12981 gen_rtx_NEG (compare_mode,
12982 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
12983 op0 = temp;
12984 break;
12985
12986 case UNGE:
bc9ec0e0 12987 /* a UNGE 0 <-> (a GE 0 || -a UNLT 0) */
3148ad6d 12988 temp = gen_reg_rtx (result_mode);
50a0b056 12989 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 12990 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
12991 gen_rtx_GE (VOIDmode,
12992 op0, op1),
12993 true_cond, false_cond)));
bc9ec0e0
GK
12994 false_cond = true_cond;
12995 true_cond = temp;
50a0b056 12996
3148ad6d
DJ
12997 temp = gen_reg_rtx (compare_mode);
12998 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
12999 op0 = temp;
13000 break;
13001
13002 case GT:
bc9ec0e0 13003 /* a GT 0 <-> (a GE 0 && -a UNLT 0) */
3148ad6d 13004 temp = gen_reg_rtx (result_mode);
50a0b056 13005 emit_insn (gen_rtx_SET (VOIDmode, temp,
f676971a 13006 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
13007 gen_rtx_GE (VOIDmode,
13008 op0, op1),
13009 true_cond, false_cond)));
bc9ec0e0
GK
13010 true_cond = false_cond;
13011 false_cond = temp;
50a0b056 13012
3148ad6d
DJ
13013 temp = gen_reg_rtx (compare_mode);
13014 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
13015 op0 = temp;
13016 break;
13017
13018 default:
37409796 13019 gcc_unreachable ();
50a0b056
GK
13020 }
13021
13022 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 13023 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
13024 gen_rtx_GE (VOIDmode,
13025 op0, op1),
13026 true_cond, false_cond)));
13027 return 1;
13028}
13029
a3170dc6
AH
13030/* Same as above, but for ints (isel). */
13031
13032static int
a2369ed3 13033rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
a3170dc6
AH
13034{
13035 rtx condition_rtx, cr;
13036
13037 /* All isel implementations thus far are 32-bits. */
13038 if (GET_MODE (rs6000_compare_op0) != SImode)
13039 return 0;
13040
13041 /* We still have to do the compare, because isel doesn't do a
13042 compare, it just looks at the CRx bits set by a previous compare
13043 instruction. */
13044 condition_rtx = rs6000_generate_compare (GET_CODE (op));
13045 cr = XEXP (condition_rtx, 0);
13046
13047 if (GET_MODE (cr) == CCmode)
13048 emit_insn (gen_isel_signed (dest, condition_rtx,
13049 true_cond, false_cond, cr));
13050 else
13051 emit_insn (gen_isel_unsigned (dest, condition_rtx,
13052 true_cond, false_cond, cr));
13053
13054 return 1;
13055}
13056
13057const char *
a2369ed3 13058output_isel (rtx *operands)
a3170dc6
AH
13059{
13060 enum rtx_code code;
13061
13062 code = GET_CODE (operands[1]);
13063 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
13064 {
13065 PUT_CODE (operands[1], reverse_condition (code));
13066 return "isel %0,%3,%2,%j1";
13067 }
13068 else
13069 return "isel %0,%2,%3,%j1";
13070}
13071
50a0b056 13072void
a2369ed3 13073rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
50a0b056
GK
13074{
13075 enum machine_mode mode = GET_MODE (op0);
5dc8d536 13076 enum rtx_code c;
50a0b056 13077 rtx target;
5dc8d536
AH
13078
13079 if (code == SMAX || code == SMIN)
13080 c = GE;
13081 else
13082 c = GEU;
13083
50a0b056 13084 if (code == SMAX || code == UMAX)
f676971a 13085 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
13086 op0, op1, mode, 0);
13087 else
f676971a 13088 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056 13089 op1, op0, mode, 0);
37409796 13090 gcc_assert (target);
50a0b056
GK
13091 if (target != dest)
13092 emit_move_insn (dest, target);
13093}
46c07df8 13094
915167f5
GK
13095/* Emit instructions to perform a load-reserved/store-conditional operation.
13096 The operation performed is an atomic
13097 (set M (CODE:MODE M OP))
13098 If not NULL, BEFORE is atomically set to M before the operation, and
13099 AFTER is set to M after the operation (that is, (CODE:MODE M OP)).
bb8df8a6 13100 If SYNC_P then a memory barrier is emitted before the operation.
915167f5
GK
13101 Either OP or M may be wrapped in a NOT operation. */
13102
13103void
13104rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
13105 rtx m, rtx op, rtx before_param, rtx after_param,
13106 bool sync_p)
13107{
13108 enum machine_mode used_mode;
13109 rtx the_op, set_before, set_after, set_atomic, cc_scratch, before, after;
13110 rtx used_m;
13111 rtvec vec;
13112 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
13113 rtx shift = NULL_RTX;
bb8df8a6 13114
915167f5
GK
13115 if (sync_p)
13116 emit_insn (gen_memory_barrier ());
bb8df8a6 13117
915167f5
GK
13118 if (GET_CODE (m) == NOT)
13119 used_m = XEXP (m, 0);
13120 else
13121 used_m = m;
13122
13123 /* If this is smaller than SImode, we'll have to use SImode with
13124 adjustments. */
13125 if (mode == QImode || mode == HImode)
13126 {
13127 rtx newop, oldop;
13128
13129 if (MEM_ALIGN (used_m) >= 32)
13130 {
13131 int ishift = 0;
13132 if (BYTES_BIG_ENDIAN)
13133 ishift = GET_MODE_BITSIZE (SImode) - GET_MODE_BITSIZE (mode);
bb8df8a6 13134
915167f5 13135 shift = GEN_INT (ishift);
c75c6d11 13136 used_m = change_address (used_m, SImode, 0);
915167f5
GK
13137 }
13138 else
13139 {
13140 rtx addrSI, aligned_addr;
a9c9d3fa 13141 int shift_mask = mode == QImode ? 0x18 : 0x10;
bb8df8a6 13142
c75c6d11
JJ
13143 addrSI = gen_lowpart_common (SImode,
13144 force_reg (Pmode, XEXP (used_m, 0)));
13145 addrSI = force_reg (SImode, addrSI);
915167f5
GK
13146 shift = gen_reg_rtx (SImode);
13147
13148 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
a9c9d3fa
GK
13149 GEN_INT (shift_mask)));
13150 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
915167f5
GK
13151
13152 aligned_addr = expand_binop (Pmode, and_optab,
13153 XEXP (used_m, 0),
13154 GEN_INT (-4), NULL_RTX,
13155 1, OPTAB_LIB_WIDEN);
13156 used_m = change_address (used_m, SImode, aligned_addr);
13157 set_mem_align (used_m, 32);
915167f5 13158 }
c75c6d11
JJ
13159 /* It's safe to keep the old alias set of USED_M, because
13160 the operation is atomic and only affects the original
13161 USED_M. */
13162 if (GET_CODE (m) == NOT)
13163 m = gen_rtx_NOT (SImode, used_m);
13164 else
13165 m = used_m;
915167f5
GK
13166
13167 if (GET_CODE (op) == NOT)
13168 {
13169 oldop = lowpart_subreg (SImode, XEXP (op, 0), mode);
13170 oldop = gen_rtx_NOT (SImode, oldop);
13171 }
13172 else
13173 oldop = lowpart_subreg (SImode, op, mode);
9f0076e5 13174
915167f5
GK
13175 switch (code)
13176 {
13177 case IOR:
13178 case XOR:
13179 newop = expand_binop (SImode, and_optab,
13180 oldop, GEN_INT (imask), NULL_RTX,
13181 1, OPTAB_LIB_WIDEN);
13182 emit_insn (gen_ashlsi3 (newop, newop, shift));
13183 break;
13184
13185 case AND:
13186 newop = expand_binop (SImode, ior_optab,
13187 oldop, GEN_INT (~imask), NULL_RTX,
13188 1, OPTAB_LIB_WIDEN);
a9c9d3fa 13189 emit_insn (gen_rotlsi3 (newop, newop, shift));
915167f5
GK
13190 break;
13191
13192 case PLUS:
9f0076e5 13193 case MINUS:
915167f5
GK
13194 {
13195 rtx mask;
bb8df8a6 13196
915167f5
GK
13197 newop = expand_binop (SImode, and_optab,
13198 oldop, GEN_INT (imask), NULL_RTX,
13199 1, OPTAB_LIB_WIDEN);
13200 emit_insn (gen_ashlsi3 (newop, newop, shift));
13201
13202 mask = gen_reg_rtx (SImode);
13203 emit_move_insn (mask, GEN_INT (imask));
13204 emit_insn (gen_ashlsi3 (mask, mask, shift));
13205
9f0076e5
DE
13206 if (code == PLUS)
13207 newop = gen_rtx_PLUS (SImode, m, newop);
13208 else
13209 newop = gen_rtx_MINUS (SImode, m, newop);
13210 newop = gen_rtx_AND (SImode, newop, mask);
915167f5
GK
13211 newop = gen_rtx_IOR (SImode, newop,
13212 gen_rtx_AND (SImode,
13213 gen_rtx_NOT (SImode, mask),
13214 m));
13215 break;
13216 }
13217
13218 default:
13219 gcc_unreachable ();
13220 }
13221
a9c9d3fa
GK
13222 if (GET_CODE (m) == NOT)
13223 {
13224 rtx mask, xorm;
13225
13226 mask = gen_reg_rtx (SImode);
13227 emit_move_insn (mask, GEN_INT (imask));
13228 emit_insn (gen_ashlsi3 (mask, mask, shift));
13229
13230 xorm = gen_rtx_XOR (SImode, used_m, mask);
13231 /* Depending on the value of 'op', the XOR or the operation might
13232 be able to be simplified away. */
13233 newop = simplify_gen_binary (code, SImode, xorm, newop);
13234 }
915167f5
GK
13235 op = newop;
13236 used_mode = SImode;
13237 before = gen_reg_rtx (used_mode);
13238 after = gen_reg_rtx (used_mode);
13239 }
13240 else
13241 {
13242 used_mode = mode;
13243 before = before_param;
13244 after = after_param;
13245
13246 if (before == NULL_RTX)
13247 before = gen_reg_rtx (used_mode);
13248 if (after == NULL_RTX)
13249 after = gen_reg_rtx (used_mode);
13250 }
bb8df8a6 13251
9f0076e5
DE
13252 if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT)
13253 && used_mode != mode)
915167f5
GK
13254 the_op = op; /* Computed above. */
13255 else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
13256 the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
13257 else
13258 the_op = gen_rtx_fmt_ee (code, used_mode, m, op);
13259
13260 set_after = gen_rtx_SET (VOIDmode, after, the_op);
13261 set_before = gen_rtx_SET (VOIDmode, before, used_m);
13262 set_atomic = gen_rtx_SET (VOIDmode, used_m,
9f0076e5
DE
13263 gen_rtx_UNSPEC (used_mode,
13264 gen_rtvec (1, the_op),
13265 UNSPEC_SYNC_OP));
915167f5
GK
13266 cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
13267
9f0076e5 13268 if ((code == PLUS || code == MINUS) && used_mode != mode)
915167f5
GK
13269 vec = gen_rtvec (5, set_after, set_before, set_atomic, cc_scratch,
13270 gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (SImode)));
13271 else
13272 vec = gen_rtvec (4, set_after, set_before, set_atomic, cc_scratch);
13273 emit_insn (gen_rtx_PARALLEL (VOIDmode, vec));
13274
13275 /* Shift and mask the return values properly. */
13276 if (used_mode != mode && before_param)
13277 {
13278 emit_insn (gen_lshrsi3 (before, before, shift));
13279 convert_move (before_param, before, 1);
13280 }
13281
13282 if (used_mode != mode && after_param)
13283 {
13284 emit_insn (gen_lshrsi3 (after, after, shift));
13285 convert_move (after_param, after, 1);
13286 }
13287
13288 /* The previous sequence will end with a branch that's dependent on
13289 the conditional store, so placing an isync will ensure that no
13290 other instructions (especially, no load or store instructions)
13291 can start before the atomic operation completes. */
13292 if (sync_p)
13293 emit_insn (gen_isync ());
13294}
13295
b52110d4
DE
13296/* A subroutine of the atomic operation splitters. Jump to LABEL if
13297 COND is true. Mark the jump as unlikely to be taken. */
13298
13299static void
13300emit_unlikely_jump (rtx cond, rtx label)
13301{
13302 rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
13303 rtx x;
13304
13305 x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
13306 x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
13307 REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
13308}
13309
13310/* A subroutine of the atomic operation splitters. Emit a load-locked
13311 instruction in MODE. */
13312
13313static void
13314emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
13315{
13316 rtx (*fn) (rtx, rtx) = NULL;
13317 if (mode == SImode)
13318 fn = gen_load_locked_si;
13319 else if (mode == DImode)
13320 fn = gen_load_locked_di;
13321 emit_insn (fn (reg, mem));
13322}
13323
13324/* A subroutine of the atomic operation splitters. Emit a store-conditional
13325 instruction in MODE. */
13326
13327static void
13328emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
13329{
13330 rtx (*fn) (rtx, rtx, rtx) = NULL;
13331 if (mode == SImode)
13332 fn = gen_store_conditional_si;
13333 else if (mode == DImode)
13334 fn = gen_store_conditional_di;
13335
9f0076e5 13336 /* Emit sync before stwcx. to address PPC405 Erratum. */
b52110d4
DE
13337 if (PPC405_ERRATUM77)
13338 emit_insn (gen_memory_barrier ());
13339
13340 emit_insn (fn (res, mem, val));
13341}
13342
ea2c620c 13343/* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
bb8df8a6 13344 to perform. MEM is the memory on which to operate. VAL is the second
9f0076e5
DE
13345 operand of the binary operator. BEFORE and AFTER are optional locations to
13346 return the value of MEM either before of after the operation. SCRATCH is
13347 a scratch register. */
13348
13349void
13350rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val,
13351 rtx before, rtx after, rtx scratch)
13352{
13353 enum machine_mode mode = GET_MODE (mem);
13354 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13355
13356 emit_insn (gen_memory_barrier ());
13357
13358 label = gen_label_rtx ();
13359 emit_label (label);
13360 label = gen_rtx_LABEL_REF (VOIDmode, label);
13361
13362 if (before == NULL_RTX)
13363 before = scratch;
13364 emit_load_locked (mode, before, mem);
13365
13366 if (code == NOT)
13367 x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val);
13368 else if (code == AND)
13369 x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND);
13370 else
13371 x = gen_rtx_fmt_ee (code, mode, before, val);
13372
13373 if (after != NULL_RTX)
13374 emit_insn (gen_rtx_SET (VOIDmode, after, copy_rtx (x)));
13375 emit_insn (gen_rtx_SET (VOIDmode, scratch, x));
13376
13377 emit_store_conditional (mode, cond, mem, scratch);
13378
13379 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13380 emit_unlikely_jump (x, label);
13381
13382 emit_insn (gen_isync ());
13383}
13384
b52110d4
DE
13385/* Expand an atomic compare and swap operation. MEM is the memory on which
13386 to operate. OLDVAL is the old value to be compared. NEWVAL is the new
13387 value to be stored. SCRATCH is a scratch GPR. */
13388
13389void
13390rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
13391 rtx scratch)
13392{
13393 enum machine_mode mode = GET_MODE (mem);
13394 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13395
13396 emit_insn (gen_memory_barrier ());
13397
13398 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13399 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13400 emit_label (XEXP (label1, 0));
13401
13402 emit_load_locked (mode, retval, mem);
13403
13404 x = gen_rtx_COMPARE (CCmode, retval, oldval);
13405 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
13406
13407 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13408 emit_unlikely_jump (x, label2);
13409
13410 emit_move_insn (scratch, newval);
13411 emit_store_conditional (mode, cond, mem, scratch);
13412
13413 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13414 emit_unlikely_jump (x, label1);
13415
13416 emit_insn (gen_isync ());
13417 emit_label (XEXP (label2, 0));
13418}
13419
13420/* Expand an atomic test and set operation. MEM is the memory on which
13421 to operate. VAL is the value set. SCRATCH is a scratch GPR. */
13422
13423void
13424rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
13425{
13426 enum machine_mode mode = GET_MODE (mem);
13427 rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13428
13429 emit_insn (gen_memory_barrier ());
13430
13431 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13432 emit_label (XEXP (label, 0));
13433
13434 emit_load_locked (mode, retval, mem);
13435 emit_move_insn (scratch, val);
13436 emit_store_conditional (mode, cond, mem, scratch);
13437
13438 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13439 emit_unlikely_jump (x, label);
13440
13441 emit_insn (gen_isync ());
13442}
13443
9fc75b97
DE
13444void
13445rs6000_expand_compare_and_swapqhi (rtx dst, rtx mem, rtx oldval, rtx newval)
13446{
13447 enum machine_mode mode = GET_MODE (mem);
13448 rtx addrSI, align, wdst, shift, mask;
13449 HOST_WIDE_INT shift_mask = mode == QImode ? 0x18 : 0x10;
13450 HOST_WIDE_INT imask = GET_MODE_MASK (mode);
13451
13452 /* Shift amount for subword relative to aligned word. */
13453 addrSI = force_reg (SImode, gen_lowpart_common (SImode, XEXP (mem, 0)));
13454 shift = gen_reg_rtx (SImode);
13455 emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
13456 GEN_INT (shift_mask)));
13457 emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
13458
13459 /* Shift and mask old value into position within word. */
13460 oldval = convert_modes (SImode, mode, oldval, 1);
13461 oldval = expand_binop (SImode, and_optab,
13462 oldval, GEN_INT (imask), NULL_RTX,
13463 1, OPTAB_LIB_WIDEN);
13464 emit_insn (gen_ashlsi3 (oldval, oldval, shift));
13465
13466 /* Shift and mask new value into position within word. */
13467 newval = convert_modes (SImode, mode, newval, 1);
13468 newval = expand_binop (SImode, and_optab,
13469 newval, GEN_INT (imask), NULL_RTX,
13470 1, OPTAB_LIB_WIDEN);
13471 emit_insn (gen_ashlsi3 (newval, newval, shift));
13472
13473 /* Mask for insertion. */
13474 mask = gen_reg_rtx (SImode);
13475 emit_move_insn (mask, GEN_INT (imask));
13476 emit_insn (gen_ashlsi3 (mask, mask, shift));
13477
13478 /* Address of aligned word containing subword. */
13479 align = expand_binop (Pmode, and_optab, XEXP (mem, 0), GEN_INT (-4),
13480 NULL_RTX, 1, OPTAB_LIB_WIDEN);
13481 mem = change_address (mem, SImode, align);
13482 set_mem_align (mem, 32);
13483 MEM_VOLATILE_P (mem) = 1;
13484
13485 wdst = gen_reg_rtx (SImode);
13486 emit_insn (gen_sync_compare_and_swapqhi_internal (wdst, mask,
13487 oldval, newval, mem));
13488
13489 emit_move_insn (dst, gen_lowpart (mode, wdst));
13490}
13491
13492void
13493rs6000_split_compare_and_swapqhi (rtx dest, rtx mask,
13494 rtx oldval, rtx newval, rtx mem,
13495 rtx scratch)
13496{
13497 rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
13498
13499 emit_insn (gen_memory_barrier ());
13500 label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13501 label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
13502 emit_label (XEXP (label1, 0));
13503
13504 emit_load_locked (SImode, scratch, mem);
13505
13506 /* Mask subword within loaded value for comparison with oldval.
13507 Use UNSPEC_AND to avoid clobber.*/
13508 emit_insn (gen_rtx_SET (SImode, dest,
13509 gen_rtx_UNSPEC (SImode,
13510 gen_rtvec (2, scratch, mask),
13511 UNSPEC_AND)));
13512
13513 x = gen_rtx_COMPARE (CCmode, dest, oldval);
13514 emit_insn (gen_rtx_SET (VOIDmode, cond, x));
13515
13516 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13517 emit_unlikely_jump (x, label2);
13518
13519 /* Clear subword within loaded value for insertion of new value. */
13520 emit_insn (gen_rtx_SET (SImode, scratch,
13521 gen_rtx_AND (SImode,
13522 gen_rtx_NOT (SImode, mask), scratch)));
13523 emit_insn (gen_iorsi3 (scratch, scratch, newval));
13524 emit_store_conditional (SImode, cond, mem, scratch);
13525
13526 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
13527 emit_unlikely_jump (x, label1);
13528
13529 emit_insn (gen_isync ());
13530 emit_label (XEXP (label2, 0));
13531}
13532
13533
b52110d4 13534 /* Emit instructions to move SRC to DST. Called by splitters for
a9baceb1
GK
13535 multi-register moves. It will emit at most one instruction for
13536 each register that is accessed; that is, it won't emit li/lis pairs
13537 (or equivalent for 64-bit code). One of SRC or DST must be a hard
13538 register. */
46c07df8 13539
46c07df8 13540void
a9baceb1 13541rs6000_split_multireg_move (rtx dst, rtx src)
46c07df8 13542{
a9baceb1
GK
13543 /* The register number of the first register being moved. */
13544 int reg;
13545 /* The mode that is to be moved. */
13546 enum machine_mode mode;
13547 /* The mode that the move is being done in, and its size. */
13548 enum machine_mode reg_mode;
13549 int reg_mode_size;
13550 /* The number of registers that will be moved. */
13551 int nregs;
13552
13553 reg = REG_P (dst) ? REGNO (dst) : REGNO (src);
13554 mode = GET_MODE (dst);
c8b622ff 13555 nregs = hard_regno_nregs[reg][mode];
a9baceb1 13556 if (FP_REGNO_P (reg))
7393f7f8 13557 reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
a9baceb1
GK
13558 else if (ALTIVEC_REGNO_P (reg))
13559 reg_mode = V16QImode;
8521c414
JM
13560 else if (TARGET_E500_DOUBLE && mode == TFmode)
13561 reg_mode = DFmode;
a9baceb1
GK
13562 else
13563 reg_mode = word_mode;
13564 reg_mode_size = GET_MODE_SIZE (reg_mode);
f676971a 13565
37409796 13566 gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode));
f676971a 13567
a9baceb1
GK
13568 if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst)))
13569 {
13570 /* Move register range backwards, if we might have destructive
13571 overlap. */
13572 int i;
13573 for (i = nregs - 1; i >= 0; i--)
f676971a 13574 emit_insn (gen_rtx_SET (VOIDmode,
a9baceb1
GK
13575 simplify_gen_subreg (reg_mode, dst, mode,
13576 i * reg_mode_size),
13577 simplify_gen_subreg (reg_mode, src, mode,
13578 i * reg_mode_size)));
13579 }
46c07df8
HP
13580 else
13581 {
a9baceb1
GK
13582 int i;
13583 int j = -1;
13584 bool used_update = false;
46c07df8 13585
c1e55850 13586 if (MEM_P (src) && INT_REGNO_P (reg))
c4ad648e
AM
13587 {
13588 rtx breg;
3a1f863f 13589
a9baceb1
GK
13590 if (GET_CODE (XEXP (src, 0)) == PRE_INC
13591 || GET_CODE (XEXP (src, 0)) == PRE_DEC)
3a1f863f
DE
13592 {
13593 rtx delta_rtx;
a9baceb1 13594 breg = XEXP (XEXP (src, 0), 0);
c4ad648e
AM
13595 delta_rtx = (GET_CODE (XEXP (src, 0)) == PRE_INC
13596 ? GEN_INT (GET_MODE_SIZE (GET_MODE (src)))
13597 : GEN_INT (-GET_MODE_SIZE (GET_MODE (src))));
a9baceb1
GK
13598 emit_insn (TARGET_32BIT
13599 ? gen_addsi3 (breg, breg, delta_rtx)
13600 : gen_adddi3 (breg, breg, delta_rtx));
13e2e16e 13601 src = replace_equiv_address (src, breg);
3a1f863f 13602 }
d04b6e6e 13603 else if (! rs6000_offsettable_memref_p (src))
c1e55850 13604 {
13e2e16e 13605 rtx basereg;
c1e55850
GK
13606 basereg = gen_rtx_REG (Pmode, reg);
13607 emit_insn (gen_rtx_SET (VOIDmode, basereg, XEXP (src, 0)));
13e2e16e 13608 src = replace_equiv_address (src, basereg);
c1e55850 13609 }
3a1f863f 13610
0423421f
AM
13611 breg = XEXP (src, 0);
13612 if (GET_CODE (breg) == PLUS || GET_CODE (breg) == LO_SUM)
13613 breg = XEXP (breg, 0);
13614
13615 /* If the base register we are using to address memory is
13616 also a destination reg, then change that register last. */
13617 if (REG_P (breg)
13618 && REGNO (breg) >= REGNO (dst)
3a1f863f
DE
13619 && REGNO (breg) < REGNO (dst) + nregs)
13620 j = REGNO (breg) - REGNO (dst);
c4ad648e 13621 }
46c07df8 13622
a9baceb1 13623 if (GET_CODE (dst) == MEM && INT_REGNO_P (reg))
3a1f863f
DE
13624 {
13625 rtx breg;
13626
a9baceb1
GK
13627 if (GET_CODE (XEXP (dst, 0)) == PRE_INC
13628 || GET_CODE (XEXP (dst, 0)) == PRE_DEC)
3a1f863f
DE
13629 {
13630 rtx delta_rtx;
a9baceb1 13631 breg = XEXP (XEXP (dst, 0), 0);
c4ad648e
AM
13632 delta_rtx = (GET_CODE (XEXP (dst, 0)) == PRE_INC
13633 ? GEN_INT (GET_MODE_SIZE (GET_MODE (dst)))
13634 : GEN_INT (-GET_MODE_SIZE (GET_MODE (dst))));
3a1f863f
DE
13635
13636 /* We have to update the breg before doing the store.
13637 Use store with update, if available. */
13638
13639 if (TARGET_UPDATE)
13640 {
a9baceb1 13641 rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0);
c4ad648e
AM
13642 emit_insn (TARGET_32BIT
13643 ? (TARGET_POWERPC64
13644 ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc)
13645 : gen_movsi_update (breg, breg, delta_rtx, nsrc))
13646 : gen_movdi_di_update (breg, breg, delta_rtx, nsrc));
a9baceb1 13647 used_update = true;
3a1f863f
DE
13648 }
13649 else
a9baceb1
GK
13650 emit_insn (TARGET_32BIT
13651 ? gen_addsi3 (breg, breg, delta_rtx)
13652 : gen_adddi3 (breg, breg, delta_rtx));
13e2e16e 13653 dst = replace_equiv_address (dst, breg);
3a1f863f 13654 }
37409796 13655 else
d04b6e6e 13656 gcc_assert (rs6000_offsettable_memref_p (dst));
3a1f863f
DE
13657 }
13658
46c07df8 13659 for (i = 0; i < nregs; i++)
f676971a 13660 {
3a1f863f
DE
13661 /* Calculate index to next subword. */
13662 ++j;
f676971a 13663 if (j == nregs)
3a1f863f 13664 j = 0;
46c07df8 13665
112cdef5 13666 /* If compiler already emitted move of first word by
a9baceb1 13667 store with update, no need to do anything. */
3a1f863f 13668 if (j == 0 && used_update)
a9baceb1 13669 continue;
f676971a 13670
a9baceb1
GK
13671 emit_insn (gen_rtx_SET (VOIDmode,
13672 simplify_gen_subreg (reg_mode, dst, mode,
13673 j * reg_mode_size),
13674 simplify_gen_subreg (reg_mode, src, mode,
13675 j * reg_mode_size)));
3a1f863f 13676 }
46c07df8
HP
13677 }
13678}
13679
12a4e8c5 13680\f
a4f6c312
SS
13681/* This page contains routines that are used to determine what the
13682 function prologue and epilogue code will do and write them out. */
9878760c 13683
a4f6c312
SS
13684/* Return the first fixed-point register that is required to be
13685 saved. 32 if none. */
9878760c
RK
13686
13687int
863d938c 13688first_reg_to_save (void)
9878760c
RK
13689{
13690 int first_reg;
13691
13692 /* Find lowest numbered live register. */
13693 for (first_reg = 13; first_reg <= 31; first_reg++)
6fb5fa3c 13694 if (df_regs_ever_live_p (first_reg)
a38d360d 13695 && (! call_used_regs[first_reg]
1db02437 13696 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 13697 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
b4db40bf
JJ
13698 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)
13699 || (TARGET_TOC && TARGET_MINIMAL_TOC)))))
9878760c
RK
13700 break;
13701
ee890fe2 13702#if TARGET_MACHO
93638d7a
AM
13703 if (flag_pic
13704 && current_function_uses_pic_offset_table
13705 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 13706 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
13707#endif
13708
9878760c
RK
13709 return first_reg;
13710}
13711
13712/* Similar, for FP regs. */
13713
13714int
863d938c 13715first_fp_reg_to_save (void)
9878760c
RK
13716{
13717 int first_reg;
13718
13719 /* Find lowest numbered live register. */
13720 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
6fb5fa3c 13721 if (df_regs_ever_live_p (first_reg))
9878760c
RK
13722 break;
13723
13724 return first_reg;
13725}
00b960c7
AH
13726
13727/* Similar, for AltiVec regs. */
13728
13729static int
863d938c 13730first_altivec_reg_to_save (void)
00b960c7
AH
13731{
13732 int i;
13733
13734 /* Stack frame remains as is unless we are in AltiVec ABI. */
13735 if (! TARGET_ALTIVEC_ABI)
13736 return LAST_ALTIVEC_REGNO + 1;
13737
22fa69da 13738 /* On Darwin, the unwind routines are compiled without
982afe02 13739 TARGET_ALTIVEC, and use save_world to save/restore the
22fa69da
GK
13740 altivec registers when necessary. */
13741 if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
13742 && ! TARGET_ALTIVEC)
13743 return FIRST_ALTIVEC_REGNO + 20;
13744
00b960c7
AH
13745 /* Find lowest numbered live register. */
13746 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
6fb5fa3c 13747 if (df_regs_ever_live_p (i))
00b960c7
AH
13748 break;
13749
13750 return i;
13751}
13752
13753/* Return a 32-bit mask of the AltiVec registers we need to set in
13754 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
13755 the 32-bit word is 0. */
13756
13757static unsigned int
863d938c 13758compute_vrsave_mask (void)
00b960c7
AH
13759{
13760 unsigned int i, mask = 0;
13761
22fa69da 13762 /* On Darwin, the unwind routines are compiled without
982afe02 13763 TARGET_ALTIVEC, and use save_world to save/restore the
22fa69da
GK
13764 call-saved altivec registers when necessary. */
13765 if (DEFAULT_ABI == ABI_DARWIN && current_function_calls_eh_return
13766 && ! TARGET_ALTIVEC)
13767 mask |= 0xFFF;
13768
00b960c7
AH
13769 /* First, find out if we use _any_ altivec registers. */
13770 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
6fb5fa3c 13771 if (df_regs_ever_live_p (i))
00b960c7
AH
13772 mask |= ALTIVEC_REG_BIT (i);
13773
13774 if (mask == 0)
13775 return mask;
13776
00b960c7
AH
13777 /* Next, remove the argument registers from the set. These must
13778 be in the VRSAVE mask set by the caller, so we don't need to add
13779 them in again. More importantly, the mask we compute here is
13780 used to generate CLOBBERs in the set_vrsave insn, and we do not
13781 wish the argument registers to die. */
a6cf80f2 13782 for (i = cfun->args_info.vregno - 1; i >= ALTIVEC_ARG_MIN_REG; --i)
00b960c7
AH
13783 mask &= ~ALTIVEC_REG_BIT (i);
13784
13785 /* Similarly, remove the return value from the set. */
13786 {
13787 bool yes = false;
13788 diddle_return_value (is_altivec_return_reg, &yes);
13789 if (yes)
13790 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
13791 }
13792
13793 return mask;
13794}
13795
d62294f5 13796/* For a very restricted set of circumstances, we can cut down the
f57fe068
AM
13797 size of prologues/epilogues by calling our own save/restore-the-world
13798 routines. */
d62294f5
FJ
13799
13800static void
f57fe068
AM
13801compute_save_world_info (rs6000_stack_t *info_ptr)
13802{
13803 info_ptr->world_save_p = 1;
13804 info_ptr->world_save_p
13805 = (WORLD_SAVE_P (info_ptr)
13806 && DEFAULT_ABI == ABI_DARWIN
13807 && ! (current_function_calls_setjmp && flag_exceptions)
13808 && info_ptr->first_fp_reg_save == FIRST_SAVED_FP_REGNO
13809 && info_ptr->first_gp_reg_save == FIRST_SAVED_GP_REGNO
13810 && info_ptr->first_altivec_reg_save == FIRST_SAVED_ALTIVEC_REGNO
13811 && info_ptr->cr_save_p);
f676971a 13812
d62294f5
FJ
13813 /* This will not work in conjunction with sibcalls. Make sure there
13814 are none. (This check is expensive, but seldom executed.) */
f57fe068 13815 if (WORLD_SAVE_P (info_ptr))
f676971a 13816 {
d62294f5
FJ
13817 rtx insn;
13818 for ( insn = get_last_insn_anywhere (); insn; insn = PREV_INSN (insn))
c4ad648e
AM
13819 if ( GET_CODE (insn) == CALL_INSN
13820 && SIBLING_CALL_P (insn))
13821 {
13822 info_ptr->world_save_p = 0;
13823 break;
13824 }
d62294f5 13825 }
f676971a 13826
f57fe068 13827 if (WORLD_SAVE_P (info_ptr))
d62294f5
FJ
13828 {
13829 /* Even if we're not touching VRsave, make sure there's room on the
13830 stack for it, if it looks like we're calling SAVE_WORLD, which
c4ad648e 13831 will attempt to save it. */
d62294f5
FJ
13832 info_ptr->vrsave_size = 4;
13833
13834 /* "Save" the VRsave register too if we're saving the world. */
13835 if (info_ptr->vrsave_mask == 0)
c4ad648e 13836 info_ptr->vrsave_mask = compute_vrsave_mask ();
d62294f5
FJ
13837
13838 /* Because the Darwin register save/restore routines only handle
c4ad648e 13839 F14 .. F31 and V20 .. V31 as per the ABI, perform a consistency
992d08b1 13840 check. */
37409796
NS
13841 gcc_assert (info_ptr->first_fp_reg_save >= FIRST_SAVED_FP_REGNO
13842 && (info_ptr->first_altivec_reg_save
13843 >= FIRST_SAVED_ALTIVEC_REGNO));
d62294f5 13844 }
f676971a 13845 return;
d62294f5
FJ
13846}
13847
13848
00b960c7 13849static void
a2369ed3 13850is_altivec_return_reg (rtx reg, void *xyes)
00b960c7
AH
13851{
13852 bool *yes = (bool *) xyes;
13853 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
13854 *yes = true;
13855}
13856
4697a36c
MM
13857\f
13858/* Calculate the stack information for the current function. This is
13859 complicated by having two separate calling sequences, the AIX calling
13860 sequence and the V.4 calling sequence.
13861
592696dd 13862 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 13863 32-bit 64-bit
4697a36c 13864 SP----> +---------------------------------------+
a260abc9 13865 | back chain to caller | 0 0
4697a36c 13866 +---------------------------------------+
a260abc9 13867 | saved CR | 4 8 (8-11)
4697a36c 13868 +---------------------------------------+
a260abc9 13869 | saved LR | 8 16
4697a36c 13870 +---------------------------------------+
a260abc9 13871 | reserved for compilers | 12 24
4697a36c 13872 +---------------------------------------+
a260abc9 13873 | reserved for binders | 16 32
4697a36c 13874 +---------------------------------------+
a260abc9 13875 | saved TOC pointer | 20 40
4697a36c 13876 +---------------------------------------+
a260abc9 13877 | Parameter save area (P) | 24 48
4697a36c 13878 +---------------------------------------+
a260abc9 13879 | Alloca space (A) | 24+P etc.
802a0058 13880 +---------------------------------------+
a7df97e6 13881 | Local variable space (L) | 24+P+A
4697a36c 13882 +---------------------------------------+
a7df97e6 13883 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 13884 +---------------------------------------+
00b960c7
AH
13885 | Save area for AltiVec registers (W) | 24+P+A+L+X
13886 +---------------------------------------+
13887 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
13888 +---------------------------------------+
13889 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 13890 +---------------------------------------+
00b960c7
AH
13891 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
13892 +---------------------------------------+
13893 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
13894 +---------------------------------------+
13895 old SP->| back chain to caller's caller |
13896 +---------------------------------------+
13897
5376a30c
KR
13898 The required alignment for AIX configurations is two words (i.e., 8
13899 or 16 bytes).
13900
13901
4697a36c
MM
13902 V.4 stack frames look like:
13903
13904 SP----> +---------------------------------------+
13905 | back chain to caller | 0
13906 +---------------------------------------+
5eb387b8 13907 | caller's saved LR | 4
4697a36c
MM
13908 +---------------------------------------+
13909 | Parameter save area (P) | 8
13910 +---------------------------------------+
a7df97e6 13911 | Alloca space (A) | 8+P
f676971a 13912 +---------------------------------------+
a7df97e6 13913 | Varargs save area (V) | 8+P+A
f676971a 13914 +---------------------------------------+
a7df97e6 13915 | Local variable space (L) | 8+P+A+V
f676971a 13916 +---------------------------------------+
a7df97e6 13917 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 13918 +---------------------------------------+
00b960c7
AH
13919 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
13920 +---------------------------------------+
13921 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
13922 +---------------------------------------+
13923 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
13924 +---------------------------------------+
c4ad648e
AM
13925 | SPE: area for 64-bit GP registers |
13926 +---------------------------------------+
13927 | SPE alignment padding |
13928 +---------------------------------------+
00b960c7 13929 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
f676971a 13930 +---------------------------------------+
00b960c7 13931 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
f676971a 13932 +---------------------------------------+
00b960c7 13933 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
13934 +---------------------------------------+
13935 old SP->| back chain to caller's caller |
13936 +---------------------------------------+
b6c9286a 13937
5376a30c
KR
13938 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
13939 given. (But note below and in sysv4.h that we require only 8 and
13940 may round up the size of our stack frame anyways. The historical
13941 reason is early versions of powerpc-linux which didn't properly
13942 align the stack at program startup. A happy side-effect is that
13943 -mno-eabi libraries can be used with -meabi programs.)
13944
50d440bc 13945 The EABI configuration defaults to the V.4 layout. However,
5376a30c
KR
13946 the stack alignment requirements may differ. If -mno-eabi is not
13947 given, the required stack alignment is 8 bytes; if -mno-eabi is
13948 given, the required alignment is 16 bytes. (But see V.4 comment
13949 above.) */
4697a36c 13950
61b2fbe7
MM
13951#ifndef ABI_STACK_BOUNDARY
13952#define ABI_STACK_BOUNDARY STACK_BOUNDARY
13953#endif
13954
d1d0c603 13955static rs6000_stack_t *
863d938c 13956rs6000_stack_info (void)
4697a36c 13957{
022123e6 13958 static rs6000_stack_t info;
4697a36c 13959 rs6000_stack_t *info_ptr = &info;
327e5343 13960 int reg_size = TARGET_32BIT ? 4 : 8;
83720594 13961 int ehrd_size;
64045029 13962 int save_align;
8070c91a 13963 int first_gp;
44688022 13964 HOST_WIDE_INT non_fixed_size;
4697a36c 13965
022123e6 13966 memset (&info, 0, sizeof (info));
4697a36c 13967
c19de7aa
AH
13968 if (TARGET_SPE)
13969 {
13970 /* Cache value so we don't rescan instruction chain over and over. */
9b7b447f 13971 if (cfun->machine->insn_chain_scanned_p == 0)
b5a5beb9
AH
13972 cfun->machine->insn_chain_scanned_p
13973 = spe_func_has_64bit_regs_p () + 1;
13974 info_ptr->spe_64bit_regs_used = cfun->machine->insn_chain_scanned_p - 1;
c19de7aa
AH
13975 }
13976
a4f6c312 13977 /* Select which calling sequence. */
178274da 13978 info_ptr->abi = DEFAULT_ABI;
9878760c 13979
a4f6c312 13980 /* Calculate which registers need to be saved & save area size. */
4697a36c 13981 info_ptr->first_gp_reg_save = first_reg_to_save ();
f676971a 13982 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
8070c91a
DJ
13983 even if it currently looks like we won't. Reload may need it to
13984 get at a constant; if so, it will have already created a constant
13985 pool entry for it. */
2bfcf297 13986 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
178274da
AM
13987 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
13988 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
8070c91a 13989 && current_function_uses_const_pool
1db02437 13990 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
8070c91a 13991 first_gp = RS6000_PIC_OFFSET_TABLE_REGNUM;
906fb125 13992 else
8070c91a
DJ
13993 first_gp = info_ptr->first_gp_reg_save;
13994
13995 info_ptr->gp_size = reg_size * (32 - first_gp);
4697a36c 13996
a3170dc6
AH
13997 /* For the SPE, we have an additional upper 32-bits on each GPR.
13998 Ideally we should save the entire 64-bits only when the upper
13999 half is used in SIMD instructions. Since we only record
14000 registers live (not the size they are used in), this proves
14001 difficult because we'd have to traverse the instruction chain at
14002 the right time, taking reload into account. This is a real pain,
c19de7aa
AH
14003 so we opt to save the GPRs in 64-bits always if but one register
14004 gets used in 64-bits. Otherwise, all the registers in the frame
14005 get saved in 32-bits.
a3170dc6 14006
c19de7aa 14007 So... since when we save all GPRs (except the SP) in 64-bits, the
a3170dc6 14008 traditional GP save area will be empty. */
c19de7aa 14009 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
14010 info_ptr->gp_size = 0;
14011
4697a36c
MM
14012 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
14013 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
14014
00b960c7
AH
14015 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
14016 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
14017 - info_ptr->first_altivec_reg_save);
14018
592696dd 14019 /* Does this function call anything? */
71f123ca
FS
14020 info_ptr->calls_p = (! current_function_is_leaf
14021 || cfun->machine->ra_needs_full_frame);
b6c9286a 14022
a4f6c312 14023 /* Determine if we need to save the link register. */
022123e6
AM
14024 if ((DEFAULT_ABI == ABI_AIX
14025 && current_function_profile
14026 && !TARGET_PROFILE_KERNEL)
4697a36c
MM
14027#ifdef TARGET_RELOCATABLE
14028 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
14029#endif
14030 || (info_ptr->first_fp_reg_save != 64
14031 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 14032 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
178274da 14033 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
022123e6
AM
14034 || info_ptr->calls_p
14035 || rs6000_ra_ever_killed ())
4697a36c
MM
14036 {
14037 info_ptr->lr_save_p = 1;
1de43f85 14038 df_set_regs_ever_live (LR_REGNO, true);
4697a36c
MM
14039 }
14040
9ebbca7d 14041 /* Determine if we need to save the condition code registers. */
6fb5fa3c
DB
14042 if (df_regs_ever_live_p (CR2_REGNO)
14043 || df_regs_ever_live_p (CR3_REGNO)
14044 || df_regs_ever_live_p (CR4_REGNO))
4697a36c
MM
14045 {
14046 info_ptr->cr_save_p = 1;
178274da 14047 if (DEFAULT_ABI == ABI_V4)
4697a36c
MM
14048 info_ptr->cr_size = reg_size;
14049 }
14050
83720594
RH
14051 /* If the current function calls __builtin_eh_return, then we need
14052 to allocate stack space for registers that will hold data for
14053 the exception handler. */
14054 if (current_function_calls_eh_return)
14055 {
14056 unsigned int i;
14057 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
14058 continue;
a3170dc6
AH
14059
14060 /* SPE saves EH registers in 64-bits. */
c19de7aa
AH
14061 ehrd_size = i * (TARGET_SPE_ABI
14062 && info_ptr->spe_64bit_regs_used != 0
14063 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
14064 }
14065 else
14066 ehrd_size = 0;
14067
592696dd 14068 /* Determine various sizes. */
4697a36c
MM
14069 info_ptr->reg_size = reg_size;
14070 info_ptr->fixed_size = RS6000_SAVE_AREA;
189e03e3 14071 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312 14072 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
03e007d7 14073 TARGET_ALTIVEC ? 16 : 8);
7d5175e1
JJ
14074 if (FRAME_GROWS_DOWNWARD)
14075 info_ptr->vars_size
5b667039
JJ
14076 += RS6000_ALIGN (info_ptr->fixed_size + info_ptr->vars_size
14077 + info_ptr->parm_size,
7d5175e1 14078 ABI_STACK_BOUNDARY / BITS_PER_UNIT)
5b667039
JJ
14079 - (info_ptr->fixed_size + info_ptr->vars_size
14080 + info_ptr->parm_size);
00b960c7 14081
c19de7aa 14082 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
8070c91a 14083 info_ptr->spe_gp_size = 8 * (32 - first_gp);
a3170dc6
AH
14084 else
14085 info_ptr->spe_gp_size = 0;
14086
4d774ff8
HP
14087 if (TARGET_ALTIVEC_ABI)
14088 info_ptr->vrsave_mask = compute_vrsave_mask ();
00b960c7 14089 else
4d774ff8
HP
14090 info_ptr->vrsave_mask = 0;
14091
14092 if (TARGET_ALTIVEC_VRSAVE && info_ptr->vrsave_mask)
14093 info_ptr->vrsave_size = 4;
14094 else
14095 info_ptr->vrsave_size = 0;
b6c9286a 14096
d62294f5
FJ
14097 compute_save_world_info (info_ptr);
14098
592696dd 14099 /* Calculate the offsets. */
178274da 14100 switch (DEFAULT_ABI)
4697a36c 14101 {
b6c9286a 14102 case ABI_NONE:
24d304eb 14103 default:
37409796 14104 gcc_unreachable ();
b6c9286a
MM
14105
14106 case ABI_AIX:
ee890fe2 14107 case ABI_DARWIN:
b6c9286a
MM
14108 info_ptr->fp_save_offset = - info_ptr->fp_size;
14109 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
14110
14111 if (TARGET_ALTIVEC_ABI)
14112 {
14113 info_ptr->vrsave_save_offset
14114 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
14115
982afe02 14116 /* Align stack so vector save area is on a quadword boundary.
9278121c 14117 The padding goes above the vectors. */
00b960c7
AH
14118 if (info_ptr->altivec_size != 0)
14119 info_ptr->altivec_padding_size
9278121c 14120 = info_ptr->vrsave_save_offset & 0xF;
00b960c7
AH
14121 else
14122 info_ptr->altivec_padding_size = 0;
14123
14124 info_ptr->altivec_save_offset
14125 = info_ptr->vrsave_save_offset
14126 - info_ptr->altivec_padding_size
14127 - info_ptr->altivec_size;
9278121c
GK
14128 gcc_assert (info_ptr->altivec_size == 0
14129 || info_ptr->altivec_save_offset % 16 == 0);
00b960c7
AH
14130
14131 /* Adjust for AltiVec case. */
14132 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
14133 }
14134 else
14135 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
14136 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
14137 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
14138 break;
14139
14140 case ABI_V4:
b6c9286a
MM
14141 info_ptr->fp_save_offset = - info_ptr->fp_size;
14142 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 14143 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 14144
c19de7aa 14145 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
c4ad648e
AM
14146 {
14147 /* Align stack so SPE GPR save area is aligned on a
14148 double-word boundary. */
14149 if (info_ptr->spe_gp_size != 0)
14150 info_ptr->spe_padding_size
14151 = 8 - (-info_ptr->cr_save_offset % 8);
14152 else
14153 info_ptr->spe_padding_size = 0;
14154
14155 info_ptr->spe_gp_save_offset
14156 = info_ptr->cr_save_offset
14157 - info_ptr->spe_padding_size
14158 - info_ptr->spe_gp_size;
14159
14160 /* Adjust for SPE case. */
022123e6 14161 info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
c4ad648e 14162 }
a3170dc6 14163 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
14164 {
14165 info_ptr->vrsave_save_offset
14166 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
14167
14168 /* Align stack so vector save area is on a quadword boundary. */
14169 if (info_ptr->altivec_size != 0)
14170 info_ptr->altivec_padding_size
14171 = 16 - (-info_ptr->vrsave_save_offset % 16);
14172 else
14173 info_ptr->altivec_padding_size = 0;
14174
14175 info_ptr->altivec_save_offset
14176 = info_ptr->vrsave_save_offset
14177 - info_ptr->altivec_padding_size
14178 - info_ptr->altivec_size;
14179
14180 /* Adjust for AltiVec case. */
022123e6 14181 info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
00b960c7
AH
14182 }
14183 else
022123e6
AM
14184 info_ptr->ehrd_offset = info_ptr->cr_save_offset;
14185 info_ptr->ehrd_offset -= ehrd_size;
b6c9286a
MM
14186 info_ptr->lr_save_offset = reg_size;
14187 break;
4697a36c
MM
14188 }
14189
64045029 14190 save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
00b960c7
AH
14191 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
14192 + info_ptr->gp_size
14193 + info_ptr->altivec_size
14194 + info_ptr->altivec_padding_size
a3170dc6
AH
14195 + info_ptr->spe_gp_size
14196 + info_ptr->spe_padding_size
00b960c7
AH
14197 + ehrd_size
14198 + info_ptr->cr_size
022123e6 14199 + info_ptr->vrsave_size,
64045029 14200 save_align);
00b960c7 14201
44688022 14202 non_fixed_size = (info_ptr->vars_size
ff381587 14203 + info_ptr->parm_size
5b667039 14204 + info_ptr->save_size);
ff381587 14205
44688022
AM
14206 info_ptr->total_size = RS6000_ALIGN (non_fixed_size + info_ptr->fixed_size,
14207 ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
14208
14209 /* Determine if we need to allocate any stack frame:
14210
a4f6c312
SS
14211 For AIX we need to push the stack if a frame pointer is needed
14212 (because the stack might be dynamically adjusted), if we are
14213 debugging, if we make calls, or if the sum of fp_save, gp_save,
14214 and local variables are more than the space needed to save all
14215 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
14216 + 18*8 = 288 (GPR13 reserved).
ff381587 14217
a4f6c312
SS
14218 For V.4 we don't have the stack cushion that AIX uses, but assume
14219 that the debugger can handle stackless frames. */
ff381587
MM
14220
14221 if (info_ptr->calls_p)
14222 info_ptr->push_p = 1;
14223
178274da 14224 else if (DEFAULT_ABI == ABI_V4)
44688022 14225 info_ptr->push_p = non_fixed_size != 0;
ff381587 14226
178274da
AM
14227 else if (frame_pointer_needed)
14228 info_ptr->push_p = 1;
14229
14230 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
14231 info_ptr->push_p = 1;
14232
ff381587 14233 else
44688022 14234 info_ptr->push_p = non_fixed_size > (TARGET_32BIT ? 220 : 288);
ff381587 14235
a4f6c312 14236 /* Zero offsets if we're not saving those registers. */
8dda1a21 14237 if (info_ptr->fp_size == 0)
4697a36c
MM
14238 info_ptr->fp_save_offset = 0;
14239
8dda1a21 14240 if (info_ptr->gp_size == 0)
4697a36c
MM
14241 info_ptr->gp_save_offset = 0;
14242
00b960c7
AH
14243 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
14244 info_ptr->altivec_save_offset = 0;
14245
14246 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
14247 info_ptr->vrsave_save_offset = 0;
14248
c19de7aa
AH
14249 if (! TARGET_SPE_ABI
14250 || info_ptr->spe_64bit_regs_used == 0
14251 || info_ptr->spe_gp_size == 0)
a3170dc6
AH
14252 info_ptr->spe_gp_save_offset = 0;
14253
c81fc13e 14254 if (! info_ptr->lr_save_p)
4697a36c
MM
14255 info_ptr->lr_save_offset = 0;
14256
c81fc13e 14257 if (! info_ptr->cr_save_p)
4697a36c
MM
14258 info_ptr->cr_save_offset = 0;
14259
14260 return info_ptr;
14261}
14262
c19de7aa
AH
14263/* Return true if the current function uses any GPRs in 64-bit SIMD
14264 mode. */
14265
14266static bool
863d938c 14267spe_func_has_64bit_regs_p (void)
c19de7aa
AH
14268{
14269 rtx insns, insn;
14270
14271 /* Functions that save and restore all the call-saved registers will
14272 need to save/restore the registers in 64-bits. */
14273 if (current_function_calls_eh_return
14274 || current_function_calls_setjmp
14275 || current_function_has_nonlocal_goto)
14276 return true;
14277
14278 insns = get_insns ();
14279
14280 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
14281 {
14282 if (INSN_P (insn))
14283 {
14284 rtx i;
14285
b5a5beb9
AH
14286 /* FIXME: This should be implemented with attributes...
14287
14288 (set_attr "spe64" "true")....then,
14289 if (get_spe64(insn)) return true;
14290
14291 It's the only reliable way to do the stuff below. */
14292
c19de7aa 14293 i = PATTERN (insn);
f82f556d
AH
14294 if (GET_CODE (i) == SET)
14295 {
14296 enum machine_mode mode = GET_MODE (SET_SRC (i));
14297
14298 if (SPE_VECTOR_MODE (mode))
14299 return true;
17caeff2 14300 if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode))
f82f556d
AH
14301 return true;
14302 }
c19de7aa
AH
14303 }
14304 }
14305
14306 return false;
14307}
14308
d1d0c603 14309static void
a2369ed3 14310debug_stack_info (rs6000_stack_t *info)
9878760c 14311{
d330fd93 14312 const char *abi_string;
24d304eb 14313
c81fc13e 14314 if (! info)
4697a36c
MM
14315 info = rs6000_stack_info ();
14316
14317 fprintf (stderr, "\nStack information for function %s:\n",
14318 ((current_function_decl && DECL_NAME (current_function_decl))
14319 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
14320 : "<unknown>"));
14321
24d304eb
RK
14322 switch (info->abi)
14323 {
b6c9286a
MM
14324 default: abi_string = "Unknown"; break;
14325 case ABI_NONE: abi_string = "NONE"; break;
50d440bc 14326 case ABI_AIX: abi_string = "AIX"; break;
ee890fe2 14327 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 14328 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
14329 }
14330
14331 fprintf (stderr, "\tABI = %5s\n", abi_string);
14332
00b960c7
AH
14333 if (TARGET_ALTIVEC_ABI)
14334 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
14335
a3170dc6
AH
14336 if (TARGET_SPE_ABI)
14337 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
14338
4697a36c
MM
14339 if (info->first_gp_reg_save != 32)
14340 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
14341
14342 if (info->first_fp_reg_save != 64)
14343 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 14344
00b960c7
AH
14345 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
14346 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
14347 info->first_altivec_reg_save);
14348
4697a36c
MM
14349 if (info->lr_save_p)
14350 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 14351
4697a36c
MM
14352 if (info->cr_save_p)
14353 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
14354
00b960c7
AH
14355 if (info->vrsave_mask)
14356 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
14357
4697a36c
MM
14358 if (info->push_p)
14359 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
14360
14361 if (info->calls_p)
14362 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
14363
4697a36c
MM
14364 if (info->gp_save_offset)
14365 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
14366
14367 if (info->fp_save_offset)
14368 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
14369
00b960c7
AH
14370 if (info->altivec_save_offset)
14371 fprintf (stderr, "\taltivec_save_offset = %5d\n",
14372 info->altivec_save_offset);
14373
a3170dc6
AH
14374 if (info->spe_gp_save_offset)
14375 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
14376 info->spe_gp_save_offset);
14377
00b960c7
AH
14378 if (info->vrsave_save_offset)
14379 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
14380 info->vrsave_save_offset);
14381
4697a36c
MM
14382 if (info->lr_save_offset)
14383 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
14384
14385 if (info->cr_save_offset)
14386 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
14387
14388 if (info->varargs_save_offset)
14389 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
14390
14391 if (info->total_size)
d1d0c603
JJ
14392 fprintf (stderr, "\ttotal_size = "HOST_WIDE_INT_PRINT_DEC"\n",
14393 info->total_size);
4697a36c 14394
4697a36c 14395 if (info->vars_size)
d1d0c603
JJ
14396 fprintf (stderr, "\tvars_size = "HOST_WIDE_INT_PRINT_DEC"\n",
14397 info->vars_size);
4697a36c
MM
14398
14399 if (info->parm_size)
14400 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
14401
14402 if (info->fixed_size)
14403 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
14404
14405 if (info->gp_size)
14406 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
14407
a3170dc6
AH
14408 if (info->spe_gp_size)
14409 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
14410
4697a36c
MM
14411 if (info->fp_size)
14412 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
14413
00b960c7
AH
14414 if (info->altivec_size)
14415 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
14416
14417 if (info->vrsave_size)
14418 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
14419
14420 if (info->altivec_padding_size)
14421 fprintf (stderr, "\taltivec_padding_size= %5d\n",
14422 info->altivec_padding_size);
14423
a3170dc6
AH
14424 if (info->spe_padding_size)
14425 fprintf (stderr, "\tspe_padding_size = %5d\n",
14426 info->spe_padding_size);
14427
4697a36c
MM
14428 if (info->cr_size)
14429 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
14430
14431 if (info->save_size)
14432 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
14433
14434 if (info->reg_size != 4)
14435 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
14436
14437 fprintf (stderr, "\n");
9878760c 14438}
71f123ca
FS
14439
14440rtx
a2369ed3 14441rs6000_return_addr (int count, rtx frame)
71f123ca 14442{
a4f6c312
SS
14443 /* Currently we don't optimize very well between prolog and body
14444 code and for PIC code the code can be actually quite bad, so
14445 don't try to be too clever here. */
f1384257 14446 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
71f123ca
FS
14447 {
14448 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
14449
14450 return
14451 gen_rtx_MEM
14452 (Pmode,
14453 memory_address
14454 (Pmode,
14455 plus_constant (copy_to_reg
14456 (gen_rtx_MEM (Pmode,
14457 memory_address (Pmode, frame))),
14458 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
14459 }
14460
8c29550d 14461 cfun->machine->ra_need_lr = 1;
1de43f85 14462 return get_hard_reg_initial_val (Pmode, LR_REGNO);
71f123ca
FS
14463}
14464
5e1bf043
DJ
14465/* Say whether a function is a candidate for sibcall handling or not.
14466 We do not allow indirect calls to be optimized into sibling calls.
14467 Also, we can't do it if there are any vector parameters; there's
14468 nowhere to put the VRsave code so it works; note that functions with
14469 vector parameters are required to have a prototype, so the argument
14470 type info must be available here. (The tail recursion case can work
14471 with vector parameters, but there's no way to distinguish here.) */
4977bab6 14472static bool
a2369ed3 14473rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
5e1bf043
DJ
14474{
14475 tree type;
4977bab6 14476 if (decl)
5e1bf043
DJ
14477 {
14478 if (TARGET_ALTIVEC_VRSAVE)
c4ad648e 14479 {
4977bab6 14480 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
5e1bf043
DJ
14481 type; type = TREE_CHAIN (type))
14482 {
c15b529f 14483 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
4977bab6 14484 return false;
5e1bf043 14485 }
c4ad648e 14486 }
5e1bf043 14487 if (DEFAULT_ABI == ABI_DARWIN
8aa19d95
JJ
14488 || ((*targetm.binds_local_p) (decl)
14489 && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
2bcc50d0 14490 {
4977bab6 14491 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
2bcc50d0
AM
14492
14493 if (!lookup_attribute ("longcall", attr_list)
14494 || lookup_attribute ("shortcall", attr_list))
4977bab6 14495 return true;
2bcc50d0 14496 }
5e1bf043 14497 }
4977bab6 14498 return false;
5e1bf043
DJ
14499}
14500
e7e64a25
AS
14501/* NULL if INSN insn is valid within a low-overhead loop.
14502 Otherwise return why doloop cannot be applied.
9419649c
DE
14503 PowerPC uses the COUNT register for branch on table instructions. */
14504
e7e64a25 14505static const char *
3101faab 14506rs6000_invalid_within_doloop (const_rtx insn)
9419649c
DE
14507{
14508 if (CALL_P (insn))
e7e64a25 14509 return "Function call in the loop.";
9419649c
DE
14510
14511 if (JUMP_P (insn)
14512 && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
14513 || GET_CODE (PATTERN (insn)) == ADDR_VEC))
e7e64a25 14514 return "Computed branch in the loop.";
9419649c 14515
e7e64a25 14516 return NULL;
9419649c
DE
14517}
14518
71f123ca 14519static int
863d938c 14520rs6000_ra_ever_killed (void)
71f123ca
FS
14521{
14522 rtx top;
5e1bf043
DJ
14523 rtx reg;
14524 rtx insn;
71f123ca 14525
dd292d0a 14526 if (current_function_is_thunk)
71f123ca 14527 return 0;
eb0424da 14528
36f7e964
AH
14529 /* regs_ever_live has LR marked as used if any sibcalls are present,
14530 but this should not force saving and restoring in the
14531 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
a3c9585f 14532 clobbers LR, so that is inappropriate. */
36f7e964 14533
5e1bf043
DJ
14534 /* Also, the prologue can generate a store into LR that
14535 doesn't really count, like this:
36f7e964 14536
5e1bf043
DJ
14537 move LR->R0
14538 bcl to set PIC register
14539 move LR->R31
14540 move R0->LR
36f7e964
AH
14541
14542 When we're called from the epilogue, we need to avoid counting
14543 this as a store. */
f676971a 14544
71f123ca
FS
14545 push_topmost_sequence ();
14546 top = get_insns ();
14547 pop_topmost_sequence ();
1de43f85 14548 reg = gen_rtx_REG (Pmode, LR_REGNO);
71f123ca 14549
5e1bf043
DJ
14550 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
14551 {
14552 if (INSN_P (insn))
14553 {
022123e6
AM
14554 if (CALL_P (insn))
14555 {
14556 if (!SIBLING_CALL_P (insn))
14557 return 1;
14558 }
1de43f85 14559 else if (find_regno_note (insn, REG_INC, LR_REGNO))
5e1bf043 14560 return 1;
36f7e964
AH
14561 else if (set_of (reg, insn) != NULL_RTX
14562 && !prologue_epilogue_contains (insn))
5e1bf043
DJ
14563 return 1;
14564 }
14565 }
14566 return 0;
71f123ca 14567}
4697a36c 14568\f
9ebbca7d 14569/* Emit instructions needed to load the TOC register.
c7ca610e 14570 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 14571 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
14572
14573void
a2369ed3 14574rs6000_emit_load_toc_table (int fromprolog)
c7ca610e 14575{
6fb5fa3c 14576 rtx dest;
1db02437 14577 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 14578
7f970b70 14579 if (TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI != ABI_AIX && flag_pic)
20b71b17 14580 {
7f970b70 14581 char buf[30];
e65a3857 14582 rtx lab, tmp1, tmp2, got;
7f970b70
AM
14583
14584 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
14585 lab = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
14586 if (flag_pic == 2)
14587 got = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
14588 else
14589 got = rs6000_got_sym ();
14590 tmp1 = tmp2 = dest;
14591 if (!fromprolog)
14592 {
14593 tmp1 = gen_reg_rtx (Pmode);
14594 tmp2 = gen_reg_rtx (Pmode);
14595 }
6fb5fa3c
DB
14596 emit_insn (gen_load_toc_v4_PIC_1 (lab));
14597 emit_move_insn (tmp1,
1de43f85 14598 gen_rtx_REG (Pmode, LR_REGNO));
6fb5fa3c
DB
14599 emit_insn (gen_load_toc_v4_PIC_3b (tmp2, tmp1, got, lab));
14600 emit_insn (gen_load_toc_v4_PIC_3c (dest, tmp2, got, lab));
7f970b70
AM
14601 }
14602 else if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
14603 {
6fb5fa3c 14604 emit_insn (gen_load_toc_v4_pic_si ());
1de43f85 14605 emit_move_insn (dest, gen_rtx_REG (Pmode, LR_REGNO));
20b71b17
AM
14606 }
14607 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
14608 {
14609 char buf[30];
20b71b17
AM
14610 rtx temp0 = (fromprolog
14611 ? gen_rtx_REG (Pmode, 0)
14612 : gen_reg_rtx (Pmode));
20b71b17 14613
20b71b17
AM
14614 if (fromprolog)
14615 {
ccbca5e4 14616 rtx symF, symL;
38c1f2d7 14617
20b71b17
AM
14618 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
14619 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 14620
20b71b17
AM
14621 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
14622 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
14623
6fb5fa3c
DB
14624 emit_insn (gen_load_toc_v4_PIC_1 (symF));
14625 emit_move_insn (dest,
1de43f85 14626 gen_rtx_REG (Pmode, LR_REGNO));
6fb5fa3c 14627 emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest, symL, symF));
9ebbca7d
GK
14628 }
14629 else
20b71b17
AM
14630 {
14631 rtx tocsym;
20b71b17
AM
14632
14633 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
e65a3857
DE
14634 emit_insn (gen_load_toc_v4_PIC_1b (tocsym));
14635 emit_move_insn (dest,
1de43f85 14636 gen_rtx_REG (Pmode, LR_REGNO));
027fbf43 14637 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
20b71b17 14638 }
6fb5fa3c 14639 emit_insn (gen_addsi3 (dest, temp0, dest));
9ebbca7d 14640 }
20b71b17
AM
14641 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
14642 {
14643 /* This is for AIX code running in non-PIC ELF32. */
14644 char buf[30];
14645 rtx realsym;
14646 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
14647 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
14648
6fb5fa3c
DB
14649 emit_insn (gen_elf_high (dest, realsym));
14650 emit_insn (gen_elf_low (dest, dest, realsym));
20b71b17 14651 }
37409796 14652 else
9ebbca7d 14653 {
37409796 14654 gcc_assert (DEFAULT_ABI == ABI_AIX);
bb8df8a6 14655
9ebbca7d 14656 if (TARGET_32BIT)
6fb5fa3c 14657 emit_insn (gen_load_toc_aix_si (dest));
9ebbca7d 14658 else
6fb5fa3c 14659 emit_insn (gen_load_toc_aix_di (dest));
9ebbca7d
GK
14660 }
14661}
14662
d1d0c603
JJ
14663/* Emit instructions to restore the link register after determining where
14664 its value has been stored. */
14665
14666void
14667rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
14668{
14669 rs6000_stack_t *info = rs6000_stack_info ();
14670 rtx operands[2];
14671
14672 operands[0] = source;
14673 operands[1] = scratch;
14674
14675 if (info->lr_save_p)
14676 {
14677 rtx frame_rtx = stack_pointer_rtx;
14678 HOST_WIDE_INT sp_offset = 0;
14679 rtx tmp;
14680
14681 if (frame_pointer_needed
14682 || current_function_calls_alloca
14683 || info->total_size > 32767)
14684 {
0be76840 14685 tmp = gen_frame_mem (Pmode, frame_rtx);
8308679f 14686 emit_move_insn (operands[1], tmp);
d1d0c603
JJ
14687 frame_rtx = operands[1];
14688 }
14689 else if (info->push_p)
14690 sp_offset = info->total_size;
14691
14692 tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
0be76840 14693 tmp = gen_frame_mem (Pmode, tmp);
d1d0c603
JJ
14694 emit_move_insn (tmp, operands[0]);
14695 }
14696 else
1de43f85 14697 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO), operands[0]);
d1d0c603
JJ
14698}
14699
4862826d 14700static GTY(()) alias_set_type set = -1;
f103e34d 14701
4862826d 14702alias_set_type
863d938c 14703get_TOC_alias_set (void)
9ebbca7d 14704{
f103e34d
GK
14705 if (set == -1)
14706 set = new_alias_set ();
14707 return set;
f676971a 14708}
9ebbca7d 14709
c1207243 14710/* This returns nonzero if the current function uses the TOC. This is
3c9eb5f4
AM
14711 determined by the presence of (use (unspec ... UNSPEC_TOC)), which
14712 is generated by the ABI_V4 load_toc_* patterns. */
c954844a 14713#if TARGET_ELF
3c9eb5f4 14714static int
f676971a 14715uses_TOC (void)
9ebbca7d 14716{
c4501e62 14717 rtx insn;
38c1f2d7 14718
c4501e62
JJ
14719 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
14720 if (INSN_P (insn))
14721 {
14722 rtx pat = PATTERN (insn);
14723 int i;
9ebbca7d 14724
f676971a 14725 if (GET_CODE (pat) == PARALLEL)
c4501e62
JJ
14726 for (i = 0; i < XVECLEN (pat, 0); i++)
14727 {
14728 rtx sub = XVECEXP (pat, 0, i);
14729 if (GET_CODE (sub) == USE)
14730 {
14731 sub = XEXP (sub, 0);
14732 if (GET_CODE (sub) == UNSPEC
14733 && XINT (sub, 1) == UNSPEC_TOC)
14734 return 1;
14735 }
14736 }
14737 }
14738 return 0;
9ebbca7d 14739}
c954844a 14740#endif
38c1f2d7 14741
9ebbca7d 14742rtx
f676971a 14743create_TOC_reference (rtx symbol)
9ebbca7d 14744{
b3a13419 14745 if (!can_create_pseudo_p ())
6fb5fa3c 14746 df_set_regs_ever_live (TOC_REGISTER, true);
f676971a 14747 return gen_rtx_PLUS (Pmode,
a8a05998 14748 gen_rtx_REG (Pmode, TOC_REGISTER),
f676971a
EC
14749 gen_rtx_CONST (Pmode,
14750 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 14751 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 14752}
38c1f2d7 14753
fc4767bb
JJ
14754/* If _Unwind_* has been called from within the same module,
14755 toc register is not guaranteed to be saved to 40(1) on function
14756 entry. Save it there in that case. */
c7ca610e 14757
9ebbca7d 14758void
863d938c 14759rs6000_aix_emit_builtin_unwind_init (void)
9ebbca7d
GK
14760{
14761 rtx mem;
14762 rtx stack_top = gen_reg_rtx (Pmode);
14763 rtx opcode_addr = gen_reg_rtx (Pmode);
fc4767bb
JJ
14764 rtx opcode = gen_reg_rtx (SImode);
14765 rtx tocompare = gen_reg_rtx (SImode);
14766 rtx no_toc_save_needed = gen_label_rtx ();
9ebbca7d 14767
8308679f 14768 mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
9ebbca7d
GK
14769 emit_move_insn (stack_top, mem);
14770
8308679f
DE
14771 mem = gen_frame_mem (Pmode,
14772 gen_rtx_PLUS (Pmode, stack_top,
14773 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9ebbca7d 14774 emit_move_insn (opcode_addr, mem);
fc4767bb
JJ
14775 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
14776 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
2496c7bd 14777 : 0xE8410028, SImode));
9ebbca7d 14778
fc4767bb 14779 do_compare_rtx_and_jump (opcode, tocompare, EQ, 1,
06f4e019 14780 SImode, NULL_RTX, NULL_RTX,
fc4767bb 14781 no_toc_save_needed);
9ebbca7d 14782
8308679f
DE
14783 mem = gen_frame_mem (Pmode,
14784 gen_rtx_PLUS (Pmode, stack_top,
14785 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
fc4767bb
JJ
14786 emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
14787 emit_label (no_toc_save_needed);
9ebbca7d 14788}
38c1f2d7 14789\f
0be76840
DE
14790/* This ties together stack memory (MEM with an alias set of frame_alias_set)
14791 and the change to the stack pointer. */
ba4828e0 14792
9ebbca7d 14793static void
863d938c 14794rs6000_emit_stack_tie (void)
9ebbca7d 14795{
0be76840
DE
14796 rtx mem = gen_frame_mem (BLKmode,
14797 gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
ba4828e0 14798
9ebbca7d
GK
14799 emit_insn (gen_stack_tie (mem));
14800}
38c1f2d7 14801
9ebbca7d
GK
14802/* Emit the correct code for allocating stack space, as insns.
14803 If COPY_R12, make sure a copy of the old frame is left in r12.
14804 The generated code may use hard register 0 as a temporary. */
14805
14806static void
a2369ed3 14807rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12)
38c1f2d7 14808{
9ebbca7d
GK
14809 rtx insn;
14810 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
14811 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
61168ff1
RS
14812 rtx todec = gen_int_mode (-size, Pmode);
14813
14814 if (INTVAL (todec) != -size)
14815 {
d4ee4d25 14816 warning (0, "stack frame too large");
61168ff1
RS
14817 emit_insn (gen_trap ());
14818 return;
14819 }
a157febd
GK
14820
14821 if (current_function_limit_stack)
14822 {
14823 if (REG_P (stack_limit_rtx)
f676971a 14824 && REGNO (stack_limit_rtx) > 1
a157febd
GK
14825 && REGNO (stack_limit_rtx) <= 31)
14826 {
5b71a4e7 14827 emit_insn (TARGET_32BIT
9ebbca7d
GK
14828 ? gen_addsi3 (tmp_reg,
14829 stack_limit_rtx,
14830 GEN_INT (size))
14831 : gen_adddi3 (tmp_reg,
14832 stack_limit_rtx,
14833 GEN_INT (size)));
5b71a4e7 14834
9ebbca7d
GK
14835 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14836 const0_rtx));
a157febd
GK
14837 }
14838 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 14839 && TARGET_32BIT
f607bc57 14840 && DEFAULT_ABI == ABI_V4)
a157febd 14841 {
9ebbca7d 14842 rtx toload = gen_rtx_CONST (VOIDmode,
f676971a
EC
14843 gen_rtx_PLUS (Pmode,
14844 stack_limit_rtx,
9ebbca7d 14845 GEN_INT (size)));
5b71a4e7 14846
9ebbca7d
GK
14847 emit_insn (gen_elf_high (tmp_reg, toload));
14848 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
14849 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
14850 const0_rtx));
a157febd
GK
14851 }
14852 else
d4ee4d25 14853 warning (0, "stack limit expression is not supported");
a157febd
GK
14854 }
14855
9ebbca7d
GK
14856 if (copy_r12 || ! TARGET_UPDATE)
14857 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
14858
38c1f2d7
MM
14859 if (TARGET_UPDATE)
14860 {
9ebbca7d 14861 if (size > 32767)
38c1f2d7 14862 {
9ebbca7d 14863 /* Need a note here so that try_split doesn't get confused. */
9390387d 14864 if (get_last_insn () == NULL_RTX)
2e040219 14865 emit_note (NOTE_INSN_DELETED);
9ebbca7d
GK
14866 insn = emit_move_insn (tmp_reg, todec);
14867 try_split (PATTERN (insn), insn, 0);
14868 todec = tmp_reg;
38c1f2d7 14869 }
5b71a4e7
DE
14870
14871 insn = emit_insn (TARGET_32BIT
14872 ? gen_movsi_update (stack_reg, stack_reg,
14873 todec, stack_reg)
c4ad648e 14874 : gen_movdi_di_update (stack_reg, stack_reg,
9ebbca7d 14875 todec, stack_reg));
38c1f2d7
MM
14876 }
14877 else
14878 {
5b71a4e7
DE
14879 insn = emit_insn (TARGET_32BIT
14880 ? gen_addsi3 (stack_reg, stack_reg, todec)
14881 : gen_adddi3 (stack_reg, stack_reg, todec));
9ebbca7d
GK
14882 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
14883 gen_rtx_REG (Pmode, 12));
14884 }
f676971a 14885
9ebbca7d 14886 RTX_FRAME_RELATED_P (insn) = 1;
f676971a 14887 REG_NOTES (insn) =
9ebbca7d 14888 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
f676971a 14889 gen_rtx_SET (VOIDmode, stack_reg,
9ebbca7d
GK
14890 gen_rtx_PLUS (Pmode, stack_reg,
14891 GEN_INT (-size))),
14892 REG_NOTES (insn));
14893}
14894
a4f6c312
SS
14895/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
14896 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
14897 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
14898 deduce these equivalences by itself so it wasn't necessary to hold
14899 its hand so much. */
9ebbca7d
GK
14900
14901static void
f676971a 14902rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
a2369ed3 14903 rtx reg2, rtx rreg)
9ebbca7d
GK
14904{
14905 rtx real, temp;
14906
e56c4463
JL
14907 /* copy_rtx will not make unique copies of registers, so we need to
14908 ensure we don't have unwanted sharing here. */
14909 if (reg == reg2)
14910 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14911
14912 if (reg == rreg)
14913 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
14914
9ebbca7d
GK
14915 real = copy_rtx (PATTERN (insn));
14916
89e7058f
AH
14917 if (reg2 != NULL_RTX)
14918 real = replace_rtx (real, reg2, rreg);
f676971a
EC
14919
14920 real = replace_rtx (real, reg,
9ebbca7d
GK
14921 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
14922 STACK_POINTER_REGNUM),
14923 GEN_INT (val)));
f676971a 14924
9ebbca7d
GK
14925 /* We expect that 'real' is either a SET or a PARALLEL containing
14926 SETs (and possibly other stuff). In a PARALLEL, all the SETs
14927 are important so they all have to be marked RTX_FRAME_RELATED_P. */
14928
14929 if (GET_CODE (real) == SET)
14930 {
14931 rtx set = real;
f676971a 14932
9ebbca7d
GK
14933 temp = simplify_rtx (SET_SRC (set));
14934 if (temp)
14935 SET_SRC (set) = temp;
14936 temp = simplify_rtx (SET_DEST (set));
14937 if (temp)
14938 SET_DEST (set) = temp;
14939 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 14940 {
9ebbca7d
GK
14941 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14942 if (temp)
14943 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 14944 }
38c1f2d7 14945 }
37409796 14946 else
9ebbca7d
GK
14947 {
14948 int i;
37409796
NS
14949
14950 gcc_assert (GET_CODE (real) == PARALLEL);
9ebbca7d
GK
14951 for (i = 0; i < XVECLEN (real, 0); i++)
14952 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
14953 {
14954 rtx set = XVECEXP (real, 0, i);
f676971a 14955
9ebbca7d
GK
14956 temp = simplify_rtx (SET_SRC (set));
14957 if (temp)
14958 SET_SRC (set) = temp;
14959 temp = simplify_rtx (SET_DEST (set));
14960 if (temp)
14961 SET_DEST (set) = temp;
14962 if (GET_CODE (SET_DEST (set)) == MEM)
14963 {
14964 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
14965 if (temp)
14966 XEXP (SET_DEST (set), 0) = temp;
14967 }
14968 RTX_FRAME_RELATED_P (set) = 1;
14969 }
14970 }
c19de7aa
AH
14971
14972 if (TARGET_SPE)
14973 real = spe_synthesize_frame_save (real);
14974
9ebbca7d
GK
14975 RTX_FRAME_RELATED_P (insn) = 1;
14976 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
14977 real,
14978 REG_NOTES (insn));
38c1f2d7
MM
14979}
14980
c19de7aa
AH
14981/* Given an SPE frame note, return a PARALLEL of SETs with the
14982 original note, plus a synthetic register save. */
14983
14984static rtx
a2369ed3 14985spe_synthesize_frame_save (rtx real)
c19de7aa
AH
14986{
14987 rtx synth, offset, reg, real2;
14988
14989 if (GET_CODE (real) != SET
14990 || GET_MODE (SET_SRC (real)) != V2SImode)
14991 return real;
14992
14993 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
14994 frame related note. The parallel contains a set of the register
41f3a930 14995 being saved, and another set to a synthetic register (n+1200).
c19de7aa
AH
14996 This is so we can differentiate between 64-bit and 32-bit saves.
14997 Words cannot describe this nastiness. */
14998
37409796
NS
14999 gcc_assert (GET_CODE (SET_DEST (real)) == MEM
15000 && GET_CODE (XEXP (SET_DEST (real), 0)) == PLUS
15001 && GET_CODE (SET_SRC (real)) == REG);
c19de7aa
AH
15002
15003 /* Transform:
15004 (set (mem (plus (reg x) (const y)))
15005 (reg z))
15006 into:
15007 (set (mem (plus (reg x) (const y+4)))
41f3a930 15008 (reg z+1200))
c19de7aa
AH
15009 */
15010
15011 real2 = copy_rtx (real);
15012 PUT_MODE (SET_DEST (real2), SImode);
15013 reg = SET_SRC (real2);
15014 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
15015 synth = copy_rtx (real2);
15016
15017 if (BYTES_BIG_ENDIAN)
15018 {
15019 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
15020 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
15021 }
15022
15023 reg = SET_SRC (synth);
41f3a930 15024
c19de7aa 15025 synth = replace_rtx (synth, reg,
41f3a930 15026 gen_rtx_REG (SImode, REGNO (reg) + 1200));
c19de7aa
AH
15027
15028 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
15029 synth = replace_rtx (synth, offset,
15030 GEN_INT (INTVAL (offset)
15031 + (BYTES_BIG_ENDIAN ? 0 : 4)));
15032
15033 RTX_FRAME_RELATED_P (synth) = 1;
15034 RTX_FRAME_RELATED_P (real2) = 1;
15035 if (BYTES_BIG_ENDIAN)
15036 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
15037 else
15038 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
15039
15040 return real;
15041}
15042
00b960c7
AH
15043/* Returns an insn that has a vrsave set operation with the
15044 appropriate CLOBBERs. */
15045
15046static rtx
a2369ed3 15047generate_set_vrsave (rtx reg, rs6000_stack_t *info, int epiloguep)
00b960c7
AH
15048{
15049 int nclobs, i;
15050 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 15051 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 15052
a004eb82
AH
15053 clobs[0]
15054 = gen_rtx_SET (VOIDmode,
15055 vrsave,
15056 gen_rtx_UNSPEC_VOLATILE (SImode,
15057 gen_rtvec (2, reg, vrsave),
3aca4bff 15058 UNSPECV_SET_VRSAVE));
00b960c7
AH
15059
15060 nclobs = 1;
15061
9aa86737
AH
15062 /* We need to clobber the registers in the mask so the scheduler
15063 does not move sets to VRSAVE before sets of AltiVec registers.
15064
15065 However, if the function receives nonlocal gotos, reload will set
15066 all call saved registers live. We will end up with:
15067
15068 (set (reg 999) (mem))
15069 (parallel [ (set (reg vrsave) (unspec blah))
15070 (clobber (reg 999))])
15071
15072 The clobber will cause the store into reg 999 to be dead, and
15073 flow will attempt to delete an epilogue insn. In this case, we
15074 need an unspec use/set of the register. */
00b960c7
AH
15075
15076 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
44688022 15077 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
9aa86737
AH
15078 {
15079 if (!epiloguep || call_used_regs [i])
15080 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
15081 gen_rtx_REG (V4SImode, i));
15082 else
15083 {
15084 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
15085
15086 clobs[nclobs++]
a004eb82
AH
15087 = gen_rtx_SET (VOIDmode,
15088 reg,
15089 gen_rtx_UNSPEC (V4SImode,
15090 gen_rtvec (1, reg), 27));
9aa86737
AH
15091 }
15092 }
00b960c7
AH
15093
15094 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
15095
15096 for (i = 0; i < nclobs; ++i)
15097 XVECEXP (insn, 0, i) = clobs[i];
15098
15099 return insn;
15100}
15101
89e7058f
AH
15102/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
15103 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
15104
15105static void
f676971a 15106emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
d1d0c603 15107 unsigned int regno, int offset, HOST_WIDE_INT total_size)
89e7058f
AH
15108{
15109 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
15110 rtx replacea, replaceb;
15111
15112 int_rtx = GEN_INT (offset);
15113
15114 /* Some cases that need register indexed addressing. */
15115 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
4d4cbc0e 15116 || (TARGET_E500_DOUBLE && mode == DFmode)
a3170dc6
AH
15117 || (TARGET_SPE_ABI
15118 && SPE_VECTOR_MODE (mode)
15119 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
15120 {
15121 /* Whomever calls us must make sure r11 is available in the
c4ad648e 15122 flow path of instructions in the prologue. */
89e7058f
AH
15123 offset_rtx = gen_rtx_REG (Pmode, 11);
15124 emit_move_insn (offset_rtx, int_rtx);
15125
15126 replacea = offset_rtx;
15127 replaceb = int_rtx;
15128 }
15129 else
15130 {
15131 offset_rtx = int_rtx;
15132 replacea = NULL_RTX;
15133 replaceb = NULL_RTX;
15134 }
15135
15136 reg = gen_rtx_REG (mode, regno);
15137 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
0be76840 15138 mem = gen_frame_mem (mode, addr);
89e7058f
AH
15139
15140 insn = emit_move_insn (mem, reg);
15141
15142 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
15143}
15144
a3170dc6
AH
15145/* Emit an offset memory reference suitable for a frame store, while
15146 converting to a valid addressing mode. */
15147
15148static rtx
a2369ed3 15149gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
a3170dc6
AH
15150{
15151 rtx int_rtx, offset_rtx;
15152
15153 int_rtx = GEN_INT (offset);
15154
4d4cbc0e
AH
15155 if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
15156 || (TARGET_E500_DOUBLE && mode == DFmode))
a3170dc6
AH
15157 {
15158 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
15159 emit_move_insn (offset_rtx, int_rtx);
15160 }
15161 else
15162 offset_rtx = int_rtx;
15163
0be76840 15164 return gen_frame_mem (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
a3170dc6
AH
15165}
15166
6d0a8091
DJ
15167/* Look for user-defined global regs. We should not save and restore these,
15168 and cannot use stmw/lmw if there are any in its range. */
15169
15170static bool
15171no_global_regs_above (int first_greg)
15172{
15173 int i;
15174 for (i = 0; i < 32 - first_greg; i++)
15175 if (global_regs[first_greg + i])
15176 return false;
15177 return true;
15178}
15179
699c914a
MS
15180#ifndef TARGET_FIX_AND_CONTINUE
15181#define TARGET_FIX_AND_CONTINUE 0
15182#endif
15183
52ff33d0
NF
15184/* Determine whether the gp REG is really used. */
15185
15186static bool
15187rs6000_reg_live_or_pic_offset_p (int reg)
15188{
6fb5fa3c 15189 return ((df_regs_ever_live_p (reg)
52ff33d0
NF
15190 && (!call_used_regs[reg]
15191 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
15192 && TARGET_TOC && TARGET_MINIMAL_TOC)))
15193 || (reg == RS6000_PIC_OFFSET_TABLE_REGNUM
15194 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
15195 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))));
15196}
15197
9ebbca7d
GK
15198/* Emit function prologue as insns. */
15199
9878760c 15200void
863d938c 15201rs6000_emit_prologue (void)
9878760c 15202{
4697a36c 15203 rs6000_stack_t *info = rs6000_stack_info ();
0e67400a 15204 enum machine_mode reg_mode = Pmode;
327e5343 15205 int reg_size = TARGET_32BIT ? 4 : 8;
9ebbca7d
GK
15206 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
15207 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
15208 rtx frame_reg_rtx = sp_reg_rtx;
b78d48dd 15209 rtx cr_save_rtx = NULL_RTX;
9ebbca7d
GK
15210 rtx insn;
15211 int saving_FPRs_inline;
15212 int using_store_multiple;
15213 HOST_WIDE_INT sp_offset = 0;
f676971a 15214
699c914a
MS
15215 if (TARGET_FIX_AND_CONTINUE)
15216 {
15217 /* gdb on darwin arranges to forward a function from the old
de2ab0ca 15218 address by modifying the first 5 instructions of the function
699c914a
MS
15219 to branch to the overriding function. This is necessary to
15220 permit function pointers that point to the old function to
15221 actually forward to the new function. */
15222 emit_insn (gen_nop ());
15223 emit_insn (gen_nop ());
de2ab0ca 15224 emit_insn (gen_nop ());
699c914a
MS
15225 emit_insn (gen_nop ());
15226 emit_insn (gen_nop ());
15227 }
15228
15229 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
15230 {
15231 reg_mode = V2SImode;
15232 reg_size = 8;
15233 }
a3170dc6 15234
9ebbca7d 15235 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
15236 && (!TARGET_SPE_ABI
15237 || info->spe_64bit_regs_used == 0)
6d0a8091
DJ
15238 && info->first_gp_reg_save < 31
15239 && no_global_regs_above (info->first_gp_reg_save));
9ebbca7d 15240 saving_FPRs_inline = (info->first_fp_reg_save == 64
8c29550d 15241 || FP_SAVE_INLINE (info->first_fp_reg_save)
acd0b319 15242 || current_function_calls_eh_return
8c29550d 15243 || cfun->machine->ra_need_lr);
9ebbca7d
GK
15244
15245 /* For V.4, update stack before we do any saving and set back pointer. */
22fa69da
GK
15246 if (! WORLD_SAVE_P (info)
15247 && info->push_p
acd0b319
AM
15248 && (DEFAULT_ABI == ABI_V4
15249 || current_function_calls_eh_return))
9ebbca7d
GK
15250 {
15251 if (info->total_size < 32767)
15252 sp_offset = info->total_size;
15253 else
15254 frame_reg_rtx = frame_ptr_rtx;
f676971a 15255 rs6000_emit_allocate_stack (info->total_size,
9ebbca7d
GK
15256 (frame_reg_rtx != sp_reg_rtx
15257 && (info->cr_save_p
15258 || info->lr_save_p
15259 || info->first_fp_reg_save < 64
15260 || info->first_gp_reg_save < 32
15261 )));
15262 if (frame_reg_rtx != sp_reg_rtx)
15263 rs6000_emit_stack_tie ();
15264 }
15265
d62294f5 15266 /* Handle world saves specially here. */
f57fe068 15267 if (WORLD_SAVE_P (info))
d62294f5
FJ
15268 {
15269 int i, j, sz;
15270 rtx treg;
15271 rtvec p;
22fa69da 15272 rtx reg0;
d62294f5
FJ
15273
15274 /* save_world expects lr in r0. */
22fa69da 15275 reg0 = gen_rtx_REG (Pmode, 0);
d62294f5 15276 if (info->lr_save_p)
c4ad648e 15277 {
22fa69da 15278 insn = emit_move_insn (reg0,
1de43f85 15279 gen_rtx_REG (Pmode, LR_REGNO));
c4ad648e
AM
15280 RTX_FRAME_RELATED_P (insn) = 1;
15281 }
d62294f5
FJ
15282
15283 /* The SAVE_WORLD and RESTORE_WORLD routines make a number of
c4ad648e 15284 assumptions about the offsets of various bits of the stack
992d08b1 15285 frame. */
37409796
NS
15286 gcc_assert (info->gp_save_offset == -220
15287 && info->fp_save_offset == -144
15288 && info->lr_save_offset == 8
15289 && info->cr_save_offset == 4
15290 && info->push_p
15291 && info->lr_save_p
15292 && (!current_function_calls_eh_return
15293 || info->ehrd_offset == -432)
15294 && info->vrsave_save_offset == -224
22fa69da 15295 && info->altivec_save_offset == -416);
d62294f5
FJ
15296
15297 treg = gen_rtx_REG (SImode, 11);
15298 emit_move_insn (treg, GEN_INT (-info->total_size));
15299
15300 /* SAVE_WORLD takes the caller's LR in R0 and the frame size
c4ad648e 15301 in R11. It also clobbers R12, so beware! */
d62294f5
FJ
15302
15303 /* Preserve CR2 for save_world prologues */
22fa69da 15304 sz = 5;
d62294f5
FJ
15305 sz += 32 - info->first_gp_reg_save;
15306 sz += 64 - info->first_fp_reg_save;
15307 sz += LAST_ALTIVEC_REGNO - info->first_altivec_reg_save + 1;
15308 p = rtvec_alloc (sz);
15309 j = 0;
15310 RTVEC_ELT (p, j++) = gen_rtx_CLOBBER (VOIDmode,
a5ad2017 15311 gen_rtx_REG (SImode,
1de43f85 15312 LR_REGNO));
d62294f5 15313 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
c4ad648e
AM
15314 gen_rtx_SYMBOL_REF (Pmode,
15315 "*save_world"));
d62294f5 15316 /* We do floats first so that the instruction pattern matches
c4ad648e
AM
15317 properly. */
15318 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15319 {
15320 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15321 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15322 GEN_INT (info->fp_save_offset
15323 + sp_offset + 8 * i));
0be76840 15324 rtx mem = gen_frame_mem (DFmode, addr);
c4ad648e
AM
15325
15326 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15327 }
d62294f5 15328 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
c4ad648e
AM
15329 {
15330 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
15331 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15332 GEN_INT (info->altivec_save_offset
15333 + sp_offset + 16 * i));
0be76840 15334 rtx mem = gen_frame_mem (V4SImode, addr);
c4ad648e
AM
15335
15336 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15337 }
d62294f5 15338 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
c4ad648e
AM
15339 {
15340 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15341 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15342 GEN_INT (info->gp_save_offset
15343 + sp_offset + reg_size * i));
0be76840 15344 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
15345
15346 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15347 }
15348
15349 {
15350 /* CR register traditionally saved as CR2. */
15351 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
15352 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15353 GEN_INT (info->cr_save_offset
15354 + sp_offset));
0be76840 15355 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
15356
15357 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg);
15358 }
22fa69da
GK
15359 /* Explain about use of R0. */
15360 if (info->lr_save_p)
15361 {
15362 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15363 GEN_INT (info->lr_save_offset
15364 + sp_offset));
15365 rtx mem = gen_frame_mem (reg_mode, addr);
982afe02 15366
22fa69da
GK
15367 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, mem, reg0);
15368 }
15369 /* Explain what happens to the stack pointer. */
15370 {
15371 rtx newval = gen_rtx_PLUS (Pmode, sp_reg_rtx, treg);
15372 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, sp_reg_rtx, newval);
15373 }
d62294f5
FJ
15374
15375 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
15376 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
22fa69da
GK
15377 treg, GEN_INT (-info->total_size));
15378 sp_offset = info->total_size;
d62294f5
FJ
15379 }
15380
9ebbca7d 15381 /* If we use the link register, get it into r0. */
f57fe068 15382 if (!WORLD_SAVE_P (info) && info->lr_save_p)
f8a57be8 15383 {
52ff33d0
NF
15384 rtx addr, reg, mem;
15385
f8a57be8 15386 insn = emit_move_insn (gen_rtx_REG (Pmode, 0),
1de43f85 15387 gen_rtx_REG (Pmode, LR_REGNO));
f8a57be8 15388 RTX_FRAME_RELATED_P (insn) = 1;
52ff33d0
NF
15389
15390 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15391 GEN_INT (info->lr_save_offset + sp_offset));
15392 reg = gen_rtx_REG (Pmode, 0);
15393 mem = gen_rtx_MEM (Pmode, addr);
15394 /* This should not be of rs6000_sr_alias_set, because of
15395 __builtin_return_address. */
15396
15397 insn = emit_move_insn (mem, reg);
15398 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15399 NULL_RTX, NULL_RTX);
f8a57be8 15400 }
9ebbca7d
GK
15401
15402 /* If we need to save CR, put it into r12. */
f57fe068 15403 if (!WORLD_SAVE_P (info) && info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
9ebbca7d 15404 {
f8a57be8 15405 rtx set;
f676971a 15406
9ebbca7d 15407 cr_save_rtx = gen_rtx_REG (SImode, 12);
f8a57be8
GK
15408 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
15409 RTX_FRAME_RELATED_P (insn) = 1;
15410 /* Now, there's no way that dwarf2out_frame_debug_expr is going
15411 to understand '(unspec:SI [(reg:CC 68) ...] UNSPEC_MOVESI_FROM_CR)'.
15412 But that's OK. All we have to do is specify that _one_ condition
15413 code register is saved in this stack slot. The thrower's epilogue
15414 will then restore all the call-saved registers.
15415 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
15416 set = gen_rtx_SET (VOIDmode, cr_save_rtx,
15417 gen_rtx_REG (SImode, CR2_REGNO));
15418 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15419 set,
15420 REG_NOTES (insn));
9ebbca7d
GK
15421 }
15422
a4f6c312
SS
15423 /* Do any required saving of fpr's. If only one or two to save, do
15424 it ourselves. Otherwise, call function. */
f57fe068 15425 if (!WORLD_SAVE_P (info) && saving_FPRs_inline)
9ebbca7d
GK
15426 {
15427 int i;
15428 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
6fb5fa3c 15429 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
9ebbca7d 15430 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
15431 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
15432 info->first_fp_reg_save + i,
15433 info->fp_save_offset + sp_offset + 8 * i,
15434 info->total_size);
9ebbca7d 15435 }
f57fe068 15436 else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64)
9ebbca7d
GK
15437 {
15438 int i;
15439 char rname[30];
520a57c8 15440 const char *alloc_rname;
9ebbca7d
GK
15441 rtvec p;
15442 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
f676971a
EC
15443
15444 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
15445 gen_rtx_REG (Pmode,
1de43f85 15446 LR_REGNO));
9ebbca7d
GK
15447 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
15448 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 15449 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
15450 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
15451 gen_rtx_SYMBOL_REF (Pmode,
15452 alloc_rname));
15453 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
15454 {
15455 rtx addr, reg, mem;
15456 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15457 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
f676971a 15458 GEN_INT (info->fp_save_offset
9ebbca7d 15459 + sp_offset + 8*i));
0be76840 15460 mem = gen_frame_mem (DFmode, addr);
9ebbca7d
GK
15461
15462 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
15463 }
15464 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
f676971a 15465 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
9ebbca7d
GK
15466 NULL_RTX, NULL_RTX);
15467 }
b6c9286a 15468
9ebbca7d
GK
15469 /* Save GPRs. This is done as a PARALLEL if we are using
15470 the store-multiple instructions. */
f57fe068 15471 if (!WORLD_SAVE_P (info) && using_store_multiple)
b6c9286a 15472 {
308c142a 15473 rtvec p;
9ebbca7d
GK
15474 int i;
15475 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
15476 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15477 {
15478 rtx addr, reg, mem;
15479 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
f676971a
EC
15480 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15481 GEN_INT (info->gp_save_offset
15482 + sp_offset
9ebbca7d 15483 + reg_size * i));
0be76840 15484 mem = gen_frame_mem (reg_mode, addr);
9ebbca7d
GK
15485
15486 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
15487 }
15488 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
f676971a 15489 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
9ebbca7d 15490 NULL_RTX, NULL_RTX);
b6c9286a 15491 }
52ff33d0
NF
15492 else if (!WORLD_SAVE_P (info)
15493 && TARGET_SPE_ABI
15494 && info->spe_64bit_regs_used != 0
15495 && info->first_gp_reg_save != 32)
15496 {
15497 int i;
15498 rtx spe_save_area_ptr;
15499 int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
6fb5fa3c 15500 && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
52ff33d0
NF
15501 && !call_used_regs[STATIC_CHAIN_REGNUM]);
15502
15503 /* Determine whether we can address all of the registers that need
15504 to be saved with an offset from the stack pointer that fits in
15505 the small const field for SPE memory instructions. */
15506 int spe_regs_addressable_via_sp
15507 = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
15508 + (32 - info->first_gp_reg_save - 1) * reg_size);
15509 int spe_offset;
15510
15511 if (spe_regs_addressable_via_sp)
15512 {
15513 spe_save_area_ptr = sp_reg_rtx;
15514 spe_offset = info->spe_gp_save_offset + sp_offset;
15515 }
15516 else
15517 {
15518 /* Make r11 point to the start of the SPE save area. We need
15519 to be careful here if r11 is holding the static chain. If
15520 it is, then temporarily save it in r0. We would use r0 as
15521 our base register here, but using r0 as a base register in
15522 loads and stores means something different from what we
15523 would like. */
15524 if (using_static_chain_p)
15525 {
15526 rtx r0 = gen_rtx_REG (Pmode, 0);
15527
15528 gcc_assert (info->first_gp_reg_save > 11);
15529
15530 emit_move_insn (r0, gen_rtx_REG (Pmode, 11));
15531 }
15532
15533 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
15534 emit_insn (gen_addsi3 (spe_save_area_ptr, sp_reg_rtx,
15535 GEN_INT (info->spe_gp_save_offset + sp_offset)));
15536
15537 spe_offset = 0;
15538 }
15539
15540 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
15541 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
15542 {
15543 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15544 rtx offset, addr, mem;
15545
15546 /* We're doing all this to ensure that the offset fits into
15547 the immediate offset of 'evstdd'. */
15548 gcc_assert (SPE_CONST_OFFSET_OK (reg_size * i + spe_offset));
15549
15550 offset = GEN_INT (reg_size * i + spe_offset);
15551 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
15552 mem = gen_rtx_MEM (V2SImode, addr);
15553
15554 insn = emit_move_insn (mem, reg);
15555
15556 rs6000_frame_related (insn, spe_save_area_ptr,
15557 info->spe_gp_save_offset
15558 + sp_offset + reg_size * i,
15559 offset, const0_rtx);
15560 }
15561
15562 /* Move the static chain pointer back. */
15563 if (using_static_chain_p && !spe_regs_addressable_via_sp)
15564 emit_move_insn (gen_rtx_REG (Pmode, 11), gen_rtx_REG (Pmode, 0));
15565 }
f57fe068 15566 else if (!WORLD_SAVE_P (info))
b6c9286a 15567 {
9ebbca7d
GK
15568 int i;
15569 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
52ff33d0
NF
15570 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
15571 {
15572 rtx addr, reg, mem;
15573 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
a3170dc6 15574
52ff33d0
NF
15575 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15576 GEN_INT (info->gp_save_offset
15577 + sp_offset
15578 + reg_size * i));
15579 mem = gen_frame_mem (reg_mode, addr);
a3170dc6 15580
52ff33d0
NF
15581 insn = emit_move_insn (mem, reg);
15582 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15583 NULL_RTX, NULL_RTX);
15584 }
9ebbca7d
GK
15585 }
15586
83720594
RH
15587 /* ??? There's no need to emit actual instructions here, but it's the
15588 easiest way to get the frame unwind information emitted. */
22fa69da 15589 if (current_function_calls_eh_return)
83720594 15590 {
78e1b90d
DE
15591 unsigned int i, regno;
15592
fc4767bb
JJ
15593 /* In AIX ABI we need to pretend we save r2 here. */
15594 if (TARGET_AIX)
15595 {
15596 rtx addr, reg, mem;
15597
15598 reg = gen_rtx_REG (reg_mode, 2);
15599 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15600 GEN_INT (sp_offset + 5 * reg_size));
0be76840 15601 mem = gen_frame_mem (reg_mode, addr);
fc4767bb
JJ
15602
15603 insn = emit_move_insn (mem, reg);
f676971a 15604 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
fc4767bb
JJ
15605 NULL_RTX, NULL_RTX);
15606 PATTERN (insn) = gen_blockage ();
15607 }
15608
83720594
RH
15609 for (i = 0; ; ++i)
15610 {
83720594
RH
15611 regno = EH_RETURN_DATA_REGNO (i);
15612 if (regno == INVALID_REGNUM)
15613 break;
15614
89e7058f
AH
15615 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
15616 info->ehrd_offset + sp_offset
15617 + reg_size * (int) i,
15618 info->total_size);
83720594
RH
15619 }
15620 }
15621
9ebbca7d 15622 /* Save CR if we use any that must be preserved. */
f57fe068 15623 if (!WORLD_SAVE_P (info) && info->cr_save_p)
9ebbca7d
GK
15624 {
15625 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15626 GEN_INT (info->cr_save_offset + sp_offset));
0be76840 15627 rtx mem = gen_frame_mem (SImode, addr);
f8a57be8
GK
15628 /* See the large comment above about why CR2_REGNO is used. */
15629 rtx magic_eh_cr_reg = gen_rtx_REG (SImode, CR2_REGNO);
ba4828e0 15630
9ebbca7d
GK
15631 /* If r12 was used to hold the original sp, copy cr into r0 now
15632 that it's free. */
15633 if (REGNO (frame_reg_rtx) == 12)
15634 {
f8a57be8
GK
15635 rtx set;
15636
9ebbca7d 15637 cr_save_rtx = gen_rtx_REG (SImode, 0);
f8a57be8
GK
15638 insn = emit_insn (gen_movesi_from_cr (cr_save_rtx));
15639 RTX_FRAME_RELATED_P (insn) = 1;
15640 set = gen_rtx_SET (VOIDmode, cr_save_rtx, magic_eh_cr_reg);
15641 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
15642 set,
15643 REG_NOTES (insn));
f676971a 15644
9ebbca7d
GK
15645 }
15646 insn = emit_move_insn (mem, cr_save_rtx);
15647
f676971a 15648 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
f8a57be8 15649 NULL_RTX, NULL_RTX);
9ebbca7d
GK
15650 }
15651
f676971a 15652 /* Update stack and set back pointer unless this is V.4,
9ebbca7d 15653 for which it was done previously. */
f57fe068 15654 if (!WORLD_SAVE_P (info) && info->push_p
fc4767bb 15655 && !(DEFAULT_ABI == ABI_V4 || current_function_calls_eh_return))
2b2c2fe5 15656 {
bcb2d701 15657 if (info->total_size < 32767)
2b2c2fe5 15658 sp_offset = info->total_size;
bcb2d701
EC
15659 else
15660 frame_reg_rtx = frame_ptr_rtx;
15661 rs6000_emit_allocate_stack (info->total_size,
15662 (frame_reg_rtx != sp_reg_rtx
15663 && ((info->altivec_size != 0)
15664 || (info->vrsave_mask != 0)
15665 )));
15666 if (frame_reg_rtx != sp_reg_rtx)
15667 rs6000_emit_stack_tie ();
2b2c2fe5 15668 }
9ebbca7d
GK
15669
15670 /* Set frame pointer, if needed. */
15671 if (frame_pointer_needed)
15672 {
7d5175e1 15673 insn = emit_move_insn (gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
9ebbca7d
GK
15674 sp_reg_rtx);
15675 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 15676 }
9878760c 15677
2b2c2fe5
EC
15678 /* Save AltiVec registers if needed. Save here because the red zone does
15679 not include AltiVec registers. */
15680 if (!WORLD_SAVE_P (info) && TARGET_ALTIVEC_ABI && info->altivec_size != 0)
15681 {
15682 int i;
15683
15684 /* There should be a non inline version of this, for when we
15685 are saving lots of vector registers. */
15686 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
15687 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
15688 {
15689 rtx areg, savereg, mem;
15690 int offset;
15691
15692 offset = info->altivec_save_offset + sp_offset
15693 + 16 * (i - info->first_altivec_reg_save);
15694
15695 savereg = gen_rtx_REG (V4SImode, i);
15696
15697 areg = gen_rtx_REG (Pmode, 0);
15698 emit_move_insn (areg, GEN_INT (offset));
15699
15700 /* AltiVec addressing mode is [reg+reg]. */
15701 mem = gen_frame_mem (V4SImode,
15702 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
15703
15704 insn = emit_move_insn (mem, savereg);
15705
15706 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
15707 areg, GEN_INT (offset));
15708 }
15709 }
15710
15711 /* VRSAVE is a bit vector representing which AltiVec registers
15712 are used. The OS uses this to determine which vector
15713 registers to save on a context switch. We need to save
15714 VRSAVE on the stack frame, add whatever AltiVec registers we
15715 used in this function, and do the corresponding magic in the
15716 epilogue. */
15717
15718 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
15719 && info->vrsave_mask != 0)
15720 {
15721 rtx reg, mem, vrsave;
15722 int offset;
15723
15724 /* Get VRSAVE onto a GPR. Note that ABI_V4 might be using r12
15725 as frame_reg_rtx and r11 as the static chain pointer for
15726 nested functions. */
15727 reg = gen_rtx_REG (SImode, 0);
15728 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
15729 if (TARGET_MACHO)
15730 emit_insn (gen_get_vrsave_internal (reg));
15731 else
15732 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
15733
15734 if (!WORLD_SAVE_P (info))
15735 {
15736 /* Save VRSAVE. */
15737 offset = info->vrsave_save_offset + sp_offset;
15738 mem = gen_frame_mem (SImode,
15739 gen_rtx_PLUS (Pmode, frame_reg_rtx,
15740 GEN_INT (offset)));
15741 insn = emit_move_insn (mem, reg);
15742 }
15743
15744 /* Include the registers in the mask. */
15745 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
15746
15747 insn = emit_insn (generate_set_vrsave (reg, info, 0));
15748 }
15749
1db02437 15750 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 15751 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
7f970b70
AM
15752 || (DEFAULT_ABI == ABI_V4
15753 && (flag_pic == 1 || (flag_pic && TARGET_SECURE_PLT))
6fb5fa3c 15754 && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)))
c4ad648e
AM
15755 {
15756 /* If emit_load_toc_table will use the link register, we need to save
15757 it. We use R12 for this purpose because emit_load_toc_table
15758 can use register 0. This allows us to use a plain 'blr' to return
15759 from the procedure more often. */
15760 int save_LR_around_toc_setup = (TARGET_ELF
15761 && DEFAULT_ABI != ABI_AIX
15762 && flag_pic
15763 && ! info->lr_save_p
15764 && EDGE_COUNT (EXIT_BLOCK_PTR->preds) > 0);
15765 if (save_LR_around_toc_setup)
15766 {
1de43f85 15767 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
f8a57be8 15768
c4ad648e 15769 insn = emit_move_insn (frame_ptr_rtx, lr);
c4ad648e 15770 RTX_FRAME_RELATED_P (insn) = 1;
f8a57be8 15771
c4ad648e 15772 rs6000_emit_load_toc_table (TRUE);
f8a57be8 15773
c4ad648e 15774 insn = emit_move_insn (lr, frame_ptr_rtx);
c4ad648e
AM
15775 RTX_FRAME_RELATED_P (insn) = 1;
15776 }
15777 else
15778 rs6000_emit_load_toc_table (TRUE);
15779 }
ee890fe2 15780
fcce224d 15781#if TARGET_MACHO
ee890fe2
SS
15782 if (DEFAULT_ABI == ABI_DARWIN
15783 && flag_pic && current_function_uses_pic_offset_table)
15784 {
1de43f85 15785 rtx lr = gen_rtx_REG (Pmode, LR_REGNO);
11abc112 15786 rtx src = machopic_function_base_sym ();
ee890fe2 15787
6d0a8091
DJ
15788 /* Save and restore LR locally around this call (in R0). */
15789 if (!info->lr_save_p)
6fb5fa3c 15790 emit_move_insn (gen_rtx_REG (Pmode, 0), lr);
6d0a8091 15791
6fb5fa3c 15792 emit_insn (gen_load_macho_picbase (src));
ee890fe2 15793
6fb5fa3c
DB
15794 emit_move_insn (gen_rtx_REG (Pmode,
15795 RS6000_PIC_OFFSET_TABLE_REGNUM),
15796 lr);
6d0a8091
DJ
15797
15798 if (!info->lr_save_p)
6fb5fa3c 15799 emit_move_insn (lr, gen_rtx_REG (Pmode, 0));
ee890fe2 15800 }
fcce224d 15801#endif
9ebbca7d
GK
15802}
15803
9ebbca7d 15804/* Write function prologue. */
a4f6c312 15805
08c148a8 15806static void
f676971a 15807rs6000_output_function_prologue (FILE *file,
a2369ed3 15808 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
9ebbca7d
GK
15809{
15810 rs6000_stack_t *info = rs6000_stack_info ();
15811
4697a36c
MM
15812 if (TARGET_DEBUG_STACK)
15813 debug_stack_info (info);
9878760c 15814
a4f6c312
SS
15815 /* Write .extern for any function we will call to save and restore
15816 fp values. */
15817 if (info->first_fp_reg_save < 64
15818 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 15819 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 15820 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
15821 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
15822 RESTORE_FP_SUFFIX);
9878760c 15823
c764f757
RK
15824 /* Write .extern for AIX common mode routines, if needed. */
15825 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
15826 {
f6709c70
JW
15827 fputs ("\t.extern __mulh\n", file);
15828 fputs ("\t.extern __mull\n", file);
15829 fputs ("\t.extern __divss\n", file);
15830 fputs ("\t.extern __divus\n", file);
15831 fputs ("\t.extern __quoss\n", file);
15832 fputs ("\t.extern __quous\n", file);
c764f757
RK
15833 common_mode_defined = 1;
15834 }
9878760c 15835
9ebbca7d 15836 if (! HAVE_prologue)
979721f8 15837 {
9ebbca7d 15838 start_sequence ();
9dda4cc8 15839
a4f6c312
SS
15840 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
15841 the "toplevel" insn chain. */
2e040219 15842 emit_note (NOTE_INSN_DELETED);
9ebbca7d 15843 rs6000_emit_prologue ();
2e040219 15844 emit_note (NOTE_INSN_DELETED);
178c3eff 15845
a3c9585f 15846 /* Expand INSN_ADDRESSES so final() doesn't crash. */
178c3eff
DJ
15847 {
15848 rtx insn;
15849 unsigned addr = 0;
15850 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
15851 {
15852 INSN_ADDRESSES_NEW (insn, addr);
15853 addr += 4;
15854 }
15855 }
9dda4cc8 15856
9ebbca7d 15857 if (TARGET_DEBUG_STACK)
a4f6c312 15858 debug_rtx_list (get_insns (), 100);
c9d691e9 15859 final (get_insns (), file, FALSE);
9ebbca7d 15860 end_sequence ();
979721f8
MM
15861 }
15862
9ebbca7d
GK
15863 rs6000_pic_labelno++;
15864}
f676971a 15865
9ebbca7d 15866/* Emit function epilogue as insns.
9878760c 15867
9ebbca7d
GK
15868 At present, dwarf2out_frame_debug_expr doesn't understand
15869 register restores, so we don't bother setting RTX_FRAME_RELATED_P
15870 anywhere in the epilogue. Most of the insns below would in any case
15871 need special notes to explain where r11 is in relation to the stack. */
9878760c 15872
9ebbca7d 15873void
a2369ed3 15874rs6000_emit_epilogue (int sibcall)
9ebbca7d
GK
15875{
15876 rs6000_stack_t *info;
15877 int restoring_FPRs_inline;
15878 int using_load_multiple;
d296e02e 15879 int using_mtcr_multiple;
9ebbca7d
GK
15880 int use_backchain_to_restore_sp;
15881 int sp_offset = 0;
15882 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
15883 rtx frame_reg_rtx = sp_reg_rtx;
0e67400a 15884 enum machine_mode reg_mode = Pmode;
327e5343 15885 int reg_size = TARGET_32BIT ? 4 : 8;
9ebbca7d
GK
15886 int i;
15887
c19de7aa
AH
15888 info = rs6000_stack_info ();
15889
15890 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
15891 {
15892 reg_mode = V2SImode;
15893 reg_size = 8;
15894 }
15895
9ebbca7d 15896 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
15897 && (!TARGET_SPE_ABI
15898 || info->spe_64bit_regs_used == 0)
6d0a8091
DJ
15899 && info->first_gp_reg_save < 31
15900 && no_global_regs_above (info->first_gp_reg_save));
9ebbca7d 15901 restoring_FPRs_inline = (sibcall
83720594 15902 || current_function_calls_eh_return
9ebbca7d
GK
15903 || info->first_fp_reg_save == 64
15904 || FP_SAVE_INLINE (info->first_fp_reg_save));
f676971a 15905 use_backchain_to_restore_sp = (frame_pointer_needed
9ebbca7d
GK
15906 || current_function_calls_alloca
15907 || info->total_size > 32767);
d296e02e 15908 using_mtcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
9ebbca7d
GK
15909 || rs6000_cpu == PROCESSOR_PPC603
15910 || rs6000_cpu == PROCESSOR_PPC750
15911 || optimize_size);
15912
f57fe068 15913 if (WORLD_SAVE_P (info))
d62294f5
FJ
15914 {
15915 int i, j;
15916 char rname[30];
15917 const char *alloc_rname;
15918 rtvec p;
15919
15920 /* eh_rest_world_r10 will return to the location saved in the LR
c4ad648e
AM
15921 stack slot (which is not likely to be our caller.)
15922 Input: R10 -- stack adjustment. Clobbers R0, R11, R12, R7, R8.
15923 rest_world is similar, except any R10 parameter is ignored.
15924 The exception-handling stuff that was here in 2.95 is no
15925 longer necessary. */
d62294f5
FJ
15926
15927 p = rtvec_alloc (9
15928 + 1
f676971a 15929 + 32 - info->first_gp_reg_save
c4ad648e
AM
15930 + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
15931 + 63 + 1 - info->first_fp_reg_save);
d62294f5 15932
c4ad648e
AM
15933 strcpy (rname, ((current_function_calls_eh_return) ?
15934 "*eh_rest_world_r10" : "*rest_world"));
d62294f5
FJ
15935 alloc_rname = ggc_strdup (rname);
15936
15937 j = 0;
15938 RTVEC_ELT (p, j++) = gen_rtx_RETURN (VOIDmode);
15939 RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode,
c4ad648e 15940 gen_rtx_REG (Pmode,
1de43f85 15941 LR_REGNO));
d62294f5 15942 RTVEC_ELT (p, j++)
c4ad648e 15943 = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname));
d62294f5 15944 /* The instruction pattern requires a clobber here;
c4ad648e 15945 it is shared with the restVEC helper. */
d62294f5 15946 RTVEC_ELT (p, j++)
c4ad648e 15947 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 11));
d62294f5
FJ
15948
15949 {
c4ad648e
AM
15950 /* CR register traditionally saved as CR2. */
15951 rtx reg = gen_rtx_REG (reg_mode, CR2_REGNO);
15952 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15953 GEN_INT (info->cr_save_offset));
0be76840 15954 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
15955
15956 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
d62294f5
FJ
15957 }
15958
15959 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
c4ad648e
AM
15960 {
15961 rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
15962 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15963 GEN_INT (info->gp_save_offset
15964 + reg_size * i));
0be76840 15965 rtx mem = gen_frame_mem (reg_mode, addr);
c4ad648e
AM
15966
15967 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15968 }
d62294f5 15969 for (i = 0; info->first_altivec_reg_save + i <= LAST_ALTIVEC_REGNO; i++)
c4ad648e
AM
15970 {
15971 rtx reg = gen_rtx_REG (V4SImode, info->first_altivec_reg_save + i);
15972 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15973 GEN_INT (info->altivec_save_offset
15974 + 16 * i));
0be76840 15975 rtx mem = gen_frame_mem (V4SImode, addr);
c4ad648e
AM
15976
15977 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15978 }
d62294f5 15979 for (i = 0; info->first_fp_reg_save + i <= 63; i++)
c4ad648e
AM
15980 {
15981 rtx reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
15982 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
15983 GEN_INT (info->fp_save_offset
15984 + 8 * i));
0be76840 15985 rtx mem = gen_frame_mem (DFmode, addr);
c4ad648e
AM
15986
15987 RTVEC_ELT (p, j++) = gen_rtx_SET (VOIDmode, reg, mem);
15988 }
d62294f5 15989 RTVEC_ELT (p, j++)
c4ad648e 15990 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 0));
d62294f5 15991 RTVEC_ELT (p, j++)
c4ad648e 15992 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 12));
d62294f5 15993 RTVEC_ELT (p, j++)
c4ad648e 15994 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 7));
d62294f5 15995 RTVEC_ELT (p, j++)
c4ad648e 15996 = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 8));
d62294f5 15997 RTVEC_ELT (p, j++)
c4ad648e 15998 = gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 10));
d62294f5
FJ
15999 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
16000
16001 return;
16002 }
16003
2b2c2fe5 16004 /* Set sp_offset based on the stack push from the prologue. */
bcb2d701 16005 if (info->total_size < 32767)
2b2c2fe5 16006 sp_offset = info->total_size;
f676971a 16007
9aa86737
AH
16008 /* Restore AltiVec registers if needed. */
16009 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
16010 {
16011 int i;
16012
16013 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
16014 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
16015 {
16016 rtx addr, areg, mem;
16017
16018 areg = gen_rtx_REG (Pmode, 0);
16019 emit_move_insn
16020 (areg, GEN_INT (info->altivec_save_offset
16021 + sp_offset
16022 + 16 * (i - info->first_altivec_reg_save)));
16023
16024 /* AltiVec addressing mode is [reg+reg]. */
16025 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
0be76840 16026 mem = gen_frame_mem (V4SImode, addr);
9aa86737
AH
16027
16028 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
16029 }
16030 }
16031
16032 /* Restore VRSAVE if needed. */
44688022 16033 if (TARGET_ALTIVEC && TARGET_ALTIVEC_VRSAVE
4d774ff8 16034 && info->vrsave_mask != 0)
9aa86737
AH
16035 {
16036 rtx addr, mem, reg;
16037
16038 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16039 GEN_INT (info->vrsave_save_offset + sp_offset));
0be76840 16040 mem = gen_frame_mem (SImode, addr);
9aa86737
AH
16041 reg = gen_rtx_REG (SImode, 12);
16042 emit_move_insn (reg, mem);
16043
16044 emit_insn (generate_set_vrsave (reg, info, 1));
16045 }
16046
2b2c2fe5
EC
16047 sp_offset = 0;
16048
16049 /* If we have a frame pointer, a call to alloca, or a large stack
16050 frame, restore the old stack pointer using the backchain. Otherwise,
16051 we know what size to update it with. */
16052 if (use_backchain_to_restore_sp)
16053 {
16054 /* Under V.4, don't reset the stack pointer until after we're done
16055 loading the saved registers. */
16056 if (DEFAULT_ABI == ABI_V4)
16057 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
16058
16059 emit_move_insn (frame_reg_rtx,
16060 gen_rtx_MEM (Pmode, sp_reg_rtx));
16061 }
16062 else if (info->push_p)
16063 {
16064 if (DEFAULT_ABI == ABI_V4
16065 || current_function_calls_eh_return)
16066 sp_offset = info->total_size;
16067 else
16068 {
16069 emit_insn (TARGET_32BIT
16070 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
16071 GEN_INT (info->total_size))
16072 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
16073 GEN_INT (info->total_size)));
16074 }
16075 }
16076
9ebbca7d
GK
16077 /* Get the old lr if we saved it. */
16078 if (info->lr_save_p)
b6c9286a 16079 {
a3170dc6
AH
16080 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
16081 info->lr_save_offset + sp_offset);
ba4828e0 16082
9ebbca7d 16083 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 16084 }
f676971a 16085
9ebbca7d
GK
16086 /* Get the old cr if we saved it. */
16087 if (info->cr_save_p)
16088 {
16089 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16090 GEN_INT (info->cr_save_offset + sp_offset));
0be76840 16091 rtx mem = gen_frame_mem (SImode, addr);
b6c9286a 16092
9ebbca7d
GK
16093 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
16094 }
f676971a 16095
9ebbca7d 16096 /* Set LR here to try to overlap restores below. */
4697a36c 16097 if (info->lr_save_p)
1de43f85 16098 emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
9ebbca7d 16099 gen_rtx_REG (Pmode, 0));
f676971a 16100
83720594
RH
16101 /* Load exception handler data registers, if needed. */
16102 if (current_function_calls_eh_return)
16103 {
78e1b90d
DE
16104 unsigned int i, regno;
16105
fc4767bb
JJ
16106 if (TARGET_AIX)
16107 {
16108 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16109 GEN_INT (sp_offset + 5 * reg_size));
0be76840 16110 rtx mem = gen_frame_mem (reg_mode, addr);
fc4767bb
JJ
16111
16112 emit_move_insn (gen_rtx_REG (reg_mode, 2), mem);
16113 }
16114
83720594
RH
16115 for (i = 0; ; ++i)
16116 {
a3170dc6 16117 rtx mem;
83720594
RH
16118
16119 regno = EH_RETURN_DATA_REGNO (i);
16120 if (regno == INVALID_REGNUM)
16121 break;
16122
a3170dc6
AH
16123 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
16124 info->ehrd_offset + sp_offset
16125 + reg_size * (int) i);
83720594
RH
16126
16127 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
16128 }
16129 }
f676971a 16130
9ebbca7d
GK
16131 /* Restore GPRs. This is done as a PARALLEL if we are using
16132 the load-multiple instructions. */
16133 if (using_load_multiple)
979721f8 16134 {
9ebbca7d
GK
16135 rtvec p;
16136 p = rtvec_alloc (32 - info->first_gp_reg_save);
16137 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 16138 {
f676971a
EC
16139 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16140 GEN_INT (info->gp_save_offset
16141 + sp_offset
9ebbca7d 16142 + reg_size * i));
0be76840 16143 rtx mem = gen_frame_mem (reg_mode, addr);
9ebbca7d 16144
f676971a 16145 RTVEC_ELT (p, i) =
9ebbca7d
GK
16146 gen_rtx_SET (VOIDmode,
16147 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
16148 mem);
979721f8 16149 }
9ebbca7d 16150 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 16151 }
52ff33d0
NF
16152 else if (TARGET_SPE_ABI
16153 && info->spe_64bit_regs_used != 0
16154 && info->first_gp_reg_save != 32)
16155 {
16156 rtx spe_save_area_ptr;
16157 /* Determine whether we can address all of the registers that need
16158 to be saved with an offset from the stack pointer that fits in
16159 the small const field for SPE memory instructions. */
16160 int spe_regs_addressable_via_sp
16161 = SPE_CONST_OFFSET_OK(info->spe_gp_save_offset + sp_offset
16162 + (32 - info->first_gp_reg_save - 1) * reg_size);
16163 int spe_offset;
16164
16165 if (spe_regs_addressable_via_sp)
16166 {
16167 spe_save_area_ptr = frame_reg_rtx;
16168 spe_offset = info->spe_gp_save_offset + sp_offset;
16169 }
16170 else
16171 {
16172 /* Make r11 point to the start of the SPE save area. We worried about
6ed3da00 16173 not clobbering it when we were saving registers in the prologue.
52ff33d0
NF
16174 There's no need to worry here because the static chain is passed
16175 anew to every function. */
16176 spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
16177
16178 emit_insn (gen_addsi3 (spe_save_area_ptr, frame_reg_rtx,
16179 GEN_INT (info->spe_gp_save_offset + sp_offset)));
16180
16181 spe_offset = 0;
16182 }
16183
16184 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
16185 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
16186 {
16187 rtx offset, addr, mem;
16188
16189 /* We're doing all this to ensure that the immediate offset
16190 fits into the immediate field of 'evldd'. */
16191 gcc_assert (SPE_CONST_OFFSET_OK (spe_offset + reg_size * i));
16192
16193 offset = GEN_INT (spe_offset + reg_size * i);
16194 addr = gen_rtx_PLUS (Pmode, spe_save_area_ptr, offset);
16195 mem = gen_rtx_MEM (V2SImode, addr);
16196
16197 emit_move_insn (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
16198 mem);
16199 }
16200 }
9ebbca7d
GK
16201 else
16202 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
52ff33d0 16203 if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i))
9ebbca7d 16204 {
f676971a
EC
16205 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
16206 GEN_INT (info->gp_save_offset
16207 + sp_offset
9ebbca7d 16208 + reg_size * i));
0be76840 16209 rtx mem = gen_frame_mem (reg_mode, addr);
ba4828e0 16210
f676971a 16211 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 16212 info->first_gp_reg_save + i), mem);
9ebbca7d 16213 }
9878760c 16214
9ebbca7d
GK
16215 /* Restore fpr's if we need to do it without calling a function. */
16216 if (restoring_FPRs_inline)
16217 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
6fb5fa3c 16218 if ((df_regs_ever_live_p (info->first_fp_reg_save+i)
9ebbca7d
GK
16219 && ! call_used_regs[info->first_fp_reg_save+i]))
16220 {
16221 rtx addr, mem;
16222 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
f676971a
EC
16223 GEN_INT (info->fp_save_offset
16224 + sp_offset
a4f6c312 16225 + 8 * i));
0be76840 16226 mem = gen_frame_mem (DFmode, addr);
9ebbca7d 16227
f676971a 16228 emit_move_insn (gen_rtx_REG (DFmode,
9ebbca7d
GK
16229 info->first_fp_reg_save + i),
16230 mem);
16231 }
8d30c4ee 16232
9ebbca7d
GK
16233 /* If we saved cr, restore it here. Just those that were used. */
16234 if (info->cr_save_p)
979721f8 16235 {
9ebbca7d 16236 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 16237 int count = 0;
f676971a 16238
d296e02e 16239 if (using_mtcr_multiple)
979721f8 16240 {
9ebbca7d 16241 for (i = 0; i < 8; i++)
6fb5fa3c 16242 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
e35b9579 16243 count++;
37409796 16244 gcc_assert (count);
e35b9579
GK
16245 }
16246
d296e02e 16247 if (using_mtcr_multiple && count > 1)
e35b9579
GK
16248 {
16249 rtvec p;
16250 int ndx;
f676971a 16251
e35b9579 16252 p = rtvec_alloc (count);
9ebbca7d 16253
e35b9579 16254 ndx = 0;
9ebbca7d 16255 for (i = 0; i < 8; i++)
6fb5fa3c 16256 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
9ebbca7d
GK
16257 {
16258 rtvec r = rtvec_alloc (2);
16259 RTVEC_ELT (r, 0) = r12_rtx;
16260 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 16261 RTVEC_ELT (p, ndx) =
f676971a 16262 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
615158e2 16263 gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR));
e35b9579 16264 ndx++;
9ebbca7d
GK
16265 }
16266 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
37409796 16267 gcc_assert (ndx == count);
979721f8
MM
16268 }
16269 else
9ebbca7d 16270 for (i = 0; i < 8; i++)
6fb5fa3c 16271 if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i])
979721f8 16272 {
f676971a 16273 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
9ebbca7d
GK
16274 CR0_REGNO+i),
16275 r12_rtx));
979721f8 16276 }
979721f8
MM
16277 }
16278
9ebbca7d 16279 /* If this is V.4, unwind the stack pointer after all of the loads
022123e6
AM
16280 have been done. */
16281 if (frame_reg_rtx != sp_reg_rtx)
16282 {
16283 /* This blockage is needed so that sched doesn't decide to move
16284 the sp change before the register restores. */
16285 rs6000_emit_stack_tie ();
52ff33d0
NF
16286 if (TARGET_SPE_ABI
16287 && info->spe_64bit_regs_used != 0
16288 && info->first_gp_reg_save != 32)
16289 emit_insn (gen_addsi3 (sp_reg_rtx, gen_rtx_REG (Pmode, 11),
16290 GEN_INT (-(info->spe_gp_save_offset + sp_offset))));
16291 else
16292 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
022123e6
AM
16293 }
16294 else if (sp_offset != 0)
16295 emit_insn (TARGET_32BIT
16296 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
16297 GEN_INT (sp_offset))
16298 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
16299 GEN_INT (sp_offset)));
b6c9286a 16300
83720594
RH
16301 if (current_function_calls_eh_return)
16302 {
16303 rtx sa = EH_RETURN_STACKADJ_RTX;
5b71a4e7 16304 emit_insn (TARGET_32BIT
83720594
RH
16305 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
16306 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
16307 }
16308
9ebbca7d
GK
16309 if (!sibcall)
16310 {
16311 rtvec p;
16312 if (! restoring_FPRs_inline)
16313 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
16314 else
16315 p = rtvec_alloc (2);
b6c9286a 16316
e35b9579 16317 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
f676971a
EC
16318 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
16319 gen_rtx_REG (Pmode,
1de43f85 16320 LR_REGNO));
9ebbca7d
GK
16321
16322 /* If we have to restore more than two FP registers, branch to the
16323 restore function. It will return to our caller. */
16324 if (! restoring_FPRs_inline)
16325 {
16326 int i;
16327 char rname[30];
520a57c8 16328 const char *alloc_rname;
979721f8 16329
f676971a 16330 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
9ebbca7d 16331 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 16332 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
16333 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
16334 gen_rtx_SYMBOL_REF (Pmode,
16335 alloc_rname));
b6c9286a 16336
9ebbca7d
GK
16337 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
16338 {
16339 rtx addr, mem;
16340 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
16341 GEN_INT (info->fp_save_offset + 8*i));
0be76840 16342 mem = gen_frame_mem (DFmode, addr);
9ebbca7d 16343
f676971a 16344 RTVEC_ELT (p, i+3) =
9ebbca7d
GK
16345 gen_rtx_SET (VOIDmode,
16346 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
16347 mem);
b6c9286a
MM
16348 }
16349 }
f676971a 16350
9ebbca7d 16351 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 16352 }
9878760c
RK
16353}
16354
16355/* Write function epilogue. */
16356
08c148a8 16357static void
f676971a 16358rs6000_output_function_epilogue (FILE *file,
a2369ed3 16359 HOST_WIDE_INT size ATTRIBUTE_UNUSED)
9878760c 16360{
9ebbca7d 16361 if (! HAVE_epilogue)
9878760c 16362 {
9ebbca7d
GK
16363 rtx insn = get_last_insn ();
16364 /* If the last insn was a BARRIER, we don't have to write anything except
16365 the trace table. */
16366 if (GET_CODE (insn) == NOTE)
16367 insn = prev_nonnote_insn (insn);
16368 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 16369 {
9ebbca7d
GK
16370 /* This is slightly ugly, but at least we don't have two
16371 copies of the epilogue-emitting code. */
16372 start_sequence ();
16373
16374 /* A NOTE_INSN_DELETED is supposed to be at the start
16375 and end of the "toplevel" insn chain. */
2e040219 16376 emit_note (NOTE_INSN_DELETED);
9ebbca7d 16377 rs6000_emit_epilogue (FALSE);
2e040219 16378 emit_note (NOTE_INSN_DELETED);
9ebbca7d 16379
a3c9585f 16380 /* Expand INSN_ADDRESSES so final() doesn't crash. */
178c3eff
DJ
16381 {
16382 rtx insn;
16383 unsigned addr = 0;
16384 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
16385 {
16386 INSN_ADDRESSES_NEW (insn, addr);
16387 addr += 4;
16388 }
16389 }
16390
9ebbca7d 16391 if (TARGET_DEBUG_STACK)
a4f6c312 16392 debug_rtx_list (get_insns (), 100);
c9d691e9 16393 final (get_insns (), file, FALSE);
9ebbca7d 16394 end_sequence ();
4697a36c 16395 }
9878760c 16396 }
b4ac57ab 16397
efdba735
SH
16398#if TARGET_MACHO
16399 macho_branch_islands ();
0e5da0be
GK
16400 /* Mach-O doesn't support labels at the end of objects, so if
16401 it looks like we might want one, insert a NOP. */
16402 {
16403 rtx insn = get_last_insn ();
16404 while (insn
16405 && NOTE_P (insn)
a38e7aa5 16406 && NOTE_KIND (insn) != NOTE_INSN_DELETED_LABEL)
0e5da0be 16407 insn = PREV_INSN (insn);
f676971a
EC
16408 if (insn
16409 && (LABEL_P (insn)
0e5da0be 16410 || (NOTE_P (insn)
a38e7aa5 16411 && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL)))
0e5da0be
GK
16412 fputs ("\tnop\n", file);
16413 }
16414#endif
16415
9b30bae2 16416 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
16417 on its format.
16418
16419 We don't output a traceback table if -finhibit-size-directive was
16420 used. The documentation for -finhibit-size-directive reads
16421 ``don't output a @code{.size} assembler directive, or anything
16422 else that would cause trouble if the function is split in the
16423 middle, and the two halves are placed at locations far apart in
16424 memory.'' The traceback table has this property, since it
16425 includes the offset from the start of the function to the
4d30c363
MM
16426 traceback table itself.
16427
16428 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 16429 different traceback table. */
57ac7be9 16430 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
8097c268 16431 && rs6000_traceback != traceback_none && !current_function_is_thunk)
9b30bae2 16432 {
69c75916 16433 const char *fname = NULL;
3ac88239 16434 const char *language_string = lang_hooks.name;
6041bf2f 16435 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 16436 int i;
57ac7be9 16437 int optional_tbtab;
8097c268 16438 rs6000_stack_t *info = rs6000_stack_info ();
57ac7be9
AM
16439
16440 if (rs6000_traceback == traceback_full)
16441 optional_tbtab = 1;
16442 else if (rs6000_traceback == traceback_part)
16443 optional_tbtab = 0;
16444 else
16445 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 16446
69c75916
AM
16447 if (optional_tbtab)
16448 {
16449 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
16450 while (*fname == '.') /* V.4 encodes . in the name */
16451 fname++;
16452
16453 /* Need label immediately before tbtab, so we can compute
16454 its offset from the function start. */
16455 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
16456 ASM_OUTPUT_LABEL (file, fname);
16457 }
314fc5a9
ILT
16458
16459 /* The .tbtab pseudo-op can only be used for the first eight
16460 expressions, since it can't handle the possibly variable
16461 length fields that follow. However, if you omit the optional
16462 fields, the assembler outputs zeros for all optional fields
16463 anyways, giving each variable length field is minimum length
16464 (as defined in sys/debug.h). Thus we can not use the .tbtab
16465 pseudo-op at all. */
16466
16467 /* An all-zero word flags the start of the tbtab, for debuggers
16468 that have to find it by searching forward from the entry
16469 point or from the current pc. */
19d2d16f 16470 fputs ("\t.long 0\n", file);
314fc5a9
ILT
16471
16472 /* Tbtab format type. Use format type 0. */
19d2d16f 16473 fputs ("\t.byte 0,", file);
314fc5a9 16474
5fc921c1
DE
16475 /* Language type. Unfortunately, there does not seem to be any
16476 official way to discover the language being compiled, so we
16477 use language_string.
16478 C is 0. Fortran is 1. Pascal is 2. Ada is 3. C++ is 9.
56438901
AM
16479 Java is 13. Objective-C is 14. Objective-C++ isn't assigned
16480 a number, so for now use 9. */
5fc921c1 16481 if (! strcmp (language_string, "GNU C"))
314fc5a9 16482 i = 0;
6de9cd9a
DN
16483 else if (! strcmp (language_string, "GNU F77")
16484 || ! strcmp (language_string, "GNU F95"))
314fc5a9 16485 i = 1;
8b83775b 16486 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9 16487 i = 2;
5fc921c1
DE
16488 else if (! strcmp (language_string, "GNU Ada"))
16489 i = 3;
56438901
AM
16490 else if (! strcmp (language_string, "GNU C++")
16491 || ! strcmp (language_string, "GNU Objective-C++"))
314fc5a9 16492 i = 9;
9517ead8
AG
16493 else if (! strcmp (language_string, "GNU Java"))
16494 i = 13;
5fc921c1
DE
16495 else if (! strcmp (language_string, "GNU Objective-C"))
16496 i = 14;
314fc5a9 16497 else
37409796 16498 gcc_unreachable ();
314fc5a9
ILT
16499 fprintf (file, "%d,", i);
16500
16501 /* 8 single bit fields: global linkage (not set for C extern linkage,
16502 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
16503 from start of procedure stored in tbtab, internal function, function
16504 has controlled storage, function has no toc, function uses fp,
16505 function logs/aborts fp operations. */
16506 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
16507 fprintf (file, "%d,",
16508 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
16509
16510 /* 6 bitfields: function is interrupt handler, name present in
16511 proc table, function calls alloca, on condition directives
16512 (controls stack walks, 3 bits), saves condition reg, saves
16513 link reg. */
16514 /* The `function calls alloca' bit seems to be set whenever reg 31 is
16515 set up as a frame pointer, even when there is no alloca call. */
16516 fprintf (file, "%d,",
6041bf2f
DE
16517 ((optional_tbtab << 6)
16518 | ((optional_tbtab & frame_pointer_needed) << 5)
16519 | (info->cr_save_p << 1)
16520 | (info->lr_save_p)));
314fc5a9 16521
6041bf2f 16522 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
16523 (6 bits). */
16524 fprintf (file, "%d,",
4697a36c 16525 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
16526
16527 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
16528 fprintf (file, "%d,", (32 - first_reg_to_save ()));
16529
6041bf2f
DE
16530 if (optional_tbtab)
16531 {
16532 /* Compute the parameter info from the function decl argument
16533 list. */
16534 tree decl;
16535 int next_parm_info_bit = 31;
314fc5a9 16536
6041bf2f
DE
16537 for (decl = DECL_ARGUMENTS (current_function_decl);
16538 decl; decl = TREE_CHAIN (decl))
16539 {
16540 rtx parameter = DECL_INCOMING_RTL (decl);
16541 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 16542
6041bf2f
DE
16543 if (GET_CODE (parameter) == REG)
16544 {
ebb109ad 16545 if (SCALAR_FLOAT_MODE_P (mode))
6041bf2f
DE
16546 {
16547 int bits;
16548
16549 float_parms++;
16550
37409796
NS
16551 switch (mode)
16552 {
16553 case SFmode:
16554 bits = 0x2;
16555 break;
16556
16557 case DFmode:
7393f7f8 16558 case DDmode:
37409796 16559 case TFmode:
7393f7f8 16560 case TDmode:
37409796
NS
16561 bits = 0x3;
16562 break;
16563
16564 default:
16565 gcc_unreachable ();
16566 }
6041bf2f
DE
16567
16568 /* If only one bit will fit, don't or in this entry. */
16569 if (next_parm_info_bit > 0)
16570 parm_info |= (bits << (next_parm_info_bit - 1));
16571 next_parm_info_bit -= 2;
16572 }
16573 else
16574 {
16575 fixed_parms += ((GET_MODE_SIZE (mode)
16576 + (UNITS_PER_WORD - 1))
16577 / UNITS_PER_WORD);
16578 next_parm_info_bit -= 1;
16579 }
16580 }
16581 }
16582 }
314fc5a9
ILT
16583
16584 /* Number of fixed point parameters. */
16585 /* This is actually the number of words of fixed point parameters; thus
16586 an 8 byte struct counts as 2; and thus the maximum value is 8. */
16587 fprintf (file, "%d,", fixed_parms);
16588
16589 /* 2 bitfields: number of floating point parameters (7 bits), parameters
16590 all on stack. */
16591 /* This is actually the number of fp registers that hold parameters;
16592 and thus the maximum value is 13. */
16593 /* Set parameters on stack bit if parameters are not in their original
16594 registers, regardless of whether they are on the stack? Xlc
16595 seems to set the bit when not optimizing. */
16596 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
16597
6041bf2f
DE
16598 if (! optional_tbtab)
16599 return;
16600
314fc5a9
ILT
16601 /* Optional fields follow. Some are variable length. */
16602
16603 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
16604 11 double float. */
16605 /* There is an entry for each parameter in a register, in the order that
16606 they occur in the parameter list. Any intervening arguments on the
16607 stack are ignored. If the list overflows a long (max possible length
16608 34 bits) then completely leave off all elements that don't fit. */
16609 /* Only emit this long if there was at least one parameter. */
16610 if (fixed_parms || float_parms)
16611 fprintf (file, "\t.long %d\n", parm_info);
16612
16613 /* Offset from start of code to tb table. */
19d2d16f 16614 fputs ("\t.long ", file);
314fc5a9 16615 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
85b776df
AM
16616 if (TARGET_AIX)
16617 RS6000_OUTPUT_BASENAME (file, fname);
16618 else
16619 assemble_name (file, fname);
16620 putc ('-', file);
16621 rs6000_output_function_entry (file, fname);
19d2d16f 16622 putc ('\n', file);
314fc5a9
ILT
16623
16624 /* Interrupt handler mask. */
16625 /* Omit this long, since we never set the interrupt handler bit
16626 above. */
16627
16628 /* Number of CTL (controlled storage) anchors. */
16629 /* Omit this long, since the has_ctl bit is never set above. */
16630
16631 /* Displacement into stack of each CTL anchor. */
16632 /* Omit this list of longs, because there are no CTL anchors. */
16633
16634 /* Length of function name. */
69c75916
AM
16635 if (*fname == '*')
16636 ++fname;
296b8152 16637 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
16638
16639 /* Function name. */
16640 assemble_string (fname, strlen (fname));
16641
16642 /* Register for alloca automatic storage; this is always reg 31.
16643 Only emit this if the alloca bit was set above. */
16644 if (frame_pointer_needed)
19d2d16f 16645 fputs ("\t.byte 31\n", file);
b1765bde
DE
16646
16647 fputs ("\t.align 2\n", file);
9b30bae2 16648 }
9878760c 16649}
17167fd8 16650\f
a4f6c312
SS
16651/* A C compound statement that outputs the assembler code for a thunk
16652 function, used to implement C++ virtual function calls with
16653 multiple inheritance. The thunk acts as a wrapper around a virtual
16654 function, adjusting the implicit object parameter before handing
16655 control off to the real function.
16656
16657 First, emit code to add the integer DELTA to the location that
16658 contains the incoming first argument. Assume that this argument
16659 contains a pointer, and is the one used to pass the `this' pointer
16660 in C++. This is the incoming argument *before* the function
16661 prologue, e.g. `%o0' on a sparc. The addition must preserve the
16662 values of all other incoming arguments.
17167fd8
MM
16663
16664 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
16665 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
16666 not touch the return address. Hence returning from FUNCTION will
16667 return to whoever called the current `thunk'.
17167fd8 16668
a4f6c312
SS
16669 The effect must be as if FUNCTION had been called directly with the
16670 adjusted first argument. This macro is responsible for emitting
16671 all of the code for a thunk function; output_function_prologue()
16672 and output_function_epilogue() are not invoked.
17167fd8 16673
a4f6c312
SS
16674 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
16675 been extracted from it.) It might possibly be useful on some
16676 targets, but probably not.
17167fd8 16677
a4f6c312
SS
16678 If you do not define this macro, the target-independent code in the
16679 C++ frontend will generate a less efficient heavyweight thunk that
16680 calls FUNCTION instead of jumping to it. The generic approach does
16681 not support varargs. */
17167fd8 16682
3961e8fe 16683static void
f676971a
EC
16684rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
16685 HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
a2369ed3 16686 tree function)
17167fd8 16687{
5b71a4e7 16688 rtx this, insn, funexp;
17167fd8 16689
5b71a4e7 16690 reload_completed = 1;
fe3ad572 16691 epilogue_completed = 1;
56a7189a 16692
5b71a4e7 16693 /* Mark the end of the (empty) prologue. */
2e040219 16694 emit_note (NOTE_INSN_PROLOGUE_END);
17167fd8 16695
5b71a4e7
DE
16696 /* Find the "this" pointer. If the function returns a structure,
16697 the structure return pointer is in r3. */
61f71b34 16698 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
5b71a4e7 16699 this = gen_rtx_REG (Pmode, 4);
56a7189a 16700 else
5b71a4e7 16701 this = gen_rtx_REG (Pmode, 3);
17167fd8 16702
5b71a4e7
DE
16703 /* Apply the constant offset, if required. */
16704 if (delta)
16705 {
16706 rtx delta_rtx = GEN_INT (delta);
16707 emit_insn (TARGET_32BIT
16708 ? gen_addsi3 (this, this, delta_rtx)
16709 : gen_adddi3 (this, this, delta_rtx));
17167fd8
MM
16710 }
16711
5b71a4e7
DE
16712 /* Apply the offset from the vtable, if required. */
16713 if (vcall_offset)
17167fd8 16714 {
5b71a4e7
DE
16715 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
16716 rtx tmp = gen_rtx_REG (Pmode, 12);
17167fd8 16717
5b71a4e7 16718 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
eeff9307
JJ
16719 if (((unsigned HOST_WIDE_INT) vcall_offset) + 0x8000 >= 0x10000)
16720 {
16721 emit_insn (TARGET_32BIT
16722 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
16723 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
16724 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
16725 }
16726 else
16727 {
16728 rtx loc = gen_rtx_PLUS (Pmode, tmp, vcall_offset_rtx);
16729
16730 emit_move_insn (tmp, gen_rtx_MEM (Pmode, loc));
16731 }
5b71a4e7
DE
16732 emit_insn (TARGET_32BIT
16733 ? gen_addsi3 (this, this, tmp)
16734 : gen_adddi3 (this, this, tmp));
17167fd8
MM
16735 }
16736
5b71a4e7
DE
16737 /* Generate a tail call to the target function. */
16738 if (!TREE_USED (function))
16739 {
16740 assemble_external (function);
16741 TREE_USED (function) = 1;
16742 }
16743 funexp = XEXP (DECL_RTL (function), 0);
5b71a4e7 16744 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
ee890fe2
SS
16745
16746#if TARGET_MACHO
ab82a49f 16747 if (MACHOPIC_INDIRECT)
5b71a4e7 16748 funexp = machopic_indirect_call_target (funexp);
ee890fe2 16749#endif
5b71a4e7
DE
16750
16751 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
992d08b1 16752 generate sibcall RTL explicitly. */
5b71a4e7
DE
16753 insn = emit_call_insn (
16754 gen_rtx_PARALLEL (VOIDmode,
16755 gen_rtvec (4,
16756 gen_rtx_CALL (VOIDmode,
16757 funexp, const0_rtx),
16758 gen_rtx_USE (VOIDmode, const0_rtx),
16759 gen_rtx_USE (VOIDmode,
16760 gen_rtx_REG (SImode,
1de43f85 16761 LR_REGNO)),
5b71a4e7
DE
16762 gen_rtx_RETURN (VOIDmode))));
16763 SIBLING_CALL_P (insn) = 1;
16764 emit_barrier ();
16765
16766 /* Run just enough of rest_of_compilation to get the insns emitted.
16767 There's not really enough bulk here to make other passes such as
16768 instruction scheduling worth while. Note that use_thunk calls
16769 assemble_start_function and assemble_end_function. */
16770 insn = get_insns ();
55e092c4 16771 insn_locators_alloc ();
5b71a4e7
DE
16772 shorten_branches (insn);
16773 final_start_function (insn, file, 1);
c9d691e9 16774 final (insn, file, 1);
5b71a4e7
DE
16775 final_end_function ();
16776
16777 reload_completed = 0;
fe3ad572 16778 epilogue_completed = 0;
9ebbca7d 16779}
9ebbca7d
GK
16780\f
16781/* A quick summary of the various types of 'constant-pool tables'
16782 under PowerPC:
16783
f676971a 16784 Target Flags Name One table per
9ebbca7d
GK
16785 AIX (none) AIX TOC object file
16786 AIX -mfull-toc AIX TOC object file
16787 AIX -mminimal-toc AIX minimal TOC translation unit
16788 SVR4/EABI (none) SVR4 SDATA object file
16789 SVR4/EABI -fpic SVR4 pic object file
16790 SVR4/EABI -fPIC SVR4 PIC translation unit
16791 SVR4/EABI -mrelocatable EABI TOC function
16792 SVR4/EABI -maix AIX TOC object file
f676971a 16793 SVR4/EABI -maix -mminimal-toc
9ebbca7d
GK
16794 AIX minimal TOC translation unit
16795
16796 Name Reg. Set by entries contains:
16797 made by addrs? fp? sum?
16798
16799 AIX TOC 2 crt0 as Y option option
16800 AIX minimal TOC 30 prolog gcc Y Y option
16801 SVR4 SDATA 13 crt0 gcc N Y N
16802 SVR4 pic 30 prolog ld Y not yet N
16803 SVR4 PIC 30 prolog gcc Y option option
16804 EABI TOC 30 prolog gcc Y option option
16805
16806*/
16807
9ebbca7d
GK
16808/* Hash functions for the hash table. */
16809
16810static unsigned
a2369ed3 16811rs6000_hash_constant (rtx k)
9ebbca7d 16812{
46b33600
RH
16813 enum rtx_code code = GET_CODE (k);
16814 enum machine_mode mode = GET_MODE (k);
16815 unsigned result = (code << 3) ^ mode;
16816 const char *format;
16817 int flen, fidx;
f676971a 16818
46b33600
RH
16819 format = GET_RTX_FORMAT (code);
16820 flen = strlen (format);
16821 fidx = 0;
9ebbca7d 16822
46b33600
RH
16823 switch (code)
16824 {
16825 case LABEL_REF:
16826 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
16827
16828 case CONST_DOUBLE:
16829 if (mode != VOIDmode)
16830 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
16831 flen = 2;
16832 break;
16833
16834 case CODE_LABEL:
16835 fidx = 3;
16836 break;
16837
16838 default:
16839 break;
16840 }
9ebbca7d
GK
16841
16842 for (; fidx < flen; fidx++)
16843 switch (format[fidx])
16844 {
16845 case 's':
16846 {
16847 unsigned i, len;
16848 const char *str = XSTR (k, fidx);
16849 len = strlen (str);
16850 result = result * 613 + len;
16851 for (i = 0; i < len; i++)
16852 result = result * 613 + (unsigned) str[i];
17167fd8
MM
16853 break;
16854 }
9ebbca7d
GK
16855 case 'u':
16856 case 'e':
16857 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
16858 break;
16859 case 'i':
16860 case 'n':
16861 result = result * 613 + (unsigned) XINT (k, fidx);
16862 break;
16863 case 'w':
16864 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
16865 result = result * 613 + (unsigned) XWINT (k, fidx);
16866 else
16867 {
16868 size_t i;
9390387d 16869 for (i = 0; i < sizeof (HOST_WIDE_INT) / sizeof (unsigned); i++)
9ebbca7d
GK
16870 result = result * 613 + (unsigned) (XWINT (k, fidx)
16871 >> CHAR_BIT * i);
16872 }
16873 break;
09501938
DE
16874 case '0':
16875 break;
9ebbca7d 16876 default:
37409796 16877 gcc_unreachable ();
9ebbca7d 16878 }
46b33600 16879
9ebbca7d
GK
16880 return result;
16881}
16882
16883static unsigned
a2369ed3 16884toc_hash_function (const void *hash_entry)
9ebbca7d 16885{
f676971a 16886 const struct toc_hash_struct *thc =
a9098fd0
GK
16887 (const struct toc_hash_struct *) hash_entry;
16888 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
16889}
16890
16891/* Compare H1 and H2 for equivalence. */
16892
16893static int
a2369ed3 16894toc_hash_eq (const void *h1, const void *h2)
9ebbca7d
GK
16895{
16896 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
16897 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
16898
a9098fd0
GK
16899 if (((const struct toc_hash_struct *) h1)->key_mode
16900 != ((const struct toc_hash_struct *) h2)->key_mode)
16901 return 0;
16902
5692c7bc 16903 return rtx_equal_p (r1, r2);
9ebbca7d
GK
16904}
16905
28e510bd
MM
16906/* These are the names given by the C++ front-end to vtables, and
16907 vtable-like objects. Ideally, this logic should not be here;
16908 instead, there should be some programmatic way of inquiring as
16909 to whether or not an object is a vtable. */
16910
16911#define VTABLE_NAME_P(NAME) \
9390387d 16912 (strncmp ("_vt.", name, strlen ("_vt.")) == 0 \
28e510bd
MM
16913 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
16914 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
26be75db 16915 || strncmp ("_ZTI", name, strlen ("_ZTI")) == 0 \
f676971a 16916 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
28e510bd
MM
16917
16918void
a2369ed3 16919rs6000_output_symbol_ref (FILE *file, rtx x)
28e510bd
MM
16920{
16921 /* Currently C++ toc references to vtables can be emitted before it
16922 is decided whether the vtable is public or private. If this is
16923 the case, then the linker will eventually complain that there is
f676971a 16924 a reference to an unknown section. Thus, for vtables only,
28e510bd
MM
16925 we emit the TOC reference to reference the symbol and not the
16926 section. */
16927 const char *name = XSTR (x, 0);
54ee9799 16928
f676971a 16929 if (VTABLE_NAME_P (name))
54ee9799
DE
16930 {
16931 RS6000_OUTPUT_BASENAME (file, name);
16932 }
16933 else
16934 assemble_name (file, name);
28e510bd
MM
16935}
16936
a4f6c312
SS
16937/* Output a TOC entry. We derive the entry name from what is being
16938 written. */
9878760c
RK
16939
16940void
a2369ed3 16941output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
9878760c
RK
16942{
16943 char buf[256];
3cce094d 16944 const char *name = buf;
ec940faa 16945 const char *real_name;
9878760c 16946 rtx base = x;
16fdeb48 16947 HOST_WIDE_INT offset = 0;
9878760c 16948
37409796 16949 gcc_assert (!TARGET_NO_TOC);
4697a36c 16950
9ebbca7d
GK
16951 /* When the linker won't eliminate them, don't output duplicate
16952 TOC entries (this happens on AIX if there is any kind of TOC,
17211ab5
GK
16953 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
16954 CODE_LABELs. */
16955 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
9ebbca7d
GK
16956 {
16957 struct toc_hash_struct *h;
16958 void * * found;
f676971a 16959
17211ab5 16960 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
c4ad648e 16961 time because GGC is not initialized at that point. */
17211ab5 16962 if (toc_hash_table == NULL)
f676971a 16963 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
17211ab5
GK
16964 toc_hash_eq, NULL);
16965
9ebbca7d
GK
16966 h = ggc_alloc (sizeof (*h));
16967 h->key = x;
a9098fd0 16968 h->key_mode = mode;
9ebbca7d 16969 h->labelno = labelno;
f676971a 16970
9ebbca7d
GK
16971 found = htab_find_slot (toc_hash_table, h, 1);
16972 if (*found == NULL)
16973 *found = h;
f676971a 16974 else /* This is indeed a duplicate.
9ebbca7d
GK
16975 Set this label equal to that label. */
16976 {
16977 fputs ("\t.set ", file);
16978 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
16979 fprintf (file, "%d,", labelno);
16980 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
f676971a 16981 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
9ebbca7d
GK
16982 found)->labelno));
16983 return;
16984 }
16985 }
16986
16987 /* If we're going to put a double constant in the TOC, make sure it's
16988 aligned properly when strict alignment is on. */
ff1720ed
RK
16989 if (GET_CODE (x) == CONST_DOUBLE
16990 && STRICT_ALIGNMENT
a9098fd0 16991 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
16992 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
16993 ASM_OUTPUT_ALIGN (file, 3);
16994 }
16995
4977bab6 16996 (*targetm.asm_out.internal_label) (file, "LC", labelno);
9878760c 16997
37c37a57
RK
16998 /* Handle FP constants specially. Note that if we have a minimal
16999 TOC, things we put here aren't actually in the TOC, so we can allow
17000 FP constants. */
00b79d54
BE
17001 if (GET_CODE (x) == CONST_DOUBLE &&
17002 (GET_MODE (x) == TFmode || GET_MODE (x) == TDmode))
fcce224d
DE
17003 {
17004 REAL_VALUE_TYPE rv;
17005 long k[4];
17006
17007 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
00b79d54
BE
17008 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17009 REAL_VALUE_TO_TARGET_DECIMAL128 (rv, k);
17010 else
17011 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
fcce224d
DE
17012
17013 if (TARGET_64BIT)
17014 {
17015 if (TARGET_MINIMAL_TOC)
17016 fputs (DOUBLE_INT_ASM_OP, file);
17017 else
17018 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17019 k[0] & 0xffffffff, k[1] & 0xffffffff,
17020 k[2] & 0xffffffff, k[3] & 0xffffffff);
17021 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
17022 k[0] & 0xffffffff, k[1] & 0xffffffff,
17023 k[2] & 0xffffffff, k[3] & 0xffffffff);
17024 return;
17025 }
17026 else
17027 {
17028 if (TARGET_MINIMAL_TOC)
17029 fputs ("\t.long ", file);
17030 else
17031 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
17032 k[0] & 0xffffffff, k[1] & 0xffffffff,
17033 k[2] & 0xffffffff, k[3] & 0xffffffff);
17034 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
17035 k[0] & 0xffffffff, k[1] & 0xffffffff,
17036 k[2] & 0xffffffff, k[3] & 0xffffffff);
17037 return;
17038 }
17039 }
00b79d54
BE
17040 else if (GET_CODE (x) == CONST_DOUBLE &&
17041 (GET_MODE (x) == DFmode || GET_MODE (x) == DDmode))
9878760c 17042 {
042259f2
DE
17043 REAL_VALUE_TYPE rv;
17044 long k[2];
0adc764e 17045
042259f2 17046 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
00b79d54
BE
17047
17048 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17049 REAL_VALUE_TO_TARGET_DECIMAL64 (rv, k);
17050 else
17051 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 17052
13ded975
DE
17053 if (TARGET_64BIT)
17054 {
17055 if (TARGET_MINIMAL_TOC)
2bfcf297 17056 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 17057 else
2f0552b6
AM
17058 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
17059 k[0] & 0xffffffff, k[1] & 0xffffffff);
17060 fprintf (file, "0x%lx%08lx\n",
17061 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
17062 return;
17063 }
1875cc88 17064 else
13ded975
DE
17065 {
17066 if (TARGET_MINIMAL_TOC)
2bfcf297 17067 fputs ("\t.long ", file);
13ded975 17068 else
2f0552b6
AM
17069 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
17070 k[0] & 0xffffffff, k[1] & 0xffffffff);
17071 fprintf (file, "0x%lx,0x%lx\n",
17072 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
17073 return;
17074 }
9878760c 17075 }
00b79d54
BE
17076 else if (GET_CODE (x) == CONST_DOUBLE &&
17077 (GET_MODE (x) == SFmode || GET_MODE (x) == SDmode))
9878760c 17078 {
042259f2
DE
17079 REAL_VALUE_TYPE rv;
17080 long l;
9878760c 17081
042259f2 17082 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
00b79d54
BE
17083 if (DECIMAL_FLOAT_MODE_P (GET_MODE (x)))
17084 REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
17085 else
17086 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
042259f2 17087
31bfaa0b
DE
17088 if (TARGET_64BIT)
17089 {
17090 if (TARGET_MINIMAL_TOC)
2bfcf297 17091 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 17092 else
2f0552b6
AM
17093 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
17094 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
17095 return;
17096 }
042259f2 17097 else
31bfaa0b
DE
17098 {
17099 if (TARGET_MINIMAL_TOC)
2bfcf297 17100 fputs ("\t.long ", file);
31bfaa0b 17101 else
2f0552b6
AM
17102 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
17103 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
17104 return;
17105 }
042259f2 17106 }
f176e826 17107 else if (GET_MODE (x) == VOIDmode
a9098fd0 17108 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 17109 {
e2c953b6 17110 unsigned HOST_WIDE_INT low;
042259f2
DE
17111 HOST_WIDE_INT high;
17112
17113 if (GET_CODE (x) == CONST_DOUBLE)
17114 {
17115 low = CONST_DOUBLE_LOW (x);
17116 high = CONST_DOUBLE_HIGH (x);
17117 }
17118 else
17119#if HOST_BITS_PER_WIDE_INT == 32
17120 {
17121 low = INTVAL (x);
0858c623 17122 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
17123 }
17124#else
17125 {
c4ad648e
AM
17126 low = INTVAL (x) & 0xffffffff;
17127 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
042259f2
DE
17128 }
17129#endif
9878760c 17130
a9098fd0
GK
17131 /* TOC entries are always Pmode-sized, but since this
17132 is a bigendian machine then if we're putting smaller
17133 integer constants in the TOC we have to pad them.
17134 (This is still a win over putting the constants in
17135 a separate constant pool, because then we'd have
02a4ec28
FS
17136 to have both a TOC entry _and_ the actual constant.)
17137
17138 For a 32-bit target, CONST_INT values are loaded and shifted
17139 entirely within `low' and can be stored in one TOC entry. */
17140
37409796
NS
17141 /* It would be easy to make this work, but it doesn't now. */
17142 gcc_assert (!TARGET_64BIT || POINTER_SIZE >= GET_MODE_BITSIZE (mode));
02a4ec28
FS
17143
17144 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
17145 {
17146#if HOST_BITS_PER_WIDE_INT == 32
17147 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
17148 POINTER_SIZE, &low, &high, 0);
17149#else
17150 low |= high << 32;
17151 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
17152 high = (HOST_WIDE_INT) low >> 32;
17153 low &= 0xffffffff;
17154#endif
17155 }
a9098fd0 17156
13ded975
DE
17157 if (TARGET_64BIT)
17158 {
17159 if (TARGET_MINIMAL_TOC)
2bfcf297 17160 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 17161 else
2f0552b6
AM
17162 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
17163 (long) high & 0xffffffff, (long) low & 0xffffffff);
17164 fprintf (file, "0x%lx%08lx\n",
17165 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
17166 return;
17167 }
1875cc88 17168 else
13ded975 17169 {
02a4ec28
FS
17170 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
17171 {
17172 if (TARGET_MINIMAL_TOC)
2bfcf297 17173 fputs ("\t.long ", file);
02a4ec28 17174 else
2bfcf297 17175 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
17176 (long) high & 0xffffffff, (long) low & 0xffffffff);
17177 fprintf (file, "0x%lx,0x%lx\n",
17178 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 17179 }
13ded975 17180 else
02a4ec28
FS
17181 {
17182 if (TARGET_MINIMAL_TOC)
2bfcf297 17183 fputs ("\t.long ", file);
02a4ec28 17184 else
2f0552b6
AM
17185 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
17186 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 17187 }
13ded975
DE
17188 return;
17189 }
9878760c
RK
17190 }
17191
17192 if (GET_CODE (x) == CONST)
17193 {
37409796 17194 gcc_assert (GET_CODE (XEXP (x, 0)) == PLUS);
2bfcf297 17195
9878760c
RK
17196 base = XEXP (XEXP (x, 0), 0);
17197 offset = INTVAL (XEXP (XEXP (x, 0), 1));
17198 }
f676971a 17199
37409796
NS
17200 switch (GET_CODE (base))
17201 {
17202 case SYMBOL_REF:
17203 name = XSTR (base, 0);
17204 break;
17205
17206 case LABEL_REF:
17207 ASM_GENERATE_INTERNAL_LABEL (buf, "L",
17208 CODE_LABEL_NUMBER (XEXP (base, 0)));
17209 break;
17210
17211 case CODE_LABEL:
17212 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
17213 break;
17214
17215 default:
17216 gcc_unreachable ();
17217 }
9878760c 17218
772c5265 17219 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 17220 if (TARGET_MINIMAL_TOC)
2bfcf297 17221 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
17222 else
17223 {
b6c9286a 17224 fprintf (file, "\t.tc %s", real_name);
9878760c 17225
1875cc88 17226 if (offset < 0)
16fdeb48 17227 fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
1875cc88 17228 else if (offset)
16fdeb48 17229 fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
9878760c 17230
19d2d16f 17231 fputs ("[TC],", file);
1875cc88 17232 }
581bc4de
MM
17233
17234 /* Currently C++ toc references to vtables can be emitted before it
17235 is decided whether the vtable is public or private. If this is
17236 the case, then the linker will eventually complain that there is
17237 a TOC reference to an unknown section. Thus, for vtables only,
17238 we emit the TOC reference to reference the symbol and not the
17239 section. */
28e510bd 17240 if (VTABLE_NAME_P (name))
581bc4de 17241 {
54ee9799 17242 RS6000_OUTPUT_BASENAME (file, name);
581bc4de 17243 if (offset < 0)
16fdeb48 17244 fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
581bc4de 17245 else if (offset > 0)
16fdeb48 17246 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
581bc4de
MM
17247 }
17248 else
17249 output_addr_const (file, x);
19d2d16f 17250 putc ('\n', file);
9878760c
RK
17251}
17252\f
17253/* Output an assembler pseudo-op to write an ASCII string of N characters
17254 starting at P to FILE.
17255
17256 On the RS/6000, we have to do this using the .byte operation and
17257 write out special characters outside the quoted string.
17258 Also, the assembler is broken; very long strings are truncated,
a4f6c312 17259 so we must artificially break them up early. */
9878760c
RK
17260
17261void
a2369ed3 17262output_ascii (FILE *file, const char *p, int n)
9878760c
RK
17263{
17264 char c;
17265 int i, count_string;
d330fd93
KG
17266 const char *for_string = "\t.byte \"";
17267 const char *for_decimal = "\t.byte ";
17268 const char *to_close = NULL;
9878760c
RK
17269
17270 count_string = 0;
17271 for (i = 0; i < n; i++)
17272 {
17273 c = *p++;
17274 if (c >= ' ' && c < 0177)
17275 {
17276 if (for_string)
17277 fputs (for_string, file);
17278 putc (c, file);
17279
17280 /* Write two quotes to get one. */
17281 if (c == '"')
17282 {
17283 putc (c, file);
17284 ++count_string;
17285 }
17286
17287 for_string = NULL;
17288 for_decimal = "\"\n\t.byte ";
17289 to_close = "\"\n";
17290 ++count_string;
17291
17292 if (count_string >= 512)
17293 {
17294 fputs (to_close, file);
17295
17296 for_string = "\t.byte \"";
17297 for_decimal = "\t.byte ";
17298 to_close = NULL;
17299 count_string = 0;
17300 }
17301 }
17302 else
17303 {
17304 if (for_decimal)
17305 fputs (for_decimal, file);
17306 fprintf (file, "%d", c);
17307
17308 for_string = "\n\t.byte \"";
17309 for_decimal = ", ";
17310 to_close = "\n";
17311 count_string = 0;
17312 }
17313 }
17314
17315 /* Now close the string if we have written one. Then end the line. */
17316 if (to_close)
9ebbca7d 17317 fputs (to_close, file);
9878760c
RK
17318}
17319\f
17320/* Generate a unique section name for FILENAME for a section type
17321 represented by SECTION_DESC. Output goes into BUF.
17322
17323 SECTION_DESC can be any string, as long as it is different for each
17324 possible section type.
17325
17326 We name the section in the same manner as xlc. The name begins with an
17327 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
17328 names) with the last period replaced by the string SECTION_DESC. If
17329 FILENAME does not contain a period, SECTION_DESC is appended to the end of
17330 the name. */
9878760c
RK
17331
17332void
f676971a 17333rs6000_gen_section_name (char **buf, const char *filename,
c4ad648e 17334 const char *section_desc)
9878760c 17335{
9ebbca7d 17336 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
17337 char *p;
17338 int len;
9878760c
RK
17339
17340 after_last_slash = filename;
17341 for (q = filename; *q; q++)
11e5fe42
RK
17342 {
17343 if (*q == '/')
17344 after_last_slash = q + 1;
17345 else if (*q == '.')
17346 last_period = q;
17347 }
9878760c 17348
11e5fe42 17349 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 17350 *buf = (char *) xmalloc (len);
9878760c
RK
17351
17352 p = *buf;
17353 *p++ = '_';
17354
17355 for (q = after_last_slash; *q; q++)
17356 {
11e5fe42 17357 if (q == last_period)
c4ad648e 17358 {
9878760c
RK
17359 strcpy (p, section_desc);
17360 p += strlen (section_desc);
e3981aab 17361 break;
c4ad648e 17362 }
9878760c 17363
e9a780ec 17364 else if (ISALNUM (*q))
c4ad648e 17365 *p++ = *q;
9878760c
RK
17366 }
17367
11e5fe42 17368 if (last_period == 0)
9878760c
RK
17369 strcpy (p, section_desc);
17370 else
17371 *p = '\0';
17372}
e165f3f0 17373\f
a4f6c312 17374/* Emit profile function. */
411707f4 17375
411707f4 17376void
a2369ed3 17377output_profile_hook (int labelno ATTRIBUTE_UNUSED)
411707f4 17378{
858081ad
AH
17379 /* Non-standard profiling for kernels, which just saves LR then calls
17380 _mcount without worrying about arg saves. The idea is to change
17381 the function prologue as little as possible as it isn't easy to
17382 account for arg save/restore code added just for _mcount. */
ffcfcb5f
AM
17383 if (TARGET_PROFILE_KERNEL)
17384 return;
17385
8480e480
CC
17386 if (DEFAULT_ABI == ABI_AIX)
17387 {
9739c90c
JJ
17388#ifndef NO_PROFILE_COUNTERS
17389# define NO_PROFILE_COUNTERS 0
17390#endif
f676971a 17391 if (NO_PROFILE_COUNTERS)
9739c90c
JJ
17392 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
17393 else
17394 {
17395 char buf[30];
17396 const char *label_name;
17397 rtx fun;
411707f4 17398
9739c90c
JJ
17399 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
17400 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
17401 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 17402
9739c90c
JJ
17403 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
17404 fun, Pmode);
17405 }
8480e480 17406 }
ee890fe2
SS
17407 else if (DEFAULT_ABI == ABI_DARWIN)
17408 {
d5fa86ba 17409 const char *mcount_name = RS6000_MCOUNT;
1de43f85 17410 int caller_addr_regno = LR_REGNO;
ee890fe2
SS
17411
17412 /* Be conservative and always set this, at least for now. */
17413 current_function_uses_pic_offset_table = 1;
17414
17415#if TARGET_MACHO
17416 /* For PIC code, set up a stub and collect the caller's address
17417 from r0, which is where the prologue puts it. */
11abc112
MM
17418 if (MACHOPIC_INDIRECT
17419 && current_function_uses_pic_offset_table)
17420 caller_addr_regno = 0;
ee890fe2
SS
17421#endif
17422 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
17423 0, VOIDmode, 1,
17424 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
17425 }
411707f4
CC
17426}
17427
a4f6c312 17428/* Write function profiler code. */
e165f3f0
RK
17429
17430void
a2369ed3 17431output_function_profiler (FILE *file, int labelno)
e165f3f0 17432{
3daf36a4 17433 char buf[100];
e165f3f0 17434
38c1f2d7 17435 switch (DEFAULT_ABI)
3daf36a4 17436 {
38c1f2d7 17437 default:
37409796 17438 gcc_unreachable ();
38c1f2d7
MM
17439
17440 case ABI_V4:
09eeeacb
AM
17441 if (!TARGET_32BIT)
17442 {
d4ee4d25 17443 warning (0, "no profiling of 64-bit code for this ABI");
09eeeacb
AM
17444 return;
17445 }
ffcfcb5f 17446 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 17447 fprintf (file, "\tmflr %s\n", reg_names[0]);
71625f3d
AM
17448 if (NO_PROFILE_COUNTERS)
17449 {
17450 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17451 reg_names[0], reg_names[1]);
17452 }
17453 else if (TARGET_SECURE_PLT && flag_pic)
17454 {
17455 asm_fprintf (file, "\tbcl 20,31,1f\n1:\n\t{st|stw} %s,4(%s)\n",
17456 reg_names[0], reg_names[1]);
17457 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
17458 asm_fprintf (file, "\t{cau|addis} %s,%s,",
17459 reg_names[12], reg_names[12]);
17460 assemble_name (file, buf);
17461 asm_fprintf (file, "-1b@ha\n\t{cal|la} %s,", reg_names[0]);
17462 assemble_name (file, buf);
17463 asm_fprintf (file, "-1b@l(%s)\n", reg_names[12]);
17464 }
17465 else if (flag_pic == 1)
38c1f2d7 17466 {
dfdfa60f 17467 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
71625f3d
AM
17468 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17469 reg_names[0], reg_names[1]);
17167fd8 17470 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 17471 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 17472 assemble_name (file, buf);
17167fd8 17473 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 17474 }
9ebbca7d 17475 else if (flag_pic > 1)
38c1f2d7 17476 {
71625f3d
AM
17477 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17478 reg_names[0], reg_names[1]);
9ebbca7d 17479 /* Now, we need to get the address of the label. */
71625f3d 17480 fputs ("\tbcl 20,31,1f\n\t.long ", file);
034e84c4 17481 assemble_name (file, buf);
9ebbca7d
GK
17482 fputs ("-.\n1:", file);
17483 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
f676971a 17484 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
9ebbca7d
GK
17485 reg_names[0], reg_names[11]);
17486 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
17487 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 17488 }
38c1f2d7
MM
17489 else
17490 {
17167fd8 17491 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 17492 assemble_name (file, buf);
dfdfa60f 17493 fputs ("@ha\n", file);
71625f3d
AM
17494 asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
17495 reg_names[0], reg_names[1]);
a260abc9 17496 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 17497 assemble_name (file, buf);
17167fd8 17498 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
17499 }
17500
50d440bc 17501 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
3b6ce0af
DE
17502 fprintf (file, "\tbl %s%s\n",
17503 RS6000_MCOUNT, flag_pic ? "@plt" : "");
38c1f2d7
MM
17504 break;
17505
17506 case ABI_AIX:
ee890fe2 17507 case ABI_DARWIN:
ffcfcb5f
AM
17508 if (!TARGET_PROFILE_KERNEL)
17509 {
a3c9585f 17510 /* Don't do anything, done in output_profile_hook (). */
ffcfcb5f
AM
17511 }
17512 else
17513 {
37409796 17514 gcc_assert (!TARGET_32BIT);
ffcfcb5f
AM
17515
17516 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
17517 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
17518
6de9cd9a 17519 if (cfun->static_chain_decl != NULL)
ffcfcb5f
AM
17520 {
17521 asm_fprintf (file, "\tstd %s,24(%s)\n",
17522 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
17523 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
17524 asm_fprintf (file, "\tld %s,24(%s)\n",
17525 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
17526 }
17527 else
17528 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
17529 }
38c1f2d7
MM
17530 break;
17531 }
e165f3f0 17532}
a251ffd0 17533
b54cf83a 17534\f
44cd321e
PS
17535
17536/* The following variable value is the last issued insn. */
17537
17538static rtx last_scheduled_insn;
17539
17540/* The following variable helps to balance issuing of load and
17541 store instructions */
17542
17543static int load_store_pendulum;
17544
b54cf83a
DE
17545/* Power4 load update and store update instructions are cracked into a
17546 load or store and an integer insn which are executed in the same cycle.
17547 Branches have their own dispatch slot which does not count against the
17548 GCC issue rate, but it changes the program flow so there are no other
17549 instructions to issue in this cycle. */
17550
17551static int
f676971a
EC
17552rs6000_variable_issue (FILE *stream ATTRIBUTE_UNUSED,
17553 int verbose ATTRIBUTE_UNUSED,
a2369ed3 17554 rtx insn, int more)
b54cf83a 17555{
44cd321e 17556 last_scheduled_insn = insn;
b54cf83a
DE
17557 if (GET_CODE (PATTERN (insn)) == USE
17558 || GET_CODE (PATTERN (insn)) == CLOBBER)
44cd321e
PS
17559 {
17560 cached_can_issue_more = more;
17561 return cached_can_issue_more;
17562 }
17563
17564 if (insn_terminates_group_p (insn, current_group))
17565 {
17566 cached_can_issue_more = 0;
17567 return cached_can_issue_more;
17568 }
b54cf83a 17569
d296e02e
AP
17570 /* If no reservation, but reach here */
17571 if (recog_memoized (insn) < 0)
17572 return more;
17573
ec507f2d 17574 if (rs6000_sched_groups)
b54cf83a 17575 {
cbe26ab8 17576 if (is_microcoded_insn (insn))
44cd321e 17577 cached_can_issue_more = 0;
cbe26ab8 17578 else if (is_cracked_insn (insn))
44cd321e
PS
17579 cached_can_issue_more = more > 2 ? more - 2 : 0;
17580 else
17581 cached_can_issue_more = more - 1;
17582
17583 return cached_can_issue_more;
b54cf83a 17584 }
165b263e 17585
d296e02e
AP
17586 if (rs6000_cpu_attr == CPU_CELL && is_nonpipeline_insn (insn))
17587 return 0;
17588
44cd321e
PS
17589 cached_can_issue_more = more - 1;
17590 return cached_can_issue_more;
b54cf83a
DE
17591}
17592
a251ffd0
TG
17593/* Adjust the cost of a scheduling dependency. Return the new cost of
17594 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
17595
c237e94a 17596static int
0a4f0294 17597rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
a251ffd0 17598{
44cd321e 17599 enum attr_type attr_type;
a251ffd0 17600
44cd321e 17601 if (! recog_memoized (insn))
a251ffd0
TG
17602 return 0;
17603
44cd321e 17604 switch (REG_NOTE_KIND (link))
a251ffd0 17605 {
44cd321e
PS
17606 case REG_DEP_TRUE:
17607 {
17608 /* Data dependency; DEP_INSN writes a register that INSN reads
17609 some cycles later. */
17610
17611 /* Separate a load from a narrower, dependent store. */
17612 if (rs6000_sched_groups
17613 && GET_CODE (PATTERN (insn)) == SET
17614 && GET_CODE (PATTERN (dep_insn)) == SET
17615 && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM
17616 && GET_CODE (XEXP (PATTERN (dep_insn), 0)) == MEM
17617 && (GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (insn), 1)))
17618 > GET_MODE_SIZE (GET_MODE (XEXP (PATTERN (dep_insn), 0)))))
17619 return cost + 14;
17620
17621 attr_type = get_attr_type (insn);
17622
17623 switch (attr_type)
17624 {
17625 case TYPE_JMPREG:
17626 /* Tell the first scheduling pass about the latency between
17627 a mtctr and bctr (and mtlr and br/blr). The first
17628 scheduling pass will not know about this latency since
17629 the mtctr instruction, which has the latency associated
17630 to it, will be generated by reload. */
17631 return TARGET_POWER ? 5 : 4;
17632 case TYPE_BRANCH:
17633 /* Leave some extra cycles between a compare and its
17634 dependent branch, to inhibit expensive mispredicts. */
17635 if ((rs6000_cpu_attr == CPU_PPC603
17636 || rs6000_cpu_attr == CPU_PPC604
17637 || rs6000_cpu_attr == CPU_PPC604E
17638 || rs6000_cpu_attr == CPU_PPC620
17639 || rs6000_cpu_attr == CPU_PPC630
17640 || rs6000_cpu_attr == CPU_PPC750
17641 || rs6000_cpu_attr == CPU_PPC7400
17642 || rs6000_cpu_attr == CPU_PPC7450
17643 || rs6000_cpu_attr == CPU_POWER4
d296e02e
AP
17644 || rs6000_cpu_attr == CPU_POWER5
17645 || rs6000_cpu_attr == CPU_CELL)
44cd321e
PS
17646 && recog_memoized (dep_insn)
17647 && (INSN_CODE (dep_insn) >= 0))
982afe02 17648
44cd321e
PS
17649 switch (get_attr_type (dep_insn))
17650 {
17651 case TYPE_CMP:
17652 case TYPE_COMPARE:
17653 case TYPE_DELAYED_COMPARE:
17654 case TYPE_IMUL_COMPARE:
17655 case TYPE_LMUL_COMPARE:
17656 case TYPE_FPCOMPARE:
17657 case TYPE_CR_LOGICAL:
17658 case TYPE_DELAYED_CR:
17659 return cost + 2;
17660 default:
17661 break;
17662 }
17663 break;
17664
17665 case TYPE_STORE:
17666 case TYPE_STORE_U:
17667 case TYPE_STORE_UX:
17668 case TYPE_FPSTORE:
17669 case TYPE_FPSTORE_U:
17670 case TYPE_FPSTORE_UX:
17671 if ((rs6000_cpu == PROCESSOR_POWER6)
17672 && recog_memoized (dep_insn)
17673 && (INSN_CODE (dep_insn) >= 0))
17674 {
17675
17676 if (GET_CODE (PATTERN (insn)) != SET)
17677 /* If this happens, we have to extend this to schedule
17678 optimally. Return default for now. */
17679 return cost;
17680
17681 /* Adjust the cost for the case where the value written
17682 by a fixed point operation is used as the address
17683 gen value on a store. */
17684 switch (get_attr_type (dep_insn))
17685 {
17686 case TYPE_LOAD:
17687 case TYPE_LOAD_U:
17688 case TYPE_LOAD_UX:
17689 case TYPE_CNTLZ:
17690 {
17691 if (! store_data_bypass_p (dep_insn, insn))
17692 return 4;
17693 break;
17694 }
17695 case TYPE_LOAD_EXT:
17696 case TYPE_LOAD_EXT_U:
17697 case TYPE_LOAD_EXT_UX:
17698 case TYPE_VAR_SHIFT_ROTATE:
17699 case TYPE_VAR_DELAYED_COMPARE:
17700 {
17701 if (! store_data_bypass_p (dep_insn, insn))
17702 return 6;
17703 break;
17704 }
17705 case TYPE_INTEGER:
17706 case TYPE_COMPARE:
17707 case TYPE_FAST_COMPARE:
17708 case TYPE_EXTS:
17709 case TYPE_SHIFT:
17710 case TYPE_INSERT_WORD:
17711 case TYPE_INSERT_DWORD:
17712 case TYPE_FPLOAD_U:
17713 case TYPE_FPLOAD_UX:
17714 case TYPE_STORE_U:
17715 case TYPE_STORE_UX:
17716 case TYPE_FPSTORE_U:
17717 case TYPE_FPSTORE_UX:
17718 {
17719 if (! store_data_bypass_p (dep_insn, insn))
17720 return 3;
17721 break;
17722 }
17723 case TYPE_IMUL:
17724 case TYPE_IMUL2:
17725 case TYPE_IMUL3:
17726 case TYPE_LMUL:
17727 case TYPE_IMUL_COMPARE:
17728 case TYPE_LMUL_COMPARE:
17729 {
17730 if (! store_data_bypass_p (dep_insn, insn))
17731 return 17;
17732 break;
17733 }
17734 case TYPE_IDIV:
17735 {
17736 if (! store_data_bypass_p (dep_insn, insn))
17737 return 45;
17738 break;
17739 }
17740 case TYPE_LDIV:
17741 {
17742 if (! store_data_bypass_p (dep_insn, insn))
17743 return 57;
17744 break;
17745 }
17746 default:
17747 break;
17748 }
17749 }
17750 break;
17751
17752 case TYPE_LOAD:
17753 case TYPE_LOAD_U:
17754 case TYPE_LOAD_UX:
17755 case TYPE_LOAD_EXT:
17756 case TYPE_LOAD_EXT_U:
17757 case TYPE_LOAD_EXT_UX:
17758 if ((rs6000_cpu == PROCESSOR_POWER6)
17759 && recog_memoized (dep_insn)
17760 && (INSN_CODE (dep_insn) >= 0))
17761 {
17762
17763 /* Adjust the cost for the case where the value written
17764 by a fixed point instruction is used within the address
17765 gen portion of a subsequent load(u)(x) */
17766 switch (get_attr_type (dep_insn))
17767 {
17768 case TYPE_LOAD:
17769 case TYPE_LOAD_U:
17770 case TYPE_LOAD_UX:
17771 case TYPE_CNTLZ:
17772 {
17773 if (set_to_load_agen (dep_insn, insn))
17774 return 4;
17775 break;
17776 }
17777 case TYPE_LOAD_EXT:
17778 case TYPE_LOAD_EXT_U:
17779 case TYPE_LOAD_EXT_UX:
17780 case TYPE_VAR_SHIFT_ROTATE:
17781 case TYPE_VAR_DELAYED_COMPARE:
17782 {
17783 if (set_to_load_agen (dep_insn, insn))
17784 return 6;
17785 break;
17786 }
17787 case TYPE_INTEGER:
17788 case TYPE_COMPARE:
17789 case TYPE_FAST_COMPARE:
17790 case TYPE_EXTS:
17791 case TYPE_SHIFT:
17792 case TYPE_INSERT_WORD:
17793 case TYPE_INSERT_DWORD:
17794 case TYPE_FPLOAD_U:
17795 case TYPE_FPLOAD_UX:
17796 case TYPE_STORE_U:
17797 case TYPE_STORE_UX:
17798 case TYPE_FPSTORE_U:
17799 case TYPE_FPSTORE_UX:
17800 {
17801 if (set_to_load_agen (dep_insn, insn))
17802 return 3;
17803 break;
17804 }
17805 case TYPE_IMUL:
17806 case TYPE_IMUL2:
17807 case TYPE_IMUL3:
17808 case TYPE_LMUL:
17809 case TYPE_IMUL_COMPARE:
17810 case TYPE_LMUL_COMPARE:
17811 {
17812 if (set_to_load_agen (dep_insn, insn))
17813 return 17;
17814 break;
17815 }
17816 case TYPE_IDIV:
17817 {
17818 if (set_to_load_agen (dep_insn, insn))
17819 return 45;
17820 break;
17821 }
17822 case TYPE_LDIV:
17823 {
17824 if (set_to_load_agen (dep_insn, insn))
17825 return 57;
17826 break;
17827 }
17828 default:
17829 break;
17830 }
17831 }
17832 break;
17833
17834 case TYPE_FPLOAD:
17835 if ((rs6000_cpu == PROCESSOR_POWER6)
17836 && recog_memoized (dep_insn)
17837 && (INSN_CODE (dep_insn) >= 0)
17838 && (get_attr_type (dep_insn) == TYPE_MFFGPR))
17839 return 2;
17840
17841 default:
17842 break;
17843 }
c9dbf840 17844
a251ffd0 17845 /* Fall out to return default cost. */
44cd321e
PS
17846 }
17847 break;
17848
17849 case REG_DEP_OUTPUT:
17850 /* Output dependency; DEP_INSN writes a register that INSN writes some
17851 cycles later. */
17852 if ((rs6000_cpu == PROCESSOR_POWER6)
17853 && recog_memoized (dep_insn)
17854 && (INSN_CODE (dep_insn) >= 0))
17855 {
17856 attr_type = get_attr_type (insn);
17857
17858 switch (attr_type)
17859 {
17860 case TYPE_FP:
17861 if (get_attr_type (dep_insn) == TYPE_FP)
17862 return 1;
17863 break;
17864 case TYPE_FPLOAD:
17865 if (get_attr_type (dep_insn) == TYPE_MFFGPR)
17866 return 2;
17867 break;
17868 default:
17869 break;
17870 }
17871 }
17872 case REG_DEP_ANTI:
17873 /* Anti dependency; DEP_INSN reads a register that INSN writes some
17874 cycles later. */
17875 return 0;
17876
17877 default:
17878 gcc_unreachable ();
a251ffd0
TG
17879 }
17880
17881 return cost;
17882}
b6c9286a 17883
cbe26ab8 17884/* The function returns a true if INSN is microcoded.
839a4992 17885 Return false otherwise. */
cbe26ab8
DN
17886
17887static bool
17888is_microcoded_insn (rtx insn)
17889{
17890 if (!insn || !INSN_P (insn)
17891 || GET_CODE (PATTERN (insn)) == USE
17892 || GET_CODE (PATTERN (insn)) == CLOBBER)
17893 return false;
17894
d296e02e
AP
17895 if (rs6000_cpu_attr == CPU_CELL)
17896 return get_attr_cell_micro (insn) == CELL_MICRO_ALWAYS;
17897
ec507f2d 17898 if (rs6000_sched_groups)
cbe26ab8
DN
17899 {
17900 enum attr_type type = get_attr_type (insn);
17901 if (type == TYPE_LOAD_EXT_U
17902 || type == TYPE_LOAD_EXT_UX
17903 || type == TYPE_LOAD_UX
17904 || type == TYPE_STORE_UX
17905 || type == TYPE_MFCR)
c4ad648e 17906 return true;
cbe26ab8
DN
17907 }
17908
17909 return false;
17910}
17911
cbe26ab8
DN
17912/* The function returns true if INSN is cracked into 2 instructions
17913 by the processor (and therefore occupies 2 issue slots). */
17914
17915static bool
17916is_cracked_insn (rtx insn)
17917{
17918 if (!insn || !INSN_P (insn)
17919 || GET_CODE (PATTERN (insn)) == USE
17920 || GET_CODE (PATTERN (insn)) == CLOBBER)
17921 return false;
17922
ec507f2d 17923 if (rs6000_sched_groups)
cbe26ab8
DN
17924 {
17925 enum attr_type type = get_attr_type (insn);
17926 if (type == TYPE_LOAD_U || type == TYPE_STORE_U
c4ad648e
AM
17927 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
17928 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
17929 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
17930 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
17931 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
17932 || type == TYPE_IDIV || type == TYPE_LDIV
17933 || type == TYPE_INSERT_WORD)
17934 return true;
cbe26ab8
DN
17935 }
17936
17937 return false;
17938}
17939
17940/* The function returns true if INSN can be issued only from
a3c9585f 17941 the branch slot. */
cbe26ab8
DN
17942
17943static bool
17944is_branch_slot_insn (rtx insn)
17945{
17946 if (!insn || !INSN_P (insn)
17947 || GET_CODE (PATTERN (insn)) == USE
17948 || GET_CODE (PATTERN (insn)) == CLOBBER)
17949 return false;
17950
ec507f2d 17951 if (rs6000_sched_groups)
cbe26ab8
DN
17952 {
17953 enum attr_type type = get_attr_type (insn);
17954 if (type == TYPE_BRANCH || type == TYPE_JMPREG)
f676971a 17955 return true;
cbe26ab8
DN
17956 return false;
17957 }
17958
17959 return false;
17960}
79ae11c4 17961
44cd321e
PS
17962/* The function returns true if out_inst sets a value that is
17963 used in the address generation computation of in_insn */
17964static bool
17965set_to_load_agen (rtx out_insn, rtx in_insn)
17966{
17967 rtx out_set, in_set;
17968
17969 /* For performance reasons, only handle the simple case where
17970 both loads are a single_set. */
17971 out_set = single_set (out_insn);
17972 if (out_set)
17973 {
17974 in_set = single_set (in_insn);
17975 if (in_set)
17976 return reg_mentioned_p (SET_DEST (out_set), SET_SRC (in_set));
17977 }
17978
17979 return false;
17980}
17981
17982/* The function returns true if the target storage location of
17983 out_insn is adjacent to the target storage location of in_insn */
17984/* Return 1 if memory locations are adjacent. */
17985
17986static bool
17987adjacent_mem_locations (rtx insn1, rtx insn2)
17988{
17989
e3a0e200
PB
17990 rtx a = get_store_dest (PATTERN (insn1));
17991 rtx b = get_store_dest (PATTERN (insn2));
17992
44cd321e
PS
17993 if ((GET_CODE (XEXP (a, 0)) == REG
17994 || (GET_CODE (XEXP (a, 0)) == PLUS
17995 && GET_CODE (XEXP (XEXP (a, 0), 1)) == CONST_INT))
17996 && (GET_CODE (XEXP (b, 0)) == REG
17997 || (GET_CODE (XEXP (b, 0)) == PLUS
17998 && GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
17999 {
18000 HOST_WIDE_INT val0 = 0, val1 = 0;
18001 rtx reg0, reg1;
18002 int val_diff;
18003
18004 if (GET_CODE (XEXP (a, 0)) == PLUS)
18005 {
18006 reg0 = XEXP (XEXP (a, 0), 0);
18007 val0 = INTVAL (XEXP (XEXP (a, 0), 1));
18008 }
18009 else
18010 reg0 = XEXP (a, 0);
18011
18012 if (GET_CODE (XEXP (b, 0)) == PLUS)
18013 {
18014 reg1 = XEXP (XEXP (b, 0), 0);
18015 val1 = INTVAL (XEXP (XEXP (b, 0), 1));
18016 }
18017 else
18018 reg1 = XEXP (b, 0);
18019
18020 val_diff = val1 - val0;
18021
18022 return ((REGNO (reg0) == REGNO (reg1))
18023 && (val_diff == INTVAL (MEM_SIZE (a))
18024 || val_diff == -INTVAL (MEM_SIZE (b))));
18025 }
18026
18027 return false;
18028}
18029
a4f6c312 18030/* A C statement (sans semicolon) to update the integer scheduling
79ae11c4
DN
18031 priority INSN_PRIORITY (INSN). Increase the priority to execute the
18032 INSN earlier, reduce the priority to execute INSN later. Do not
a4f6c312
SS
18033 define this macro if you do not need to adjust the scheduling
18034 priorities of insns. */
bef84347 18035
c237e94a 18036static int
a2369ed3 18037rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
bef84347 18038{
a4f6c312
SS
18039 /* On machines (like the 750) which have asymmetric integer units,
18040 where one integer unit can do multiply and divides and the other
18041 can't, reduce the priority of multiply/divide so it is scheduled
18042 before other integer operations. */
bef84347
VM
18043
18044#if 0
2c3c49de 18045 if (! INSN_P (insn))
bef84347
VM
18046 return priority;
18047
18048 if (GET_CODE (PATTERN (insn)) == USE)
18049 return priority;
18050
18051 switch (rs6000_cpu_attr) {
18052 case CPU_PPC750:
18053 switch (get_attr_type (insn))
18054 {
18055 default:
18056 break;
18057
18058 case TYPE_IMUL:
18059 case TYPE_IDIV:
3cb999d8
DE
18060 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
18061 priority, priority);
bef84347
VM
18062 if (priority >= 0 && priority < 0x01000000)
18063 priority >>= 3;
18064 break;
18065 }
18066 }
18067#endif
18068
44cd321e 18069 if (insn_must_be_first_in_group (insn)
79ae11c4 18070 && reload_completed
f676971a 18071 && current_sched_info->sched_max_insns_priority
79ae11c4
DN
18072 && rs6000_sched_restricted_insns_priority)
18073 {
18074
c4ad648e
AM
18075 /* Prioritize insns that can be dispatched only in the first
18076 dispatch slot. */
79ae11c4 18077 if (rs6000_sched_restricted_insns_priority == 1)
f676971a
EC
18078 /* Attach highest priority to insn. This means that in
18079 haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
79ae11c4 18080 precede 'priority' (critical path) considerations. */
f676971a 18081 return current_sched_info->sched_max_insns_priority;
79ae11c4 18082 else if (rs6000_sched_restricted_insns_priority == 2)
f676971a 18083 /* Increase priority of insn by a minimal amount. This means that in
c4ad648e
AM
18084 haifa-sched.c:ready_sort(), only 'priority' (critical path)
18085 considerations precede dispatch-slot restriction considerations. */
f676971a
EC
18086 return (priority + 1);
18087 }
79ae11c4 18088
44cd321e
PS
18089 if (rs6000_cpu == PROCESSOR_POWER6
18090 && ((load_store_pendulum == -2 && is_load_insn (insn))
18091 || (load_store_pendulum == 2 && is_store_insn (insn))))
18092 /* Attach highest priority to insn if the scheduler has just issued two
18093 stores and this instruction is a load, or two loads and this instruction
18094 is a store. Power6 wants loads and stores scheduled alternately
18095 when possible */
18096 return current_sched_info->sched_max_insns_priority;
18097
bef84347
VM
18098 return priority;
18099}
18100
d296e02e
AP
18101/* Return true if the instruction is nonpipelined on the Cell. */
18102static bool
18103is_nonpipeline_insn (rtx insn)
18104{
18105 enum attr_type type;
18106 if (!insn || !INSN_P (insn)
18107 || GET_CODE (PATTERN (insn)) == USE
18108 || GET_CODE (PATTERN (insn)) == CLOBBER)
18109 return false;
18110
18111 type = get_attr_type (insn);
18112 if (type == TYPE_IMUL
18113 || type == TYPE_IMUL2
18114 || type == TYPE_IMUL3
18115 || type == TYPE_LMUL
18116 || type == TYPE_IDIV
18117 || type == TYPE_LDIV
18118 || type == TYPE_SDIV
18119 || type == TYPE_DDIV
18120 || type == TYPE_SSQRT
18121 || type == TYPE_DSQRT
18122 || type == TYPE_MFCR
18123 || type == TYPE_MFCRF
18124 || type == TYPE_MFJMPR)
18125 {
18126 return true;
18127 }
18128 return false;
18129}
18130
18131
a4f6c312
SS
18132/* Return how many instructions the machine can issue per cycle. */
18133
c237e94a 18134static int
863d938c 18135rs6000_issue_rate (void)
b6c9286a 18136{
3317bab1
DE
18137 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
18138 if (!reload_completed)
18139 return 1;
18140
b6c9286a 18141 switch (rs6000_cpu_attr) {
3cb999d8
DE
18142 case CPU_RIOS1: /* ? */
18143 case CPU_RS64A:
18144 case CPU_PPC601: /* ? */
ed947a96 18145 case CPU_PPC7450:
3cb999d8 18146 return 3;
b54cf83a 18147 case CPU_PPC440:
b6c9286a 18148 case CPU_PPC603:
bef84347 18149 case CPU_PPC750:
ed947a96 18150 case CPU_PPC7400:
be12c2b0 18151 case CPU_PPC8540:
d296e02e 18152 case CPU_CELL:
f676971a 18153 return 2;
3cb999d8 18154 case CPU_RIOS2:
b6c9286a 18155 case CPU_PPC604:
19684119 18156 case CPU_PPC604E:
b6c9286a 18157 case CPU_PPC620:
3cb999d8 18158 case CPU_PPC630:
b6c9286a 18159 return 4;
cbe26ab8 18160 case CPU_POWER4:
ec507f2d 18161 case CPU_POWER5:
44cd321e 18162 case CPU_POWER6:
cbe26ab8 18163 return 5;
b6c9286a
MM
18164 default:
18165 return 1;
18166 }
18167}
18168
be12c2b0
VM
18169/* Return how many instructions to look ahead for better insn
18170 scheduling. */
18171
18172static int
863d938c 18173rs6000_use_sched_lookahead (void)
be12c2b0
VM
18174{
18175 if (rs6000_cpu_attr == CPU_PPC8540)
18176 return 4;
d296e02e
AP
18177 if (rs6000_cpu_attr == CPU_CELL)
18178 return (reload_completed ? 8 : 0);
be12c2b0
VM
18179 return 0;
18180}
18181
d296e02e
AP
18182/* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
18183static int
18184rs6000_use_sched_lookahead_guard (rtx insn)
18185{
18186 if (rs6000_cpu_attr != CPU_CELL)
18187 return 1;
18188
18189 if (insn == NULL_RTX || !INSN_P (insn))
18190 abort ();
982afe02 18191
d296e02e
AP
18192 if (!reload_completed
18193 || is_nonpipeline_insn (insn)
18194 || is_microcoded_insn (insn))
18195 return 0;
18196
18197 return 1;
18198}
18199
569fa502
DN
18200/* Determine is PAT refers to memory. */
18201
18202static bool
18203is_mem_ref (rtx pat)
18204{
18205 const char * fmt;
18206 int i, j;
18207 bool ret = false;
18208
18209 if (GET_CODE (pat) == MEM)
18210 return true;
18211
18212 /* Recursively process the pattern. */
18213 fmt = GET_RTX_FORMAT (GET_CODE (pat));
18214
18215 for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0 && !ret; i--)
18216 {
18217 if (fmt[i] == 'e')
18218 ret |= is_mem_ref (XEXP (pat, i));
18219 else if (fmt[i] == 'E')
18220 for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
18221 ret |= is_mem_ref (XVECEXP (pat, i, j));
18222 }
18223
18224 return ret;
18225}
18226
18227/* Determine if PAT is a PATTERN of a load insn. */
f676971a 18228
569fa502
DN
18229static bool
18230is_load_insn1 (rtx pat)
18231{
18232 if (!pat || pat == NULL_RTX)
18233 return false;
18234
18235 if (GET_CODE (pat) == SET)
18236 return is_mem_ref (SET_SRC (pat));
18237
18238 if (GET_CODE (pat) == PARALLEL)
18239 {
18240 int i;
18241
18242 for (i = 0; i < XVECLEN (pat, 0); i++)
18243 if (is_load_insn1 (XVECEXP (pat, 0, i)))
18244 return true;
18245 }
18246
18247 return false;
18248}
18249
18250/* Determine if INSN loads from memory. */
18251
18252static bool
18253is_load_insn (rtx insn)
18254{
18255 if (!insn || !INSN_P (insn))
18256 return false;
18257
18258 if (GET_CODE (insn) == CALL_INSN)
18259 return false;
18260
18261 return is_load_insn1 (PATTERN (insn));
18262}
18263
18264/* Determine if PAT is a PATTERN of a store insn. */
18265
18266static bool
18267is_store_insn1 (rtx pat)
18268{
18269 if (!pat || pat == NULL_RTX)
18270 return false;
18271
18272 if (GET_CODE (pat) == SET)
18273 return is_mem_ref (SET_DEST (pat));
18274
18275 if (GET_CODE (pat) == PARALLEL)
18276 {
18277 int i;
18278
18279 for (i = 0; i < XVECLEN (pat, 0); i++)
18280 if (is_store_insn1 (XVECEXP (pat, 0, i)))
18281 return true;
18282 }
18283
18284 return false;
18285}
18286
18287/* Determine if INSN stores to memory. */
18288
18289static bool
18290is_store_insn (rtx insn)
18291{
18292 if (!insn || !INSN_P (insn))
18293 return false;
18294
18295 return is_store_insn1 (PATTERN (insn));
18296}
18297
e3a0e200
PB
18298/* Return the dest of a store insn. */
18299
18300static rtx
18301get_store_dest (rtx pat)
18302{
18303 gcc_assert (is_store_insn1 (pat));
18304
18305 if (GET_CODE (pat) == SET)
18306 return SET_DEST (pat);
18307 else if (GET_CODE (pat) == PARALLEL)
18308 {
18309 int i;
18310
18311 for (i = 0; i < XVECLEN (pat, 0); i++)
18312 {
18313 rtx inner_pat = XVECEXP (pat, 0, i);
18314 if (GET_CODE (inner_pat) == SET
18315 && is_mem_ref (SET_DEST (inner_pat)))
18316 return inner_pat;
18317 }
18318 }
18319 /* We shouldn't get here, because we should have either a simple
18320 store insn or a store with update which are covered above. */
18321 gcc_unreachable();
18322}
18323
569fa502
DN
18324/* Returns whether the dependence between INSN and NEXT is considered
18325 costly by the given target. */
18326
18327static bool
b198261f 18328rs6000_is_costly_dependence (dep_t dep, int cost, int distance)
f676971a 18329{
b198261f
MK
18330 rtx insn;
18331 rtx next;
18332
aabcd309 18333 /* If the flag is not enabled - no dependence is considered costly;
f676971a 18334 allow all dependent insns in the same group.
569fa502
DN
18335 This is the most aggressive option. */
18336 if (rs6000_sched_costly_dep == no_dep_costly)
18337 return false;
18338
f676971a 18339 /* If the flag is set to 1 - a dependence is always considered costly;
569fa502
DN
18340 do not allow dependent instructions in the same group.
18341 This is the most conservative option. */
18342 if (rs6000_sched_costly_dep == all_deps_costly)
f676971a 18343 return true;
569fa502 18344
b198261f
MK
18345 insn = DEP_PRO (dep);
18346 next = DEP_CON (dep);
18347
f676971a
EC
18348 if (rs6000_sched_costly_dep == store_to_load_dep_costly
18349 && is_load_insn (next)
569fa502
DN
18350 && is_store_insn (insn))
18351 /* Prevent load after store in the same group. */
18352 return true;
18353
18354 if (rs6000_sched_costly_dep == true_store_to_load_dep_costly
f676971a 18355 && is_load_insn (next)
569fa502 18356 && is_store_insn (insn)
e2f6ff94 18357 && DEP_TYPE (dep) == REG_DEP_TRUE)
c4ad648e
AM
18358 /* Prevent load after store in the same group if it is a true
18359 dependence. */
569fa502 18360 return true;
f676971a
EC
18361
18362 /* The flag is set to X; dependences with latency >= X are considered costly,
569fa502
DN
18363 and will not be scheduled in the same group. */
18364 if (rs6000_sched_costly_dep <= max_dep_latency
18365 && ((cost - distance) >= (int)rs6000_sched_costly_dep))
18366 return true;
18367
18368 return false;
18369}
18370
f676971a 18371/* Return the next insn after INSN that is found before TAIL is reached,
cbe26ab8
DN
18372 skipping any "non-active" insns - insns that will not actually occupy
18373 an issue slot. Return NULL_RTX if such an insn is not found. */
18374
18375static rtx
18376get_next_active_insn (rtx insn, rtx tail)
18377{
f489aff8 18378 if (insn == NULL_RTX || insn == tail)
cbe26ab8
DN
18379 return NULL_RTX;
18380
f489aff8 18381 while (1)
cbe26ab8 18382 {
f489aff8
AM
18383 insn = NEXT_INSN (insn);
18384 if (insn == NULL_RTX || insn == tail)
18385 return NULL_RTX;
cbe26ab8 18386
f489aff8
AM
18387 if (CALL_P (insn)
18388 || JUMP_P (insn)
18389 || (NONJUMP_INSN_P (insn)
18390 && GET_CODE (PATTERN (insn)) != USE
18391 && GET_CODE (PATTERN (insn)) != CLOBBER
309ebcd0 18392 && INSN_CODE (insn) != CODE_FOR_stack_tie))
f489aff8
AM
18393 break;
18394 }
18395 return insn;
cbe26ab8
DN
18396}
18397
44cd321e
PS
18398/* We are about to begin issuing insns for this clock cycle. */
18399
18400static int
18401rs6000_sched_reorder (FILE *dump ATTRIBUTE_UNUSED, int sched_verbose,
18402 rtx *ready ATTRIBUTE_UNUSED,
18403 int *pn_ready ATTRIBUTE_UNUSED,
18404 int clock_var ATTRIBUTE_UNUSED)
18405{
d296e02e
AP
18406 int n_ready = *pn_ready;
18407
44cd321e
PS
18408 if (sched_verbose)
18409 fprintf (dump, "// rs6000_sched_reorder :\n");
18410
d296e02e
AP
18411 /* Reorder the ready list, if the second to last ready insn
18412 is a nonepipeline insn. */
18413 if (rs6000_cpu_attr == CPU_CELL && n_ready > 1)
18414 {
18415 if (is_nonpipeline_insn (ready[n_ready - 1])
18416 && (recog_memoized (ready[n_ready - 2]) > 0))
18417 /* Simply swap first two insns. */
18418 {
18419 rtx tmp = ready[n_ready - 1];
18420 ready[n_ready - 1] = ready[n_ready - 2];
18421 ready[n_ready - 2] = tmp;
18422 }
18423 }
18424
44cd321e
PS
18425 if (rs6000_cpu == PROCESSOR_POWER6)
18426 load_store_pendulum = 0;
18427
18428 return rs6000_issue_rate ();
18429}
18430
18431/* Like rs6000_sched_reorder, but called after issuing each insn. */
18432
18433static int
18434rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx *ready,
18435 int *pn_ready, int clock_var ATTRIBUTE_UNUSED)
18436{
18437 if (sched_verbose)
18438 fprintf (dump, "// rs6000_sched_reorder2 :\n");
18439
18440 /* For Power6, we need to handle some special cases to try and keep the
18441 store queue from overflowing and triggering expensive flushes.
18442
18443 This code monitors how load and store instructions are being issued
18444 and skews the ready list one way or the other to increase the likelihood
18445 that a desired instruction is issued at the proper time.
18446
18447 A couple of things are done. First, we maintain a "load_store_pendulum"
18448 to track the current state of load/store issue.
18449
18450 - If the pendulum is at zero, then no loads or stores have been
18451 issued in the current cycle so we do nothing.
18452
18453 - If the pendulum is 1, then a single load has been issued in this
18454 cycle and we attempt to locate another load in the ready list to
18455 issue with it.
18456
2f8e468b 18457 - If the pendulum is -2, then two stores have already been
44cd321e
PS
18458 issued in this cycle, so we increase the priority of the first load
18459 in the ready list to increase it's likelihood of being chosen first
18460 in the next cycle.
18461
18462 - If the pendulum is -1, then a single store has been issued in this
18463 cycle and we attempt to locate another store in the ready list to
18464 issue with it, preferring a store to an adjacent memory location to
18465 facilitate store pairing in the store queue.
18466
18467 - If the pendulum is 2, then two loads have already been
18468 issued in this cycle, so we increase the priority of the first store
18469 in the ready list to increase it's likelihood of being chosen first
18470 in the next cycle.
18471
18472 - If the pendulum < -2 or > 2, then do nothing.
18473
18474 Note: This code covers the most common scenarios. There exist non
18475 load/store instructions which make use of the LSU and which
18476 would need to be accounted for to strictly model the behavior
18477 of the machine. Those instructions are currently unaccounted
18478 for to help minimize compile time overhead of this code.
18479 */
18480 if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn)
18481 {
18482 int pos;
18483 int i;
18484 rtx tmp;
18485
18486 if (is_store_insn (last_scheduled_insn))
18487 /* Issuing a store, swing the load_store_pendulum to the left */
18488 load_store_pendulum--;
18489 else if (is_load_insn (last_scheduled_insn))
18490 /* Issuing a load, swing the load_store_pendulum to the right */
18491 load_store_pendulum++;
18492 else
18493 return cached_can_issue_more;
18494
18495 /* If the pendulum is balanced, or there is only one instruction on
18496 the ready list, then all is well, so return. */
18497 if ((load_store_pendulum == 0) || (*pn_ready <= 1))
18498 return cached_can_issue_more;
18499
18500 if (load_store_pendulum == 1)
18501 {
18502 /* A load has been issued in this cycle. Scan the ready list
18503 for another load to issue with it */
18504 pos = *pn_ready-1;
18505
18506 while (pos >= 0)
18507 {
18508 if (is_load_insn (ready[pos]))
18509 {
18510 /* Found a load. Move it to the head of the ready list,
18511 and adjust it's priority so that it is more likely to
18512 stay there */
18513 tmp = ready[pos];
18514 for (i=pos; i<*pn_ready-1; i++)
18515 ready[i] = ready[i + 1];
18516 ready[*pn_ready-1] = tmp;
18517 if INSN_PRIORITY_KNOWN (tmp)
18518 INSN_PRIORITY (tmp)++;
18519 break;
18520 }
18521 pos--;
18522 }
18523 }
18524 else if (load_store_pendulum == -2)
18525 {
18526 /* Two stores have been issued in this cycle. Increase the
18527 priority of the first load in the ready list to favor it for
18528 issuing in the next cycle. */
18529 pos = *pn_ready-1;
18530
18531 while (pos >= 0)
18532 {
18533 if (is_load_insn (ready[pos])
18534 && INSN_PRIORITY_KNOWN (ready[pos]))
18535 {
18536 INSN_PRIORITY (ready[pos])++;
18537
18538 /* Adjust the pendulum to account for the fact that a load
18539 was found and increased in priority. This is to prevent
18540 increasing the priority of multiple loads */
18541 load_store_pendulum--;
18542
18543 break;
18544 }
18545 pos--;
18546 }
18547 }
18548 else if (load_store_pendulum == -1)
18549 {
18550 /* A store has been issued in this cycle. Scan the ready list for
18551 another store to issue with it, preferring a store to an adjacent
18552 memory location */
18553 int first_store_pos = -1;
18554
18555 pos = *pn_ready-1;
18556
18557 while (pos >= 0)
18558 {
18559 if (is_store_insn (ready[pos]))
18560 {
18561 /* Maintain the index of the first store found on the
18562 list */
18563 if (first_store_pos == -1)
18564 first_store_pos = pos;
18565
18566 if (is_store_insn (last_scheduled_insn)
18567 && adjacent_mem_locations (last_scheduled_insn,ready[pos]))
18568 {
18569 /* Found an adjacent store. Move it to the head of the
18570 ready list, and adjust it's priority so that it is
18571 more likely to stay there */
18572 tmp = ready[pos];
18573 for (i=pos; i<*pn_ready-1; i++)
18574 ready[i] = ready[i + 1];
18575 ready[*pn_ready-1] = tmp;
18576 if INSN_PRIORITY_KNOWN (tmp)
18577 INSN_PRIORITY (tmp)++;
18578 first_store_pos = -1;
18579
18580 break;
18581 };
18582 }
18583 pos--;
18584 }
18585
18586 if (first_store_pos >= 0)
18587 {
18588 /* An adjacent store wasn't found, but a non-adjacent store was,
18589 so move the non-adjacent store to the front of the ready
18590 list, and adjust its priority so that it is more likely to
18591 stay there. */
18592 tmp = ready[first_store_pos];
18593 for (i=first_store_pos; i<*pn_ready-1; i++)
18594 ready[i] = ready[i + 1];
18595 ready[*pn_ready-1] = tmp;
18596 if INSN_PRIORITY_KNOWN (tmp)
18597 INSN_PRIORITY (tmp)++;
18598 }
18599 }
18600 else if (load_store_pendulum == 2)
18601 {
18602 /* Two loads have been issued in this cycle. Increase the priority
18603 of the first store in the ready list to favor it for issuing in
18604 the next cycle. */
18605 pos = *pn_ready-1;
18606
18607 while (pos >= 0)
18608 {
18609 if (is_store_insn (ready[pos])
18610 && INSN_PRIORITY_KNOWN (ready[pos]))
18611 {
18612 INSN_PRIORITY (ready[pos])++;
18613
18614 /* Adjust the pendulum to account for the fact that a store
18615 was found and increased in priority. This is to prevent
18616 increasing the priority of multiple stores */
18617 load_store_pendulum++;
18618
18619 break;
18620 }
18621 pos--;
18622 }
18623 }
18624 }
18625
18626 return cached_can_issue_more;
18627}
18628
839a4992 18629/* Return whether the presence of INSN causes a dispatch group termination
cbe26ab8
DN
18630 of group WHICH_GROUP.
18631
18632 If WHICH_GROUP == current_group, this function will return true if INSN
18633 causes the termination of the current group (i.e, the dispatch group to
18634 which INSN belongs). This means that INSN will be the last insn in the
18635 group it belongs to.
18636
18637 If WHICH_GROUP == previous_group, this function will return true if INSN
18638 causes the termination of the previous group (i.e, the dispatch group that
18639 precedes the group to which INSN belongs). This means that INSN will be
18640 the first insn in the group it belongs to). */
18641
18642static bool
18643insn_terminates_group_p (rtx insn, enum group_termination which_group)
18644{
44cd321e 18645 bool first, last;
cbe26ab8
DN
18646
18647 if (! insn)
18648 return false;
569fa502 18649
44cd321e
PS
18650 first = insn_must_be_first_in_group (insn);
18651 last = insn_must_be_last_in_group (insn);
cbe26ab8 18652
44cd321e 18653 if (first && last)
cbe26ab8
DN
18654 return true;
18655
18656 if (which_group == current_group)
44cd321e 18657 return last;
cbe26ab8 18658 else if (which_group == previous_group)
44cd321e
PS
18659 return first;
18660
18661 return false;
18662}
18663
18664
18665static bool
18666insn_must_be_first_in_group (rtx insn)
18667{
18668 enum attr_type type;
18669
18670 if (!insn
18671 || insn == NULL_RTX
18672 || GET_CODE (insn) == NOTE
18673 || GET_CODE (PATTERN (insn)) == USE
18674 || GET_CODE (PATTERN (insn)) == CLOBBER)
18675 return false;
18676
18677 switch (rs6000_cpu)
cbe26ab8 18678 {
44cd321e
PS
18679 case PROCESSOR_POWER5:
18680 if (is_cracked_insn (insn))
18681 return true;
18682 case PROCESSOR_POWER4:
18683 if (is_microcoded_insn (insn))
18684 return true;
18685
18686 if (!rs6000_sched_groups)
18687 return false;
18688
18689 type = get_attr_type (insn);
18690
18691 switch (type)
18692 {
18693 case TYPE_MFCR:
18694 case TYPE_MFCRF:
18695 case TYPE_MTCR:
18696 case TYPE_DELAYED_CR:
18697 case TYPE_CR_LOGICAL:
18698 case TYPE_MTJMPR:
18699 case TYPE_MFJMPR:
18700 case TYPE_IDIV:
18701 case TYPE_LDIV:
18702 case TYPE_LOAD_L:
18703 case TYPE_STORE_C:
18704 case TYPE_ISYNC:
18705 case TYPE_SYNC:
18706 return true;
18707 default:
18708 break;
18709 }
18710 break;
18711 case PROCESSOR_POWER6:
18712 type = get_attr_type (insn);
18713
18714 switch (type)
18715 {
18716 case TYPE_INSERT_DWORD:
18717 case TYPE_EXTS:
18718 case TYPE_CNTLZ:
18719 case TYPE_SHIFT:
18720 case TYPE_VAR_SHIFT_ROTATE:
18721 case TYPE_TRAP:
18722 case TYPE_IMUL:
18723 case TYPE_IMUL2:
18724 case TYPE_IMUL3:
18725 case TYPE_LMUL:
18726 case TYPE_IDIV:
18727 case TYPE_INSERT_WORD:
18728 case TYPE_DELAYED_COMPARE:
18729 case TYPE_IMUL_COMPARE:
18730 case TYPE_LMUL_COMPARE:
18731 case TYPE_FPCOMPARE:
18732 case TYPE_MFCR:
18733 case TYPE_MTCR:
18734 case TYPE_MFJMPR:
18735 case TYPE_MTJMPR:
18736 case TYPE_ISYNC:
18737 case TYPE_SYNC:
18738 case TYPE_LOAD_L:
18739 case TYPE_STORE_C:
18740 case TYPE_LOAD_U:
18741 case TYPE_LOAD_UX:
18742 case TYPE_LOAD_EXT_UX:
18743 case TYPE_STORE_U:
18744 case TYPE_STORE_UX:
18745 case TYPE_FPLOAD_U:
18746 case TYPE_FPLOAD_UX:
18747 case TYPE_FPSTORE_U:
18748 case TYPE_FPSTORE_UX:
18749 return true;
18750 default:
18751 break;
18752 }
18753 break;
18754 default:
18755 break;
18756 }
18757
18758 return false;
18759}
18760
18761static bool
18762insn_must_be_last_in_group (rtx insn)
18763{
18764 enum attr_type type;
18765
18766 if (!insn
18767 || insn == NULL_RTX
18768 || GET_CODE (insn) == NOTE
18769 || GET_CODE (PATTERN (insn)) == USE
18770 || GET_CODE (PATTERN (insn)) == CLOBBER)
18771 return false;
18772
18773 switch (rs6000_cpu) {
18774 case PROCESSOR_POWER4:
18775 case PROCESSOR_POWER5:
18776 if (is_microcoded_insn (insn))
18777 return true;
18778
18779 if (is_branch_slot_insn (insn))
18780 return true;
18781
18782 break;
18783 case PROCESSOR_POWER6:
18784 type = get_attr_type (insn);
18785
18786 switch (type)
18787 {
18788 case TYPE_EXTS:
18789 case TYPE_CNTLZ:
18790 case TYPE_SHIFT:
18791 case TYPE_VAR_SHIFT_ROTATE:
18792 case TYPE_TRAP:
18793 case TYPE_IMUL:
18794 case TYPE_IMUL2:
18795 case TYPE_IMUL3:
18796 case TYPE_LMUL:
18797 case TYPE_IDIV:
18798 case TYPE_DELAYED_COMPARE:
18799 case TYPE_IMUL_COMPARE:
18800 case TYPE_LMUL_COMPARE:
18801 case TYPE_FPCOMPARE:
18802 case TYPE_MFCR:
18803 case TYPE_MTCR:
18804 case TYPE_MFJMPR:
18805 case TYPE_MTJMPR:
18806 case TYPE_ISYNC:
18807 case TYPE_SYNC:
18808 case TYPE_LOAD_L:
18809 case TYPE_STORE_C:
18810 return true;
18811 default:
18812 break;
cbe26ab8 18813 }
44cd321e
PS
18814 break;
18815 default:
18816 break;
18817 }
cbe26ab8
DN
18818
18819 return false;
18820}
18821
839a4992 18822/* Return true if it is recommended to keep NEXT_INSN "far" (in a separate
cbe26ab8
DN
18823 dispatch group) from the insns in GROUP_INSNS. Return false otherwise. */
18824
18825static bool
18826is_costly_group (rtx *group_insns, rtx next_insn)
18827{
18828 int i;
cbe26ab8
DN
18829 int issue_rate = rs6000_issue_rate ();
18830
18831 for (i = 0; i < issue_rate; i++)
18832 {
e2f6ff94
MK
18833 sd_iterator_def sd_it;
18834 dep_t dep;
cbe26ab8 18835 rtx insn = group_insns[i];
b198261f 18836
cbe26ab8 18837 if (!insn)
c4ad648e 18838 continue;
b198261f 18839
e2f6ff94 18840 FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
c4ad648e 18841 {
b198261f
MK
18842 rtx next = DEP_CON (dep);
18843
18844 if (next == next_insn
18845 && rs6000_is_costly_dependence (dep, dep_cost (dep), 0))
18846 return true;
c4ad648e 18847 }
cbe26ab8
DN
18848 }
18849
18850 return false;
18851}
18852
f676971a 18853/* Utility of the function redefine_groups.
cbe26ab8
DN
18854 Check if it is too costly to schedule NEXT_INSN together with GROUP_INSNS
18855 in the same dispatch group. If so, insert nops before NEXT_INSN, in order
18856 to keep it "far" (in a separate group) from GROUP_INSNS, following
18857 one of the following schemes, depending on the value of the flag
18858 -minsert_sched_nops = X:
18859 (1) X == sched_finish_regroup_exact: insert exactly as many nops as needed
839a4992 18860 in order to force NEXT_INSN into a separate group.
f676971a
EC
18861 (2) X < sched_finish_regroup_exact: insert exactly X nops.
18862 GROUP_END, CAN_ISSUE_MORE and GROUP_COUNT record the state after nop
cbe26ab8
DN
18863 insertion (has a group just ended, how many vacant issue slots remain in the
18864 last group, and how many dispatch groups were encountered so far). */
18865
f676971a 18866static int
c4ad648e
AM
18867force_new_group (int sched_verbose, FILE *dump, rtx *group_insns,
18868 rtx next_insn, bool *group_end, int can_issue_more,
18869 int *group_count)
cbe26ab8
DN
18870{
18871 rtx nop;
18872 bool force;
18873 int issue_rate = rs6000_issue_rate ();
18874 bool end = *group_end;
18875 int i;
18876
18877 if (next_insn == NULL_RTX)
18878 return can_issue_more;
18879
18880 if (rs6000_sched_insert_nops > sched_finish_regroup_exact)
18881 return can_issue_more;
18882
18883 force = is_costly_group (group_insns, next_insn);
18884 if (!force)
18885 return can_issue_more;
18886
18887 if (sched_verbose > 6)
18888 fprintf (dump,"force: group count = %d, can_issue_more = %d\n",
c4ad648e 18889 *group_count ,can_issue_more);
cbe26ab8
DN
18890
18891 if (rs6000_sched_insert_nops == sched_finish_regroup_exact)
18892 {
18893 if (*group_end)
c4ad648e 18894 can_issue_more = 0;
cbe26ab8
DN
18895
18896 /* Since only a branch can be issued in the last issue_slot, it is
18897 sufficient to insert 'can_issue_more - 1' nops if next_insn is not
18898 a branch. If next_insn is a branch, we insert 'can_issue_more' nops;
c4ad648e
AM
18899 in this case the last nop will start a new group and the branch
18900 will be forced to the new group. */
cbe26ab8 18901 if (can_issue_more && !is_branch_slot_insn (next_insn))
c4ad648e 18902 can_issue_more--;
cbe26ab8
DN
18903
18904 while (can_issue_more > 0)
c4ad648e 18905 {
9390387d 18906 nop = gen_nop ();
c4ad648e
AM
18907 emit_insn_before (nop, next_insn);
18908 can_issue_more--;
18909 }
cbe26ab8
DN
18910
18911 *group_end = true;
18912 return 0;
f676971a 18913 }
cbe26ab8
DN
18914
18915 if (rs6000_sched_insert_nops < sched_finish_regroup_exact)
18916 {
18917 int n_nops = rs6000_sched_insert_nops;
18918
f676971a 18919 /* Nops can't be issued from the branch slot, so the effective
c4ad648e 18920 issue_rate for nops is 'issue_rate - 1'. */
cbe26ab8 18921 if (can_issue_more == 0)
c4ad648e 18922 can_issue_more = issue_rate;
cbe26ab8
DN
18923 can_issue_more--;
18924 if (can_issue_more == 0)
c4ad648e
AM
18925 {
18926 can_issue_more = issue_rate - 1;
18927 (*group_count)++;
18928 end = true;
18929 for (i = 0; i < issue_rate; i++)
18930 {
18931 group_insns[i] = 0;
18932 }
18933 }
cbe26ab8
DN
18934
18935 while (n_nops > 0)
c4ad648e
AM
18936 {
18937 nop = gen_nop ();
18938 emit_insn_before (nop, next_insn);
18939 if (can_issue_more == issue_rate - 1) /* new group begins */
18940 end = false;
18941 can_issue_more--;
18942 if (can_issue_more == 0)
18943 {
18944 can_issue_more = issue_rate - 1;
18945 (*group_count)++;
18946 end = true;
18947 for (i = 0; i < issue_rate; i++)
18948 {
18949 group_insns[i] = 0;
18950 }
18951 }
18952 n_nops--;
18953 }
cbe26ab8
DN
18954
18955 /* Scale back relative to 'issue_rate' (instead of 'issue_rate - 1'). */
f676971a 18956 can_issue_more++;
cbe26ab8 18957
c4ad648e
AM
18958 /* Is next_insn going to start a new group? */
18959 *group_end
18960 = (end
cbe26ab8
DN
18961 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
18962 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
18963 || (can_issue_more < issue_rate &&
c4ad648e 18964 insn_terminates_group_p (next_insn, previous_group)));
cbe26ab8 18965 if (*group_end && end)
c4ad648e 18966 (*group_count)--;
cbe26ab8
DN
18967
18968 if (sched_verbose > 6)
c4ad648e
AM
18969 fprintf (dump, "done force: group count = %d, can_issue_more = %d\n",
18970 *group_count, can_issue_more);
f676971a
EC
18971 return can_issue_more;
18972 }
cbe26ab8
DN
18973
18974 return can_issue_more;
18975}
18976
18977/* This function tries to synch the dispatch groups that the compiler "sees"
f676971a 18978 with the dispatch groups that the processor dispatcher is expected to
cbe26ab8
DN
18979 form in practice. It tries to achieve this synchronization by forcing the
18980 estimated processor grouping on the compiler (as opposed to the function
18981 'pad_goups' which tries to force the scheduler's grouping on the processor).
18982
18983 The function scans the insn sequence between PREV_HEAD_INSN and TAIL and
18984 examines the (estimated) dispatch groups that will be formed by the processor
18985 dispatcher. It marks these group boundaries to reflect the estimated
18986 processor grouping, overriding the grouping that the scheduler had marked.
18987 Depending on the value of the flag '-minsert-sched-nops' this function can
18988 force certain insns into separate groups or force a certain distance between
18989 them by inserting nops, for example, if there exists a "costly dependence"
18990 between the insns.
18991
18992 The function estimates the group boundaries that the processor will form as
0fa2e4df 18993 follows: It keeps track of how many vacant issue slots are available after
cbe26ab8
DN
18994 each insn. A subsequent insn will start a new group if one of the following
18995 4 cases applies:
18996 - no more vacant issue slots remain in the current dispatch group.
18997 - only the last issue slot, which is the branch slot, is vacant, but the next
18998 insn is not a branch.
18999 - only the last 2 or less issue slots, including the branch slot, are vacant,
19000 which means that a cracked insn (which occupies two issue slots) can't be
19001 issued in this group.
f676971a 19002 - less than 'issue_rate' slots are vacant, and the next insn always needs to
cbe26ab8
DN
19003 start a new group. */
19004
19005static int
19006redefine_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
19007{
19008 rtx insn, next_insn;
19009 int issue_rate;
19010 int can_issue_more;
19011 int slot, i;
19012 bool group_end;
19013 int group_count = 0;
19014 rtx *group_insns;
19015
19016 /* Initialize. */
19017 issue_rate = rs6000_issue_rate ();
19018 group_insns = alloca (issue_rate * sizeof (rtx));
f676971a 19019 for (i = 0; i < issue_rate; i++)
cbe26ab8
DN
19020 {
19021 group_insns[i] = 0;
19022 }
19023 can_issue_more = issue_rate;
19024 slot = 0;
19025 insn = get_next_active_insn (prev_head_insn, tail);
19026 group_end = false;
19027
19028 while (insn != NULL_RTX)
19029 {
19030 slot = (issue_rate - can_issue_more);
19031 group_insns[slot] = insn;
19032 can_issue_more =
c4ad648e 19033 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
cbe26ab8 19034 if (insn_terminates_group_p (insn, current_group))
c4ad648e 19035 can_issue_more = 0;
cbe26ab8
DN
19036
19037 next_insn = get_next_active_insn (insn, tail);
19038 if (next_insn == NULL_RTX)
c4ad648e 19039 return group_count + 1;
cbe26ab8 19040
c4ad648e
AM
19041 /* Is next_insn going to start a new group? */
19042 group_end
19043 = (can_issue_more == 0
19044 || (can_issue_more == 1 && !is_branch_slot_insn (next_insn))
19045 || (can_issue_more <= 2 && is_cracked_insn (next_insn))
19046 || (can_issue_more < issue_rate &&
19047 insn_terminates_group_p (next_insn, previous_group)));
cbe26ab8 19048
f676971a 19049 can_issue_more = force_new_group (sched_verbose, dump, group_insns,
c4ad648e
AM
19050 next_insn, &group_end, can_issue_more,
19051 &group_count);
cbe26ab8
DN
19052
19053 if (group_end)
c4ad648e
AM
19054 {
19055 group_count++;
19056 can_issue_more = 0;
19057 for (i = 0; i < issue_rate; i++)
19058 {
19059 group_insns[i] = 0;
19060 }
19061 }
cbe26ab8
DN
19062
19063 if (GET_MODE (next_insn) == TImode && can_issue_more)
9390387d 19064 PUT_MODE (next_insn, VOIDmode);
cbe26ab8 19065 else if (!can_issue_more && GET_MODE (next_insn) != TImode)
c4ad648e 19066 PUT_MODE (next_insn, TImode);
cbe26ab8
DN
19067
19068 insn = next_insn;
19069 if (can_issue_more == 0)
c4ad648e
AM
19070 can_issue_more = issue_rate;
19071 } /* while */
cbe26ab8
DN
19072
19073 return group_count;
19074}
19075
19076/* Scan the insn sequence between PREV_HEAD_INSN and TAIL and examine the
19077 dispatch group boundaries that the scheduler had marked. Pad with nops
19078 any dispatch groups which have vacant issue slots, in order to force the
19079 scheduler's grouping on the processor dispatcher. The function
19080 returns the number of dispatch groups found. */
19081
19082static int
19083pad_groups (FILE *dump, int sched_verbose, rtx prev_head_insn, rtx tail)
19084{
19085 rtx insn, next_insn;
19086 rtx nop;
19087 int issue_rate;
19088 int can_issue_more;
19089 int group_end;
19090 int group_count = 0;
19091
19092 /* Initialize issue_rate. */
19093 issue_rate = rs6000_issue_rate ();
19094 can_issue_more = issue_rate;
19095
19096 insn = get_next_active_insn (prev_head_insn, tail);
19097 next_insn = get_next_active_insn (insn, tail);
19098
19099 while (insn != NULL_RTX)
19100 {
19101 can_issue_more =
19102 rs6000_variable_issue (dump, sched_verbose, insn, can_issue_more);
19103
19104 group_end = (next_insn == NULL_RTX || GET_MODE (next_insn) == TImode);
19105
19106 if (next_insn == NULL_RTX)
c4ad648e 19107 break;
cbe26ab8
DN
19108
19109 if (group_end)
c4ad648e
AM
19110 {
19111 /* If the scheduler had marked group termination at this location
19112 (between insn and next_indn), and neither insn nor next_insn will
19113 force group termination, pad the group with nops to force group
19114 termination. */
19115 if (can_issue_more
19116 && (rs6000_sched_insert_nops == sched_finish_pad_groups)
19117 && !insn_terminates_group_p (insn, current_group)
19118 && !insn_terminates_group_p (next_insn, previous_group))
19119 {
9390387d 19120 if (!is_branch_slot_insn (next_insn))
c4ad648e
AM
19121 can_issue_more--;
19122
19123 while (can_issue_more)
19124 {
19125 nop = gen_nop ();
19126 emit_insn_before (nop, next_insn);
19127 can_issue_more--;
19128 }
19129 }
19130
19131 can_issue_more = issue_rate;
19132 group_count++;
19133 }
cbe26ab8
DN
19134
19135 insn = next_insn;
19136 next_insn = get_next_active_insn (insn, tail);
19137 }
19138
19139 return group_count;
19140}
19141
44cd321e
PS
19142/* We're beginning a new block. Initialize data structures as necessary. */
19143
19144static void
19145rs6000_sched_init (FILE *dump ATTRIBUTE_UNUSED,
19146 int sched_verbose ATTRIBUTE_UNUSED,
19147 int max_ready ATTRIBUTE_UNUSED)
982afe02 19148{
44cd321e
PS
19149 last_scheduled_insn = NULL_RTX;
19150 load_store_pendulum = 0;
19151}
19152
cbe26ab8
DN
19153/* The following function is called at the end of scheduling BB.
19154 After reload, it inserts nops at insn group bundling. */
19155
19156static void
38f391a5 19157rs6000_sched_finish (FILE *dump, int sched_verbose)
cbe26ab8
DN
19158{
19159 int n_groups;
19160
19161 if (sched_verbose)
19162 fprintf (dump, "=== Finishing schedule.\n");
19163
ec507f2d 19164 if (reload_completed && rs6000_sched_groups)
cbe26ab8
DN
19165 {
19166 if (rs6000_sched_insert_nops == sched_finish_none)
c4ad648e 19167 return;
cbe26ab8
DN
19168
19169 if (rs6000_sched_insert_nops == sched_finish_pad_groups)
c4ad648e
AM
19170 n_groups = pad_groups (dump, sched_verbose,
19171 current_sched_info->prev_head,
19172 current_sched_info->next_tail);
cbe26ab8 19173 else
c4ad648e
AM
19174 n_groups = redefine_groups (dump, sched_verbose,
19175 current_sched_info->prev_head,
19176 current_sched_info->next_tail);
cbe26ab8
DN
19177
19178 if (sched_verbose >= 6)
19179 {
19180 fprintf (dump, "ngroups = %d\n", n_groups);
19181 print_rtl (dump, current_sched_info->prev_head);
19182 fprintf (dump, "Done finish_sched\n");
19183 }
19184 }
19185}
b6c9286a 19186\f
b6c9286a
MM
19187/* Length in units of the trampoline for entering a nested function. */
19188
19189int
863d938c 19190rs6000_trampoline_size (void)
b6c9286a
MM
19191{
19192 int ret = 0;
19193
19194 switch (DEFAULT_ABI)
19195 {
19196 default:
37409796 19197 gcc_unreachable ();
b6c9286a
MM
19198
19199 case ABI_AIX:
8f802bfb 19200 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
19201 break;
19202
4dabc42d 19203 case ABI_DARWIN:
b6c9286a 19204 case ABI_V4:
03a7e1a5 19205 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 19206 break;
b6c9286a
MM
19207 }
19208
19209 return ret;
19210}
19211
19212/* Emit RTL insns to initialize the variable parts of a trampoline.
19213 FNADDR is an RTX for the address of the function's pure code.
19214 CXT is an RTX for the static chain value for the function. */
19215
19216void
a2369ed3 19217rs6000_initialize_trampoline (rtx addr, rtx fnaddr, rtx cxt)
b6c9286a 19218{
8bd04c56 19219 int regsize = (TARGET_32BIT) ? 4 : 8;
9613eaff 19220 rtx ctx_reg = force_reg (Pmode, cxt);
b6c9286a
MM
19221
19222 switch (DEFAULT_ABI)
19223 {
19224 default:
37409796 19225 gcc_unreachable ();
b6c9286a 19226
8bd04c56 19227/* Macros to shorten the code expansions below. */
9613eaff 19228#define MEM_DEREF(addr) gen_rtx_MEM (Pmode, memory_address (Pmode, addr))
c5c76735 19229#define MEM_PLUS(addr,offset) \
9613eaff 19230 gen_rtx_MEM (Pmode, memory_address (Pmode, plus_constant (addr, offset)))
7c59dc5d 19231
b6c9286a
MM
19232 /* Under AIX, just build the 3 word function descriptor */
19233 case ABI_AIX:
8bd04c56 19234 {
9613eaff
SH
19235 rtx fn_reg = gen_reg_rtx (Pmode);
19236 rtx toc_reg = gen_reg_rtx (Pmode);
8bd04c56 19237 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 19238 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
19239 emit_move_insn (MEM_DEREF (addr), fn_reg);
19240 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
19241 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
19242 }
b6c9286a
MM
19243 break;
19244
4dabc42d
TC
19245 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
19246 case ABI_DARWIN:
b6c9286a 19247 case ABI_V4:
9613eaff 19248 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__trampoline_setup"),
eaf1bcf1 19249 FALSE, VOIDmode, 4,
9613eaff 19250 addr, Pmode,
eaf1bcf1 19251 GEN_INT (rs6000_trampoline_size ()), SImode,
9613eaff
SH
19252 fnaddr, Pmode,
19253 ctx_reg, Pmode);
b6c9286a 19254 break;
b6c9286a
MM
19255 }
19256
19257 return;
19258}
7509c759
MM
19259
19260\f
91d231cb 19261/* Table of valid machine attributes. */
a4f6c312 19262
91d231cb 19263const struct attribute_spec rs6000_attribute_table[] =
7509c759 19264{
91d231cb 19265 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
8bb418a3 19266 { "altivec", 1, 1, false, true, false, rs6000_handle_altivec_attribute },
a5c76ee6
ZW
19267 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
19268 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
77ccdfed
EC
19269 { "ms_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
19270 { "gcc_struct", 0, 0, false, false, false, rs6000_handle_struct_attribute },
005c1a13
GK
19271#ifdef SUBTARGET_ATTRIBUTE_TABLE
19272 SUBTARGET_ATTRIBUTE_TABLE,
19273#endif
a5c76ee6 19274 { NULL, 0, 0, false, false, false, NULL }
91d231cb 19275};
7509c759 19276
8bb418a3
ZL
19277/* Handle the "altivec" attribute. The attribute may have
19278 arguments as follows:
f676971a 19279
8bb418a3
ZL
19280 __attribute__((altivec(vector__)))
19281 __attribute__((altivec(pixel__))) (always followed by 'unsigned short')
19282 __attribute__((altivec(bool__))) (always followed by 'unsigned')
19283
19284 and may appear more than once (e.g., 'vector bool char') in a
19285 given declaration. */
19286
19287static tree
f90ac3f0
UP
19288rs6000_handle_altivec_attribute (tree *node,
19289 tree name ATTRIBUTE_UNUSED,
19290 tree args,
8bb418a3
ZL
19291 int flags ATTRIBUTE_UNUSED,
19292 bool *no_add_attrs)
19293{
19294 tree type = *node, result = NULL_TREE;
19295 enum machine_mode mode;
19296 int unsigned_p;
19297 char altivec_type
19298 = ((args && TREE_CODE (args) == TREE_LIST && TREE_VALUE (args)
19299 && TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE)
19300 ? *IDENTIFIER_POINTER (TREE_VALUE (args))
f676971a 19301 : '?');
8bb418a3
ZL
19302
19303 while (POINTER_TYPE_P (type)
19304 || TREE_CODE (type) == FUNCTION_TYPE
19305 || TREE_CODE (type) == METHOD_TYPE
19306 || TREE_CODE (type) == ARRAY_TYPE)
19307 type = TREE_TYPE (type);
19308
19309 mode = TYPE_MODE (type);
19310
f90ac3f0
UP
19311 /* Check for invalid AltiVec type qualifiers. */
19312 if (type == long_unsigned_type_node || type == long_integer_type_node)
19313 {
19314 if (TARGET_64BIT)
19315 error ("use of %<long%> in AltiVec types is invalid for 64-bit code");
19316 else if (rs6000_warn_altivec_long)
d4ee4d25 19317 warning (0, "use of %<long%> in AltiVec types is deprecated; use %<int%>");
f90ac3f0
UP
19318 }
19319 else if (type == long_long_unsigned_type_node
19320 || type == long_long_integer_type_node)
19321 error ("use of %<long long%> in AltiVec types is invalid");
19322 else if (type == double_type_node)
19323 error ("use of %<double%> in AltiVec types is invalid");
19324 else if (type == long_double_type_node)
19325 error ("use of %<long double%> in AltiVec types is invalid");
19326 else if (type == boolean_type_node)
19327 error ("use of boolean types in AltiVec types is invalid");
19328 else if (TREE_CODE (type) == COMPLEX_TYPE)
19329 error ("use of %<complex%> in AltiVec types is invalid");
00b79d54
BE
19330 else if (DECIMAL_FLOAT_MODE_P (mode))
19331 error ("use of decimal floating point types in AltiVec types is invalid");
8bb418a3
ZL
19332
19333 switch (altivec_type)
19334 {
19335 case 'v':
8df83eae 19336 unsigned_p = TYPE_UNSIGNED (type);
8bb418a3
ZL
19337 switch (mode)
19338 {
c4ad648e
AM
19339 case SImode:
19340 result = (unsigned_p ? unsigned_V4SI_type_node : V4SI_type_node);
19341 break;
19342 case HImode:
19343 result = (unsigned_p ? unsigned_V8HI_type_node : V8HI_type_node);
19344 break;
19345 case QImode:
19346 result = (unsigned_p ? unsigned_V16QI_type_node : V16QI_type_node);
19347 break;
19348 case SFmode: result = V4SF_type_node; break;
19349 /* If the user says 'vector int bool', we may be handed the 'bool'
19350 attribute _before_ the 'vector' attribute, and so select the
19351 proper type in the 'b' case below. */
19352 case V4SImode: case V8HImode: case V16QImode: case V4SFmode:
19353 result = type;
19354 default: break;
8bb418a3
ZL
19355 }
19356 break;
19357 case 'b':
19358 switch (mode)
19359 {
c4ad648e
AM
19360 case SImode: case V4SImode: result = bool_V4SI_type_node; break;
19361 case HImode: case V8HImode: result = bool_V8HI_type_node; break;
19362 case QImode: case V16QImode: result = bool_V16QI_type_node;
19363 default: break;
8bb418a3
ZL
19364 }
19365 break;
19366 case 'p':
19367 switch (mode)
19368 {
c4ad648e
AM
19369 case V8HImode: result = pixel_V8HI_type_node;
19370 default: break;
8bb418a3
ZL
19371 }
19372 default: break;
19373 }
19374
7958a2a6
FJ
19375 if (result && result != type && TYPE_READONLY (type))
19376 result = build_qualified_type (result, TYPE_QUAL_CONST);
19377
8bb418a3
ZL
19378 *no_add_attrs = true; /* No need to hang on to the attribute. */
19379
f90ac3f0 19380 if (result)
8bb418a3
ZL
19381 *node = reconstruct_complex_type (*node, result);
19382
19383 return NULL_TREE;
19384}
19385
f18eca82
ZL
19386/* AltiVec defines four built-in scalar types that serve as vector
19387 elements; we must teach the compiler how to mangle them. */
19388
19389static const char *
3101faab 19390rs6000_mangle_type (const_tree type)
f18eca82 19391{
608063c3
JB
19392 type = TYPE_MAIN_VARIANT (type);
19393
19394 if (TREE_CODE (type) != VOID_TYPE && TREE_CODE (type) != BOOLEAN_TYPE
19395 && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
19396 return NULL;
19397
f18eca82
ZL
19398 if (type == bool_char_type_node) return "U6__boolc";
19399 if (type == bool_short_type_node) return "U6__bools";
19400 if (type == pixel_type_node) return "u7__pixel";
19401 if (type == bool_int_type_node) return "U6__booli";
19402
337bde91
DE
19403 /* Mangle IBM extended float long double as `g' (__float128) on
19404 powerpc*-linux where long-double-64 previously was the default. */
19405 if (TYPE_MAIN_VARIANT (type) == long_double_type_node
19406 && TARGET_ELF
19407 && TARGET_LONG_DOUBLE_128
19408 && !TARGET_IEEEQUAD)
19409 return "g";
19410
f18eca82
ZL
19411 /* For all other types, use normal C++ mangling. */
19412 return NULL;
19413}
19414
a5c76ee6
ZW
19415/* Handle a "longcall" or "shortcall" attribute; arguments as in
19416 struct attribute_spec.handler. */
a4f6c312 19417
91d231cb 19418static tree
f676971a
EC
19419rs6000_handle_longcall_attribute (tree *node, tree name,
19420 tree args ATTRIBUTE_UNUSED,
19421 int flags ATTRIBUTE_UNUSED,
a2369ed3 19422 bool *no_add_attrs)
91d231cb
JM
19423{
19424 if (TREE_CODE (*node) != FUNCTION_TYPE
19425 && TREE_CODE (*node) != FIELD_DECL
19426 && TREE_CODE (*node) != TYPE_DECL)
19427 {
5c498b10 19428 warning (OPT_Wattributes, "%qs attribute only applies to functions",
91d231cb
JM
19429 IDENTIFIER_POINTER (name));
19430 *no_add_attrs = true;
19431 }
6a4cee5f 19432
91d231cb 19433 return NULL_TREE;
7509c759
MM
19434}
19435
a5c76ee6
ZW
19436/* Set longcall attributes on all functions declared when
19437 rs6000_default_long_calls is true. */
19438static void
a2369ed3 19439rs6000_set_default_type_attributes (tree type)
a5c76ee6
ZW
19440{
19441 if (rs6000_default_long_calls
19442 && (TREE_CODE (type) == FUNCTION_TYPE
19443 || TREE_CODE (type) == METHOD_TYPE))
19444 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
19445 NULL_TREE,
19446 TYPE_ATTRIBUTES (type));
16d6f994
EC
19447
19448#if TARGET_MACHO
19449 darwin_set_default_type_attributes (type);
19450#endif
a5c76ee6
ZW
19451}
19452
3cb999d8
DE
19453/* Return a reference suitable for calling a function with the
19454 longcall attribute. */
a4f6c312 19455
9390387d 19456rtx
a2369ed3 19457rs6000_longcall_ref (rtx call_ref)
6a4cee5f 19458{
d330fd93 19459 const char *call_name;
6a4cee5f
MM
19460 tree node;
19461
19462 if (GET_CODE (call_ref) != SYMBOL_REF)
19463 return call_ref;
19464
19465 /* System V adds '.' to the internal name, so skip them. */
19466 call_name = XSTR (call_ref, 0);
19467 if (*call_name == '.')
19468 {
19469 while (*call_name == '.')
19470 call_name++;
19471
19472 node = get_identifier (call_name);
39403d82 19473 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
19474 }
19475
19476 return force_reg (Pmode, call_ref);
19477}
7509c759 19478\f
77ccdfed
EC
19479#ifndef TARGET_USE_MS_BITFIELD_LAYOUT
19480#define TARGET_USE_MS_BITFIELD_LAYOUT 0
19481#endif
19482
19483/* Handle a "ms_struct" or "gcc_struct" attribute; arguments as in
19484 struct attribute_spec.handler. */
19485static tree
19486rs6000_handle_struct_attribute (tree *node, tree name,
19487 tree args ATTRIBUTE_UNUSED,
19488 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
19489{
19490 tree *type = NULL;
19491 if (DECL_P (*node))
19492 {
19493 if (TREE_CODE (*node) == TYPE_DECL)
19494 type = &TREE_TYPE (*node);
19495 }
19496 else
19497 type = node;
19498
19499 if (!(type && (TREE_CODE (*type) == RECORD_TYPE
19500 || TREE_CODE (*type) == UNION_TYPE)))
19501 {
19502 warning (OPT_Wattributes, "%qs attribute ignored", IDENTIFIER_POINTER (name));
19503 *no_add_attrs = true;
19504 }
19505
19506 else if ((is_attribute_p ("ms_struct", name)
19507 && lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (*type)))
19508 || ((is_attribute_p ("gcc_struct", name)
19509 && lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (*type)))))
19510 {
19511 warning (OPT_Wattributes, "%qs incompatible attribute ignored",
19512 IDENTIFIER_POINTER (name));
19513 *no_add_attrs = true;
19514 }
19515
19516 return NULL_TREE;
19517}
19518
19519static bool
3101faab 19520rs6000_ms_bitfield_layout_p (const_tree record_type)
77ccdfed
EC
19521{
19522 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
19523 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
19524 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
19525}
19526\f
b64a1b53
RH
19527#ifdef USING_ELFOS_H
19528
d6b5193b 19529/* A get_unnamed_section callback, used for switching to toc_section. */
7509c759 19530
d6b5193b
RS
19531static void
19532rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
19533{
19534 if (DEFAULT_ABI == ABI_AIX
19535 && TARGET_MINIMAL_TOC
19536 && !TARGET_RELOCATABLE)
19537 {
19538 if (!toc_initialized)
19539 {
19540 toc_initialized = 1;
19541 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
19542 (*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
19543 fprintf (asm_out_file, "\t.tc ");
19544 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
19545 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
19546 fprintf (asm_out_file, "\n");
19547
19548 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
19549 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
19550 fprintf (asm_out_file, " = .+32768\n");
19551 }
19552 else
19553 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
19554 }
19555 else if (DEFAULT_ABI == ABI_AIX && !TARGET_RELOCATABLE)
19556 fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
19557 else
19558 {
19559 fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
19560 if (!toc_initialized)
19561 {
19562 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
19563 fprintf (asm_out_file, " = .+32768\n");
19564 toc_initialized = 1;
19565 }
19566 }
19567}
19568
19569/* Implement TARGET_ASM_INIT_SECTIONS. */
7509c759 19570
b64a1b53 19571static void
d6b5193b
RS
19572rs6000_elf_asm_init_sections (void)
19573{
19574 toc_section
19575 = get_unnamed_section (0, rs6000_elf_output_toc_section_asm_op, NULL);
19576
19577 sdata2_section
19578 = get_unnamed_section (SECTION_WRITE, output_section_asm_op,
19579 SDATA2_SECTION_ASM_OP);
19580}
19581
19582/* Implement TARGET_SELECT_RTX_SECTION. */
19583
19584static section *
f676971a 19585rs6000_elf_select_rtx_section (enum machine_mode mode, rtx x,
a2369ed3 19586 unsigned HOST_WIDE_INT align)
7509c759 19587{
a9098fd0 19588 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
d6b5193b 19589 return toc_section;
7509c759 19590 else
d6b5193b 19591 return default_elf_select_rtx_section (mode, x, align);
7509c759 19592}
d9407988 19593\f
d1908feb
JJ
19594/* For a SYMBOL_REF, set generic flags and then perform some
19595 target-specific processing.
19596
d1908feb
JJ
19597 When the AIX ABI is requested on a non-AIX system, replace the
19598 function name with the real name (with a leading .) rather than the
19599 function descriptor name. This saves a lot of overriding code to
19600 read the prefixes. */
d9407988 19601
fb49053f 19602static void
a2369ed3 19603rs6000_elf_encode_section_info (tree decl, rtx rtl, int first)
d9407988 19604{
d1908feb 19605 default_encode_section_info (decl, rtl, first);
b2003250 19606
d1908feb
JJ
19607 if (first
19608 && TREE_CODE (decl) == FUNCTION_DECL
19609 && !TARGET_AIX
19610 && DEFAULT_ABI == ABI_AIX)
d9407988 19611 {
c6a2438a 19612 rtx sym_ref = XEXP (rtl, 0);
d1908feb
JJ
19613 size_t len = strlen (XSTR (sym_ref, 0));
19614 char *str = alloca (len + 2);
19615 str[0] = '.';
19616 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
19617 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988 19618 }
d9407988
MM
19619}
19620
21d9bb3f
PB
19621static inline bool
19622compare_section_name (const char *section, const char *template)
19623{
19624 int len;
19625
19626 len = strlen (template);
19627 return (strncmp (section, template, len) == 0
19628 && (section[len] == 0 || section[len] == '.'));
19629}
19630
c1b7d95a 19631bool
3101faab 19632rs6000_elf_in_small_data_p (const_tree decl)
0e5dbd9b
DE
19633{
19634 if (rs6000_sdata == SDATA_NONE)
19635 return false;
19636
7482ad25
AF
19637 /* We want to merge strings, so we never consider them small data. */
19638 if (TREE_CODE (decl) == STRING_CST)
19639 return false;
19640
19641 /* Functions are never in the small data area. */
19642 if (TREE_CODE (decl) == FUNCTION_DECL)
19643 return false;
19644
0e5dbd9b
DE
19645 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
19646 {
19647 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
ca2ba153
JJ
19648 if (compare_section_name (section, ".sdata")
19649 || compare_section_name (section, ".sdata2")
19650 || compare_section_name (section, ".gnu.linkonce.s")
19651 || compare_section_name (section, ".sbss")
19652 || compare_section_name (section, ".sbss2")
19653 || compare_section_name (section, ".gnu.linkonce.sb")
20bfcd69
GK
19654 || strcmp (section, ".PPC.EMB.sdata0") == 0
19655 || strcmp (section, ".PPC.EMB.sbss0") == 0)
0e5dbd9b
DE
19656 return true;
19657 }
19658 else
19659 {
19660 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
19661
19662 if (size > 0
307b599c 19663 && (unsigned HOST_WIDE_INT) size <= g_switch_value
20bfcd69
GK
19664 /* If it's not public, and we're not going to reference it there,
19665 there's no need to put it in the small data section. */
0e5dbd9b
DE
19666 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
19667 return true;
19668 }
19669
19670 return false;
19671}
19672
b91da81f 19673#endif /* USING_ELFOS_H */
aacd3885
RS
19674\f
19675/* Implement TARGET_USE_BLOCKS_FOR_CONSTANT_P. */
000034eb 19676
aacd3885 19677static bool
3101faab 19678rs6000_use_blocks_for_constant_p (enum machine_mode mode, const_rtx x)
aacd3885
RS
19679{
19680 return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
19681}
a6c2a102 19682\f
000034eb 19683/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
19684 ADDR can be effectively incremented by incrementing REG.
19685
19686 r0 is special and we must not select it as an address
19687 register by this routine since our caller will try to
19688 increment the returned register via an "la" instruction. */
000034eb 19689
9390387d 19690rtx
a2369ed3 19691find_addr_reg (rtx addr)
000034eb
DE
19692{
19693 while (GET_CODE (addr) == PLUS)
19694 {
02441cd6
JL
19695 if (GET_CODE (XEXP (addr, 0)) == REG
19696 && REGNO (XEXP (addr, 0)) != 0)
000034eb 19697 addr = XEXP (addr, 0);
02441cd6
JL
19698 else if (GET_CODE (XEXP (addr, 1)) == REG
19699 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
19700 addr = XEXP (addr, 1);
19701 else if (CONSTANT_P (XEXP (addr, 0)))
19702 addr = XEXP (addr, 1);
19703 else if (CONSTANT_P (XEXP (addr, 1)))
19704 addr = XEXP (addr, 0);
19705 else
37409796 19706 gcc_unreachable ();
000034eb 19707 }
37409796
NS
19708 gcc_assert (GET_CODE (addr) == REG && REGNO (addr) != 0);
19709 return addr;
000034eb
DE
19710}
19711
a6c2a102 19712void
a2369ed3 19713rs6000_fatal_bad_address (rtx op)
a6c2a102
DE
19714{
19715 fatal_insn ("bad address", op);
19716}
c8023011 19717
ee890fe2
SS
19718#if TARGET_MACHO
19719
efdba735 19720static tree branch_island_list = 0;
ee890fe2 19721
efdba735
SH
19722/* Remember to generate a branch island for far calls to the given
19723 function. */
ee890fe2 19724
f676971a 19725static void
c4ad648e
AM
19726add_compiler_branch_island (tree label_name, tree function_name,
19727 int line_number)
ee890fe2 19728{
efdba735 19729 tree branch_island = build_tree_list (function_name, label_name);
7d60be94 19730 TREE_TYPE (branch_island) = build_int_cst (NULL_TREE, line_number);
efdba735
SH
19731 TREE_CHAIN (branch_island) = branch_island_list;
19732 branch_island_list = branch_island;
ee890fe2
SS
19733}
19734
efdba735
SH
19735#define BRANCH_ISLAND_LABEL_NAME(BRANCH_ISLAND) TREE_VALUE (BRANCH_ISLAND)
19736#define BRANCH_ISLAND_FUNCTION_NAME(BRANCH_ISLAND) TREE_PURPOSE (BRANCH_ISLAND)
19737#define BRANCH_ISLAND_LINE_NUMBER(BRANCH_ISLAND) \
19738 TREE_INT_CST_LOW (TREE_TYPE (BRANCH_ISLAND))
ee890fe2 19739
efdba735
SH
19740/* Generate far-jump branch islands for everything on the
19741 branch_island_list. Invoked immediately after the last instruction
19742 of the epilogue has been emitted; the branch-islands must be
19743 appended to, and contiguous with, the function body. Mach-O stubs
19744 are generated in machopic_output_stub(). */
ee890fe2 19745
efdba735
SH
19746static void
19747macho_branch_islands (void)
19748{
19749 char tmp_buf[512];
19750 tree branch_island;
19751
19752 for (branch_island = branch_island_list;
19753 branch_island;
19754 branch_island = TREE_CHAIN (branch_island))
19755 {
19756 const char *label =
19757 IDENTIFIER_POINTER (BRANCH_ISLAND_LABEL_NAME (branch_island));
19758 const char *name =
11abc112 19759 IDENTIFIER_POINTER (BRANCH_ISLAND_FUNCTION_NAME (branch_island));
efdba735
SH
19760 char name_buf[512];
19761 /* Cheap copy of the details from the Darwin ASM_OUTPUT_LABELREF(). */
19762 if (name[0] == '*' || name[0] == '&')
19763 strcpy (name_buf, name+1);
19764 else
19765 {
19766 name_buf[0] = '_';
19767 strcpy (name_buf+1, name);
19768 }
19769 strcpy (tmp_buf, "\n");
19770 strcat (tmp_buf, label);
ee890fe2 19771#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
efdba735 19772 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
93a27b7b 19773 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
ee890fe2 19774#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
efdba735
SH
19775 if (flag_pic)
19776 {
19777 strcat (tmp_buf, ":\n\tmflr r0\n\tbcl 20,31,");
19778 strcat (tmp_buf, label);
19779 strcat (tmp_buf, "_pic\n");
19780 strcat (tmp_buf, label);
19781 strcat (tmp_buf, "_pic:\n\tmflr r11\n");
f676971a 19782
efdba735
SH
19783 strcat (tmp_buf, "\taddis r11,r11,ha16(");
19784 strcat (tmp_buf, name_buf);
19785 strcat (tmp_buf, " - ");
19786 strcat (tmp_buf, label);
19787 strcat (tmp_buf, "_pic)\n");
f676971a 19788
efdba735 19789 strcat (tmp_buf, "\tmtlr r0\n");
f676971a 19790
efdba735
SH
19791 strcat (tmp_buf, "\taddi r12,r11,lo16(");
19792 strcat (tmp_buf, name_buf);
19793 strcat (tmp_buf, " - ");
19794 strcat (tmp_buf, label);
19795 strcat (tmp_buf, "_pic)\n");
f676971a 19796
efdba735
SH
19797 strcat (tmp_buf, "\tmtctr r12\n\tbctr\n");
19798 }
19799 else
19800 {
19801 strcat (tmp_buf, ":\nlis r12,hi16(");
19802 strcat (tmp_buf, name_buf);
19803 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
19804 strcat (tmp_buf, name_buf);
19805 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
19806 }
19807 output_asm_insn (tmp_buf, 0);
ee890fe2 19808#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
efdba735 19809 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
93a27b7b 19810 dbxout_stabd (N_SLINE, BRANCH_ISLAND_LINE_NUMBER (branch_island));
ee890fe2 19811#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
efdba735 19812 }
ee890fe2 19813
efdba735 19814 branch_island_list = 0;
ee890fe2
SS
19815}
19816
19817/* NO_PREVIOUS_DEF checks in the link list whether the function name is
19818 already there or not. */
19819
efdba735 19820static int
a2369ed3 19821no_previous_def (tree function_name)
ee890fe2 19822{
efdba735
SH
19823 tree branch_island;
19824 for (branch_island = branch_island_list;
19825 branch_island;
19826 branch_island = TREE_CHAIN (branch_island))
19827 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
ee890fe2
SS
19828 return 0;
19829 return 1;
19830}
19831
19832/* GET_PREV_LABEL gets the label name from the previous definition of
19833 the function. */
19834
efdba735 19835static tree
a2369ed3 19836get_prev_label (tree function_name)
ee890fe2 19837{
efdba735
SH
19838 tree branch_island;
19839 for (branch_island = branch_island_list;
19840 branch_island;
19841 branch_island = TREE_CHAIN (branch_island))
19842 if (function_name == BRANCH_ISLAND_FUNCTION_NAME (branch_island))
19843 return BRANCH_ISLAND_LABEL_NAME (branch_island);
ee890fe2
SS
19844 return 0;
19845}
19846
75b1b789
MS
19847#ifndef DARWIN_LINKER_GENERATES_ISLANDS
19848#define DARWIN_LINKER_GENERATES_ISLANDS 0
19849#endif
19850
19851/* KEXTs still need branch islands. */
19852#define DARWIN_GENERATE_ISLANDS (!DARWIN_LINKER_GENERATES_ISLANDS \
19853 || flag_mkernel || flag_apple_kext)
19854
ee890fe2 19855/* INSN is either a function call or a millicode call. It may have an
f676971a 19856 unconditional jump in its delay slot.
ee890fe2
SS
19857
19858 CALL_DEST is the routine we are calling. */
19859
19860char *
c4ad648e
AM
19861output_call (rtx insn, rtx *operands, int dest_operand_number,
19862 int cookie_operand_number)
ee890fe2
SS
19863{
19864 static char buf[256];
75b1b789
MS
19865 if (DARWIN_GENERATE_ISLANDS
19866 && GET_CODE (operands[dest_operand_number]) == SYMBOL_REF
efdba735 19867 && (INTVAL (operands[cookie_operand_number]) & CALL_LONG))
ee890fe2
SS
19868 {
19869 tree labelname;
efdba735 19870 tree funname = get_identifier (XSTR (operands[dest_operand_number], 0));
f676971a 19871
ee890fe2
SS
19872 if (no_previous_def (funname))
19873 {
ee890fe2
SS
19874 rtx label_rtx = gen_label_rtx ();
19875 char *label_buf, temp_buf[256];
19876 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
19877 CODE_LABEL_NUMBER (label_rtx));
19878 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
19879 labelname = get_identifier (label_buf);
a38e7aa5 19880 add_compiler_branch_island (labelname, funname, insn_line (insn));
ee890fe2
SS
19881 }
19882 else
19883 labelname = get_prev_label (funname);
19884
efdba735
SH
19885 /* "jbsr foo, L42" is Mach-O for "Link as 'bl foo' if a 'bl'
19886 instruction will reach 'foo', otherwise link as 'bl L42'".
19887 "L42" should be a 'branch island', that will do a far jump to
19888 'foo'. Branch islands are generated in
19889 macho_branch_islands(). */
ee890fe2 19890 sprintf (buf, "jbsr %%z%d,%.246s",
efdba735 19891 dest_operand_number, IDENTIFIER_POINTER (labelname));
ee890fe2
SS
19892 }
19893 else
efdba735
SH
19894 sprintf (buf, "bl %%z%d", dest_operand_number);
19895 return buf;
ee890fe2
SS
19896}
19897
ee890fe2
SS
19898/* Generate PIC and indirect symbol stubs. */
19899
19900void
a2369ed3 19901machopic_output_stub (FILE *file, const char *symb, const char *stub)
ee890fe2
SS
19902{
19903 unsigned int length;
a4f6c312
SS
19904 char *symbol_name, *lazy_ptr_name;
19905 char *local_label_0;
ee890fe2
SS
19906 static int label = 0;
19907
df56a27f 19908 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 19909 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 19910
ee890fe2 19911
ee890fe2
SS
19912 length = strlen (symb);
19913 symbol_name = alloca (length + 32);
19914 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
19915
19916 lazy_ptr_name = alloca (length + 32);
19917 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
19918
ee890fe2 19919 if (flag_pic == 2)
56c779bc 19920 switch_to_section (darwin_sections[machopic_picsymbol_stub1_section]);
ee890fe2 19921 else
56c779bc 19922 switch_to_section (darwin_sections[machopic_symbol_stub1_section]);
ee890fe2
SS
19923
19924 if (flag_pic == 2)
19925 {
d974312d
DJ
19926 fprintf (file, "\t.align 5\n");
19927
19928 fprintf (file, "%s:\n", stub);
19929 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19930
876455fa 19931 label++;
89da1f32 19932 local_label_0 = alloca (sizeof ("\"L00000000000$spb\""));
876455fa 19933 sprintf (local_label_0, "\"L%011d$spb\"", label);
f676971a 19934
ee890fe2
SS
19935 fprintf (file, "\tmflr r0\n");
19936 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
19937 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
19938 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
19939 lazy_ptr_name, local_label_0);
19940 fprintf (file, "\tmtlr r0\n");
3d0e2d58
SS
19941 fprintf (file, "\t%s r12,lo16(%s-%s)(r11)\n",
19942 (TARGET_64BIT ? "ldu" : "lwzu"),
ee890fe2
SS
19943 lazy_ptr_name, local_label_0);
19944 fprintf (file, "\tmtctr r12\n");
ee890fe2
SS
19945 fprintf (file, "\tbctr\n");
19946 }
19947 else
d974312d
DJ
19948 {
19949 fprintf (file, "\t.align 4\n");
19950
19951 fprintf (file, "%s:\n", stub);
19952 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
19953
19954 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
d9e4e4f5
SS
19955 fprintf (file, "\t%s r12,lo16(%s)(r11)\n",
19956 (TARGET_64BIT ? "ldu" : "lwzu"),
19957 lazy_ptr_name);
d974312d
DJ
19958 fprintf (file, "\tmtctr r12\n");
19959 fprintf (file, "\tbctr\n");
19960 }
f676971a 19961
56c779bc 19962 switch_to_section (darwin_sections[machopic_lazy_symbol_ptr_section]);
ee890fe2
SS
19963 fprintf (file, "%s:\n", lazy_ptr_name);
19964 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
49bd1d27
SS
19965 fprintf (file, "%sdyld_stub_binding_helper\n",
19966 (TARGET_64BIT ? DOUBLE_INT_ASM_OP : "\t.long\t"));
ee890fe2
SS
19967}
19968
19969/* Legitimize PIC addresses. If the address is already
19970 position-independent, we return ORIG. Newly generated
19971 position-independent addresses go into a reg. This is REG if non
19972 zero, otherwise we allocate register(s) as necessary. */
19973
4fbbe694 19974#define SMALL_INT(X) ((UINTVAL (X) + 0x8000) < 0x10000)
ee890fe2
SS
19975
19976rtx
f676971a 19977rs6000_machopic_legitimize_pic_address (rtx orig, enum machine_mode mode,
a2369ed3 19978 rtx reg)
ee890fe2
SS
19979{
19980 rtx base, offset;
19981
19982 if (reg == NULL && ! reload_in_progress && ! reload_completed)
19983 reg = gen_reg_rtx (Pmode);
19984
19985 if (GET_CODE (orig) == CONST)
19986 {
37409796
NS
19987 rtx reg_temp;
19988
ee890fe2
SS
19989 if (GET_CODE (XEXP (orig, 0)) == PLUS
19990 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
19991 return orig;
19992
37409796 19993 gcc_assert (GET_CODE (XEXP (orig, 0)) == PLUS);
bb8df8a6 19994
37409796
NS
19995 /* Use a different reg for the intermediate value, as
19996 it will be marked UNCHANGING. */
b3a13419 19997 reg_temp = !can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode);
37409796
NS
19998 base = rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
19999 Pmode, reg_temp);
20000 offset =
20001 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
20002 Pmode, reg);
bb8df8a6 20003
ee890fe2
SS
20004 if (GET_CODE (offset) == CONST_INT)
20005 {
20006 if (SMALL_INT (offset))
ed8908e7 20007 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
20008 else if (! reload_in_progress && ! reload_completed)
20009 offset = force_reg (Pmode, offset);
20010 else
c859cda6
DJ
20011 {
20012 rtx mem = force_const_mem (Pmode, orig);
20013 return machopic_legitimize_pic_address (mem, Pmode, reg);
20014 }
ee890fe2 20015 }
f1c25d3b 20016 return gen_rtx_PLUS (Pmode, base, offset);
ee890fe2
SS
20017 }
20018
20019 /* Fall back on generic machopic code. */
20020 return machopic_legitimize_pic_address (orig, mode, reg);
20021}
20022
c4e18b1c
GK
20023/* Output a .machine directive for the Darwin assembler, and call
20024 the generic start_file routine. */
20025
20026static void
20027rs6000_darwin_file_start (void)
20028{
94ff898d 20029 static const struct
c4e18b1c
GK
20030 {
20031 const char *arg;
20032 const char *name;
20033 int if_set;
20034 } mapping[] = {
55dbfb48 20035 { "ppc64", "ppc64", MASK_64BIT },
c4e18b1c
GK
20036 { "970", "ppc970", MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 },
20037 { "power4", "ppc970", 0 },
20038 { "G5", "ppc970", 0 },
20039 { "7450", "ppc7450", 0 },
20040 { "7400", "ppc7400", MASK_ALTIVEC },
20041 { "G4", "ppc7400", 0 },
20042 { "750", "ppc750", 0 },
20043 { "740", "ppc750", 0 },
20044 { "G3", "ppc750", 0 },
20045 { "604e", "ppc604e", 0 },
20046 { "604", "ppc604", 0 },
20047 { "603e", "ppc603", 0 },
20048 { "603", "ppc603", 0 },
20049 { "601", "ppc601", 0 },
20050 { NULL, "ppc", 0 } };
20051 const char *cpu_id = "";
20052 size_t i;
94ff898d 20053
9390387d 20054 rs6000_file_start ();
192d0f89 20055 darwin_file_start ();
c4e18b1c
GK
20056
20057 /* Determine the argument to -mcpu=. Default to G3 if not specified. */
20058 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
20059 if (rs6000_select[i].set_arch_p && rs6000_select[i].string
20060 && rs6000_select[i].string[0] != '\0')
20061 cpu_id = rs6000_select[i].string;
20062
20063 /* Look through the mapping array. Pick the first name that either
20064 matches the argument, has a bit set in IF_SET that is also set
20065 in the target flags, or has a NULL name. */
20066
20067 i = 0;
20068 while (mapping[i].arg != NULL
20069 && strcmp (mapping[i].arg, cpu_id) != 0
20070 && (mapping[i].if_set & target_flags) == 0)
20071 i++;
20072
20073 fprintf (asm_out_file, "\t.machine %s\n", mapping[i].name);
20074}
20075
ee890fe2 20076#endif /* TARGET_MACHO */
7c262518
RH
20077
20078#if TARGET_ELF
9b580a0b
RH
20079static int
20080rs6000_elf_reloc_rw_mask (void)
7c262518 20081{
9b580a0b
RH
20082 if (flag_pic)
20083 return 3;
20084 else if (DEFAULT_ABI == ABI_AIX)
20085 return 2;
20086 else
20087 return 0;
7c262518 20088}
d9f6800d
RH
20089
20090/* Record an element in the table of global constructors. SYMBOL is
20091 a SYMBOL_REF of the function to be called; PRIORITY is a number
20092 between 0 and MAX_INIT_PRIORITY.
20093
20094 This differs from default_named_section_asm_out_constructor in
20095 that we have special handling for -mrelocatable. */
20096
20097static void
a2369ed3 20098rs6000_elf_asm_out_constructor (rtx symbol, int priority)
d9f6800d
RH
20099{
20100 const char *section = ".ctors";
20101 char buf[16];
20102
20103 if (priority != DEFAULT_INIT_PRIORITY)
20104 {
20105 sprintf (buf, ".ctors.%.5u",
c4ad648e
AM
20106 /* Invert the numbering so the linker puts us in the proper
20107 order; constructors are run from right to left, and the
20108 linker sorts in increasing order. */
20109 MAX_INIT_PRIORITY - priority);
d9f6800d
RH
20110 section = buf;
20111 }
20112
d6b5193b 20113 switch_to_section (get_section (section, SECTION_WRITE, NULL));
715bdd29 20114 assemble_align (POINTER_SIZE);
d9f6800d
RH
20115
20116 if (TARGET_RELOCATABLE)
20117 {
20118 fputs ("\t.long (", asm_out_file);
20119 output_addr_const (asm_out_file, symbol);
20120 fputs (")@fixup\n", asm_out_file);
20121 }
20122 else
c8af3574 20123 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
20124}
20125
20126static void
a2369ed3 20127rs6000_elf_asm_out_destructor (rtx symbol, int priority)
d9f6800d
RH
20128{
20129 const char *section = ".dtors";
20130 char buf[16];
20131
20132 if (priority != DEFAULT_INIT_PRIORITY)
20133 {
20134 sprintf (buf, ".dtors.%.5u",
c4ad648e
AM
20135 /* Invert the numbering so the linker puts us in the proper
20136 order; constructors are run from right to left, and the
20137 linker sorts in increasing order. */
20138 MAX_INIT_PRIORITY - priority);
d9f6800d
RH
20139 section = buf;
20140 }
20141
d6b5193b 20142 switch_to_section (get_section (section, SECTION_WRITE, NULL));
715bdd29 20143 assemble_align (POINTER_SIZE);
d9f6800d
RH
20144
20145 if (TARGET_RELOCATABLE)
20146 {
20147 fputs ("\t.long (", asm_out_file);
20148 output_addr_const (asm_out_file, symbol);
20149 fputs (")@fixup\n", asm_out_file);
20150 }
20151 else
c8af3574 20152 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 20153}
9739c90c
JJ
20154
20155void
a2369ed3 20156rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
9739c90c
JJ
20157{
20158 if (TARGET_64BIT)
20159 {
20160 fputs ("\t.section\t\".opd\",\"aw\"\n\t.align 3\n", file);
20161 ASM_OUTPUT_LABEL (file, name);
20162 fputs (DOUBLE_INT_ASM_OP, file);
85b776df
AM
20163 rs6000_output_function_entry (file, name);
20164 fputs (",.TOC.@tocbase,0\n\t.previous\n", file);
20165 if (DOT_SYMBOLS)
9739c90c 20166 {
85b776df 20167 fputs ("\t.size\t", file);
9739c90c 20168 assemble_name (file, name);
85b776df
AM
20169 fputs (",24\n\t.type\t.", file);
20170 assemble_name (file, name);
20171 fputs (",@function\n", file);
20172 if (TREE_PUBLIC (decl) && ! DECL_WEAK (decl))
20173 {
20174 fputs ("\t.globl\t.", file);
20175 assemble_name (file, name);
20176 putc ('\n', file);
20177 }
9739c90c 20178 }
85b776df
AM
20179 else
20180 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
9739c90c 20181 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
85b776df
AM
20182 rs6000_output_function_entry (file, name);
20183 fputs (":\n", file);
9739c90c
JJ
20184 return;
20185 }
20186
20187 if (TARGET_RELOCATABLE
7f970b70 20188 && !TARGET_SECURE_PLT
9739c90c 20189 && (get_pool_size () != 0 || current_function_profile)
3c9eb5f4 20190 && uses_TOC ())
9739c90c
JJ
20191 {
20192 char buf[256];
20193
20194 (*targetm.asm_out.internal_label) (file, "LCL", rs6000_pic_labelno);
20195
20196 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
20197 fprintf (file, "\t.long ");
20198 assemble_name (file, buf);
20199 putc ('-', file);
20200 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
20201 assemble_name (file, buf);
20202 putc ('\n', file);
20203 }
20204
20205 ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
20206 ASM_DECLARE_RESULT (file, DECL_RESULT (decl));
20207
20208 if (DEFAULT_ABI == ABI_AIX)
20209 {
20210 const char *desc_name, *orig_name;
20211
20212 orig_name = (*targetm.strip_name_encoding) (name);
20213 desc_name = orig_name;
20214 while (*desc_name == '.')
20215 desc_name++;
20216
20217 if (TREE_PUBLIC (decl))
20218 fprintf (file, "\t.globl %s\n", desc_name);
20219
20220 fprintf (file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
20221 fprintf (file, "%s:\n", desc_name);
20222 fprintf (file, "\t.long %s\n", orig_name);
20223 fputs ("\t.long _GLOBAL_OFFSET_TABLE_\n", file);
20224 if (DEFAULT_ABI == ABI_AIX)
20225 fputs ("\t.long 0\n", file);
20226 fprintf (file, "\t.previous\n");
20227 }
20228 ASM_OUTPUT_LABEL (file, name);
20229}
1334b570
AM
20230
20231static void
20232rs6000_elf_end_indicate_exec_stack (void)
20233{
20234 if (TARGET_32BIT)
20235 file_end_indicate_exec_stack ();
20236}
7c262518
RH
20237#endif
20238
cbaaba19 20239#if TARGET_XCOFF
0d5817b2
DE
20240static void
20241rs6000_xcoff_asm_output_anchor (rtx symbol)
20242{
20243 char buffer[100];
20244
20245 sprintf (buffer, "$ + " HOST_WIDE_INT_PRINT_DEC,
20246 SYMBOL_REF_BLOCK_OFFSET (symbol));
20247 ASM_OUTPUT_DEF (asm_out_file, XSTR (symbol, 0), buffer);
20248}
20249
7c262518 20250static void
a2369ed3 20251rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
b275d088
DE
20252{
20253 fputs (GLOBAL_ASM_OP, stream);
20254 RS6000_OUTPUT_BASENAME (stream, name);
20255 putc ('\n', stream);
20256}
20257
d6b5193b
RS
20258/* A get_unnamed_decl callback, used for read-only sections. PTR
20259 points to the section string variable. */
20260
20261static void
20262rs6000_xcoff_output_readonly_section_asm_op (const void *directive)
20263{
890f9edf
OH
20264 fprintf (asm_out_file, "\t.csect %s[RO],%s\n",
20265 *(const char *const *) directive,
20266 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
d6b5193b
RS
20267}
20268
20269/* Likewise for read-write sections. */
20270
20271static void
20272rs6000_xcoff_output_readwrite_section_asm_op (const void *directive)
20273{
890f9edf
OH
20274 fprintf (asm_out_file, "\t.csect %s[RW],%s\n",
20275 *(const char *const *) directive,
20276 XCOFF_CSECT_DEFAULT_ALIGNMENT_STR);
d6b5193b
RS
20277}
20278
20279/* A get_unnamed_section callback, used for switching to toc_section. */
20280
20281static void
20282rs6000_xcoff_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
20283{
20284 if (TARGET_MINIMAL_TOC)
20285 {
20286 /* toc_section is always selected at least once from
20287 rs6000_xcoff_file_start, so this is guaranteed to
20288 always be defined once and only once in each file. */
20289 if (!toc_initialized)
20290 {
20291 fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);
20292 fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file);
20293 toc_initialized = 1;
20294 }
20295 fprintf (asm_out_file, "\t.csect toc_table[RW]%s\n",
20296 (TARGET_32BIT ? "" : ",3"));
20297 }
20298 else
20299 fputs ("\t.toc\n", asm_out_file);
20300}
20301
20302/* Implement TARGET_ASM_INIT_SECTIONS. */
20303
20304static void
20305rs6000_xcoff_asm_init_sections (void)
20306{
20307 read_only_data_section
20308 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
20309 &xcoff_read_only_section_name);
20310
20311 private_data_section
20312 = get_unnamed_section (SECTION_WRITE,
20313 rs6000_xcoff_output_readwrite_section_asm_op,
20314 &xcoff_private_data_section_name);
20315
20316 read_only_private_data_section
20317 = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
20318 &xcoff_private_data_section_name);
20319
20320 toc_section
20321 = get_unnamed_section (0, rs6000_xcoff_output_toc_section_asm_op, NULL);
20322
20323 readonly_data_section = read_only_data_section;
20324 exception_section = data_section;
20325}
20326
9b580a0b
RH
20327static int
20328rs6000_xcoff_reloc_rw_mask (void)
20329{
20330 return 3;
20331}
20332
b275d088 20333static void
c18a5b6c
MM
20334rs6000_xcoff_asm_named_section (const char *name, unsigned int flags,
20335 tree decl ATTRIBUTE_UNUSED)
7c262518 20336{
0e5dbd9b
DE
20337 int smclass;
20338 static const char * const suffix[3] = { "PR", "RO", "RW" };
20339
20340 if (flags & SECTION_CODE)
20341 smclass = 0;
20342 else if (flags & SECTION_WRITE)
20343 smclass = 2;
20344 else
20345 smclass = 1;
20346
5b5198f7 20347 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 20348 (flags & SECTION_CODE) ? "." : "",
5b5198f7 20349 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 20350}
ae46c4e0 20351
d6b5193b 20352static section *
f676971a 20353rs6000_xcoff_select_section (tree decl, int reloc,
c4ad648e 20354 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
ae46c4e0 20355{
9b580a0b 20356 if (decl_readonly_section (decl, reloc))
ae46c4e0 20357 {
0e5dbd9b 20358 if (TREE_PUBLIC (decl))
d6b5193b 20359 return read_only_data_section;
ae46c4e0 20360 else
d6b5193b 20361 return read_only_private_data_section;
ae46c4e0
RH
20362 }
20363 else
20364 {
0e5dbd9b 20365 if (TREE_PUBLIC (decl))
d6b5193b 20366 return data_section;
ae46c4e0 20367 else
d6b5193b 20368 return private_data_section;
ae46c4e0
RH
20369 }
20370}
20371
20372static void
a2369ed3 20373rs6000_xcoff_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
ae46c4e0
RH
20374{
20375 const char *name;
ae46c4e0 20376
5b5198f7
DE
20377 /* Use select_section for private and uninitialized data. */
20378 if (!TREE_PUBLIC (decl)
20379 || DECL_COMMON (decl)
0e5dbd9b
DE
20380 || DECL_INITIAL (decl) == NULL_TREE
20381 || DECL_INITIAL (decl) == error_mark_node
20382 || (flag_zero_initialized_in_bss
20383 && initializer_zerop (DECL_INITIAL (decl))))
20384 return;
20385
20386 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
20387 name = (*targetm.strip_name_encoding) (name);
20388 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 20389}
b64a1b53 20390
fb49053f
RH
20391/* Select section for constant in constant pool.
20392
20393 On RS/6000, all constants are in the private read-only data area.
20394 However, if this is being placed in the TOC it must be output as a
20395 toc entry. */
20396
d6b5193b 20397static section *
f676971a 20398rs6000_xcoff_select_rtx_section (enum machine_mode mode, rtx x,
c4ad648e 20399 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
b64a1b53
RH
20400{
20401 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
d6b5193b 20402 return toc_section;
b64a1b53 20403 else
d6b5193b 20404 return read_only_private_data_section;
b64a1b53 20405}
772c5265
RH
20406
20407/* Remove any trailing [DS] or the like from the symbol name. */
20408
20409static const char *
a2369ed3 20410rs6000_xcoff_strip_name_encoding (const char *name)
772c5265
RH
20411{
20412 size_t len;
20413 if (*name == '*')
20414 name++;
20415 len = strlen (name);
20416 if (name[len - 1] == ']')
20417 return ggc_alloc_string (name, len - 4);
20418 else
20419 return name;
20420}
20421
5add3202
DE
20422/* Section attributes. AIX is always PIC. */
20423
20424static unsigned int
a2369ed3 20425rs6000_xcoff_section_type_flags (tree decl, const char *name, int reloc)
5add3202 20426{
5b5198f7 20427 unsigned int align;
9b580a0b 20428 unsigned int flags = default_section_type_flags (decl, name, reloc);
5b5198f7
DE
20429
20430 /* Align to at least UNIT size. */
20431 if (flags & SECTION_CODE)
20432 align = MIN_UNITS_PER_WORD;
20433 else
20434 /* Increase alignment of large objects if not already stricter. */
20435 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
20436 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
20437 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
20438
20439 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202 20440}
a5fe455b 20441
1bc7c5b6
ZW
20442/* Output at beginning of assembler file.
20443
20444 Initialize the section names for the RS/6000 at this point.
20445
20446 Specify filename, including full path, to assembler.
20447
20448 We want to go into the TOC section so at least one .toc will be emitted.
20449 Also, in order to output proper .bs/.es pairs, we need at least one static
20450 [RW] section emitted.
20451
20452 Finally, declare mcount when profiling to make the assembler happy. */
20453
20454static void
863d938c 20455rs6000_xcoff_file_start (void)
1bc7c5b6
ZW
20456{
20457 rs6000_gen_section_name (&xcoff_bss_section_name,
20458 main_input_filename, ".bss_");
20459 rs6000_gen_section_name (&xcoff_private_data_section_name,
20460 main_input_filename, ".rw_");
20461 rs6000_gen_section_name (&xcoff_read_only_section_name,
20462 main_input_filename, ".ro_");
20463
20464 fputs ("\t.file\t", asm_out_file);
20465 output_quoted_string (asm_out_file, main_input_filename);
20466 fputc ('\n', asm_out_file);
1bc7c5b6 20467 if (write_symbols != NO_DEBUG)
d6b5193b
RS
20468 switch_to_section (private_data_section);
20469 switch_to_section (text_section);
1bc7c5b6
ZW
20470 if (profile_flag)
20471 fprintf (asm_out_file, "\t.extern %s\n", RS6000_MCOUNT);
20472 rs6000_file_start ();
20473}
20474
a5fe455b
ZW
20475/* Output at end of assembler file.
20476 On the RS/6000, referencing data should automatically pull in text. */
20477
20478static void
863d938c 20479rs6000_xcoff_file_end (void)
a5fe455b 20480{
d6b5193b 20481 switch_to_section (text_section);
a5fe455b 20482 fputs ("_section_.text:\n", asm_out_file);
d6b5193b 20483 switch_to_section (data_section);
a5fe455b
ZW
20484 fputs (TARGET_32BIT
20485 ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
20486 asm_out_file);
20487}
f1384257 20488#endif /* TARGET_XCOFF */
0e5dbd9b 20489
3c50106f
RH
20490/* Compute a (partial) cost for rtx X. Return true if the complete
20491 cost has been computed, and false if subexpressions should be
20492 scanned. In either case, *TOTAL contains the cost result. */
20493
20494static bool
1494c534 20495rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
3c50106f 20496{
f0517163
RS
20497 enum machine_mode mode = GET_MODE (x);
20498
3c50106f
RH
20499 switch (code)
20500 {
30a555d9 20501 /* On the RS/6000, if it is valid in the insn, it is free. */
3c50106f 20502 case CONST_INT:
066cd967
DE
20503 if (((outer_code == SET
20504 || outer_code == PLUS
20505 || outer_code == MINUS)
279bb624
DE
20506 && (satisfies_constraint_I (x)
20507 || satisfies_constraint_L (x)))
066cd967 20508 || (outer_code == AND
279bb624
DE
20509 && (satisfies_constraint_K (x)
20510 || (mode == SImode
20511 ? satisfies_constraint_L (x)
20512 : satisfies_constraint_J (x))
1990cd79
AM
20513 || mask_operand (x, mode)
20514 || (mode == DImode
20515 && mask64_operand (x, DImode))))
22e54023 20516 || ((outer_code == IOR || outer_code == XOR)
279bb624
DE
20517 && (satisfies_constraint_K (x)
20518 || (mode == SImode
20519 ? satisfies_constraint_L (x)
20520 : satisfies_constraint_J (x))))
066cd967
DE
20521 || outer_code == ASHIFT
20522 || outer_code == ASHIFTRT
20523 || outer_code == LSHIFTRT
20524 || outer_code == ROTATE
20525 || outer_code == ROTATERT
d5861a7a 20526 || outer_code == ZERO_EXTRACT
066cd967 20527 || (outer_code == MULT
279bb624 20528 && satisfies_constraint_I (x))
22e54023
DE
20529 || ((outer_code == DIV || outer_code == UDIV
20530 || outer_code == MOD || outer_code == UMOD)
20531 && exact_log2 (INTVAL (x)) >= 0)
066cd967 20532 || (outer_code == COMPARE
279bb624
DE
20533 && (satisfies_constraint_I (x)
20534 || satisfies_constraint_K (x)))
22e54023 20535 || (outer_code == EQ
279bb624
DE
20536 && (satisfies_constraint_I (x)
20537 || satisfies_constraint_K (x)
20538 || (mode == SImode
20539 ? satisfies_constraint_L (x)
20540 : satisfies_constraint_J (x))))
22e54023 20541 || (outer_code == GTU
279bb624 20542 && satisfies_constraint_I (x))
22e54023 20543 || (outer_code == LTU
279bb624 20544 && satisfies_constraint_P (x)))
066cd967
DE
20545 {
20546 *total = 0;
20547 return true;
20548 }
20549 else if ((outer_code == PLUS
4ae234b0 20550 && reg_or_add_cint_operand (x, VOIDmode))
066cd967 20551 || (outer_code == MINUS
4ae234b0 20552 && reg_or_sub_cint_operand (x, VOIDmode))
066cd967
DE
20553 || ((outer_code == SET
20554 || outer_code == IOR
20555 || outer_code == XOR)
20556 && (INTVAL (x)
20557 & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0))
20558 {
20559 *total = COSTS_N_INSNS (1);
20560 return true;
20561 }
20562 /* FALLTHRU */
20563
20564 case CONST_DOUBLE:
f6fe3a22 20565 if (mode == DImode && code == CONST_DOUBLE)
066cd967 20566 {
f6fe3a22
DE
20567 if ((outer_code == IOR || outer_code == XOR)
20568 && CONST_DOUBLE_HIGH (x) == 0
20569 && (CONST_DOUBLE_LOW (x)
20570 & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0)
20571 {
20572 *total = 0;
20573 return true;
20574 }
20575 else if ((outer_code == AND && and64_2_operand (x, DImode))
20576 || ((outer_code == SET
20577 || outer_code == IOR
20578 || outer_code == XOR)
20579 && CONST_DOUBLE_HIGH (x) == 0))
20580 {
20581 *total = COSTS_N_INSNS (1);
20582 return true;
20583 }
066cd967
DE
20584 }
20585 /* FALLTHRU */
20586
3c50106f 20587 case CONST:
066cd967 20588 case HIGH:
3c50106f 20589 case SYMBOL_REF:
066cd967
DE
20590 case MEM:
20591 /* When optimizing for size, MEM should be slightly more expensive
20592 than generating address, e.g., (plus (reg) (const)).
c112cf2b 20593 L1 cache latency is about two instructions. */
066cd967 20594 *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2);
3c50106f
RH
20595 return true;
20596
30a555d9
DE
20597 case LABEL_REF:
20598 *total = 0;
20599 return true;
20600
3c50106f 20601 case PLUS:
f0517163 20602 if (mode == DFmode)
066cd967
DE
20603 {
20604 if (GET_CODE (XEXP (x, 0)) == MULT)
20605 {
20606 /* FNMA accounted in outer NEG. */
20607 if (outer_code == NEG)
20608 *total = rs6000_cost->dmul - rs6000_cost->fp;
20609 else
20610 *total = rs6000_cost->dmul;
20611 }
20612 else
20613 *total = rs6000_cost->fp;
20614 }
f0517163 20615 else if (mode == SFmode)
066cd967
DE
20616 {
20617 /* FNMA accounted in outer NEG. */
20618 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
20619 *total = 0;
20620 else
20621 *total = rs6000_cost->fp;
20622 }
f0517163 20623 else
066cd967
DE
20624 *total = COSTS_N_INSNS (1);
20625 return false;
3c50106f 20626
52190329 20627 case MINUS:
f0517163 20628 if (mode == DFmode)
066cd967 20629 {
762c919f
JM
20630 if (GET_CODE (XEXP (x, 0)) == MULT
20631 || GET_CODE (XEXP (x, 1)) == MULT)
066cd967
DE
20632 {
20633 /* FNMA accounted in outer NEG. */
20634 if (outer_code == NEG)
762c919f 20635 *total = rs6000_cost->dmul - rs6000_cost->fp;
066cd967
DE
20636 else
20637 *total = rs6000_cost->dmul;
20638 }
20639 else
20640 *total = rs6000_cost->fp;
20641 }
f0517163 20642 else if (mode == SFmode)
066cd967
DE
20643 {
20644 /* FNMA accounted in outer NEG. */
20645 if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT)
20646 *total = 0;
20647 else
20648 *total = rs6000_cost->fp;
20649 }
f0517163 20650 else
c4ad648e 20651 *total = COSTS_N_INSNS (1);
066cd967 20652 return false;
3c50106f
RH
20653
20654 case MULT:
c9dbf840 20655 if (GET_CODE (XEXP (x, 1)) == CONST_INT
279bb624 20656 && satisfies_constraint_I (XEXP (x, 1)))
3c50106f 20657 {
8b897cfa
RS
20658 if (INTVAL (XEXP (x, 1)) >= -256
20659 && INTVAL (XEXP (x, 1)) <= 255)
06a67bdd 20660 *total = rs6000_cost->mulsi_const9;
8b897cfa 20661 else
06a67bdd 20662 *total = rs6000_cost->mulsi_const;
3c50106f 20663 }
066cd967
DE
20664 /* FMA accounted in outer PLUS/MINUS. */
20665 else if ((mode == DFmode || mode == SFmode)
20666 && (outer_code == PLUS || outer_code == MINUS))
20667 *total = 0;
f0517163 20668 else if (mode == DFmode)
06a67bdd 20669 *total = rs6000_cost->dmul;
f0517163 20670 else if (mode == SFmode)
06a67bdd 20671 *total = rs6000_cost->fp;
f0517163 20672 else if (mode == DImode)
06a67bdd 20673 *total = rs6000_cost->muldi;
8b897cfa 20674 else
06a67bdd 20675 *total = rs6000_cost->mulsi;
066cd967 20676 return false;
3c50106f
RH
20677
20678 case DIV:
20679 case MOD:
f0517163
RS
20680 if (FLOAT_MODE_P (mode))
20681 {
06a67bdd
RS
20682 *total = mode == DFmode ? rs6000_cost->ddiv
20683 : rs6000_cost->sdiv;
066cd967 20684 return false;
f0517163 20685 }
5efb1046 20686 /* FALLTHRU */
3c50106f
RH
20687
20688 case UDIV:
20689 case UMOD:
627b6fe2
DJ
20690 if (GET_CODE (XEXP (x, 1)) == CONST_INT
20691 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
20692 {
20693 if (code == DIV || code == MOD)
20694 /* Shift, addze */
20695 *total = COSTS_N_INSNS (2);
20696 else
20697 /* Shift */
20698 *total = COSTS_N_INSNS (1);
20699 }
c4ad648e 20700 else
627b6fe2
DJ
20701 {
20702 if (GET_MODE (XEXP (x, 1)) == DImode)
20703 *total = rs6000_cost->divdi;
20704 else
20705 *total = rs6000_cost->divsi;
20706 }
20707 /* Add in shift and subtract for MOD. */
20708 if (code == MOD || code == UMOD)
20709 *total += COSTS_N_INSNS (2);
066cd967 20710 return false;
3c50106f 20711
32f56aad 20712 case CTZ:
3c50106f
RH
20713 case FFS:
20714 *total = COSTS_N_INSNS (4);
066cd967 20715 return false;
3c50106f 20716
32f56aad
DE
20717 case POPCOUNT:
20718 *total = COSTS_N_INSNS (6);
20719 return false;
20720
06a67bdd 20721 case NOT:
066cd967
DE
20722 if (outer_code == AND || outer_code == IOR || outer_code == XOR)
20723 {
20724 *total = 0;
20725 return false;
20726 }
20727 /* FALLTHRU */
20728
20729 case AND:
32f56aad 20730 case CLZ:
066cd967
DE
20731 case IOR:
20732 case XOR:
d5861a7a
DE
20733 case ZERO_EXTRACT:
20734 *total = COSTS_N_INSNS (1);
20735 return false;
20736
066cd967
DE
20737 case ASHIFT:
20738 case ASHIFTRT:
20739 case LSHIFTRT:
20740 case ROTATE:
20741 case ROTATERT:
d5861a7a 20742 /* Handle mul_highpart. */
066cd967
DE
20743 if (outer_code == TRUNCATE
20744 && GET_CODE (XEXP (x, 0)) == MULT)
20745 {
20746 if (mode == DImode)
20747 *total = rs6000_cost->muldi;
20748 else
20749 *total = rs6000_cost->mulsi;
20750 return true;
20751 }
d5861a7a
DE
20752 else if (outer_code == AND)
20753 *total = 0;
20754 else
20755 *total = COSTS_N_INSNS (1);
20756 return false;
20757
20758 case SIGN_EXTEND:
20759 case ZERO_EXTEND:
20760 if (GET_CODE (XEXP (x, 0)) == MEM)
20761 *total = 0;
20762 else
20763 *total = COSTS_N_INSNS (1);
066cd967 20764 return false;
06a67bdd 20765
066cd967
DE
20766 case COMPARE:
20767 case NEG:
20768 case ABS:
20769 if (!FLOAT_MODE_P (mode))
20770 {
20771 *total = COSTS_N_INSNS (1);
20772 return false;
20773 }
20774 /* FALLTHRU */
20775
20776 case FLOAT:
20777 case UNSIGNED_FLOAT:
20778 case FIX:
20779 case UNSIGNED_FIX:
06a67bdd
RS
20780 case FLOAT_TRUNCATE:
20781 *total = rs6000_cost->fp;
066cd967 20782 return false;
06a67bdd 20783
a2af5043
DJ
20784 case FLOAT_EXTEND:
20785 if (mode == DFmode)
20786 *total = 0;
20787 else
20788 *total = rs6000_cost->fp;
20789 return false;
20790
06a67bdd
RS
20791 case UNSPEC:
20792 switch (XINT (x, 1))
20793 {
20794 case UNSPEC_FRSP:
20795 *total = rs6000_cost->fp;
20796 return true;
20797
20798 default:
20799 break;
20800 }
20801 break;
20802
20803 case CALL:
20804 case IF_THEN_ELSE:
20805 if (optimize_size)
20806 {
20807 *total = COSTS_N_INSNS (1);
20808 return true;
20809 }
066cd967
DE
20810 else if (FLOAT_MODE_P (mode)
20811 && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
20812 {
20813 *total = rs6000_cost->fp;
20814 return false;
20815 }
06a67bdd
RS
20816 break;
20817
c0600ecd
DE
20818 case EQ:
20819 case GTU:
20820 case LTU:
22e54023
DE
20821 /* Carry bit requires mode == Pmode.
20822 NEG or PLUS already counted so only add one. */
20823 if (mode == Pmode
20824 && (outer_code == NEG || outer_code == PLUS))
c0600ecd 20825 {
22e54023
DE
20826 *total = COSTS_N_INSNS (1);
20827 return true;
20828 }
20829 if (outer_code == SET)
20830 {
20831 if (XEXP (x, 1) == const0_rtx)
c0600ecd 20832 {
22e54023 20833 *total = COSTS_N_INSNS (2);
c0600ecd 20834 return true;
c0600ecd 20835 }
22e54023
DE
20836 else if (mode == Pmode)
20837 {
20838 *total = COSTS_N_INSNS (3);
20839 return false;
20840 }
20841 }
20842 /* FALLTHRU */
20843
20844 case GT:
20845 case LT:
20846 case UNORDERED:
20847 if (outer_code == SET && (XEXP (x, 1) == const0_rtx))
20848 {
20849 *total = COSTS_N_INSNS (2);
20850 return true;
c0600ecd 20851 }
22e54023
DE
20852 /* CC COMPARE. */
20853 if (outer_code == COMPARE)
20854 {
20855 *total = 0;
20856 return true;
20857 }
20858 break;
c0600ecd 20859
3c50106f 20860 default:
06a67bdd 20861 break;
3c50106f 20862 }
06a67bdd
RS
20863
20864 return false;
3c50106f
RH
20865}
20866
34bb030a
DE
20867/* A C expression returning the cost of moving data from a register of class
20868 CLASS1 to one of CLASS2. */
20869
20870int
f676971a 20871rs6000_register_move_cost (enum machine_mode mode,
a2369ed3 20872 enum reg_class from, enum reg_class to)
34bb030a
DE
20873{
20874 /* Moves from/to GENERAL_REGS. */
20875 if (reg_classes_intersect_p (to, GENERAL_REGS)
20876 || reg_classes_intersect_p (from, GENERAL_REGS))
20877 {
20878 if (! reg_classes_intersect_p (to, GENERAL_REGS))
20879 from = to;
20880
20881 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
20882 return (rs6000_memory_move_cost (mode, from, 0)
20883 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
20884
c4ad648e
AM
20885 /* It's more expensive to move CR_REGS than CR0_REGS because of the
20886 shift. */
34bb030a
DE
20887 else if (from == CR_REGS)
20888 return 4;
20889
20890 else
c4ad648e 20891 /* A move will cost one instruction per GPR moved. */
c8b622ff 20892 return 2 * hard_regno_nregs[0][mode];
34bb030a
DE
20893 }
20894
c4ad648e 20895 /* Moving between two similar registers is just one instruction. */
34bb030a 20896 else if (reg_classes_intersect_p (to, from))
7393f7f8 20897 return (mode == TFmode || mode == TDmode) ? 4 : 2;
34bb030a 20898
c4ad648e 20899 /* Everything else has to go through GENERAL_REGS. */
34bb030a 20900 else
f676971a 20901 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
34bb030a
DE
20902 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
20903}
20904
20905/* A C expressions returning the cost of moving data of MODE from a register to
20906 or from memory. */
20907
20908int
f676971a 20909rs6000_memory_move_cost (enum machine_mode mode, enum reg_class class,
a2369ed3 20910 int in ATTRIBUTE_UNUSED)
34bb030a
DE
20911{
20912 if (reg_classes_intersect_p (class, GENERAL_REGS))
c8b622ff 20913 return 4 * hard_regno_nregs[0][mode];
34bb030a 20914 else if (reg_classes_intersect_p (class, FLOAT_REGS))
c8b622ff 20915 return 4 * hard_regno_nregs[32][mode];
34bb030a 20916 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
c8b622ff 20917 return 4 * hard_regno_nregs[FIRST_ALTIVEC_REGNO][mode];
34bb030a
DE
20918 else
20919 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
20920}
20921
9c78b944
DE
20922/* Returns a code for a target-specific builtin that implements
20923 reciprocal of the function, or NULL_TREE if not available. */
20924
20925static tree
20926rs6000_builtin_reciprocal (unsigned int fn, bool md_fn,
20927 bool sqrt ATTRIBUTE_UNUSED)
20928{
20929 if (! (TARGET_RECIP && TARGET_PPC_GFXOPT && !optimize_size
20930 && flag_finite_math_only && !flag_trapping_math
20931 && flag_unsafe_math_optimizations))
20932 return NULL_TREE;
20933
20934 if (md_fn)
20935 return NULL_TREE;
20936 else
20937 switch (fn)
20938 {
20939 case BUILT_IN_SQRTF:
20940 return rs6000_builtin_decls[RS6000_BUILTIN_RSQRTF];
20941
20942 default:
20943 return NULL_TREE;
20944 }
20945}
20946
ef765ea9
DE
20947/* Newton-Raphson approximation of single-precision floating point divide n/d.
20948 Assumes no trapping math and finite arguments. */
20949
20950void
9c78b944 20951rs6000_emit_swdivsf (rtx dst, rtx n, rtx d)
ef765ea9
DE
20952{
20953 rtx x0, e0, e1, y1, u0, v0, one;
20954
20955 x0 = gen_reg_rtx (SFmode);
20956 e0 = gen_reg_rtx (SFmode);
20957 e1 = gen_reg_rtx (SFmode);
20958 y1 = gen_reg_rtx (SFmode);
20959 u0 = gen_reg_rtx (SFmode);
20960 v0 = gen_reg_rtx (SFmode);
20961 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
20962
20963 /* x0 = 1./d estimate */
20964 emit_insn (gen_rtx_SET (VOIDmode, x0,
20965 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, d),
20966 UNSPEC_FRES)));
20967 /* e0 = 1. - d * x0 */
20968 emit_insn (gen_rtx_SET (VOIDmode, e0,
20969 gen_rtx_MINUS (SFmode, one,
20970 gen_rtx_MULT (SFmode, d, x0))));
20971 /* e1 = e0 + e0 * e0 */
20972 emit_insn (gen_rtx_SET (VOIDmode, e1,
20973 gen_rtx_PLUS (SFmode,
20974 gen_rtx_MULT (SFmode, e0, e0), e0)));
20975 /* y1 = x0 + e1 * x0 */
20976 emit_insn (gen_rtx_SET (VOIDmode, y1,
20977 gen_rtx_PLUS (SFmode,
20978 gen_rtx_MULT (SFmode, e1, x0), x0)));
20979 /* u0 = n * y1 */
20980 emit_insn (gen_rtx_SET (VOIDmode, u0,
20981 gen_rtx_MULT (SFmode, n, y1)));
20982 /* v0 = n - d * u0 */
20983 emit_insn (gen_rtx_SET (VOIDmode, v0,
20984 gen_rtx_MINUS (SFmode, n,
20985 gen_rtx_MULT (SFmode, d, u0))));
9c78b944
DE
20986 /* dst = u0 + v0 * y1 */
20987 emit_insn (gen_rtx_SET (VOIDmode, dst,
ef765ea9
DE
20988 gen_rtx_PLUS (SFmode,
20989 gen_rtx_MULT (SFmode, v0, y1), u0)));
20990}
20991
20992/* Newton-Raphson approximation of double-precision floating point divide n/d.
20993 Assumes no trapping math and finite arguments. */
20994
20995void
9c78b944 20996rs6000_emit_swdivdf (rtx dst, rtx n, rtx d)
ef765ea9
DE
20997{
20998 rtx x0, e0, e1, e2, y1, y2, y3, u0, v0, one;
20999
21000 x0 = gen_reg_rtx (DFmode);
21001 e0 = gen_reg_rtx (DFmode);
21002 e1 = gen_reg_rtx (DFmode);
21003 e2 = gen_reg_rtx (DFmode);
21004 y1 = gen_reg_rtx (DFmode);
21005 y2 = gen_reg_rtx (DFmode);
21006 y3 = gen_reg_rtx (DFmode);
21007 u0 = gen_reg_rtx (DFmode);
21008 v0 = gen_reg_rtx (DFmode);
21009 one = force_reg (DFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, DFmode));
21010
21011 /* x0 = 1./d estimate */
21012 emit_insn (gen_rtx_SET (VOIDmode, x0,
21013 gen_rtx_UNSPEC (DFmode, gen_rtvec (1, d),
21014 UNSPEC_FRES)));
21015 /* e0 = 1. - d * x0 */
21016 emit_insn (gen_rtx_SET (VOIDmode, e0,
21017 gen_rtx_MINUS (DFmode, one,
21018 gen_rtx_MULT (SFmode, d, x0))));
21019 /* y1 = x0 + e0 * x0 */
21020 emit_insn (gen_rtx_SET (VOIDmode, y1,
21021 gen_rtx_PLUS (DFmode,
21022 gen_rtx_MULT (DFmode, e0, x0), x0)));
21023 /* e1 = e0 * e0 */
21024 emit_insn (gen_rtx_SET (VOIDmode, e1,
21025 gen_rtx_MULT (DFmode, e0, e0)));
21026 /* y2 = y1 + e1 * y1 */
21027 emit_insn (gen_rtx_SET (VOIDmode, y2,
21028 gen_rtx_PLUS (DFmode,
21029 gen_rtx_MULT (DFmode, e1, y1), y1)));
21030 /* e2 = e1 * e1 */
21031 emit_insn (gen_rtx_SET (VOIDmode, e2,
21032 gen_rtx_MULT (DFmode, e1, e1)));
21033 /* y3 = y2 + e2 * y2 */
21034 emit_insn (gen_rtx_SET (VOIDmode, y3,
21035 gen_rtx_PLUS (DFmode,
21036 gen_rtx_MULT (DFmode, e2, y2), y2)));
21037 /* u0 = n * y3 */
21038 emit_insn (gen_rtx_SET (VOIDmode, u0,
21039 gen_rtx_MULT (DFmode, n, y3)));
21040 /* v0 = n - d * u0 */
21041 emit_insn (gen_rtx_SET (VOIDmode, v0,
21042 gen_rtx_MINUS (DFmode, n,
21043 gen_rtx_MULT (DFmode, d, u0))));
9c78b944
DE
21044 /* dst = u0 + v0 * y3 */
21045 emit_insn (gen_rtx_SET (VOIDmode, dst,
ef765ea9
DE
21046 gen_rtx_PLUS (DFmode,
21047 gen_rtx_MULT (DFmode, v0, y3), u0)));
21048}
21049
565ef4ba 21050
9c78b944
DE
21051/* Newton-Raphson approximation of single-precision floating point rsqrt.
21052 Assumes no trapping math and finite arguments. */
21053
21054void
21055rs6000_emit_swrsqrtsf (rtx dst, rtx src)
21056{
21057 rtx x0, x1, x2, y1, u0, u1, u2, v0, v1, v2, t0,
21058 half, one, halfthree, c1, cond, label;
21059
21060 x0 = gen_reg_rtx (SFmode);
21061 x1 = gen_reg_rtx (SFmode);
21062 x2 = gen_reg_rtx (SFmode);
21063 y1 = gen_reg_rtx (SFmode);
21064 u0 = gen_reg_rtx (SFmode);
21065 u1 = gen_reg_rtx (SFmode);
21066 u2 = gen_reg_rtx (SFmode);
21067 v0 = gen_reg_rtx (SFmode);
21068 v1 = gen_reg_rtx (SFmode);
21069 v2 = gen_reg_rtx (SFmode);
21070 t0 = gen_reg_rtx (SFmode);
21071 halfthree = gen_reg_rtx (SFmode);
21072 cond = gen_rtx_REG (CCFPmode, CR1_REGNO);
21073 label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
21074
21075 /* check 0.0, 1.0, NaN, Inf by testing src * src = src */
21076 emit_insn (gen_rtx_SET (VOIDmode, t0,
21077 gen_rtx_MULT (SFmode, src, src)));
21078
21079 emit_insn (gen_rtx_SET (VOIDmode, cond,
21080 gen_rtx_COMPARE (CCFPmode, t0, src)));
21081 c1 = gen_rtx_EQ (VOIDmode, cond, const0_rtx);
21082 emit_unlikely_jump (c1, label);
21083
21084 half = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconsthalf, SFmode));
21085 one = force_reg (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (dconst1, SFmode));
21086
21087 /* halfthree = 1.5 = 1.0 + 0.5 */
21088 emit_insn (gen_rtx_SET (VOIDmode, halfthree,
21089 gen_rtx_PLUS (SFmode, one, half)));
21090
21091 /* x0 = rsqrt estimate */
21092 emit_insn (gen_rtx_SET (VOIDmode, x0,
21093 gen_rtx_UNSPEC (SFmode, gen_rtvec (1, src),
21094 UNSPEC_RSQRT)));
21095
21096 /* y1 = 0.5 * src = 1.5 * src - src -> fewer constants */
21097 emit_insn (gen_rtx_SET (VOIDmode, y1,
21098 gen_rtx_MINUS (SFmode,
21099 gen_rtx_MULT (SFmode, src, halfthree),
21100 src)));
21101
21102 /* x1 = x0 * (1.5 - y1 * (x0 * x0)) */
21103 emit_insn (gen_rtx_SET (VOIDmode, u0,
21104 gen_rtx_MULT (SFmode, x0, x0)));
21105 emit_insn (gen_rtx_SET (VOIDmode, v0,
21106 gen_rtx_MINUS (SFmode,
21107 halfthree,
21108 gen_rtx_MULT (SFmode, y1, u0))));
21109 emit_insn (gen_rtx_SET (VOIDmode, x1,
21110 gen_rtx_MULT (SFmode, x0, v0)));
21111
21112 /* x2 = x1 * (1.5 - y1 * (x1 * x1)) */
21113 emit_insn (gen_rtx_SET (VOIDmode, u1,
21114 gen_rtx_MULT (SFmode, x1, x1)));
21115 emit_insn (gen_rtx_SET (VOIDmode, v1,
21116 gen_rtx_MINUS (SFmode,
21117 halfthree,
21118 gen_rtx_MULT (SFmode, y1, u1))));
21119 emit_insn (gen_rtx_SET (VOIDmode, x2,
21120 gen_rtx_MULT (SFmode, x1, v1)));
21121
21122 /* dst = x2 * (1.5 - y1 * (x2 * x2)) */
21123 emit_insn (gen_rtx_SET (VOIDmode, u2,
21124 gen_rtx_MULT (SFmode, x2, x2)));
21125 emit_insn (gen_rtx_SET (VOIDmode, v2,
21126 gen_rtx_MINUS (SFmode,
21127 halfthree,
21128 gen_rtx_MULT (SFmode, y1, u2))));
21129 emit_insn (gen_rtx_SET (VOIDmode, dst,
21130 gen_rtx_MULT (SFmode, x2, v2)));
21131
21132 emit_label (XEXP (label, 0));
21133}
21134
565ef4ba
RS
21135/* Emit popcount intrinsic on TARGET_POPCNTB targets. DST is the
21136 target, and SRC is the argument operand. */
21137
21138void
21139rs6000_emit_popcount (rtx dst, rtx src)
21140{
21141 enum machine_mode mode = GET_MODE (dst);
21142 rtx tmp1, tmp2;
21143
21144 tmp1 = gen_reg_rtx (mode);
21145
21146 if (mode == SImode)
21147 {
21148 emit_insn (gen_popcntbsi2 (tmp1, src));
21149 tmp2 = expand_mult (SImode, tmp1, GEN_INT (0x01010101),
21150 NULL_RTX, 0);
21151 tmp2 = force_reg (SImode, tmp2);
21152 emit_insn (gen_lshrsi3 (dst, tmp2, GEN_INT (24)));
21153 }
21154 else
21155 {
21156 emit_insn (gen_popcntbdi2 (tmp1, src));
21157 tmp2 = expand_mult (DImode, tmp1,
21158 GEN_INT ((HOST_WIDE_INT)
21159 0x01010101 << 32 | 0x01010101),
21160 NULL_RTX, 0);
21161 tmp2 = force_reg (DImode, tmp2);
21162 emit_insn (gen_lshrdi3 (dst, tmp2, GEN_INT (56)));
21163 }
21164}
21165
21166
21167/* Emit parity intrinsic on TARGET_POPCNTB targets. DST is the
21168 target, and SRC is the argument operand. */
21169
21170void
21171rs6000_emit_parity (rtx dst, rtx src)
21172{
21173 enum machine_mode mode = GET_MODE (dst);
21174 rtx tmp;
21175
21176 tmp = gen_reg_rtx (mode);
21177 if (mode == SImode)
21178 {
21179 /* Is mult+shift >= shift+xor+shift+xor? */
21180 if (rs6000_cost->mulsi_const >= COSTS_N_INSNS (3))
21181 {
21182 rtx tmp1, tmp2, tmp3, tmp4;
21183
21184 tmp1 = gen_reg_rtx (SImode);
21185 emit_insn (gen_popcntbsi2 (tmp1, src));
21186
21187 tmp2 = gen_reg_rtx (SImode);
21188 emit_insn (gen_lshrsi3 (tmp2, tmp1, GEN_INT (16)));
21189 tmp3 = gen_reg_rtx (SImode);
21190 emit_insn (gen_xorsi3 (tmp3, tmp1, tmp2));
21191
21192 tmp4 = gen_reg_rtx (SImode);
21193 emit_insn (gen_lshrsi3 (tmp4, tmp3, GEN_INT (8)));
21194 emit_insn (gen_xorsi3 (tmp, tmp3, tmp4));
21195 }
21196 else
21197 rs6000_emit_popcount (tmp, src);
21198 emit_insn (gen_andsi3 (dst, tmp, const1_rtx));
21199 }
21200 else
21201 {
21202 /* Is mult+shift >= shift+xor+shift+xor+shift+xor? */
21203 if (rs6000_cost->muldi >= COSTS_N_INSNS (5))
21204 {
21205 rtx tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
21206
21207 tmp1 = gen_reg_rtx (DImode);
21208 emit_insn (gen_popcntbdi2 (tmp1, src));
21209
21210 tmp2 = gen_reg_rtx (DImode);
21211 emit_insn (gen_lshrdi3 (tmp2, tmp1, GEN_INT (32)));
21212 tmp3 = gen_reg_rtx (DImode);
21213 emit_insn (gen_xordi3 (tmp3, tmp1, tmp2));
21214
21215 tmp4 = gen_reg_rtx (DImode);
21216 emit_insn (gen_lshrdi3 (tmp4, tmp3, GEN_INT (16)));
21217 tmp5 = gen_reg_rtx (DImode);
21218 emit_insn (gen_xordi3 (tmp5, tmp3, tmp4));
21219
21220 tmp6 = gen_reg_rtx (DImode);
21221 emit_insn (gen_lshrdi3 (tmp6, tmp5, GEN_INT (8)));
21222 emit_insn (gen_xordi3 (tmp, tmp5, tmp6));
21223 }
21224 else
21225 rs6000_emit_popcount (tmp, src);
21226 emit_insn (gen_anddi3 (dst, tmp, const1_rtx));
21227 }
21228}
21229
ded9bf77
AH
21230/* Return an RTX representing where to find the function value of a
21231 function returning MODE. */
21232static rtx
21233rs6000_complex_function_value (enum machine_mode mode)
21234{
21235 unsigned int regno;
21236 rtx r1, r2;
21237 enum machine_mode inner = GET_MODE_INNER (mode);
fb7e4164 21238 unsigned int inner_bytes = GET_MODE_SIZE (inner);
ded9bf77 21239
18f63bfa
AH
21240 if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
21241 regno = FP_ARG_RETURN;
354ed18f
AH
21242 else
21243 {
18f63bfa 21244 regno = GP_ARG_RETURN;
ded9bf77 21245
18f63bfa
AH
21246 /* 32-bit is OK since it'll go in r3/r4. */
21247 if (TARGET_32BIT && inner_bytes >= 4)
ded9bf77
AH
21248 return gen_rtx_REG (mode, regno);
21249 }
21250
18f63bfa
AH
21251 if (inner_bytes >= 8)
21252 return gen_rtx_REG (mode, regno);
21253
ded9bf77
AH
21254 r1 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno),
21255 const0_rtx);
21256 r2 = gen_rtx_EXPR_LIST (inner, gen_rtx_REG (inner, regno + 1),
fb7e4164 21257 GEN_INT (inner_bytes));
ded9bf77
AH
21258 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
21259}
21260
a6ebc39a
AH
21261/* Define how to find the value returned by a function.
21262 VALTYPE is the data type of the value (as a tree).
21263 If the precise function being called is known, FUNC is its FUNCTION_DECL;
21264 otherwise, FUNC is 0.
21265
21266 On the SPE, both FPs and vectors are returned in r3.
21267
21268 On RS/6000 an integer value is in r3 and a floating-point value is in
21269 fp1, unless -msoft-float. */
21270
21271rtx
586de218 21272rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
a6ebc39a
AH
21273{
21274 enum machine_mode mode;
2a8fa26c 21275 unsigned int regno;
a6ebc39a 21276
594a51fe
SS
21277 /* Special handling for structs in darwin64. */
21278 if (rs6000_darwin64_abi
21279 && TYPE_MODE (valtype) == BLKmode
0b5383eb
DJ
21280 && TREE_CODE (valtype) == RECORD_TYPE
21281 && int_size_in_bytes (valtype) > 0)
594a51fe
SS
21282 {
21283 CUMULATIVE_ARGS valcum;
21284 rtx valret;
21285
0b5383eb 21286 valcum.words = 0;
594a51fe
SS
21287 valcum.fregno = FP_ARG_MIN_REG;
21288 valcum.vregno = ALTIVEC_ARG_MIN_REG;
0b5383eb
DJ
21289 /* Do a trial code generation as if this were going to be passed as
21290 an argument; if any part goes in memory, we return NULL. */
21291 valret = rs6000_darwin64_record_arg (&valcum, valtype, 1, true);
594a51fe
SS
21292 if (valret)
21293 return valret;
21294 /* Otherwise fall through to standard ABI rules. */
21295 }
21296
0e67400a
FJ
21297 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
21298 {
21299 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21300 return gen_rtx_PARALLEL (DImode,
21301 gen_rtvec (2,
21302 gen_rtx_EXPR_LIST (VOIDmode,
21303 gen_rtx_REG (SImode, GP_ARG_RETURN),
21304 const0_rtx),
21305 gen_rtx_EXPR_LIST (VOIDmode,
21306 gen_rtx_REG (SImode,
21307 GP_ARG_RETURN + 1),
21308 GEN_INT (4))));
21309 }
0f086e42
FJ
21310 if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
21311 {
21312 return gen_rtx_PARALLEL (DCmode,
21313 gen_rtvec (4,
21314 gen_rtx_EXPR_LIST (VOIDmode,
21315 gen_rtx_REG (SImode, GP_ARG_RETURN),
21316 const0_rtx),
21317 gen_rtx_EXPR_LIST (VOIDmode,
21318 gen_rtx_REG (SImode,
21319 GP_ARG_RETURN + 1),
21320 GEN_INT (4)),
21321 gen_rtx_EXPR_LIST (VOIDmode,
21322 gen_rtx_REG (SImode,
21323 GP_ARG_RETURN + 2),
21324 GEN_INT (8)),
21325 gen_rtx_EXPR_LIST (VOIDmode,
21326 gen_rtx_REG (SImode,
21327 GP_ARG_RETURN + 3),
21328 GEN_INT (12))));
21329 }
602ea4d3 21330
7348aa7f
FXC
21331 mode = TYPE_MODE (valtype);
21332 if ((INTEGRAL_TYPE_P (valtype) && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
a6ebc39a 21333 || POINTER_TYPE_P (valtype))
b78d48dd 21334 mode = TARGET_32BIT ? SImode : DImode;
a6ebc39a 21335
00b79d54 21336 if (DECIMAL_FLOAT_MODE_P (mode))
7393f7f8
BE
21337 {
21338 if (TARGET_HARD_FLOAT && TARGET_FPRS)
21339 {
21340 switch (mode)
21341 {
21342 default:
21343 gcc_unreachable ();
21344 case SDmode:
21345 regno = GP_ARG_RETURN;
21346 break;
21347 case DDmode:
21348 regno = FP_ARG_RETURN;
21349 break;
21350 case TDmode:
21351 /* Use f2:f3 specified by the ABI. */
21352 regno = FP_ARG_RETURN + 1;
21353 break;
21354 }
21355 }
21356 else
21357 regno = GP_ARG_RETURN;
21358 }
00b79d54 21359 else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
2a8fa26c 21360 regno = FP_ARG_RETURN;
ded9bf77 21361 else if (TREE_CODE (valtype) == COMPLEX_TYPE
42ba5130 21362 && targetm.calls.split_complex_arg)
ded9bf77 21363 return rs6000_complex_function_value (mode);
44688022 21364 else if (TREE_CODE (valtype) == VECTOR_TYPE
d0b2079e 21365 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI
23ba09f0 21366 && ALTIVEC_VECTOR_MODE (mode))
a6ebc39a 21367 regno = ALTIVEC_ARG_RETURN;
18f63bfa 21368 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
17caeff2
JM
21369 && (mode == DFmode || mode == DCmode
21370 || mode == TFmode || mode == TCmode))
18f63bfa 21371 return spe_build_register_parallel (mode, GP_ARG_RETURN);
a6ebc39a
AH
21372 else
21373 regno = GP_ARG_RETURN;
21374
21375 return gen_rtx_REG (mode, regno);
21376}
21377
ded9bf77
AH
21378/* Define how to find the value returned by a library function
21379 assuming the value has mode MODE. */
21380rtx
21381rs6000_libcall_value (enum machine_mode mode)
21382{
21383 unsigned int regno;
21384
2e6c9641
FJ
21385 if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode)
21386 {
21387 /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
21388 return gen_rtx_PARALLEL (DImode,
21389 gen_rtvec (2,
21390 gen_rtx_EXPR_LIST (VOIDmode,
21391 gen_rtx_REG (SImode, GP_ARG_RETURN),
21392 const0_rtx),
21393 gen_rtx_EXPR_LIST (VOIDmode,
21394 gen_rtx_REG (SImode,
21395 GP_ARG_RETURN + 1),
21396 GEN_INT (4))));
21397 }
21398
00b79d54 21399 if (DECIMAL_FLOAT_MODE_P (mode))
7393f7f8
BE
21400 {
21401 if (TARGET_HARD_FLOAT && TARGET_FPRS)
21402 {
21403 switch (mode)
21404 {
21405 default:
21406 gcc_unreachable ();
21407 case SDmode:
21408 regno = GP_ARG_RETURN;
21409 break;
21410 case DDmode:
21411 regno = FP_ARG_RETURN;
21412 break;
21413 case TDmode:
21414 /* Use f2:f3 specified by the ABI. */
21415 regno = FP_ARG_RETURN + 1;
21416 break;
21417 }
21418 }
21419 else
21420 regno = GP_ARG_RETURN;
21421 }
00b79d54 21422 else if (SCALAR_FLOAT_MODE_P (mode)
ded9bf77
AH
21423 && TARGET_HARD_FLOAT && TARGET_FPRS)
21424 regno = FP_ARG_RETURN;
44688022
AM
21425 else if (ALTIVEC_VECTOR_MODE (mode)
21426 && TARGET_ALTIVEC && TARGET_ALTIVEC_ABI)
ded9bf77 21427 regno = ALTIVEC_ARG_RETURN;
42ba5130 21428 else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
ded9bf77 21429 return rs6000_complex_function_value (mode);
18f63bfa 21430 else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
17caeff2
JM
21431 && (mode == DFmode || mode == DCmode
21432 || mode == TFmode || mode == TCmode))
18f63bfa 21433 return spe_build_register_parallel (mode, GP_ARG_RETURN);
ded9bf77
AH
21434 else
21435 regno = GP_ARG_RETURN;
21436
21437 return gen_rtx_REG (mode, regno);
21438}
21439
d1d0c603
JJ
21440/* Define the offset between two registers, FROM to be eliminated and its
21441 replacement TO, at the start of a routine. */
21442HOST_WIDE_INT
21443rs6000_initial_elimination_offset (int from, int to)
21444{
21445 rs6000_stack_t *info = rs6000_stack_info ();
21446 HOST_WIDE_INT offset;
21447
7d5175e1 21448 if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
d1d0c603 21449 offset = info->push_p ? 0 : -info->total_size;
7d5175e1
JJ
21450 else if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21451 {
21452 offset = info->push_p ? 0 : -info->total_size;
21453 if (FRAME_GROWS_DOWNWARD)
5b667039 21454 offset += info->fixed_size + info->vars_size + info->parm_size;
7d5175e1
JJ
21455 }
21456 else if (from == FRAME_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
21457 offset = FRAME_GROWS_DOWNWARD
5b667039 21458 ? info->fixed_size + info->vars_size + info->parm_size
7d5175e1
JJ
21459 : 0;
21460 else if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
d1d0c603
JJ
21461 offset = info->total_size;
21462 else if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
21463 offset = info->push_p ? info->total_size : 0;
21464 else if (from == RS6000_PIC_OFFSET_TABLE_REGNUM)
21465 offset = 0;
21466 else
37409796 21467 gcc_unreachable ();
d1d0c603
JJ
21468
21469 return offset;
21470}
21471
58646b77 21472/* Return true if TYPE is a SPE or AltiVec opaque type. */
62e1dfcf 21473
c8e4f0e9 21474static bool
3101faab 21475rs6000_is_opaque_type (const_tree type)
62e1dfcf 21476{
58646b77 21477 return (type == opaque_V2SI_type_node
2abe3e28 21478 || type == opaque_V2SF_type_node
58646b77
PB
21479 || type == opaque_p_V2SI_type_node
21480 || type == opaque_V4SI_type_node);
62e1dfcf
NC
21481}
21482
96714395 21483static rtx
a2369ed3 21484rs6000_dwarf_register_span (rtx reg)
96714395
AH
21485{
21486 unsigned regno;
21487
4d4cbc0e
AH
21488 if (TARGET_SPE
21489 && (SPE_VECTOR_MODE (GET_MODE (reg))
21490 || (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode)))
21491 ;
21492 else
96714395
AH
21493 return NULL_RTX;
21494
21495 regno = REGNO (reg);
21496
21497 /* The duality of the SPE register size wreaks all kinds of havoc.
21498 This is a way of distinguishing r0 in 32-bits from r0 in
21499 64-bits. */
21500 return
21501 gen_rtx_PARALLEL (VOIDmode,
3bd104d1
AH
21502 BYTES_BIG_ENDIAN
21503 ? gen_rtvec (2,
21504 gen_rtx_REG (SImode, regno + 1200),
21505 gen_rtx_REG (SImode, regno))
21506 : gen_rtvec (2,
21507 gen_rtx_REG (SImode, regno),
21508 gen_rtx_REG (SImode, regno + 1200)));
96714395
AH
21509}
21510
37ea0b7e
JM
21511/* Fill in sizes for SPE register high parts in table used by unwinder. */
21512
21513static void
21514rs6000_init_dwarf_reg_sizes_extra (tree address)
21515{
21516 if (TARGET_SPE)
21517 {
21518 int i;
21519 enum machine_mode mode = TYPE_MODE (char_type_node);
21520 rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
21521 rtx mem = gen_rtx_MEM (BLKmode, addr);
21522 rtx value = gen_int_mode (4, mode);
21523
21524 for (i = 1201; i < 1232; i++)
21525 {
21526 int column = DWARF_REG_TO_UNWIND_COLUMN (i);
21527 HOST_WIDE_INT offset
21528 = DWARF_FRAME_REGNUM (column) * GET_MODE_SIZE (mode);
21529
21530 emit_move_insn (adjust_address (mem, mode, offset), value);
21531 }
21532 }
21533}
21534
93c9d1ba
AM
21535/* Map internal gcc register numbers to DWARF2 register numbers. */
21536
21537unsigned int
21538rs6000_dbx_register_number (unsigned int regno)
21539{
21540 if (regno <= 63 || write_symbols != DWARF2_DEBUG)
21541 return regno;
21542 if (regno == MQ_REGNO)
21543 return 100;
1de43f85 21544 if (regno == LR_REGNO)
93c9d1ba 21545 return 108;
1de43f85 21546 if (regno == CTR_REGNO)
93c9d1ba
AM
21547 return 109;
21548 if (CR_REGNO_P (regno))
21549 return regno - CR0_REGNO + 86;
21550 if (regno == XER_REGNO)
21551 return 101;
21552 if (ALTIVEC_REGNO_P (regno))
21553 return regno - FIRST_ALTIVEC_REGNO + 1124;
21554 if (regno == VRSAVE_REGNO)
21555 return 356;
21556 if (regno == VSCR_REGNO)
21557 return 67;
21558 if (regno == SPE_ACC_REGNO)
21559 return 99;
21560 if (regno == SPEFSCR_REGNO)
21561 return 612;
21562 /* SPE high reg number. We get these values of regno from
21563 rs6000_dwarf_register_span. */
37409796
NS
21564 gcc_assert (regno >= 1200 && regno < 1232);
21565 return regno;
93c9d1ba
AM
21566}
21567
93f90be6 21568/* target hook eh_return_filter_mode */
f676971a 21569static enum machine_mode
93f90be6
FJ
21570rs6000_eh_return_filter_mode (void)
21571{
21572 return TARGET_32BIT ? SImode : word_mode;
21573}
21574
00b79d54
BE
21575/* Target hook for scalar_mode_supported_p. */
21576static bool
21577rs6000_scalar_mode_supported_p (enum machine_mode mode)
21578{
21579 if (DECIMAL_FLOAT_MODE_P (mode))
21580 return true;
21581 else
21582 return default_scalar_mode_supported_p (mode);
21583}
21584
f676971a
EC
21585/* Target hook for vector_mode_supported_p. */
21586static bool
21587rs6000_vector_mode_supported_p (enum machine_mode mode)
21588{
21589
96038623
DE
21590 if (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (mode))
21591 return true;
21592
f676971a
EC
21593 if (TARGET_SPE && SPE_VECTOR_MODE (mode))
21594 return true;
21595
21596 else if (TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
21597 return true;
21598
21599 else
21600 return false;
21601}
21602
bb8df8a6
EC
21603/* Target hook for invalid_arg_for_unprototyped_fn. */
21604static const char *
3101faab 21605invalid_arg_for_unprototyped_fn (const_tree typelist, const_tree funcdecl, const_tree val)
4d3e6fae
FJ
21606{
21607 return (!rs6000_darwin64_abi
21608 && typelist == 0
21609 && TREE_CODE (TREE_TYPE (val)) == VECTOR_TYPE
21610 && (funcdecl == NULL_TREE
21611 || (TREE_CODE (funcdecl) == FUNCTION_DECL
21612 && DECL_BUILT_IN_CLASS (funcdecl) != BUILT_IN_MD)))
21613 ? N_("AltiVec argument passed to unprototyped function")
21614 : NULL;
21615}
21616
3aebbe5f
JJ
21617/* For TARGET_SECURE_PLT 32-bit PIC code we can save PIC register
21618 setup by using __stack_chk_fail_local hidden function instead of
21619 calling __stack_chk_fail directly. Otherwise it is better to call
21620 __stack_chk_fail directly. */
21621
21622static tree
21623rs6000_stack_protect_fail (void)
21624{
21625 return (DEFAULT_ABI == ABI_V4 && TARGET_SECURE_PLT && flag_pic)
21626 ? default_hidden_stack_protect_fail ()
21627 : default_external_stack_protect_fail ();
21628}
21629
17211ab5 21630#include "gt-rs6000.h"