]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
Daily bump.
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
CommitLineData
9878760c 1/* Subroutines used for code generation on IBM RS/6000.
9ebbca7d 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
95385cbb 3 2000, 2001, 2002 Free Software Foundation, Inc.
fab3bcc3 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
9878760c
RK
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
c15c9075
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
9878760c 22
956d6950 23#include "config.h"
c4d38ccb 24#include "system.h"
9878760c
RK
25#include "rtl.h"
26#include "regs.h"
27#include "hard-reg-set.h"
28#include "real.h"
29#include "insn-config.h"
30#include "conditions.h"
9878760c
RK
31#include "insn-attr.h"
32#include "flags.h"
33#include "recog.h"
9878760c 34#include "obstack.h"
9b30bae2 35#include "tree.h"
dfafc897 36#include "expr.h"
2fc1c679 37#include "optabs.h"
2a430ec1 38#include "except.h"
a7df97e6 39#include "function.h"
296b8152 40#include "output.h"
d5fa86ba 41#include "basic-block.h"
d0101753 42#include "integrate.h"
296b8152 43#include "toplev.h"
c8023011 44#include "ggc.h"
9ebbca7d
GK
45#include "hashtab.h"
46#include "tm_p.h"
672a6f42
NB
47#include "target.h"
48#include "target-def.h"
3ac88239 49#include "langhooks.h"
24ea750e 50#include "reload.h"
9b30bae2 51
7509c759
MM
52#ifndef TARGET_NO_PROTOTYPE
53#define TARGET_NO_PROTOTYPE 0
54#endif
55
9878760c
RK
56#define min(A,B) ((A) < (B) ? (A) : (B))
57#define max(A,B) ((A) > (B) ? (A) : (B))
58
5248c961
RK
59/* Target cpu type */
60
61enum processor_type rs6000_cpu;
8e3f41e7
MM
62struct rs6000_cpu_select rs6000_select[3] =
63{
815cdc52
MM
64 /* switch name, tune arch */
65 { (const char *)0, "--with-cpu=", 1, 1 },
66 { (const char *)0, "-mcpu=", 1, 1 },
67 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 68};
5248c961 69
6fa3f289
ZW
70/* Size of long double */
71const char *rs6000_long_double_size_string;
72int rs6000_long_double_type_size;
73
74/* Whether -mabi=altivec has appeared */
75int rs6000_altivec_abi;
76
08b57fb3
AH
77/* Whether VRSAVE instructions should be generated. */
78int rs6000_altivec_vrsave;
79
80/* String from -mvrsave= option. */
81const char *rs6000_altivec_vrsave_string;
82
a3170dc6
AH
83/* Nonzero if we want SPE ABI extensions. */
84int rs6000_spe_abi;
85
86/* Whether isel instructions should be generated. */
87int rs6000_isel;
88
89/* Nonzero if we have FPRs. */
90int rs6000_fprs = 1;
91
92/* String from -misel=. */
93const char *rs6000_isel_string;
94
c764f757
RK
95/* Set to non-zero once AIX common-mode calls have been defined. */
96static int common_mode_defined;
c81bebd7 97
0e5dbd9b
DE
98/* Private copy of original value of flag_pic for ABI_AIX. */
99static int rs6000_flag_pic;
100
9878760c
RK
101/* Save information from a "cmpxx" operation until the branch or scc is
102 emitted. */
9878760c
RK
103rtx rs6000_compare_op0, rs6000_compare_op1;
104int rs6000_compare_fp_p;
874a0744 105
874a0744
MM
106/* Label number of label created for -mrelocatable, to call to so we can
107 get the address of the GOT section */
108int rs6000_pic_labelno;
c81bebd7 109
b91da81f 110#ifdef USING_ELFOS_H
c81bebd7 111/* Which abi to adhere to */
815cdc52 112const char *rs6000_abi_name = RS6000_ABI_NAME;
d9407988
MM
113
114/* Semantics of the small data area */
115enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
116
117/* Which small data model to use */
815cdc52 118const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
119
120/* Counter for labels which are to be placed in .fixup. */
121int fixuplabelno = 0;
874a0744 122#endif
4697a36c 123
b6c9286a
MM
124/* ABI enumeration available for subtarget to use. */
125enum rs6000_abi rs6000_current_abi;
126
0ac081f6
AH
127/* ABI string from -mabi= option. */
128const char *rs6000_abi_string;
129
38c1f2d7 130/* Debug flags */
815cdc52 131const char *rs6000_debug_name;
38c1f2d7
MM
132int rs6000_debug_stack; /* debug stack applications */
133int rs6000_debug_arg; /* debug argument handling */
134
57ac7be9
AM
135const char *rs6000_traceback_name;
136static enum {
137 traceback_default = 0,
138 traceback_none,
139 traceback_part,
140 traceback_full
141} rs6000_traceback;
142
38c1f2d7
MM
143/* Flag to say the TOC is initialized */
144int toc_initialized;
9ebbca7d 145char toc_label_name[10];
38c1f2d7 146
9ebbca7d
GK
147/* Alias set for saves and restores from the rs6000 stack. */
148static int rs6000_sr_alias_set;
c8023011 149
a5c76ee6
ZW
150/* Call distance, overridden by -mlongcall and #pragma longcall(1).
151 The only place that looks at this is rs6000_set_default_type_attributes;
152 everywhere else should rely on the presence or absence of a longcall
153 attribute on the function declaration. */
154int rs6000_default_long_calls;
155const char *rs6000_longcall_switch;
156
a3170dc6
AH
157struct builtin_description
158{
159 /* mask is not const because we're going to alter it below. This
160 nonsense will go away when we rewrite the -march infrastructure
161 to give us more target flag bits. */
162 unsigned int mask;
163 const enum insn_code icode;
164 const char *const name;
165 const enum rs6000_builtins code;
166};
167
9ebbca7d
GK
168static void rs6000_add_gc_roots PARAMS ((void));
169static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
39a10a29
GK
170static void validate_condition_mode
171 PARAMS ((enum rtx_code, enum machine_mode));
172static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
e50f5f3d 173static void rs6000_maybe_dead PARAMS ((rtx));
9ebbca7d
GK
174static void rs6000_emit_stack_tie PARAMS ((void));
175static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
89e7058f
AH
176static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
177 unsigned int, int, int));
a3170dc6 178static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
9ebbca7d
GK
179static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
180static unsigned rs6000_hash_constant PARAMS ((rtx));
181static unsigned toc_hash_function PARAMS ((const void *));
182static int toc_hash_eq PARAMS ((const void *, const void *));
2eba1afa 183static int toc_hash_mark_entry PARAMS ((void **, void *));
9ebbca7d
GK
184static void toc_hash_mark_table PARAMS ((void *));
185static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
e2500fed 186static struct machine_function * rs6000_init_machine_status PARAMS ((void));
301d03af 187static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
5add3202 188#ifdef HAVE_GAS_HIDDEN
93638d7a 189static void rs6000_assemble_visibility PARAMS ((tree, const char *));
5add3202 190#endif
71f123ca 191static int rs6000_ra_ever_killed PARAMS ((void));
91d231cb
JM
192static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
193const struct attribute_spec rs6000_attribute_table[];
a5c76ee6 194static void rs6000_set_default_type_attributes PARAMS ((tree));
08c148a8
NB
195static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
196static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
2bfcf297
DB
197static rtx rs6000_emit_set_long_const PARAMS ((rtx,
198 HOST_WIDE_INT, HOST_WIDE_INT));
7c262518
RH
199#if TARGET_ELF
200static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
201 int));
d9f6800d
RH
202static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
203static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
ae46c4e0
RH
204static void rs6000_elf_select_section PARAMS ((tree, int,
205 unsigned HOST_WIDE_INT));
206static void rs6000_elf_unique_section PARAMS ((tree, int));
b64a1b53
RH
207static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
208 unsigned HOST_WIDE_INT));
0e5dbd9b
DE
209static void rs6000_elf_encode_section_info PARAMS ((tree, int))
210 ATTRIBUTE_UNUSED;
772c5265 211static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
0e5dbd9b 212static bool rs6000_elf_in_small_data_p PARAMS ((tree));
7c262518 213#endif
cbaaba19 214#if TARGET_XCOFF
b275d088
DE
215static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
216static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
ae46c4e0
RH
217static void rs6000_xcoff_select_section PARAMS ((tree, int,
218 unsigned HOST_WIDE_INT));
219static void rs6000_xcoff_unique_section PARAMS ((tree, int));
b64a1b53
RH
220static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
221 unsigned HOST_WIDE_INT));
772c5265 222static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
5add3202 223static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
7c262518 224#endif
fb49053f
RH
225static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
226 ATTRIBUTE_UNUSED;
2bcc50d0 227static bool rs6000_binds_local_p PARAMS ((tree));
c237e94a
ZW
228static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
229static int rs6000_adjust_priority PARAMS ((rtx, int));
230static int rs6000_issue_rate PARAMS ((void));
231
6fa3f289 232static void rs6000_init_builtins PARAMS ((void));
92898235
AH
233static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
234static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
235static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 236static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
92898235 237static void altivec_init_builtins PARAMS ((void));
a3170dc6
AH
238static void rs6000_common_init_builtins PARAMS ((void));
239
240static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
241 int, enum rs6000_builtins,
242 enum rs6000_builtins));
243static void spe_init_builtins PARAMS ((void));
244static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
245static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
246static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
247static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
248
92898235 249static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
3a9b8c7e
AH
250static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
251static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
252static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
100c4561 253static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 254static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
6525c0e7 255static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 256static void rs6000_parse_abi_options PARAMS ((void));
08b57fb3 257static void rs6000_parse_vrsave_option PARAMS ((void));
a3170dc6 258static void rs6000_parse_isel_option PARAMS ((void));
00b960c7
AH
259static int first_altivec_reg_to_save PARAMS ((void));
260static unsigned int compute_vrsave_mask PARAMS ((void));
261static void is_altivec_return_reg PARAMS ((rtx, void *));
9aa86737
AH
262static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
263static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
69ef87e2 264static int easy_vector_constant PARAMS ((rtx));
c81bebd7
MM
265\f
266/* Default register names. */
267char rs6000_reg_names[][8] =
268{
802a0058
MM
269 "0", "1", "2", "3", "4", "5", "6", "7",
270 "8", "9", "10", "11", "12", "13", "14", "15",
271 "16", "17", "18", "19", "20", "21", "22", "23",
272 "24", "25", "26", "27", "28", "29", "30", "31",
273 "0", "1", "2", "3", "4", "5", "6", "7",
274 "8", "9", "10", "11", "12", "13", "14", "15",
275 "16", "17", "18", "19", "20", "21", "22", "23",
276 "24", "25", "26", "27", "28", "29", "30", "31",
277 "mq", "lr", "ctr","ap",
278 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
279 "xer",
280 /* AltiVec registers. */
0cd5e3a1
AH
281 "0", "1", "2", "3", "4", "5", "6", "7",
282 "8", "9", "10", "11", "12", "13", "14", "15",
283 "16", "17", "18", "19", "20", "21", "22", "23",
284 "24", "25", "26", "27", "28", "29", "30", "31",
0ac081f6 285 "vrsave"
c81bebd7
MM
286};
287
288#ifdef TARGET_REGNAMES
8b60264b 289static const char alt_reg_names[][8] =
c81bebd7 290{
802a0058
MM
291 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
292 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
293 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
294 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
295 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
296 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
297 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
298 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
299 "mq", "lr", "ctr", "ap",
300 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6
AH
301 "xer",
302 /* AltiVec registers. */
303 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
304 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
305 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
306 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
76a773f3 307 "vrsave"
c81bebd7
MM
308};
309#endif
9878760c 310\f
daf11973
MM
311#ifndef MASK_STRICT_ALIGN
312#define MASK_STRICT_ALIGN 0
313#endif
672a6f42
NB
314\f
315/* Initialize the GCC target structure. */
91d231cb
JM
316#undef TARGET_ATTRIBUTE_TABLE
317#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
318#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
319#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 320
301d03af
RS
321#undef TARGET_ASM_ALIGNED_DI_OP
322#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
323
324/* Default unaligned ops are only provided for ELF. Find the ops needed
325 for non-ELF systems. */
326#ifndef OBJECT_FORMAT_ELF
cbaaba19 327#if TARGET_XCOFF
ae6c1efd 328/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
329 64-bit targets. */
330#undef TARGET_ASM_UNALIGNED_HI_OP
331#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
332#undef TARGET_ASM_UNALIGNED_SI_OP
333#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
334#undef TARGET_ASM_UNALIGNED_DI_OP
335#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
336#else
337/* For Darwin. */
338#undef TARGET_ASM_UNALIGNED_HI_OP
339#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
340#undef TARGET_ASM_UNALIGNED_SI_OP
341#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
342#endif
343#endif
344
345/* This hook deals with fixups for relocatable code and DI-mode objects
346 in 64-bit code. */
347#undef TARGET_ASM_INTEGER
348#define TARGET_ASM_INTEGER rs6000_assemble_integer
349
93638d7a
AM
350#ifdef HAVE_GAS_HIDDEN
351#undef TARGET_ASM_ASSEMBLE_VISIBILITY
352#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
353#endif
354
08c148a8
NB
355#undef TARGET_ASM_FUNCTION_PROLOGUE
356#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
357#undef TARGET_ASM_FUNCTION_EPILOGUE
358#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
359
c237e94a
ZW
360#undef TARGET_SCHED_ISSUE_RATE
361#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
362#undef TARGET_SCHED_ADJUST_COST
363#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
364#undef TARGET_SCHED_ADJUST_PRIORITY
365#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
366
0ac081f6
AH
367#undef TARGET_INIT_BUILTINS
368#define TARGET_INIT_BUILTINS rs6000_init_builtins
369
370#undef TARGET_EXPAND_BUILTIN
371#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
372
0e5dbd9b
DE
373#undef TARGET_BINDS_LOCAL_P
374#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
375
00b960c7
AH
376/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
377#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
378
f6897b10 379struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 380\f
5248c961
RK
381/* Override command line options. Mostly we process the processor
382 type and sometimes adjust other TARGET_ options. */
383
384void
8e3f41e7 385rs6000_override_options (default_cpu)
d330fd93 386 const char *default_cpu;
5248c961 387{
c4d38ccb 388 size_t i, j;
8e3f41e7 389 struct rs6000_cpu_select *ptr;
5248c961 390
85638c0d
RK
391 /* Simplify the entries below by making a mask for any POWER
392 variant and any PowerPC variant. */
393
938937d8 394#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
395#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
396 | MASK_PPC_GFXOPT | MASK_POWERPC64)
397#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 398
5248c961
RK
399 static struct ptt
400 {
8b60264b
KG
401 const char *const name; /* Canonical processor name. */
402 const enum processor_type processor; /* Processor type enum value. */
403 const int target_enable; /* Target flags to enable. */
404 const int target_disable; /* Target flags to disable. */
405 } const processor_target_table[]
cf27b467
MM
406 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
407 POWER_MASKS | POWERPC_MASKS},
db7f1e43 408 {"power", PROCESSOR_POWER,
938937d8 409 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 410 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
411 {"power2", PROCESSOR_POWER,
412 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
413 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
414 {"power3", PROCESSOR_PPC630,
415 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
416 POWER_MASKS | MASK_PPC_GPOPT},
309323c2
DE
417 {"power4", PROCESSOR_POWER4,
418 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
419 POWER_MASKS | MASK_PPC_GPOPT},
db7f1e43
RK
420 {"powerpc", PROCESSOR_POWERPC,
421 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 422 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
423 {"powerpc64", PROCESSOR_POWERPC64,
424 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
425 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 426 {"rios", PROCESSOR_RIOS1,
938937d8 427 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
428 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
429 {"rios1", PROCESSOR_RIOS1,
938937d8 430 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
431 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
432 {"rsc", PROCESSOR_PPC601,
938937d8 433 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
434 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
435 {"rsc1", PROCESSOR_PPC601,
938937d8 436 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
437 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
438 {"rios2", PROCESSOR_RIOS2,
938937d8 439 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 440 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
441 {"rs64a", PROCESSOR_RS64A,
442 MASK_POWERPC | MASK_NEW_MNEMONICS,
443 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
444 {"401", PROCESSOR_PPC403,
445 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
446 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 447 {"403", PROCESSOR_PPC403,
daf11973 448 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 449 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
450 {"405", PROCESSOR_PPC405,
451 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
452 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
453 {"505", PROCESSOR_MPCCORE,
454 MASK_POWERPC | MASK_NEW_MNEMONICS,
455 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 456 {"601", PROCESSOR_PPC601,
938937d8 457 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 458 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 459 {"602", PROCESSOR_PPC603,
cf27b467
MM
460 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
461 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 462 {"603", PROCESSOR_PPC603,
68c49ffa
RK
463 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
464 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
465 {"603e", PROCESSOR_PPC603,
466 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
467 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 468 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
469 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
470 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 471 {"604", PROCESSOR_PPC604,
b6c9286a
MM
472 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
473 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 474 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
475 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
476 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 477 {"620", PROCESSOR_PPC620,
68c49ffa 478 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
a260abc9 479 POWER_MASKS | MASK_PPC_GPOPT},
3cb999d8
DE
480 {"630", PROCESSOR_PPC630,
481 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
482 POWER_MASKS | MASK_PPC_GPOPT},
bef84347
VM
483 {"740", PROCESSOR_PPC750,
484 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
485 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
486 {"750", PROCESSOR_PPC750,
487 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
488 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
489 {"7400", PROCESSOR_PPC7400,
490 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
491 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
492 {"7450", PROCESSOR_PPC7450,
493 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
494 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a3170dc6
AH
495 {"8540", PROCESSOR_PPC8540,
496 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
497 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
498 {"801", PROCESSOR_MPCCORE,
499 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
500 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
501 {"821", PROCESSOR_MPCCORE,
502 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
503 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
504 {"823", PROCESSOR_MPCCORE,
505 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
506 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
507 {"860", PROCESSOR_MPCCORE,
508 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
509 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 510
ca7558fc 511 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 512
a4f6c312
SS
513 /* Save current -mmultiple/-mno-multiple status. */
514 int multiple = TARGET_MULTIPLE;
515 /* Save current -mstring/-mno-string status. */
516 int string = TARGET_STRING;
8a61d227 517
a4f6c312 518 /* Identify the processor type. */
8e3f41e7 519 rs6000_select[0].string = default_cpu;
3cb999d8 520 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 521
b6a1cbae 522 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 523 {
8e3f41e7
MM
524 ptr = &rs6000_select[i];
525 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 526 {
8e3f41e7
MM
527 for (j = 0; j < ptt_size; j++)
528 if (! strcmp (ptr->string, processor_target_table[j].name))
529 {
530 if (ptr->set_tune_p)
531 rs6000_cpu = processor_target_table[j].processor;
532
533 if (ptr->set_arch_p)
534 {
535 target_flags |= processor_target_table[j].target_enable;
536 target_flags &= ~processor_target_table[j].target_disable;
537 }
538 break;
539 }
540
4406229e 541 if (j == ptt_size)
8e3f41e7 542 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
543 }
544 }
8a61d227 545
a3170dc6
AH
546 if (rs6000_cpu == PROCESSOR_PPC8540)
547 rs6000_isel = 1;
548
a4f6c312
SS
549 /* If we are optimizing big endian systems for space, use the store
550 multiple instructions. */
ef792183
MM
551 if (BYTES_BIG_ENDIAN && optimize_size)
552 target_flags |= MASK_MULTIPLE;
553
8a61d227
MM
554 /* If -mmultiple or -mno-multiple was explicitly used, don't
555 override with the processor default */
556 if (TARGET_MULTIPLE_SET)
557 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 558
a4f6c312
SS
559 /* If -mstring or -mno-string was explicitly used, don't override
560 with the processor default. */
938937d8 561 if (TARGET_STRING_SET)
1f5515bf 562 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 563
a4f6c312
SS
564 /* Don't allow -mmultiple or -mstring on little endian systems
565 unless the cpu is a 750, because the hardware doesn't support the
566 instructions used in little endian mode, and causes an alignment
567 trap. The 750 does not cause an alignment trap (except when the
568 target is unaligned). */
bef84347 569
bfc79d3b 570 if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
571 {
572 if (TARGET_MULTIPLE)
573 {
574 target_flags &= ~MASK_MULTIPLE;
575 if (TARGET_MULTIPLE_SET)
576 warning ("-mmultiple is not supported on little endian systems");
577 }
578
579 if (TARGET_STRING)
580 {
581 target_flags &= ~MASK_STRING;
938937d8
MM
582 if (TARGET_STRING_SET)
583 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
584 }
585 }
3933e0e1 586
ee2ca2a2 587 if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
a260abc9 588 {
0e5dbd9b 589 rs6000_flag_pic = flag_pic;
ee2ca2a2 590 flag_pic = 0;
a260abc9
DE
591 }
592
2bfcf297 593#ifdef XCOFF_DEBUGGING_INFO
9861b0c9 594 if (flag_function_sections && (write_symbols != NO_DEBUG)
2bfcf297 595 && DEFAULT_ABI == ABI_AIX)
9861b0c9
DE
596 {
597 warning ("-ffunction-sections disabled on AIX when debugging");
598 flag_function_sections = 0;
599 }
600
601 if (flag_data_sections && (DEFAULT_ABI == ABI_AIX))
602 {
603 warning ("-fdata-sections not supported on AIX");
604 flag_data_sections = 0;
605 }
2bfcf297 606#endif
9861b0c9 607
c72bfda7
SS
608 /* For Darwin, always silently make -fpic and -fPIC identical. */
609 if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN)
610 flag_pic = 2;
611
38c1f2d7
MM
612 /* Set debug flags */
613 if (rs6000_debug_name)
614 {
bfc79d3b 615 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 616 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 617 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 618 rs6000_debug_stack = 1;
bfc79d3b 619 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
620 rs6000_debug_arg = 1;
621 else
c725bd79 622 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
623 }
624
57ac7be9
AM
625 if (rs6000_traceback_name)
626 {
627 if (! strncmp (rs6000_traceback_name, "full", 4))
628 rs6000_traceback = traceback_full;
629 else if (! strncmp (rs6000_traceback_name, "part", 4))
630 rs6000_traceback = traceback_part;
631 else if (! strncmp (rs6000_traceback_name, "no", 2))
632 rs6000_traceback = traceback_none;
633 else
634 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
635 rs6000_traceback_name);
636 }
637
6fa3f289
ZW
638 /* Set size of long double */
639 rs6000_long_double_type_size = 64;
640 if (rs6000_long_double_size_string)
641 {
642 char *tail;
643 int size = strtol (rs6000_long_double_size_string, &tail, 10);
644 if (*tail != '\0' || (size != 64 && size != 128))
645 error ("Unknown switch -mlong-double-%s",
646 rs6000_long_double_size_string);
647 else
648 rs6000_long_double_type_size = size;
649 }
650
0ac081f6
AH
651 /* Handle -mabi= options. */
652 rs6000_parse_abi_options ();
653
08b57fb3
AH
654 /* Handle -mvrsave= option. */
655 rs6000_parse_vrsave_option ();
656
a3170dc6
AH
657 /* Handle -misel= option. */
658 rs6000_parse_isel_option ();
659
a7ae18e2
AH
660#ifdef SUBTARGET_OVERRIDE_OPTIONS
661 SUBTARGET_OVERRIDE_OPTIONS;
662#endif
663#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
664 SUBSUBTARGET_OVERRIDE_OPTIONS;
665#endif
666
a5c76ee6
ZW
667 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
668 using TARGET_OPTIONS to handle a toggle switch, but we're out of
669 bits in target_flags so TARGET_SWITCHES cannot be used.
670 Assumption here is that rs6000_longcall_switch points into the
671 text of the complete option, rather than being a copy, so we can
672 scan back for the presence or absence of the no- modifier. */
673 if (rs6000_longcall_switch)
674 {
675 const char *base = rs6000_longcall_switch;
676 while (base[-1] != 'm') base--;
677
678 if (*rs6000_longcall_switch != '\0')
679 error ("invalid option `%s'", base);
680 rs6000_default_long_calls = (base[0] != 'n');
681 }
682
c81bebd7 683#ifdef TARGET_REGNAMES
a4f6c312
SS
684 /* If the user desires alternate register names, copy in the
685 alternate names now. */
c81bebd7 686 if (TARGET_REGNAMES)
4e135bdd 687 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
688#endif
689
6fa3f289
ZW
690 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
691 If -maix-struct-return or -msvr4-struct-return was explicitly
692 used, don't override with the ABI default. */
693 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
694 {
695 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
696 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
697 else
698 target_flags |= MASK_AIX_STRUCT_RET;
699 }
700
c8023011
MM
701 /* Register global variables with the garbage collector. */
702 rs6000_add_gc_roots ();
9ebbca7d
GK
703
704 /* Allocate an alias set for register saves & restores from stack. */
705 rs6000_sr_alias_set = new_alias_set ();
706
707 if (TARGET_TOC)
708 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 709
301d03af
RS
710 /* We can only guarantee the availability of DI pseudo-ops when
711 assembling for 64-bit targets. */
ae6c1efd 712 if (!TARGET_64BIT)
301d03af
RS
713 {
714 targetm.asm_out.aligned_op.di = NULL;
715 targetm.asm_out.unaligned_op.di = NULL;
716 }
717
71f123ca
FS
718 /* Arrange to save and restore machine status around nested functions. */
719 init_machine_status = rs6000_init_machine_status;
5248c961 720}
5accd822 721
a3170dc6
AH
722/* Handle -misel= option. */
723static void
724rs6000_parse_isel_option ()
725{
726 if (rs6000_isel_string == 0)
727 return;
728 else if (! strcmp (rs6000_isel_string, "yes"))
729 rs6000_isel = 1;
730 else if (! strcmp (rs6000_isel_string, "no"))
731 rs6000_isel = 0;
732 else
733 error ("unknown -misel= option specified: '%s'",
734 rs6000_isel_string);
735}
736
08b57fb3
AH
737/* Handle -mvrsave= options. */
738static void
739rs6000_parse_vrsave_option ()
740{
741 /* Generate VRSAVE instructions by default. */
742 if (rs6000_altivec_vrsave_string == 0
743 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
744 rs6000_altivec_vrsave = 1;
745 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
746 rs6000_altivec_vrsave = 0;
747 else
748 error ("unknown -mvrsave= option specified: '%s'",
749 rs6000_altivec_vrsave_string);
750}
751
0ac081f6 752/* Handle -mabi= options. */
00b960c7
AH
753static void
754rs6000_parse_abi_options ()
0ac081f6
AH
755{
756 if (rs6000_abi_string == 0)
757 return;
758 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 759 rs6000_altivec_abi = 1;
76a773f3
AH
760 else if (! strcmp (rs6000_abi_string, "no-altivec"))
761 rs6000_altivec_abi = 0;
a3170dc6
AH
762 else if (! strcmp (rs6000_abi_string, "spe"))
763 rs6000_spe_abi = 1;
764 else if (! strcmp (rs6000_abi_string, "no-spe"))
765 rs6000_spe_abi = 0;
0ac081f6 766 else
c725bd79 767 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
768}
769
5accd822
DE
770void
771optimization_options (level, size)
e2c953b6 772 int level ATTRIBUTE_UNUSED;
5accd822
DE
773 int size ATTRIBUTE_UNUSED;
774{
5accd822 775}
3cfa4909
MM
776\f
777/* Do anything needed at the start of the asm file. */
778
779void
780rs6000_file_start (file, default_cpu)
781 FILE *file;
d330fd93 782 const char *default_cpu;
3cfa4909 783{
c4d38ccb 784 size_t i;
3cfa4909 785 char buffer[80];
d330fd93 786 const char *start = buffer;
3cfa4909
MM
787 struct rs6000_cpu_select *ptr;
788
789 if (flag_verbose_asm)
790 {
791 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
792 rs6000_select[0].string = default_cpu;
793
b6a1cbae 794 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
795 {
796 ptr = &rs6000_select[i];
797 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
798 {
799 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
800 start = "";
801 }
802 }
803
b91da81f 804#ifdef USING_ELFOS_H
3cfa4909
MM
805 switch (rs6000_sdata)
806 {
807 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
808 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
809 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
810 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
811 }
812
813 if (rs6000_sdata && g_switch_value)
814 {
815 fprintf (file, "%s -G %d", start, g_switch_value);
816 start = "";
817 }
818#endif
819
820 if (*start == '\0')
949ea356 821 putc ('\n', file);
3cfa4909
MM
822 }
823}
5248c961 824\f
9878760c
RK
825/* Return non-zero if this function is known to have a null epilogue. */
826
827int
828direct_return ()
829{
4697a36c
MM
830 if (reload_completed)
831 {
832 rs6000_stack_t *info = rs6000_stack_info ();
833
834 if (info->first_gp_reg_save == 32
835 && info->first_fp_reg_save == 64
00b960c7 836 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
837 && ! info->lr_save_p
838 && ! info->cr_save_p
00b960c7 839 && info->vrsave_mask == 0
c81fc13e 840 && ! info->push_p)
4697a36c
MM
841 return 1;
842 }
843
844 return 0;
9878760c
RK
845}
846
847/* Returns 1 always. */
848
849int
850any_operand (op, mode)
592696dd 851 rtx op ATTRIBUTE_UNUSED;
296b8152 852 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
853{
854 return 1;
855}
856
a4f6c312 857/* Returns 1 if op is the count register. */
38c1f2d7 858int
a4f6c312 859count_register_operand (op, mode)
592696dd 860 rtx op;
296b8152 861 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
862{
863 if (GET_CODE (op) != REG)
864 return 0;
865
866 if (REGNO (op) == COUNT_REGISTER_REGNUM)
867 return 1;
868
869 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
870 return 1;
871
872 return 0;
873}
874
0ec4e2a8
AH
875/* Returns 1 if op is an altivec register. */
876int
877altivec_register_operand (op, mode)
878 rtx op;
879 enum machine_mode mode ATTRIBUTE_UNUSED;
880{
881
882 return (register_operand (op, mode)
883 && (GET_CODE (op) != REG
884 || REGNO (op) > FIRST_PSEUDO_REGISTER
885 || ALTIVEC_REGNO_P (REGNO (op))));
886}
887
38c1f2d7 888int
a4f6c312 889xer_operand (op, mode)
592696dd 890 rtx op;
296b8152 891 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
892{
893 if (GET_CODE (op) != REG)
894 return 0;
895
9ebbca7d 896 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
897 return 1;
898
802a0058
MM
899 return 0;
900}
901
c859cda6 902/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 903 by such constants completes more quickly. */
c859cda6
DJ
904
905int
906s8bit_cint_operand (op, mode)
907 rtx op;
908 enum machine_mode mode ATTRIBUTE_UNUSED;
909{
910 return ( GET_CODE (op) == CONST_INT
911 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
912}
913
9878760c
RK
914/* Return 1 if OP is a constant that can fit in a D field. */
915
916int
917short_cint_operand (op, mode)
592696dd 918 rtx op;
296b8152 919 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 920{
5f59ecb7
DE
921 return (GET_CODE (op) == CONST_INT
922 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
923}
924
5519a4f9 925/* Similar for an unsigned D field. */
9878760c
RK
926
927int
928u_short_cint_operand (op, mode)
592696dd 929 rtx op;
296b8152 930 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 931{
19684119 932 return (GET_CODE (op) == CONST_INT
c1f11548 933 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
934}
935
dcfedcd0
RK
936/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
937
938int
939non_short_cint_operand (op, mode)
592696dd 940 rtx op;
296b8152 941 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
942{
943 return (GET_CODE (op) == CONST_INT
a7653a2c 944 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
945}
946
2bfcf297
DB
947/* Returns 1 if OP is a CONST_INT that is a positive value
948 and an exact power of 2. */
949
950int
951exact_log2_cint_operand (op, mode)
592696dd 952 rtx op;
2bfcf297
DB
953 enum machine_mode mode ATTRIBUTE_UNUSED;
954{
955 return (GET_CODE (op) == CONST_INT
956 && INTVAL (op) > 0
957 && exact_log2 (INTVAL (op)) >= 0);
958}
959
9878760c
RK
960/* Returns 1 if OP is a register that is not special (i.e., not MQ,
961 ctr, or lr). */
962
963int
cd2b37d9 964gpc_reg_operand (op, mode)
592696dd 965 rtx op;
9878760c
RK
966 enum machine_mode mode;
967{
968 return (register_operand (op, mode)
802a0058 969 && (GET_CODE (op) != REG
9ebbca7d
GK
970 || (REGNO (op) >= ARG_POINTER_REGNUM
971 && !XER_REGNO_P (REGNO (op)))
972 || REGNO (op) < MQ_REGNO));
9878760c
RK
973}
974
975/* Returns 1 if OP is either a pseudo-register or a register denoting a
976 CR field. */
977
978int
979cc_reg_operand (op, mode)
592696dd 980 rtx op;
9878760c
RK
981 enum machine_mode mode;
982{
983 return (register_operand (op, mode)
984 && (GET_CODE (op) != REG
985 || REGNO (op) >= FIRST_PSEUDO_REGISTER
986 || CR_REGNO_P (REGNO (op))));
987}
988
815cdc52
MM
989/* Returns 1 if OP is either a pseudo-register or a register denoting a
990 CR field that isn't CR0. */
991
992int
993cc_reg_not_cr0_operand (op, mode)
592696dd 994 rtx op;
815cdc52
MM
995 enum machine_mode mode;
996{
997 return (register_operand (op, mode)
998 && (GET_CODE (op) != REG
999 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1000 || CR_REGNO_NOT_CR0_P (REGNO (op))));
1001}
1002
a4f6c312
SS
1003/* Returns 1 if OP is either a constant integer valid for a D-field or
1004 a non-special register. If a register, it must be in the proper
1005 mode unless MODE is VOIDmode. */
9878760c
RK
1006
1007int
1008reg_or_short_operand (op, mode)
592696dd 1009 rtx op;
9878760c
RK
1010 enum machine_mode mode;
1011{
f5a28898 1012 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1013}
1014
a4f6c312
SS
1015/* Similar, except check if the negation of the constant would be
1016 valid for a D-field. */
9878760c
RK
1017
1018int
1019reg_or_neg_short_operand (op, mode)
592696dd 1020 rtx op;
9878760c
RK
1021 enum machine_mode mode;
1022{
1023 if (GET_CODE (op) == CONST_INT)
1024 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1025
cd2b37d9 1026 return gpc_reg_operand (op, mode);
9878760c
RK
1027}
1028
768070a0
TR
1029/* Returns 1 if OP is either a constant integer valid for a DS-field or
1030 a non-special register. If a register, it must be in the proper
1031 mode unless MODE is VOIDmode. */
1032
1033int
1034reg_or_aligned_short_operand (op, mode)
1035 rtx op;
1036 enum machine_mode mode;
1037{
1038 if (gpc_reg_operand (op, mode))
1039 return 1;
1040 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1041 return 1;
1042
1043 return 0;
1044}
1045
1046
a4f6c312
SS
1047/* Return 1 if the operand is either a register or an integer whose
1048 high-order 16 bits are zero. */
9878760c
RK
1049
1050int
1051reg_or_u_short_operand (op, mode)
592696dd 1052 rtx op;
9878760c
RK
1053 enum machine_mode mode;
1054{
e675f625 1055 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1056}
1057
1058/* Return 1 is the operand is either a non-special register or ANY
1059 constant integer. */
1060
1061int
1062reg_or_cint_operand (op, mode)
592696dd 1063 rtx op;
9878760c
RK
1064 enum machine_mode mode;
1065{
a4f6c312 1066 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1067}
1068
1069/* Return 1 is the operand is either a non-special register or ANY
1070 32-bit signed constant integer. */
1071
1072int
1073reg_or_arith_cint_operand (op, mode)
592696dd 1074 rtx op;
f6bf7de2
DE
1075 enum machine_mode mode;
1076{
a4f6c312
SS
1077 return (gpc_reg_operand (op, mode)
1078 || (GET_CODE (op) == CONST_INT
f6bf7de2 1079#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1080 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1081 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1082#endif
a4f6c312 1083 ));
9878760c
RK
1084}
1085
2bfcf297
DB
1086/* Return 1 is the operand is either a non-special register or a 32-bit
1087 signed constant integer valid for 64-bit addition. */
1088
1089int
1090reg_or_add_cint64_operand (op, mode)
592696dd 1091 rtx op;
2bfcf297
DB
1092 enum machine_mode mode;
1093{
a4f6c312
SS
1094 return (gpc_reg_operand (op, mode)
1095 || (GET_CODE (op) == CONST_INT
a65c591c 1096#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1097 && INTVAL (op) < 0x7fff8000
a65c591c 1098#else
a4f6c312
SS
1099 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1100 < 0x100000000ll)
2bfcf297 1101#endif
a4f6c312 1102 ));
2bfcf297
DB
1103}
1104
1105/* Return 1 is the operand is either a non-special register or a 32-bit
1106 signed constant integer valid for 64-bit subtraction. */
1107
1108int
1109reg_or_sub_cint64_operand (op, mode)
592696dd 1110 rtx op;
2bfcf297
DB
1111 enum machine_mode mode;
1112{
a4f6c312
SS
1113 return (gpc_reg_operand (op, mode)
1114 || (GET_CODE (op) == CONST_INT
a65c591c 1115#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1116 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1117#else
a4f6c312
SS
1118 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1119 < 0x100000000ll)
2bfcf297 1120#endif
a4f6c312 1121 ));
2bfcf297
DB
1122}
1123
9ebbca7d
GK
1124/* Return 1 is the operand is either a non-special register or ANY
1125 32-bit unsigned constant integer. */
1126
1127int
1d328b19 1128reg_or_logical_cint_operand (op, mode)
592696dd 1129 rtx op;
9ebbca7d
GK
1130 enum machine_mode mode;
1131{
1d328b19
GK
1132 if (GET_CODE (op) == CONST_INT)
1133 {
1134 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1135 {
1136 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1137 abort ();
1d328b19
GK
1138
1139 if (INTVAL (op) < 0)
1140 return 0;
1141 }
1142
1143 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1144 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1145 }
1146 else if (GET_CODE (op) == CONST_DOUBLE)
1147 {
1148 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1149 || mode != DImode)
a4f6c312 1150 abort ();
1d328b19
GK
1151
1152 return CONST_DOUBLE_HIGH (op) == 0;
1153 }
1154 else
1155 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1156}
1157
51d3e7d6 1158/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1159
1160int
1161got_operand (op, mode)
592696dd 1162 rtx op;
296b8152 1163 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1164{
1165 return (GET_CODE (op) == SYMBOL_REF
1166 || GET_CODE (op) == CONST
1167 || GET_CODE (op) == LABEL_REF);
1168}
1169
38c1f2d7
MM
1170/* Return 1 if the operand is a simple references that can be loaded via
1171 the GOT (labels involving addition aren't allowed). */
1172
1173int
1174got_no_const_operand (op, mode)
592696dd 1175 rtx op;
296b8152 1176 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1177{
1178 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1179}
1180
4e74d8ec
MM
1181/* Return the number of instructions it takes to form a constant in an
1182 integer register. */
1183
1184static int
1185num_insns_constant_wide (value)
1186 HOST_WIDE_INT value;
1187{
1188 /* signed constant loadable with {cal|addi} */
5f59ecb7 1189 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1190 return 1;
1191
4e74d8ec 1192 /* constant loadable with {cau|addis} */
5f59ecb7 1193 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1194 return 1;
1195
5f59ecb7 1196#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1197 else if (TARGET_POWERPC64)
4e74d8ec 1198 {
a65c591c
DE
1199 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1200 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1201
a65c591c 1202 if (high == 0 || high == -1)
4e74d8ec
MM
1203 return 2;
1204
a65c591c 1205 high >>= 1;
4e74d8ec 1206
a65c591c 1207 if (low == 0)
4e74d8ec 1208 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1209 else
1210 return (num_insns_constant_wide (high)
e396202a 1211 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1212 }
1213#endif
1214
1215 else
1216 return 2;
1217}
1218
1219int
1220num_insns_constant (op, mode)
1221 rtx op;
1222 enum machine_mode mode;
1223{
4e74d8ec 1224 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1225 {
1226#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1227 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1228 && mask64_operand (op, mode))
0d30d435
DE
1229 return 2;
1230 else
1231#endif
1232 return num_insns_constant_wide (INTVAL (op));
1233 }
4e74d8ec 1234
6fc48950
MM
1235 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1236 {
1237 long l;
1238 REAL_VALUE_TYPE rv;
1239
1240 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1241 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1242 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1243 }
1244
47ad8c61 1245 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1246 {
47ad8c61
MM
1247 HOST_WIDE_INT low;
1248 HOST_WIDE_INT high;
1249 long l[2];
1250 REAL_VALUE_TYPE rv;
1251 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1252
47ad8c61
MM
1253 if (mode == VOIDmode || mode == DImode)
1254 {
1255 high = CONST_DOUBLE_HIGH (op);
1256 low = CONST_DOUBLE_LOW (op);
1257 }
1258 else
1259 {
1260 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1261 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1262 high = l[endian];
1263 low = l[1 - endian];
1264 }
4e74d8ec 1265
47ad8c61
MM
1266 if (TARGET_32BIT)
1267 return (num_insns_constant_wide (low)
1268 + num_insns_constant_wide (high));
4e74d8ec
MM
1269
1270 else
47ad8c61 1271 {
e72247f4 1272 if (high == 0 && low >= 0)
47ad8c61
MM
1273 return num_insns_constant_wide (low);
1274
e72247f4 1275 else if (high == -1 && low < 0)
47ad8c61
MM
1276 return num_insns_constant_wide (low);
1277
a260abc9
DE
1278 else if (mask64_operand (op, mode))
1279 return 2;
1280
47ad8c61
MM
1281 else if (low == 0)
1282 return num_insns_constant_wide (high) + 1;
1283
1284 else
1285 return (num_insns_constant_wide (high)
1286 + num_insns_constant_wide (low) + 1);
1287 }
4e74d8ec
MM
1288 }
1289
1290 else
1291 abort ();
1292}
1293
a4f6c312
SS
1294/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1295 register with one instruction per word. We only do this if we can
1296 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1297
1298int
1299easy_fp_constant (op, mode)
592696dd
SS
1300 rtx op;
1301 enum machine_mode mode;
9878760c 1302{
9878760c
RK
1303 if (GET_CODE (op) != CONST_DOUBLE
1304 || GET_MODE (op) != mode
4e74d8ec 1305 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1306 return 0;
1307
a4f6c312 1308 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1309 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1310 && mode != DImode)
b6c9286a
MM
1311 return 1;
1312
a4f6c312 1313 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1314 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1315 return 0;
1316
5ae4759c 1317#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1318 /* Similarly if we are using -mrelocatable, consider all constants
1319 to be hard. */
5ae4759c
MM
1320 if (TARGET_RELOCATABLE)
1321 return 0;
1322#endif
1323
042259f2
DE
1324 if (mode == DFmode)
1325 {
1326 long k[2];
1327 REAL_VALUE_TYPE rv;
1328
1329 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1330 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1331
a65c591c
DE
1332 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1333 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1334 }
4e74d8ec
MM
1335
1336 else if (mode == SFmode)
042259f2
DE
1337 {
1338 long l;
1339 REAL_VALUE_TYPE rv;
1340
1341 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1342 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1343
4e74d8ec 1344 return num_insns_constant_wide (l) == 1;
042259f2 1345 }
4e74d8ec 1346
a260abc9 1347 else if (mode == DImode)
c81fc13e 1348 return ((TARGET_POWERPC64
a260abc9
DE
1349 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1350 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1351
a9098fd0
GK
1352 else if (mode == SImode)
1353 return 1;
4e74d8ec
MM
1354 else
1355 abort ();
9878760c 1356}
8f75773e 1357
69ef87e2
AH
1358/* Return 1 if the operand is a CONST_INT and can be put into a
1359 register with one instruction. */
1360
1361static int
1362easy_vector_constant (op)
1363 rtx op;
1364{
1365 rtx elt;
1366 int units, i;
1367
1368 if (GET_CODE (op) != CONST_VECTOR)
1369 return 0;
1370
1371 units = CONST_VECTOR_NUNITS (op);
1372
1373 /* We can generate 0 easily. Look for that. */
1374 for (i = 0; i < units; ++i)
1375 {
1376 elt = CONST_VECTOR_ELT (op, i);
1377
1378 /* We could probably simplify this by just checking for equality
1379 with CONST0_RTX for the current mode, but let's be safe
1380 instead. */
1381
98ef3137
JJ
1382 switch (GET_CODE (elt))
1383 {
1384 case CONST_INT:
1385 if (INTVAL (elt) != 0)
1386 return 0;
1387 break;
1388 case CONST_DOUBLE:
1389 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1390 return 0;
1391 break;
1392 default:
1393 return 0;
1394 }
69ef87e2
AH
1395 }
1396
1397 /* We could probably generate a few other constants trivially, but
1398 gcc doesn't generate them yet. FIXME later. */
98ef3137 1399 return 1;
69ef87e2
AH
1400}
1401
1402/* Return 1 if the operand is the constant 0. This works for scalars
1403 as well as vectors. */
1404int
1405zero_constant (op, mode)
1406 rtx op;
1407 enum machine_mode mode;
1408{
1409 return op == CONST0_RTX (mode);
1410}
1411
50a0b056
GK
1412/* Return 1 if the operand is 0.0. */
1413int
1414zero_fp_constant (op, mode)
592696dd
SS
1415 rtx op;
1416 enum machine_mode mode;
50a0b056
GK
1417{
1418 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1419}
1420
a4f6c312
SS
1421/* Return 1 if the operand is in volatile memory. Note that during
1422 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1423 volatile memory references. So this function allows us to
1424 recognize volatile references where its safe. */
1425
1426int
1427volatile_mem_operand (op, mode)
592696dd 1428 rtx op;
b6c9286a
MM
1429 enum machine_mode mode;
1430{
1431 if (GET_CODE (op) != MEM)
1432 return 0;
1433
1434 if (!MEM_VOLATILE_P (op))
1435 return 0;
1436
1437 if (mode != GET_MODE (op))
1438 return 0;
1439
1440 if (reload_completed)
1441 return memory_operand (op, mode);
1442
1443 if (reload_in_progress)
1444 return strict_memory_address_p (mode, XEXP (op, 0));
1445
1446 return memory_address_p (mode, XEXP (op, 0));
1447}
1448
97f6e72f 1449/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1450
1451int
97f6e72f 1452offsettable_mem_operand (op, mode)
592696dd 1453 rtx op;
914c2e77
RK
1454 enum machine_mode mode;
1455{
97f6e72f 1456 return ((GET_CODE (op) == MEM)
677a9668 1457 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1458 mode, XEXP (op, 0)));
914c2e77
RK
1459}
1460
9878760c
RK
1461/* Return 1 if the operand is either an easy FP constant (see above) or
1462 memory. */
1463
1464int
1465mem_or_easy_const_operand (op, mode)
592696dd 1466 rtx op;
9878760c
RK
1467 enum machine_mode mode;
1468{
1469 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1470}
1471
1472/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1473 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1474
1475int
1476add_operand (op, mode)
592696dd 1477 rtx op;
9878760c
RK
1478 enum machine_mode mode;
1479{
2bfcf297 1480 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1481 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1482 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1483
1484 return gpc_reg_operand (op, mode);
9878760c
RK
1485}
1486
dcfedcd0
RK
1487/* Return 1 if OP is a constant but not a valid add_operand. */
1488
1489int
1490non_add_cint_operand (op, mode)
592696dd 1491 rtx op;
296b8152 1492 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1493{
1494 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1495 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1496 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1497}
1498
9878760c
RK
1499/* Return 1 if the operand is a non-special register or a constant that
1500 can be used as the operand of an OR or XOR insn on the RS/6000. */
1501
1502int
1503logical_operand (op, mode)
592696dd 1504 rtx op;
9878760c
RK
1505 enum machine_mode mode;
1506{
40501e5f 1507 HOST_WIDE_INT opl, oph;
1d328b19 1508
dfbdccdb
GK
1509 if (gpc_reg_operand (op, mode))
1510 return 1;
1d328b19 1511
dfbdccdb 1512 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1513 {
1514 opl = INTVAL (op) & GET_MODE_MASK (mode);
1515
1516#if HOST_BITS_PER_WIDE_INT <= 32
1517 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1518 return 0;
1519#endif
1520 }
dfbdccdb
GK
1521 else if (GET_CODE (op) == CONST_DOUBLE)
1522 {
1d328b19 1523 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1524 abort ();
1d328b19
GK
1525
1526 opl = CONST_DOUBLE_LOW (op);
1527 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1528 if (oph != 0)
38886f37 1529 return 0;
dfbdccdb
GK
1530 }
1531 else
1532 return 0;
1d328b19 1533
40501e5f
AM
1534 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1535 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1536}
1537
dcfedcd0 1538/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1539 above), but could be split into one. */
dcfedcd0
RK
1540
1541int
1542non_logical_cint_operand (op, mode)
592696dd 1543 rtx op;
5f59ecb7 1544 enum machine_mode mode;
dcfedcd0 1545{
dfbdccdb 1546 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1547 && ! logical_operand (op, mode)
1548 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1549}
1550
19ba8161 1551/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1552 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1553 Reject all ones and all zeros, since these should have been optimized
1554 away and confuse the making of MB and ME. */
1555
1556int
19ba8161 1557mask_operand (op, mode)
592696dd 1558 rtx op;
19ba8161 1559 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1560{
02071907 1561 HOST_WIDE_INT c, lsb;
9878760c 1562
19ba8161
DE
1563 if (GET_CODE (op) != CONST_INT)
1564 return 0;
1565
1566 c = INTVAL (op);
1567
57deb3a1
AM
1568 /* Fail in 64-bit mode if the mask wraps around because the upper
1569 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1570 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1571 return 0;
1572
c5059423
AM
1573 /* We don't change the number of transitions by inverting,
1574 so make sure we start with the LS bit zero. */
1575 if (c & 1)
1576 c = ~c;
1577
1578 /* Reject all zeros or all ones. */
1579 if (c == 0)
9878760c
RK
1580 return 0;
1581
c5059423
AM
1582 /* Find the first transition. */
1583 lsb = c & -c;
1584
1585 /* Invert to look for a second transition. */
1586 c = ~c;
9878760c 1587
c5059423
AM
1588 /* Erase first transition. */
1589 c &= -lsb;
9878760c 1590
c5059423
AM
1591 /* Find the second transition (if any). */
1592 lsb = c & -c;
1593
1594 /* Match if all the bits above are 1's (or c is zero). */
1595 return c == -lsb;
9878760c
RK
1596}
1597
0ba1b2ff
AM
1598/* Return 1 for the PowerPC64 rlwinm corner case. */
1599
1600int
1601mask_operand_wrap (op, mode)
1602 rtx op;
1603 enum machine_mode mode ATTRIBUTE_UNUSED;
1604{
1605 HOST_WIDE_INT c, lsb;
1606
1607 if (GET_CODE (op) != CONST_INT)
1608 return 0;
1609
1610 c = INTVAL (op);
1611
1612 if ((c & 0x80000001) != 0x80000001)
1613 return 0;
1614
1615 c = ~c;
1616 if (c == 0)
1617 return 0;
1618
1619 lsb = c & -c;
1620 c = ~c;
1621 c &= -lsb;
1622 lsb = c & -c;
1623 return c == -lsb;
1624}
1625
a260abc9
DE
1626/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1627 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1628 Reject all zeros, since zero should have been optimized away and
1629 confuses the making of MB and ME. */
9878760c
RK
1630
1631int
a260abc9 1632mask64_operand (op, mode)
592696dd 1633 rtx op;
0ba1b2ff 1634 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1635{
1636 if (GET_CODE (op) == CONST_INT)
1637 {
02071907 1638 HOST_WIDE_INT c, lsb;
a260abc9 1639
c5059423 1640 c = INTVAL (op);
a260abc9 1641
0ba1b2ff 1642 /* Reject all zeros. */
c5059423 1643 if (c == 0)
e2c953b6
DE
1644 return 0;
1645
0ba1b2ff
AM
1646 /* We don't change the number of transitions by inverting,
1647 so make sure we start with the LS bit zero. */
1648 if (c & 1)
1649 c = ~c;
1650
c5059423
AM
1651 /* Find the transition, and check that all bits above are 1's. */
1652 lsb = c & -c;
1653 return c == -lsb;
e2c953b6 1654 }
0ba1b2ff
AM
1655 return 0;
1656}
1657
1658/* Like mask64_operand, but allow up to three transitions. This
1659 predicate is used by insn patterns that generate two rldicl or
1660 rldicr machine insns. */
1661
1662int
1663mask64_2_operand (op, mode)
1664 rtx op;
1665 enum machine_mode mode ATTRIBUTE_UNUSED;
1666{
1667 if (GET_CODE (op) == CONST_INT)
a260abc9 1668 {
0ba1b2ff 1669 HOST_WIDE_INT c, lsb;
a260abc9 1670
0ba1b2ff 1671 c = INTVAL (op);
a260abc9 1672
0ba1b2ff
AM
1673 /* Disallow all zeros. */
1674 if (c == 0)
1675 return 0;
a260abc9 1676
0ba1b2ff
AM
1677 /* We don't change the number of transitions by inverting,
1678 so make sure we start with the LS bit zero. */
1679 if (c & 1)
1680 c = ~c;
a260abc9 1681
0ba1b2ff
AM
1682 /* Find the first transition. */
1683 lsb = c & -c;
a260abc9 1684
0ba1b2ff
AM
1685 /* Invert to look for a second transition. */
1686 c = ~c;
1687
1688 /* Erase first transition. */
1689 c &= -lsb;
1690
1691 /* Find the second transition. */
1692 lsb = c & -c;
1693
1694 /* Invert to look for a third transition. */
1695 c = ~c;
1696
1697 /* Erase second transition. */
1698 c &= -lsb;
1699
1700 /* Find the third transition (if any). */
1701 lsb = c & -c;
1702
1703 /* Match if all the bits above are 1's (or c is zero). */
1704 return c == -lsb;
1705 }
1706 return 0;
1707}
1708
1709/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1710 implement ANDing by the mask IN. */
1711void
1712build_mask64_2_operands (in, out)
1713 rtx in;
1714 rtx *out;
1715{
1716#if HOST_BITS_PER_WIDE_INT >= 64
1717 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1718 int shift;
1719
1720 if (GET_CODE (in) != CONST_INT)
1721 abort ();
1722
1723 c = INTVAL (in);
1724 if (c & 1)
1725 {
1726 /* Assume c initially something like 0x00fff000000fffff. The idea
1727 is to rotate the word so that the middle ^^^^^^ group of zeros
1728 is at the MS end and can be cleared with an rldicl mask. We then
1729 rotate back and clear off the MS ^^ group of zeros with a
1730 second rldicl. */
1731 c = ~c; /* c == 0xff000ffffff00000 */
1732 lsb = c & -c; /* lsb == 0x0000000000100000 */
1733 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1734 c = ~c; /* c == 0x00fff000000fffff */
1735 c &= -lsb; /* c == 0x00fff00000000000 */
1736 lsb = c & -c; /* lsb == 0x0000100000000000 */
1737 c = ~c; /* c == 0xff000fffffffffff */
1738 c &= -lsb; /* c == 0xff00000000000000 */
1739 shift = 0;
1740 while ((lsb >>= 1) != 0)
1741 shift++; /* shift == 44 on exit from loop */
1742 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1743 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1744 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1745 }
1746 else
0ba1b2ff
AM
1747 {
1748 /* Assume c initially something like 0xff000f0000000000. The idea
1749 is to rotate the word so that the ^^^ middle group of zeros
1750 is at the LS end and can be cleared with an rldicr mask. We then
1751 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1752 a second rldicr. */
1753 lsb = c & -c; /* lsb == 0x0000010000000000 */
1754 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1755 c = ~c; /* c == 0x00fff0ffffffffff */
1756 c &= -lsb; /* c == 0x00fff00000000000 */
1757 lsb = c & -c; /* lsb == 0x0000100000000000 */
1758 c = ~c; /* c == 0xff000fffffffffff */
1759 c &= -lsb; /* c == 0xff00000000000000 */
1760 shift = 0;
1761 while ((lsb >>= 1) != 0)
1762 shift++; /* shift == 44 on exit from loop */
1763 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1764 m1 >>= shift; /* m1 == 0x0000000000000fff */
1765 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1766 }
1767
1768 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1769 masks will be all 1's. We are guaranteed more than one transition. */
1770 out[0] = GEN_INT (64 - shift);
1771 out[1] = GEN_INT (m1);
1772 out[2] = GEN_INT (shift);
1773 out[3] = GEN_INT (m2);
1774#else
045572c7
GK
1775 (void)in;
1776 (void)out;
0ba1b2ff
AM
1777 abort ();
1778#endif
a260abc9
DE
1779}
1780
1781/* Return 1 if the operand is either a non-special register or a constant
1782 that can be used as the operand of a PowerPC64 logical AND insn. */
1783
1784int
1785and64_operand (op, mode)
592696dd 1786 rtx op;
9878760c
RK
1787 enum machine_mode mode;
1788{
a4f6c312 1789 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1790 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1791
1792 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1793}
1794
0ba1b2ff
AM
1795/* Like the above, but also match constants that can be implemented
1796 with two rldicl or rldicr insns. */
1797
1798int
1799and64_2_operand (op, mode)
1800 rtx op;
1801 enum machine_mode mode;
1802{
1803 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1804 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1805
1806 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1807}
1808
a260abc9
DE
1809/* Return 1 if the operand is either a non-special register or a
1810 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1811
1812int
a260abc9 1813and_operand (op, mode)
592696dd 1814 rtx op;
a260abc9 1815 enum machine_mode mode;
dcfedcd0 1816{
a4f6c312 1817 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1818 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1819
1820 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1821}
1822
9878760c
RK
1823/* Return 1 if the operand is a general register or memory operand. */
1824
1825int
1826reg_or_mem_operand (op, mode)
592696dd
SS
1827 rtx op;
1828 enum machine_mode mode;
9878760c 1829{
b6c9286a
MM
1830 return (gpc_reg_operand (op, mode)
1831 || memory_operand (op, mode)
1832 || volatile_mem_operand (op, mode));
9878760c
RK
1833}
1834
a7a813f7 1835/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1836 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1837 instruction. */
1838
1839int
1840lwa_operand (op, mode)
592696dd
SS
1841 rtx op;
1842 enum machine_mode mode;
a7a813f7
RK
1843{
1844 rtx inner = op;
1845
1846 if (reload_completed && GET_CODE (inner) == SUBREG)
1847 inner = SUBREG_REG (inner);
1848
1849 return gpc_reg_operand (inner, mode)
1850 || (memory_operand (inner, mode)
1851 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1852 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1853 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1854 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1855 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1856}
1857
cc4d5fec
JH
1858/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1859
1860int
1861symbol_ref_operand (op, mode)
1862 rtx op;
1863 enum machine_mode mode;
1864{
1865 if (mode != VOIDmode && GET_MODE (op) != mode)
1866 return 0;
1867
1868 return (GET_CODE (op) == SYMBOL_REF);
1869}
1870
9878760c 1871/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1872 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1873
1874int
1875call_operand (op, mode)
592696dd 1876 rtx op;
9878760c
RK
1877 enum machine_mode mode;
1878{
1879 if (mode != VOIDmode && GET_MODE (op) != mode)
1880 return 0;
1881
1882 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1883 || (GET_CODE (op) == REG
1884 && (REGNO (op) == LINK_REGISTER_REGNUM
1885 || REGNO (op) == COUNT_REGISTER_REGNUM
1886 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1887}
1888
2af3d377 1889/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1890 this file and the function is not weakly defined. */
2af3d377
RK
1891
1892int
1893current_file_function_operand (op, mode)
592696dd 1894 rtx op;
296b8152 1895 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1896{
1897 return (GET_CODE (op) == SYMBOL_REF
1898 && (SYMBOL_REF_FLAG (op)
8f1b829e 1899 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1900 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1901}
1902
9878760c
RK
1903/* Return 1 if this operand is a valid input for a move insn. */
1904
1905int
1906input_operand (op, mode)
592696dd 1907 rtx op;
9878760c
RK
1908 enum machine_mode mode;
1909{
eb4e8003 1910 /* Memory is always valid. */
9878760c
RK
1911 if (memory_operand (op, mode))
1912 return 1;
1913
34792e82 1914 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1915 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1916 return 1;
1917
eb4e8003
RK
1918 /* For floating-point, easy constants are valid. */
1919 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1920 && CONSTANT_P (op)
1921 && easy_fp_constant (op, mode))
1922 return 1;
1923
4e74d8ec
MM
1924 /* Allow any integer constant. */
1925 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1926 && (GET_CODE (op) == CONST_INT
e675f625 1927 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1928 return 1;
1929
eb4e8003
RK
1930 /* For floating-point or multi-word mode, the only remaining valid type
1931 is a register. */
9878760c
RK
1932 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1933 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1934 return register_operand (op, mode);
9878760c 1935
88fe15a1
RK
1936 /* The only cases left are integral modes one word or smaller (we
1937 do not get called for MODE_CC values). These can be in any
1938 register. */
1939 if (register_operand (op, mode))
a8b3aeda 1940 return 1;
88fe15a1 1941
84cf9dda 1942 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 1943 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
1944 return 1;
1945
9ebbca7d
GK
1946 /* A constant pool expression (relative to the TOC) is valid */
1947 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
1948 return 1;
1949
88228c4b
MM
1950 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1951 to be valid. */
f607bc57 1952 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
1953 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1954 && small_data_operand (op, Pmode))
1955 return 1;
1956
042259f2 1957 return 0;
9878760c 1958}
7509c759 1959
a4f6c312 1960/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
1961
1962int
1963small_data_operand (op, mode)
296b8152
KG
1964 rtx op ATTRIBUTE_UNUSED;
1965 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 1966{
38c1f2d7 1967#if TARGET_ELF
5f59ecb7 1968 rtx sym_ref;
7509c759 1969
d9407988 1970 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 1971 return 0;
a54d04b7 1972
f607bc57 1973 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
1974 return 0;
1975
88228c4b
MM
1976 if (GET_CODE (op) == SYMBOL_REF)
1977 sym_ref = op;
1978
1979 else if (GET_CODE (op) != CONST
1980 || GET_CODE (XEXP (op, 0)) != PLUS
1981 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
1982 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
1983 return 0;
1984
88228c4b 1985 else
dbf55e53
MM
1986 {
1987 rtx sum = XEXP (op, 0);
1988 HOST_WIDE_INT summand;
1989
1990 /* We have to be careful here, because it is the referenced address
1991 that must be 32k from _SDA_BASE_, not just the symbol. */
1992 summand = INTVAL (XEXP (sum, 1));
1993 if (summand < 0 || summand > g_switch_value)
1994 return 0;
1995
1996 sym_ref = XEXP (sum, 0);
1997 }
88228c4b
MM
1998
1999 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
2000 return 0;
2001
2002 return 1;
d9407988
MM
2003
2004#else
2005 return 0;
2006#endif
7509c759 2007}
9ebbca7d
GK
2008\f
2009static int
2010constant_pool_expr_1 (op, have_sym, have_toc)
2011 rtx op;
2012 int *have_sym;
2013 int *have_toc;
2014{
2015 switch (GET_CODE(op))
2016 {
2017 case SYMBOL_REF:
a4f6c312
SS
2018 if (CONSTANT_POOL_ADDRESS_P (op))
2019 {
2020 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2021 {
2022 *have_sym = 1;
2023 return 1;
2024 }
2025 else
2026 return 0;
2027 }
2028 else if (! strcmp (XSTR (op, 0), toc_label_name))
2029 {
2030 *have_toc = 1;
2031 return 1;
2032 }
2033 else
2034 return 0;
9ebbca7d
GK
2035 case PLUS:
2036 case MINUS:
c1f11548
DE
2037 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2038 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2039 case CONST:
a4f6c312 2040 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2041 case CONST_INT:
a4f6c312 2042 return 1;
9ebbca7d 2043 default:
a4f6c312 2044 return 0;
9ebbca7d
GK
2045 }
2046}
2047
2048int
2049constant_pool_expr_p (op)
2050 rtx op;
2051{
2052 int have_sym = 0;
2053 int have_toc = 0;
2054 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2055}
2056
2057int
2058toc_relative_expr_p (op)
2059 rtx op;
2060{
2061 int have_sym = 0;
2062 int have_toc = 0;
2063 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2064}
2065
2066/* Try machine-dependent ways of modifying an illegitimate address
2067 to be legitimate. If we find one, return the new, valid address.
2068 This is used from only one place: `memory_address' in explow.c.
2069
a4f6c312
SS
2070 OLDX is the address as it was before break_out_memory_refs was
2071 called. In some cases it is useful to look at this to decide what
2072 needs to be done.
9ebbca7d 2073
a4f6c312 2074 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2075
a4f6c312
SS
2076 It is always safe for this function to do nothing. It exists to
2077 recognize opportunities to optimize the output.
9ebbca7d
GK
2078
2079 On RS/6000, first check for the sum of a register with a constant
2080 integer that is out of range. If so, generate code to add the
2081 constant with the low-order 16 bits masked to the register and force
2082 this result into another register (this can be done with `cau').
2083 Then generate an address of REG+(CONST&0xffff), allowing for the
2084 possibility of bit 16 being a one.
2085
2086 Then check for the sum of a register and something not constant, try to
2087 load the other things into a register and return the sum. */
2088rtx
2089rs6000_legitimize_address (x, oldx, mode)
2090 rtx x;
2091 rtx oldx ATTRIBUTE_UNUSED;
2092 enum machine_mode mode;
0ac081f6 2093{
9ebbca7d
GK
2094 if (GET_CODE (x) == PLUS
2095 && GET_CODE (XEXP (x, 0)) == REG
2096 && GET_CODE (XEXP (x, 1)) == CONST_INT
2097 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2098 {
2099 HOST_WIDE_INT high_int, low_int;
2100 rtx sum;
a65c591c
DE
2101 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2102 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2103 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2104 GEN_INT (high_int)), 0);
2105 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2106 }
2107 else if (GET_CODE (x) == PLUS
2108 && GET_CODE (XEXP (x, 0)) == REG
2109 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2110 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2111 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2112 || TARGET_POWERPC64
2113 || mode != DFmode)
9ebbca7d
GK
2114 && (TARGET_POWERPC64 || mode != DImode)
2115 && mode != TImode)
2116 {
2117 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2118 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2119 }
0ac081f6
AH
2120 else if (ALTIVEC_VECTOR_MODE (mode))
2121 {
2122 rtx reg;
2123
2124 /* Make sure both operands are registers. */
2125 if (GET_CODE (x) == PLUS)
9f85ed45 2126 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2127 force_reg (Pmode, XEXP (x, 1)));
2128
2129 reg = force_reg (Pmode, x);
2130 return reg;
2131 }
a3170dc6
AH
2132 else if (SPE_VECTOR_MODE (mode))
2133 {
2134 /* We accept [reg + reg] and [reg + OFFSET]. */
2135
2136 if (GET_CODE (x) == PLUS)
2137 {
2138 rtx op1 = XEXP (x, 0);
2139 rtx op2 = XEXP (x, 1);
2140
2141 op1 = force_reg (Pmode, op1);
2142
2143 if (GET_CODE (op2) != REG
2144 && (GET_CODE (op2) != CONST_INT
2145 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2146 op2 = force_reg (Pmode, op2);
2147
2148 return gen_rtx_PLUS (Pmode, op1, op2);
2149 }
2150
2151 return force_reg (Pmode, x);
2152 }
9ebbca7d
GK
2153 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2154 && GET_CODE (x) != CONST_INT
2155 && GET_CODE (x) != CONST_DOUBLE
2156 && CONSTANT_P (x)
6ac7bf2c
GK
2157 && GET_MODE_NUNITS (mode) == 1
2158 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2159 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2160 {
2161 rtx reg = gen_reg_rtx (Pmode);
2162 emit_insn (gen_elf_high (reg, (x)));
2163 return gen_rtx_LO_SUM (Pmode, reg, (x));
2164 }
ee890fe2
SS
2165 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2166 && ! flag_pic
2167 && GET_CODE (x) != CONST_INT
2168 && GET_CODE (x) != CONST_DOUBLE
2169 && CONSTANT_P (x)
a3170dc6 2170 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2171 && mode != DImode
2172 && mode != TImode)
2173 {
2174 rtx reg = gen_reg_rtx (Pmode);
2175 emit_insn (gen_macho_high (reg, (x)));
2176 return gen_rtx_LO_SUM (Pmode, reg, (x));
2177 }
9ebbca7d
GK
2178 else if (TARGET_TOC
2179 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2180 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2181 {
2182 return create_TOC_reference (x);
2183 }
2184 else
2185 return NULL_RTX;
2186}
258bfae2 2187
24ea750e
DJ
2188/* The convention appears to be to define this wherever it is used.
2189 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2190 is now used here. */
2191#ifndef REG_MODE_OK_FOR_BASE_P
2192#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2193#endif
2194
2195/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2196 replace the input X, or the original X if no replacement is called for.
2197 The output parameter *WIN is 1 if the calling macro should goto WIN,
2198 0 if it should not.
2199
2200 For RS/6000, we wish to handle large displacements off a base
2201 register by splitting the addend across an addiu/addis and the mem insn.
2202 This cuts number of extra insns needed from 3 to 1.
2203
2204 On Darwin, we use this to generate code for floating point constants.
2205 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2206 The Darwin code is inside #if TARGET_MACHO because only then is
2207 machopic_function_base_name() defined. */
2208rtx
2209rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2210 rtx x;
2211 enum machine_mode mode;
2212 int opnum;
2213 int type;
2214 int ind_levels ATTRIBUTE_UNUSED;
2215 int *win;
2216{
2217 /* We must recognize output that we have already generated ourselves. */
2218 if (GET_CODE (x) == PLUS
2219 && GET_CODE (XEXP (x, 0)) == PLUS
2220 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2221 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2222 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2223 {
2224 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2225 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2226 opnum, (enum reload_type)type);
2227 *win = 1;
2228 return x;
2229 }
3deb2758 2230
24ea750e
DJ
2231#if TARGET_MACHO
2232 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2233 && GET_CODE (x) == LO_SUM
2234 && GET_CODE (XEXP (x, 0)) == PLUS
2235 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2236 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2237 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2238 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2239 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2240 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2241 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2242 {
2243 /* Result of previous invocation of this function on Darwin
6f317ef3 2244 floating point constant. */
24ea750e
DJ
2245 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2246 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2247 opnum, (enum reload_type)type);
2248 *win = 1;
2249 return x;
2250 }
2251#endif
2252 if (GET_CODE (x) == PLUS
2253 && GET_CODE (XEXP (x, 0)) == REG
2254 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2255 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2256 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 2257 && !SPE_VECTOR_MODE (mode)
78c875e8 2258 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2259 {
2260 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2261 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2262 HOST_WIDE_INT high
2263 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2264
2265 /* Check for 32-bit overflow. */
2266 if (high + low != val)
2267 {
2268 *win = 0;
2269 return x;
2270 }
2271
2272 /* Reload the high part into a base reg; leave the low part
2273 in the mem directly. */
2274
2275 x = gen_rtx_PLUS (GET_MODE (x),
2276 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2277 GEN_INT (high)),
2278 GEN_INT (low));
2279
2280 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2281 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2282 opnum, (enum reload_type)type);
2283 *win = 1;
2284 return x;
2285 }
2286#if TARGET_MACHO
2287 if (GET_CODE (x) == SYMBOL_REF
2288 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2289 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2290 && flag_pic)
2291 {
2292 /* Darwin load of floating point constant. */
2293 rtx offset = gen_rtx (CONST, Pmode,
2294 gen_rtx (MINUS, Pmode, x,
2295 gen_rtx (SYMBOL_REF, Pmode,
2296 machopic_function_base_name ())));
2297 x = gen_rtx (LO_SUM, GET_MODE (x),
2298 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2299 gen_rtx (HIGH, Pmode, offset)), offset);
2300 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2301 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2302 opnum, (enum reload_type)type);
2303 *win = 1;
2304 return x;
2305 }
2306#endif
2307 if (TARGET_TOC
c1f11548
DE
2308 && CONSTANT_POOL_EXPR_P (x)
2309 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2310 {
2311 (x) = create_TOC_reference (x);
2312 *win = 1;
2313 return x;
2314 }
2315 *win = 0;
2316 return x;
2317}
2318
258bfae2
FS
2319/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2320 that is a valid memory address for an instruction.
2321 The MODE argument is the machine mode for the MEM expression
2322 that wants to use this address.
2323
2324 On the RS/6000, there are four valid address: a SYMBOL_REF that
2325 refers to a constant pool entry of an address (or the sum of it
2326 plus a constant), a short (16-bit signed) constant plus a register,
2327 the sum of two registers, or a register indirect, possibly with an
2328 auto-increment. For DFmode and DImode with an constant plus register,
2329 we must ensure that both words are addressable or PowerPC64 with offset
2330 word aligned.
2331
2332 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2333 32-bit DImode, TImode), indexed addressing cannot be used because
2334 adjacent memory cells are accessed by adding word-sized offsets
2335 during assembly output. */
2336int
2337rs6000_legitimate_address (mode, x, reg_ok_strict)
2338 enum machine_mode mode;
2339 rtx x;
2340 int reg_ok_strict;
2341{
2342 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2343 return 1;
2344 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2345 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2346 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2347 && TARGET_UPDATE
2348 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2349 return 1;
2350 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2351 return 1;
2352 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2353 return 1;
2354 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2355 if (! reg_ok_strict
2356 && GET_CODE (x) == PLUS
2357 && GET_CODE (XEXP (x, 0)) == REG
2358 && XEXP (x, 0) == virtual_stack_vars_rtx
2359 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2360 return 1;
2361 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2362 return 1;
2363 if (mode != TImode
a3170dc6
AH
2364 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2365 || TARGET_POWERPC64
2366 || mode != DFmode)
258bfae2
FS
2367 && (TARGET_POWERPC64 || mode != DImode)
2368 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2369 return 1;
2370 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2371 return 1;
2372 return 0;
2373}
fb4d4348 2374\f
a4f6c312
SS
2375/* Try to output insns to set TARGET equal to the constant C if it can
2376 be done in less than N insns. Do all computations in MODE.
2377 Returns the place where the output has been placed if it can be
2378 done and the insns have been emitted. If it would take more than N
2379 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2380
2381rtx
2382rs6000_emit_set_const (dest, mode, source, n)
2383 rtx dest, source;
2384 enum machine_mode mode;
2385 int n ATTRIBUTE_UNUSED;
2386{
af8cb5c5 2387 rtx result, insn, set;
2bfcf297
DB
2388 HOST_WIDE_INT c0, c1;
2389
af8cb5c5 2390 if (mode == QImode || mode == HImode)
2bfcf297
DB
2391 {
2392 if (dest == NULL)
2393 dest = gen_reg_rtx (mode);
2394 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2395 return dest;
2396 }
af8cb5c5 2397 else if (mode == SImode)
2bfcf297 2398 {
af8cb5c5
DE
2399 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2400
2401 emit_insn (gen_rtx_SET (VOIDmode, result,
2402 GEN_INT (INTVAL (source)
2403 & (~ (HOST_WIDE_INT) 0xffff))));
2404 emit_insn (gen_rtx_SET (VOIDmode, dest,
2405 gen_rtx_IOR (SImode, result,
2406 GEN_INT (INTVAL (source) & 0xffff))));
2407 result = dest;
2bfcf297 2408 }
af8cb5c5 2409 else if (mode == DImode)
2bfcf297 2410 {
af8cb5c5
DE
2411 if (GET_CODE (source) == CONST_INT)
2412 {
2413 c0 = INTVAL (source);
2414 c1 = -(c0 < 0);
2415 }
2416 else if (GET_CODE (source) == CONST_DOUBLE)
2417 {
2bfcf297 2418#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
2419 c0 = CONST_DOUBLE_LOW (source);
2420 c1 = -(c0 < 0);
2bfcf297 2421#else
af8cb5c5
DE
2422 c0 = CONST_DOUBLE_LOW (source);
2423 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 2424#endif
af8cb5c5
DE
2425 }
2426 else
2427 abort ();
2428
2429 result = rs6000_emit_set_long_const (dest, c0, c1);
2bfcf297
DB
2430 }
2431 else
a4f6c312 2432 abort ();
2bfcf297 2433
af8cb5c5
DE
2434 insn = get_last_insn ();
2435 set = single_set (insn);
2436 if (! CONSTANT_P (SET_SRC (set)))
2437 set_unique_reg_note (insn, REG_EQUAL, source);
2438
2439 return result;
2bfcf297
DB
2440}
2441
2442/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2443 fall back to a straight forward decomposition. We do this to avoid
2444 exponential run times encountered when looking for longer sequences
2445 with rs6000_emit_set_const. */
2446static rtx
2447rs6000_emit_set_long_const (dest, c1, c2)
2448 rtx dest;
2449 HOST_WIDE_INT c1, c2;
2450{
2451 if (!TARGET_POWERPC64)
2452 {
2453 rtx operand1, operand2;
2454
2455 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2456 DImode);
2457 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2458 DImode);
2459 emit_move_insn (operand1, GEN_INT (c1));
2460 emit_move_insn (operand2, GEN_INT (c2));
2461 }
2462 else
2463 {
bc06712d 2464 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2465
bc06712d
TR
2466 ud1 = c1 & 0xffff;
2467 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2468#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2469 c2 = c1 >> 32;
2bfcf297 2470#endif
bc06712d
TR
2471 ud3 = c2 & 0xffff;
2472 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2473
bc06712d
TR
2474 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2475 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2476 {
bc06712d
TR
2477 if (ud1 & 0x8000)
2478 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2479 else
2480 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2481 }
2bfcf297 2482
bc06712d
TR
2483 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2484 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2485 {
bc06712d
TR
2486 if (ud2 & 0x8000)
2487 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2488 - 0x80000000));
252b88f7 2489 else
bc06712d
TR
2490 emit_move_insn (dest, GEN_INT (ud2 << 16));
2491 if (ud1 != 0)
2492 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2493 }
bc06712d
TR
2494 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2495 || (ud4 == 0 && ! (ud3 & 0x8000)))
2496 {
2497 if (ud3 & 0x8000)
2498 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2499 - 0x80000000));
2500 else
2501 emit_move_insn (dest, GEN_INT (ud3 << 16));
2502
2503 if (ud2 != 0)
2504 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2505 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2506 if (ud1 != 0)
2507 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2508 }
2509 else
2510 {
2511 if (ud4 & 0x8000)
2512 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2513 - 0x80000000));
2514 else
2515 emit_move_insn (dest, GEN_INT (ud4 << 16));
2516
2517 if (ud3 != 0)
2518 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2519
bc06712d
TR
2520 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2521 if (ud2 != 0)
2522 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2523 GEN_INT (ud2 << 16)));
2524 if (ud1 != 0)
2525 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2526 }
2527 }
2bfcf297
DB
2528 return dest;
2529}
2530
fb4d4348
GK
2531/* Emit a move from SOURCE to DEST in mode MODE. */
2532void
2533rs6000_emit_move (dest, source, mode)
2534 rtx dest;
2535 rtx source;
2536 enum machine_mode mode;
2537{
2538 rtx operands[2];
2539 operands[0] = dest;
2540 operands[1] = source;
2541
2542 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2543 if (GET_CODE (operands[1]) == CONST_DOUBLE
2544 && ! FLOAT_MODE_P (mode)
2545 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2546 {
2547 /* FIXME. This should never happen. */
2548 /* Since it seems that it does, do the safe thing and convert
2549 to a CONST_INT. */
2496c7bd 2550 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2551 }
2552 if (GET_CODE (operands[1]) == CONST_DOUBLE
2553 && ! FLOAT_MODE_P (mode)
2554 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2555 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2556 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2557 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2558 abort ();
c9e8cb32
DD
2559
2560 /* Check if GCC is setting up a block move that will end up using FP
2561 registers as temporaries. We must make sure this is acceptable. */
2562 if (GET_CODE (operands[0]) == MEM
2563 && GET_CODE (operands[1]) == MEM
2564 && mode == DImode
41543739
GK
2565 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2566 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2567 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2568 ? 32 : MEM_ALIGN (operands[0])))
2569 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2570 ? 32
2571 : MEM_ALIGN (operands[1]))))
2572 && ! MEM_VOLATILE_P (operands [0])
2573 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2574 {
41543739
GK
2575 emit_move_insn (adjust_address (operands[0], SImode, 0),
2576 adjust_address (operands[1], SImode, 0));
2577 emit_move_insn (adjust_address (operands[0], SImode, 4),
2578 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2579 return;
2580 }
fb4d4348
GK
2581
2582 if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
2583 operands[1] = force_reg (mode, operands[1]);
a9098fd0 2584
a3170dc6
AH
2585 if (mode == SFmode && ! TARGET_POWERPC
2586 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2587 && GET_CODE (operands[0]) == MEM)
fb4d4348 2588 {
ffc14f31
GK
2589 int regnum;
2590
2591 if (reload_in_progress || reload_completed)
2592 regnum = true_regnum (operands[1]);
2593 else if (GET_CODE (operands[1]) == REG)
2594 regnum = REGNO (operands[1]);
2595 else
2596 regnum = -1;
fb4d4348
GK
2597
2598 /* If operands[1] is a register, on POWER it may have
2599 double-precision data in it, so truncate it to single
2600 precision. */
2601 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2602 {
2603 rtx newreg;
2604 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2605 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2606 operands[1] = newreg;
2607 }
2608 }
2609
a9098fd0
GK
2610 /* Handle the case where reload calls us with an invalid address;
2611 and the case of CONSTANT_P_RTX. */
16861f33 2612 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2613 && (! general_operand (operands[1], mode)
2614 || ! nonimmediate_operand (operands[0], mode)
2615 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2616 {
2617 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2618 return;
2619 }
a9098fd0 2620
fb4d4348
GK
2621 /* FIXME: In the long term, this switch statement should go away
2622 and be replaced by a sequence of tests based on things like
2623 mode == Pmode. */
2624 switch (mode)
2625 {
2626 case HImode:
2627 case QImode:
2628 if (CONSTANT_P (operands[1])
2629 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2630 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2631 break;
2632
06f4e019 2633 case TFmode:
fb4d4348
GK
2634 case DFmode:
2635 case SFmode:
2636 if (CONSTANT_P (operands[1])
2637 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2638 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2639 break;
2640
0ac081f6
AH
2641 case V16QImode:
2642 case V8HImode:
2643 case V4SFmode:
2644 case V4SImode:
a3170dc6
AH
2645 case V4HImode:
2646 case V2SFmode:
2647 case V2SImode:
69ef87e2
AH
2648 if (CONSTANT_P (operands[1])
2649 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2650 operands[1] = force_const_mem (mode, operands[1]);
2651 break;
2652
fb4d4348 2653 case SImode:
a9098fd0 2654 case DImode:
fb4d4348
GK
2655 /* Use default pattern for address of ELF small data */
2656 if (TARGET_ELF
a9098fd0 2657 && mode == Pmode
f607bc57 2658 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2659 && (GET_CODE (operands[1]) == SYMBOL_REF
2660 || GET_CODE (operands[1]) == CONST)
2661 && small_data_operand (operands[1], mode))
fb4d4348
GK
2662 {
2663 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2664 return;
2665 }
2666
f607bc57 2667 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2668 && mode == Pmode && mode == SImode
2669 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2670 {
2671 emit_insn (gen_movsi_got (operands[0], operands[1]));
2672 return;
2673 }
2674
ee890fe2
SS
2675 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2676 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2677 && mode == Pmode
fb4d4348
GK
2678 && CONSTANT_P (operands[1])
2679 && GET_CODE (operands[1]) != HIGH
2680 && GET_CODE (operands[1]) != CONST_INT)
2681 {
a9098fd0 2682 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2683
2684 /* If this is a function address on -mcall-aixdesc,
2685 convert it to the address of the descriptor. */
2686 if (DEFAULT_ABI == ABI_AIX
2687 && GET_CODE (operands[1]) == SYMBOL_REF
2688 && XSTR (operands[1], 0)[0] == '.')
2689 {
2690 const char *name = XSTR (operands[1], 0);
2691 rtx new_ref;
2692 while (*name == '.')
2693 name++;
2694 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2695 CONSTANT_POOL_ADDRESS_P (new_ref)
2696 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2697 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2698 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2699 operands[1] = new_ref;
2700 }
7509c759 2701
ee890fe2
SS
2702 if (DEFAULT_ABI == ABI_DARWIN)
2703 {
2704 emit_insn (gen_macho_high (target, operands[1]));
2705 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2706 return;
2707 }
2708
fb4d4348
GK
2709 emit_insn (gen_elf_high (target, operands[1]));
2710 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2711 return;
2712 }
2713
a9098fd0
GK
2714 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2715 and we have put it in the TOC, we just need to make a TOC-relative
2716 reference to it. */
2717 if (TARGET_TOC
2718 && GET_CODE (operands[1]) == SYMBOL_REF
2719 && CONSTANT_POOL_EXPR_P (operands[1])
2720 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2721 get_pool_mode (operands[1])))
fb4d4348 2722 {
a9098fd0 2723 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2724 }
a9098fd0
GK
2725 else if (mode == Pmode
2726 && CONSTANT_P (operands[1])
38886f37
AO
2727 && ((GET_CODE (operands[1]) != CONST_INT
2728 && ! easy_fp_constant (operands[1], mode))
2729 || (GET_CODE (operands[1]) == CONST_INT
2730 && num_insns_constant (operands[1], mode) > 2)
2731 || (GET_CODE (operands[0]) == REG
2732 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2733 && GET_CODE (operands[1]) != HIGH
2734 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2735 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2736 {
2737 /* Emit a USE operation so that the constant isn't deleted if
2738 expensive optimizations are turned on because nobody
2739 references it. This should only be done for operands that
2740 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2741 This should not be done for operands that contain LABEL_REFs.
2742 For now, we just handle the obvious case. */
2743 if (GET_CODE (operands[1]) != LABEL_REF)
2744 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2745
c859cda6 2746#if TARGET_MACHO
ee890fe2
SS
2747 /* Darwin uses a special PIC legitimizer. */
2748 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2749 {
ee890fe2
SS
2750 operands[1] =
2751 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2752 operands[0]);
2753 if (operands[0] != operands[1])
2754 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2755 return;
2756 }
c859cda6 2757#endif
ee890fe2 2758
fb4d4348
GK
2759 /* If we are to limit the number of things we put in the TOC and
2760 this is a symbol plus a constant we can add in one insn,
2761 just put the symbol in the TOC and add the constant. Don't do
2762 this if reload is in progress. */
2763 if (GET_CODE (operands[1]) == CONST
2764 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2765 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2766 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2767 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2768 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2769 && ! side_effects_p (operands[0]))
2770 {
a4f6c312
SS
2771 rtx sym =
2772 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2773 rtx other = XEXP (XEXP (operands[1], 0), 1);
2774
a9098fd0
GK
2775 sym = force_reg (mode, sym);
2776 if (mode == SImode)
2777 emit_insn (gen_addsi3 (operands[0], sym, other));
2778 else
2779 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2780 return;
2781 }
2782
a9098fd0 2783 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2784
2785 if (TARGET_TOC
d34c5b80
DE
2786 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2787 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2788 get_pool_constant (XEXP (operands[1], 0)),
2789 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2790 {
ba4828e0
RK
2791 operands[1]
2792 = gen_rtx_MEM (mode,
2793 create_TOC_reference (XEXP (operands[1], 0)));
2794 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2795 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2796 }
fb4d4348
GK
2797 }
2798 break;
a9098fd0 2799
fb4d4348
GK
2800 case TImode:
2801 if (GET_CODE (operands[0]) == MEM
2802 && GET_CODE (XEXP (operands[0], 0)) != REG
2803 && ! reload_in_progress)
792760b9
RK
2804 operands[0]
2805 = replace_equiv_address (operands[0],
2806 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2807
2808 if (GET_CODE (operands[1]) == MEM
2809 && GET_CODE (XEXP (operands[1], 0)) != REG
2810 && ! reload_in_progress)
792760b9
RK
2811 operands[1]
2812 = replace_equiv_address (operands[1],
2813 copy_addr_to_reg (XEXP (operands[1], 0)));
fb4d4348
GK
2814 break;
2815
2816 default:
2817 abort ();
2818 }
2819
a9098fd0
GK
2820 /* Above, we may have called force_const_mem which may have returned
2821 an invalid address. If we can, fix this up; otherwise, reload will
2822 have to deal with it. */
2823 if (GET_CODE (operands[1]) == MEM
2824 && ! memory_address_p (mode, XEXP (operands[1], 0))
2825 && ! reload_in_progress)
f4ef873c 2826 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2827
fb4d4348 2828 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2829 return;
fb4d4348 2830}
4697a36c
MM
2831\f
2832/* Initialize a variable CUM of type CUMULATIVE_ARGS
2833 for a call to a function whose data type is FNTYPE.
2834 For a library call, FNTYPE is 0.
2835
2836 For incoming args we set the number of arguments in the prototype large
1c20ae99 2837 so we never return a PARALLEL. */
4697a36c
MM
2838
2839void
2840init_cumulative_args (cum, fntype, libname, incoming)
2841 CUMULATIVE_ARGS *cum;
2842 tree fntype;
296b8152 2843 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2844 int incoming;
2845{
2846 static CUMULATIVE_ARGS zero_cumulative;
2847
2848 *cum = zero_cumulative;
2849 cum->words = 0;
2850 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2851 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2852 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2853 cum->call_cookie = CALL_NORMAL;
4cc833b7 2854 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2855
2856 if (incoming)
bd227acc 2857 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2858
2859 else if (cum->prototype)
2860 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2861 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2862 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2863
2864 else
2865 cum->nargs_prototype = 0;
2866
2867 cum->orig_nargs = cum->nargs_prototype;
7509c759 2868
a5c76ee6
ZW
2869 /* Check for a longcall attribute. */
2870 if (fntype
2871 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2872 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2873 cum->call_cookie = CALL_LONG;
2874
4697a36c
MM
2875 if (TARGET_DEBUG_ARG)
2876 {
2877 fprintf (stderr, "\ninit_cumulative_args:");
2878 if (fntype)
2879 {
2880 tree ret_type = TREE_TYPE (fntype);
2881 fprintf (stderr, " ret code = %s,",
2882 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2883 }
2884
6a4cee5f
MM
2885 if (cum->call_cookie & CALL_LONG)
2886 fprintf (stderr, " longcall,");
2887
4697a36c
MM
2888 fprintf (stderr, " proto = %d, nargs = %d\n",
2889 cum->prototype, cum->nargs_prototype);
2890 }
2891}
2892\f
c229cba9
DE
2893/* If defined, a C expression which determines whether, and in which
2894 direction, to pad out an argument with extra space. The value
2895 should be of type `enum direction': either `upward' to pad above
2896 the argument, `downward' to pad below, or `none' to inhibit
2897 padding.
2898
2899 For the AIX ABI structs are always stored left shifted in their
2900 argument slot. */
2901
9ebbca7d 2902enum direction
c229cba9
DE
2903function_arg_padding (mode, type)
2904 enum machine_mode mode;
2905 tree type;
2906{
c85f7c16 2907 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 2908 return upward;
c229cba9
DE
2909
2910 /* This is the default definition. */
2911 return (! BYTES_BIG_ENDIAN
9ebbca7d 2912 ? upward
c229cba9
DE
2913 : ((mode == BLKmode
2914 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2915 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2916 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 2917 ? downward : upward));
c229cba9
DE
2918}
2919
b6c9286a
MM
2920/* If defined, a C expression that gives the alignment boundary, in bits,
2921 of an argument with the specified mode and type. If it is not defined,
2922 PARM_BOUNDARY is used for all arguments.
2923
2310f99a 2924 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
2925
2926int
2927function_arg_boundary (mode, type)
2928 enum machine_mode mode;
9ebbca7d 2929 tree type ATTRIBUTE_UNUSED;
b6c9286a 2930{
f607bc57 2931 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 2932 return 64;
a3170dc6
AH
2933 else if (SPE_VECTOR_MODE (mode))
2934 return 64;
0ac081f6
AH
2935 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2936 return 128;
9ebbca7d 2937 else
b6c9286a 2938 return PARM_BOUNDARY;
b6c9286a
MM
2939}
2940\f
4697a36c
MM
2941/* Update the data in CUM to advance over an argument
2942 of mode MODE and data type TYPE.
2943 (TYPE is null for libcalls where that information may not be available.) */
2944
2945void
2946function_arg_advance (cum, mode, type, named)
2947 CUMULATIVE_ARGS *cum;
2948 enum machine_mode mode;
2949 tree type;
2950 int named;
2951{
2952 cum->nargs_prototype--;
2953
0ac081f6
AH
2954 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2955 {
2956 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2957 cum->vregno++;
2958 else
2959 cum->words += RS6000_ARG_SIZE (mode, type);
2960 }
a4b0320c
AH
2961 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
2962 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
2963 cum->sysv_gregno++;
f607bc57 2964 else if (DEFAULT_ABI == ABI_V4)
4697a36c 2965 {
a3170dc6 2966 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 2967 && (mode == SFmode || mode == DFmode))
4697a36c 2968 {
4cc833b7
RH
2969 if (cum->fregno <= FP_ARG_V4_MAX_REG)
2970 cum->fregno++;
2971 else
2972 {
2973 if (mode == DFmode)
2974 cum->words += cum->words & 1;
d34c5b80 2975 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 2976 }
4697a36c 2977 }
4cc833b7
RH
2978 else
2979 {
2980 int n_words;
2981 int gregno = cum->sysv_gregno;
2982
2983 /* Aggregates and IEEE quad get passed by reference. */
2984 if ((type && AGGREGATE_TYPE_P (type))
2985 || mode == TFmode)
2986 n_words = 1;
2987 else
d34c5b80 2988 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 2989
a4b0320c 2990 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
2991 if (n_words == 2 && (gregno & 1) == 0)
2992 gregno += 1;
2993
a4b0320c
AH
2994 /* Long long and SPE vectors are not split between registers
2995 and stack. */
4cc833b7
RH
2996 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
2997 {
2998 /* Long long is aligned on the stack. */
2999 if (n_words == 2)
3000 cum->words += cum->words & 1;
3001 cum->words += n_words;
3002 }
4697a36c 3003
4cc833b7
RH
3004 /* Note: continuing to accumulate gregno past when we've started
3005 spilling to the stack indicates the fact that we've started
3006 spilling to the stack to expand_builtin_saveregs. */
3007 cum->sysv_gregno = gregno + n_words;
3008 }
4697a36c 3009
4cc833b7
RH
3010 if (TARGET_DEBUG_ARG)
3011 {
3012 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3013 cum->words, cum->fregno);
3014 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3015 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3016 fprintf (stderr, "mode = %4s, named = %d\n",
3017 GET_MODE_NAME (mode), named);
3018 }
4697a36c
MM
3019 }
3020 else
4cc833b7
RH
3021 {
3022 int align = (TARGET_32BIT && (cum->words & 1) != 0
3023 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 3024
d34c5b80 3025 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 3026
a3170dc6
AH
3027 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3028 && TARGET_HARD_FLOAT && TARGET_FPRS)
d34c5b80 3029 cum->fregno++;
4cc833b7
RH
3030
3031 if (TARGET_DEBUG_ARG)
3032 {
3033 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3034 cum->words, cum->fregno);
3035 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3036 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3037 fprintf (stderr, "named = %d, align = %d\n", named, align);
3038 }
3039 }
4697a36c
MM
3040}
3041\f
3042/* Determine where to put an argument to a function.
3043 Value is zero to push the argument on the stack,
3044 or a hard register in which to store the argument.
3045
3046 MODE is the argument's machine mode.
3047 TYPE is the data type of the argument (as a tree).
3048 This is null for libcalls where that information may
3049 not be available.
3050 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3051 the preceding args and about the function being called.
3052 NAMED is nonzero if this argument is a named parameter
3053 (otherwise it is an extra parameter matching an ellipsis).
3054
3055 On RS/6000 the first eight words of non-FP are normally in registers
3056 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3057 Under V.4, the first 8 FP args are in registers.
3058
3059 If this is floating-point and no prototype is specified, we use
3060 both an FP and integer register (or possibly FP reg and stack). Library
3061 functions (when TYPE is zero) always have the proper types for args,
3062 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3063 doesn't support PARALLEL anyway. */
4697a36c
MM
3064
3065struct rtx_def *
3066function_arg (cum, mode, type, named)
3067 CUMULATIVE_ARGS *cum;
3068 enum machine_mode mode;
3069 tree type;
20c29ebe 3070 int named;
4697a36c 3071{
4cc833b7 3072 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3073
a4f6c312
SS
3074 /* Return a marker to indicate whether CR1 needs to set or clear the
3075 bit that V.4 uses to say fp args were passed in registers.
3076 Assume that we don't need the marker for software floating point,
3077 or compiler generated library calls. */
4697a36c
MM
3078 if (mode == VOIDmode)
3079 {
f607bc57 3080 if (abi == ABI_V4
7509c759 3081 && cum->nargs_prototype < 0
4697a36c 3082 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3083 {
a3170dc6
AH
3084 /* For the SPE, we need to crxor CR6 always. */
3085 if (TARGET_SPE_ABI)
3086 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3087 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3088 return GEN_INT (cum->call_cookie
3089 | ((cum->fregno == FP_ARG_MIN_REG)
3090 ? CALL_V4_SET_FP_ARGS
3091 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3092 }
4697a36c 3093
7509c759 3094 return GEN_INT (cum->call_cookie);
4697a36c
MM
3095 }
3096
0ac081f6
AH
3097 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3098 {
20c29ebe 3099 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3100 return gen_rtx_REG (mode, cum->vregno);
3101 else
3102 return NULL;
3103 }
a4b0320c 3104 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3105 {
a4b0320c 3106 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3107 return gen_rtx_REG (mode, cum->sysv_gregno);
3108 else
3109 return NULL;
3110 }
f607bc57 3111 else if (abi == ABI_V4)
4697a36c 3112 {
a3170dc6 3113 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3114 && (mode == SFmode || mode == DFmode))
3115 {
3116 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3117 return gen_rtx_REG (mode, cum->fregno);
3118 else
3119 return NULL;
3120 }
3121 else
3122 {
3123 int n_words;
3124 int gregno = cum->sysv_gregno;
3125
3126 /* Aggregates and IEEE quad get passed by reference. */
3127 if ((type && AGGREGATE_TYPE_P (type))
3128 || mode == TFmode)
3129 n_words = 1;
3130 else
d34c5b80 3131 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3132
a4b0320c 3133 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3134 if (n_words == 2 && (gregno & 1) == 0)
3135 gregno += 1;
3136
a4b0320c
AH
3137 /* Long long and SPE vectors are not split between registers
3138 and stack. */
4cc833b7 3139 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3140 {
3141 /* SPE vectors in ... get split into 2 registers. */
3142 if (TARGET_SPE && TARGET_SPE_ABI
3143 && SPE_VECTOR_MODE (mode) && !named)
3144 {
3145 rtx r1, r2;
3146 enum machine_mode m = GET_MODE_INNER (mode);
3147
3148 r1 = gen_rtx_REG (m, gregno);
3149 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3150 r2 = gen_rtx_REG (m, gregno + 1);
3151 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3152 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3153 }
3154 return gen_rtx_REG (mode, gregno);
3155 }
4cc833b7
RH
3156 else
3157 return NULL;
3158 }
4697a36c 3159 }
4cc833b7
RH
3160 else
3161 {
3162 int align = (TARGET_32BIT && (cum->words & 1) != 0
3163 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3164 int align_words = cum->words + align;
4697a36c 3165
4cc833b7
RH
3166 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3167 return NULL_RTX;
3168
3169 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3170 {
3171 if (! type
3172 || ((cum->nargs_prototype > 0)
3173 /* IBM AIX extended its linkage convention definition always
3174 to require FP args after register save area hole on the
3175 stack. */
3176 && (DEFAULT_ABI != ABI_AIX
3177 || ! TARGET_XL_CALL
3178 || (align_words < GP_ARG_NUM_REG))))
3179 return gen_rtx_REG (mode, cum->fregno);
3180
3181 return gen_rtx_PARALLEL (mode,
3182 gen_rtvec (2,
39403d82 3183 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3184 ((align_words >= GP_ARG_NUM_REG)
3185 ? NULL_RTX
3186 : (align_words
d34c5b80 3187 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3188 > GP_ARG_NUM_REG
3189 /* If this is partially on the stack, then
3190 we only include the portion actually
3191 in registers here. */
39403d82 3192 ? gen_rtx_REG (SImode,
1c20ae99 3193 GP_ARG_MIN_REG + align_words)
39403d82 3194 : gen_rtx_REG (mode,
1c20ae99
JW
3195 GP_ARG_MIN_REG + align_words))),
3196 const0_rtx),
39403d82
DE
3197 gen_rtx_EXPR_LIST (VOIDmode,
3198 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3199 const0_rtx)));
4cc833b7
RH
3200 }
3201 else if (align_words < GP_ARG_NUM_REG)
3202 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3203 else
3204 return NULL_RTX;
4697a36c 3205 }
4697a36c
MM
3206}
3207\f
3208/* For an arg passed partly in registers and partly in memory,
3209 this is the number of registers used.
3210 For args passed entirely in registers or entirely in memory, zero. */
3211
3212int
3213function_arg_partial_nregs (cum, mode, type, named)
3214 CUMULATIVE_ARGS *cum;
3215 enum machine_mode mode;
3216 tree type;
d34c5b80 3217 int named ATTRIBUTE_UNUSED;
4697a36c 3218{
f607bc57 3219 if (DEFAULT_ABI == ABI_V4)
4697a36c 3220 return 0;
4697a36c 3221
0ac081f6
AH
3222 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3223 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3224 {
3225 if (cum->nargs_prototype >= 0)
3226 return 0;
3227 }
3228
3229 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3230 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3231 {
3232 int ret = GP_ARG_NUM_REG - cum->words;
3233 if (ret && TARGET_DEBUG_ARG)
3234 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3235
3236 return ret;
3237 }
3238
3239 return 0;
3240}
3241\f
3242/* A C expression that indicates when an argument must be passed by
3243 reference. If nonzero for an argument, a copy of that argument is
3244 made in memory and a pointer to the argument is passed instead of
3245 the argument itself. The pointer is passed in whatever way is
3246 appropriate for passing a pointer to that type.
3247
3248 Under V.4, structures and unions are passed by reference. */
3249
3250int
3251function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3252 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3253 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3254 tree type;
296b8152 3255 int named ATTRIBUTE_UNUSED;
4697a36c 3256{
f607bc57 3257 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3258 && ((type && AGGREGATE_TYPE_P (type))
3259 || mode == TFmode))
4697a36c
MM
3260 {
3261 if (TARGET_DEBUG_ARG)
3262 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3263
3264 return 1;
3265 }
4697a36c
MM
3266
3267 return 0;
3268}
4697a36c
MM
3269\f
3270/* Perform any needed actions needed for a function that is receiving a
3271 variable number of arguments.
3272
3273 CUM is as above.
3274
3275 MODE and TYPE are the mode and type of the current parameter.
3276
3277 PRETEND_SIZE is a variable that should be set to the amount of stack
3278 that must be pushed by the prolog to pretend that our caller pushed
3279 it.
3280
3281 Normally, this macro will push all remaining incoming registers on the
3282 stack and set PRETEND_SIZE to the length of the registers pushed. */
3283
3284void
3285setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3286 CUMULATIVE_ARGS *cum;
3287 enum machine_mode mode;
3288 tree type;
3289 int *pretend_size;
3290 int no_rtl;
3291
3292{
4cc833b7
RH
3293 CUMULATIVE_ARGS next_cum;
3294 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3295 rtx save_area = NULL_RTX, mem;
dfafc897 3296 int first_reg_offset, set;
d34c5b80
DE
3297 tree fntype;
3298 int stdarg_p;
4697a36c 3299
d34c5b80
DE
3300 fntype = TREE_TYPE (current_function_decl);
3301 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3302 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3303 != void_type_node));
4cc833b7 3304
d34c5b80
DE
3305 /* For varargs, we do not want to skip the dummy va_dcl argument.
3306 For stdargs, we do want to skip the last named argument. */
3307 next_cum = *cum;
3308 if (stdarg_p)
3309 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3310
f607bc57 3311 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3312 {
4cc833b7 3313 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3314 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3315 if (! no_rtl)
2c4974b7 3316 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3317 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3318
3319 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3320 }
60e2d0ca 3321 else
4697a36c 3322 {
d34c5b80 3323 first_reg_offset = next_cum.words;
4cc833b7 3324 save_area = virtual_incoming_args_rtx;
00dba523 3325 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3326
3327 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3328 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3329 }
4697a36c 3330
dfafc897 3331 set = get_varargs_alias_set ();
c81fc13e 3332 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3333 {
dfafc897
FS
3334 mem = gen_rtx_MEM (BLKmode,
3335 plus_constant (save_area,
3336 first_reg_offset * reg_size)),
ba4828e0 3337 set_mem_alias_set (mem, set);
8ac61af7 3338 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3339
4cc833b7 3340 move_block_from_reg
dfafc897 3341 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3342 GP_ARG_NUM_REG - first_reg_offset,
3343 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
3344
3345 /* ??? Does ABI_V4 need this at all? */
4697a36c
MM
3346 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
3347 }
3348
4697a36c 3349 /* Save FP registers if needed. */
f607bc57 3350 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3351 && TARGET_HARD_FLOAT && TARGET_FPRS
3352 && ! no_rtl
4cc833b7 3353 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3354 {
4cc833b7 3355 int fregno = next_cum.fregno;
9ebbca7d 3356 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3357 rtx lab = gen_label_rtx ();
3358 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3359
4cc833b7 3360 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3361 pc_rtx,
39403d82 3362 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3363 gen_rtx_NE (VOIDmode, cr1,
3364 const0_rtx),
39403d82 3365 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3366 pc_rtx)));
3367
4cc833b7
RH
3368 while (fregno <= FP_ARG_V4_MAX_REG)
3369 {
dfafc897 3370 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3371 set_mem_alias_set (mem, set);
dfafc897 3372 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3373 fregno++;
3374 off += 8;
4697a36c 3375 }
4cc833b7
RH
3376
3377 emit_label (lab);
4697a36c 3378 }
4697a36c 3379}
4697a36c 3380
dfafc897 3381/* Create the va_list data type. */
2c4974b7 3382
dfafc897
FS
3383tree
3384rs6000_build_va_list ()
3385{
bab45a51 3386 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3387
9ebbca7d
GK
3388 /* For AIX, prefer 'char *' because that's what the system
3389 header files like. */
f607bc57 3390 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3391 return build_pointer_type (char_type_node);
dfafc897 3392
f1e639b1 3393 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3394 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3395
9ebbca7d
GK
3396 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3397 unsigned_char_type_node);
3398 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3399 unsigned_char_type_node);
dfafc897
FS
3400 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3401 ptr_type_node);
3402 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3403 ptr_type_node);
3404
3405 DECL_FIELD_CONTEXT (f_gpr) = record;
3406 DECL_FIELD_CONTEXT (f_fpr) = record;
3407 DECL_FIELD_CONTEXT (f_ovf) = record;
3408 DECL_FIELD_CONTEXT (f_sav) = record;
3409
bab45a51
FS
3410 TREE_CHAIN (record) = type_decl;
3411 TYPE_NAME (record) = type_decl;
dfafc897
FS
3412 TYPE_FIELDS (record) = f_gpr;
3413 TREE_CHAIN (f_gpr) = f_fpr;
3414 TREE_CHAIN (f_fpr) = f_ovf;
3415 TREE_CHAIN (f_ovf) = f_sav;
3416
3417 layout_type (record);
3418
3419 /* The correct type is an array type of one element. */
3420 return build_array_type (record, build_index_type (size_zero_node));
3421}
3422
3423/* Implement va_start. */
3424
3425void
e5faf155 3426rs6000_va_start (valist, nextarg)
dfafc897
FS
3427 tree valist;
3428 rtx nextarg;
4697a36c 3429{
dfafc897
FS
3430 HOST_WIDE_INT words, n_gpr, n_fpr;
3431 tree f_gpr, f_fpr, f_ovf, f_sav;
3432 tree gpr, fpr, ovf, sav, t;
2c4974b7 3433
dfafc897 3434 /* Only SVR4 needs something special. */
f607bc57 3435 if (DEFAULT_ABI != ABI_V4)
dfafc897 3436 {
e5faf155 3437 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3438 return;
3439 }
3440
973a648b 3441 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3442 f_fpr = TREE_CHAIN (f_gpr);
3443 f_ovf = TREE_CHAIN (f_fpr);
3444 f_sav = TREE_CHAIN (f_ovf);
3445
8ebecc3b 3446 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3447 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3448 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3449 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3450 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3451
3452 /* Count number of gp and fp argument registers used. */
4cc833b7 3453 words = current_function_args_info.words;
dfafc897
FS
3454 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3455 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3456
3457 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3458 {
3459 fputs ("va_start: words = ", stderr);
3460 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3461 fputs (", n_gpr = ", stderr);
3462 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3463 fputs (", n_fpr = ", stderr);
3464 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3465 putc ('\n', stderr);
3466 }
dfafc897
FS
3467
3468 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3469 TREE_SIDE_EFFECTS (t) = 1;
3470 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3471
3472 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3473 TREE_SIDE_EFFECTS (t) = 1;
3474 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3475
3476 /* Find the overflow area. */
3477 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3478 if (words != 0)
3479 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3480 build_int_2 (words * UNITS_PER_WORD, 0));
3481 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3482 TREE_SIDE_EFFECTS (t) = 1;
3483 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3484
3485 /* Find the register save area. */
3486 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3487 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3488 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3489 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3490 TREE_SIDE_EFFECTS (t) = 1;
3491 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3492}
3493
3494/* Implement va_arg. */
3495
3496rtx
3497rs6000_va_arg (valist, type)
3498 tree valist, type;
3499{
3500 tree f_gpr, f_fpr, f_ovf, f_sav;
3501 tree gpr, fpr, ovf, sav, reg, t, u;
3502 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3503 rtx lab_false, lab_over, addr_rtx, r;
3504
f607bc57 3505 if (DEFAULT_ABI != ABI_V4)
2a55fd42 3506 return std_expand_builtin_va_arg (valist, type);
dfafc897 3507
973a648b 3508 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3509 f_fpr = TREE_CHAIN (f_gpr);
3510 f_ovf = TREE_CHAIN (f_fpr);
3511 f_sav = TREE_CHAIN (f_ovf);
3512
8ebecc3b 3513 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3514 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3515 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3516 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3517 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3518
3519 size = int_size_in_bytes (type);
3520 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3521
dfafc897 3522 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3523 {
dfafc897
FS
3524 /* Aggregates and long doubles are passed by reference. */
3525 indirect_p = 1;
3526 reg = gpr;
3527 n_reg = 1;
3528 sav_ofs = 0;
3529 sav_scale = 4;
d3294cd9
FS
3530 size = UNITS_PER_WORD;
3531 rsize = 1;
dfafc897 3532 }
a3170dc6 3533 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3534 {
3535 /* FP args go in FP registers, if present. */
3536 indirect_p = 0;
3537 reg = fpr;
3538 n_reg = 1;
3539 sav_ofs = 8*4;
3540 sav_scale = 8;
4cc833b7 3541 }
dfafc897
FS
3542 else
3543 {
3544 /* Otherwise into GP registers. */
3545 indirect_p = 0;
3546 reg = gpr;
3547 n_reg = rsize;
3548 sav_ofs = 0;
3549 sav_scale = 4;
3550 }
3551
a4f6c312 3552 /* Pull the value out of the saved registers ... */
dfafc897
FS
3553
3554 lab_false = gen_label_rtx ();
3555 lab_over = gen_label_rtx ();
3556 addr_rtx = gen_reg_rtx (Pmode);
3557
16861f33
AH
3558 /* AltiVec vectors never go in registers. */
3559 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3560 {
41daaf0e
AH
3561 TREE_THIS_VOLATILE (reg) = 1;
3562 emit_cmp_and_jump_insns
3563 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3564 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3565 lab_false);
dfafc897 3566
41daaf0e
AH
3567 /* Long long is aligned in the registers. */
3568 if (n_reg > 1)
3569 {
3570 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3571 build_int_2 (n_reg - 1, 0));
3572 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3573 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3574 TREE_SIDE_EFFECTS (u) = 1;
3575 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3576 }
2c4974b7 3577
41daaf0e
AH
3578 if (sav_ofs)
3579 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3580 else
3581 t = sav;
2c4974b7 3582
41daaf0e
AH
3583 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3584 build_int_2 (n_reg, 0));
3585 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3586
41daaf0e
AH
3587 u = build1 (CONVERT_EXPR, integer_type_node, u);
3588 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3589
41daaf0e
AH
3590 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3591 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3592
41daaf0e
AH
3593 t = build (PLUS_EXPR, ptr_type_node, t, u);
3594 TREE_SIDE_EFFECTS (t) = 1;
3595
3596 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3597 if (r != addr_rtx)
3598 emit_move_insn (addr_rtx, r);
3599
3600 emit_jump_insn (gen_jump (lab_over));
3601 emit_barrier ();
3602 }
dfafc897 3603
dfafc897
FS
3604 emit_label (lab_false);
3605
a4f6c312 3606 /* ... otherwise out of the overflow area. */
dfafc897 3607
41daaf0e
AH
3608 /* Make sure we don't find reg 7 for the next int arg.
3609
3610 All AltiVec vectors go in the overflow area. So in the AltiVec
3611 case we need to get the vectors from the overflow area, but
3612 remember where the GPRs and FPRs are. */
16861f33
AH
3613 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3614 || !TARGET_ALTIVEC))
dfafc897
FS
3615 {
3616 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3617 TREE_SIDE_EFFECTS (t) = 1;
3618 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3619 }
3620
3621 /* Care for on-stack alignment if needed. */
3622 if (rsize <= 1)
3623 t = ovf;
3624 else
3625 {
41daaf0e
AH
3626 int align;
3627
16861f33
AH
3628 /* AltiVec vectors are 16 byte aligned. */
3629 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3630 align = 15;
3631 else
3632 align = 7;
3633
3634 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3635 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3636 }
3637 t = save_expr (t);
3638
3639 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3640 if (r != addr_rtx)
3641 emit_move_insn (addr_rtx, r);
3642
3643 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3644 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3645 TREE_SIDE_EFFECTS (t) = 1;
3646 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3647
3648 emit_label (lab_over);
3649
3650 if (indirect_p)
3651 {
3652 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3653 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3654 emit_move_insn (addr_rtx, r);
3655 }
3656
3657 return addr_rtx;
4697a36c 3658}
0ac081f6
AH
3659
3660/* Builtins. */
3661
6a2dd09a
RS
3662#define def_builtin(MASK, NAME, TYPE, CODE) \
3663do { \
3664 if ((MASK) & target_flags) \
3665 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3666 NULL, NULL_TREE); \
0ac081f6
AH
3667} while (0)
3668
24408032
AH
3669/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3670
2212663f 3671static const struct builtin_description bdesc_3arg[] =
24408032
AH
3672{
3673 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3674 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3675 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3676 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3677 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3678 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3679 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3680 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3681 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3682 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3683 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3684 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3685 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3686 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3687 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3688 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3689 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3690 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3691 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3692 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3693 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3694 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3695 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3696};
2212663f 3697
95385cbb
AH
3698/* DST operations: void foo (void *, const int, const char). */
3699
3700static const struct builtin_description bdesc_dst[] =
3701{
3702 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3703 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3704 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3705 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3706};
3707
2212663f 3708/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3709
a3170dc6 3710static struct builtin_description bdesc_2arg[] =
0ac081f6 3711{
f18c054f
DB
3712 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3713 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3714 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3715 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3716 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3717 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3718 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3719 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3720 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3721 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3722 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3723 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3724 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3725 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3726 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3727 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3728 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3729 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3730 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3731 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3732 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3733 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3734 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3735 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3736 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3737 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3738 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3739 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3740 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3741 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3742 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3743 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3744 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3745 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3746 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3747 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3748 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3749 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
3750 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3751 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3752 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3753 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3754 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3755 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3756 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3757 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3758 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3759 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3760 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3761 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3762 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3763 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3764 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3765 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3766 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3767 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3768 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3769 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3770 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3771 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3772 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3773 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3774 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3775 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3776 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3777 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3778 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3779 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3780 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3781 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3782 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3783 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3784 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3785 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3786 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3787 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3788 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3789 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3790 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3791 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3792 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3793 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3794 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3795 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3796 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3797 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3798 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3799 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3800 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3801 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3802 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3803 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3804 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3805 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3806 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3807 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3808 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3809 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3810 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3811 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3812 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3813 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3814 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3815 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3816 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3817 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3818 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3819 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3820 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3821 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3822 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3823 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3824 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
3825
3826 /* Place holder, leave as first spe builtin. */
3827 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3828 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3829 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3830 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3831 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3832 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3833 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3834 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3835 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3836 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3837 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3838 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3839 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3840 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3841 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3842 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3843 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3844 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3845 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3846 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3847 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3848 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3849 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3850 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3851 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3852 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3853 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3854 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3855 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3856 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3857 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3858 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3859 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3860 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3861 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3862 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3863 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3864 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3865 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
3866 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
3867 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
3868 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
3869 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
3870 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
3871 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
3872 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
3873 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
3874 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
3875 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
3876 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
3877 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
3878 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
3879 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
3880 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
3881 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
3882 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
3883 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
3884 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
3885 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
3886 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
3887 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
3888 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
3889 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
3890 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
3891 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
3892 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
3893 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
3894 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
3895 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
3896 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
3897 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
3898 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
3899 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
3900 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
3901 { 0, CODE_FOR_spe_evmwlsmf, "__builtin_spe_evmwlsmf", SPE_BUILTIN_EVMWLSMF },
3902 { 0, CODE_FOR_spe_evmwlsmfa, "__builtin_spe_evmwlsmfa", SPE_BUILTIN_EVMWLSMFA },
3903 { 0, CODE_FOR_spe_evmwlsmfaaw, "__builtin_spe_evmwlsmfaaw", SPE_BUILTIN_EVMWLSMFAAW },
3904 { 0, CODE_FOR_spe_evmwlsmfanw, "__builtin_spe_evmwlsmfanw", SPE_BUILTIN_EVMWLSMFANW },
3905 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
3906 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
3907 { 0, CODE_FOR_spe_evmwlssf, "__builtin_spe_evmwlssf", SPE_BUILTIN_EVMWLSSF },
3908 { 0, CODE_FOR_spe_evmwlssfa, "__builtin_spe_evmwlssfa", SPE_BUILTIN_EVMWLSSFA },
3909 { 0, CODE_FOR_spe_evmwlssfaaw, "__builtin_spe_evmwlssfaaw", SPE_BUILTIN_EVMWLSSFAAW },
3910 { 0, CODE_FOR_spe_evmwlssfanw, "__builtin_spe_evmwlssfanw", SPE_BUILTIN_EVMWLSSFANW },
3911 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
3912 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
3913 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
3914 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
3915 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
3916 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
3917 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
3918 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
3919 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
3920 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
3921 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
3922 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
3923 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
3924 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
3925 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
3926 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
3927 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
3928 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
3929 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
3930 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
3931 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
3932 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
3933 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
3934 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
3935 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
3936 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
3937 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
3938 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
3939 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
3940 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
3941 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
3942 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
3943 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
3944
3945 /* SPE binary operations expecting a 5-bit unsigned literal. */
3946 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
3947
3948 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
3949 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
3950 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
3951 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
3952 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
3953 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
3954 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
3955 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
3956 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
3957 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
3958 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
3959 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
3960 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
3961 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
3962 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
3963 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
3964 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
3965 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
3966 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
3967 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
3968 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
3969 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
3970 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
3971 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
3972 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
3973 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
3974
3975 /* Place-holder. Leave as last binary SPE builtin. */
3976 { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
3977};
3978
3979/* AltiVec predicates. */
3980
3981struct builtin_description_predicates
3982{
3983 const unsigned int mask;
3984 const enum insn_code icode;
3985 const char *opcode;
3986 const char *const name;
3987 const enum rs6000_builtins code;
3988};
3989
3990static const struct builtin_description_predicates bdesc_altivec_preds[] =
3991{
3992 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
3993 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
3994 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
3995 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
3996 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
3997 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
3998 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
3999 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
4000 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
4001 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
4002 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
4003 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
4004 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 4005};
24408032 4006
a3170dc6
AH
4007/* SPE predicates. */
4008static struct builtin_description bdesc_spe_predicates[] =
4009{
4010 /* Place-holder. Leave as first. */
4011 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
4012 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
4013 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
4014 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4015 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4016 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4017 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4018 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4019 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4020 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4021 /* Place-holder. Leave as last. */
4022 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4023};
4024
4025/* SPE evsel predicates. */
4026static struct builtin_description bdesc_spe_evsel[] =
4027{
4028 /* Place-holder. Leave as first. */
4029 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4030 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4031 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4032 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4033 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4034 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4035 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4036 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4037 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4038 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4039 /* Place-holder. Leave as last. */
4040 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4041};
4042
100c4561
AH
4043/* ABS* opreations. */
4044
4045static const struct builtin_description bdesc_abs[] =
4046{
4047 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4048 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4049 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4050 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4051 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4052 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4053 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4054};
4055
617e0e1d
DB
4056/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4057 foo (VECa). */
24408032 4058
a3170dc6 4059static struct builtin_description bdesc_1arg[] =
2212663f 4060{
617e0e1d
DB
4061 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4062 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4063 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4064 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4065 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4066 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4067 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4068 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4069 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4070 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4071 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4072 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4073 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4074 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4075 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4076 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4077 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4078
4079 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4080 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4081 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4082 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4083 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4084 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4085 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4086 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4087 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4088 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4089 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4090 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4091 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4092 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4093 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4094 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4095 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4096 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4097 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4098 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4099 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4100 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4101 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4102 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4103 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4104 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4105 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4106 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4107 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4108 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4109 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4110 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4111
4112 /* Place-holder. Leave as last unary SPE builtin. */
4113 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4114};
4115
4116static rtx
92898235 4117rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4118 enum insn_code icode;
4119 tree arglist;
4120 rtx target;
4121{
4122 rtx pat;
4123 tree arg0 = TREE_VALUE (arglist);
4124 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4125 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4126 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4127
0559cc77
DE
4128 if (icode == CODE_FOR_nothing)
4129 /* Builtin not supported on this processor. */
4130 return 0;
4131
20e26713
AH
4132 /* If we got invalid arguments bail out before generating bad rtl. */
4133 if (arg0 == error_mark_node)
9a171fcd 4134 return const0_rtx;
20e26713 4135
0559cc77
DE
4136 if (icode == CODE_FOR_altivec_vspltisb
4137 || icode == CODE_FOR_altivec_vspltish
4138 || icode == CODE_FOR_altivec_vspltisw
4139 || icode == CODE_FOR_spe_evsplatfi
4140 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4141 {
4142 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4143 if (GET_CODE (op0) != CONST_INT
4144 || INTVAL (op0) > 0x1f
4145 || INTVAL (op0) < -0x1f)
4146 {
4147 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4148 return const0_rtx;
b44140e7 4149 }
b44140e7
AH
4150 }
4151
c62f2db5 4152 if (target == 0
2212663f
DB
4153 || GET_MODE (target) != tmode
4154 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4155 target = gen_reg_rtx (tmode);
4156
4157 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4158 op0 = copy_to_mode_reg (mode0, op0);
4159
4160 pat = GEN_FCN (icode) (target, op0);
4161 if (! pat)
4162 return 0;
4163 emit_insn (pat);
0ac081f6 4164
2212663f
DB
4165 return target;
4166}
ae4b4a02 4167
100c4561
AH
4168static rtx
4169altivec_expand_abs_builtin (icode, arglist, target)
4170 enum insn_code icode;
4171 tree arglist;
4172 rtx target;
4173{
4174 rtx pat, scratch1, scratch2;
4175 tree arg0 = TREE_VALUE (arglist);
4176 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4177 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4178 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4179
4180 /* If we have invalid arguments, bail out before generating bad rtl. */
4181 if (arg0 == error_mark_node)
9a171fcd 4182 return const0_rtx;
100c4561
AH
4183
4184 if (target == 0
4185 || GET_MODE (target) != tmode
4186 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4187 target = gen_reg_rtx (tmode);
4188
4189 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4190 op0 = copy_to_mode_reg (mode0, op0);
4191
4192 scratch1 = gen_reg_rtx (mode0);
4193 scratch2 = gen_reg_rtx (mode0);
4194
4195 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4196 if (! pat)
4197 return 0;
4198 emit_insn (pat);
4199
4200 return target;
4201}
4202
0ac081f6 4203static rtx
92898235 4204rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4205 enum insn_code icode;
4206 tree arglist;
4207 rtx target;
4208{
4209 rtx pat;
4210 tree arg0 = TREE_VALUE (arglist);
4211 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4212 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4213 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4214 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4215 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4216 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4217
0559cc77
DE
4218 if (icode == CODE_FOR_nothing)
4219 /* Builtin not supported on this processor. */
4220 return 0;
4221
20e26713
AH
4222 /* If we got invalid arguments bail out before generating bad rtl. */
4223 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4224 return const0_rtx;
20e26713 4225
0559cc77
DE
4226 if (icode == CODE_FOR_altivec_vcfux
4227 || icode == CODE_FOR_altivec_vcfsx
4228 || icode == CODE_FOR_altivec_vctsxs
4229 || icode == CODE_FOR_altivec_vctuxs
4230 || icode == CODE_FOR_altivec_vspltb
4231 || icode == CODE_FOR_altivec_vsplth
4232 || icode == CODE_FOR_altivec_vspltw
4233 || icode == CODE_FOR_spe_evaddiw
4234 || icode == CODE_FOR_spe_evldd
4235 || icode == CODE_FOR_spe_evldh
4236 || icode == CODE_FOR_spe_evldw
4237 || icode == CODE_FOR_spe_evlhhesplat
4238 || icode == CODE_FOR_spe_evlhhossplat
4239 || icode == CODE_FOR_spe_evlhhousplat
4240 || icode == CODE_FOR_spe_evlwhe
4241 || icode == CODE_FOR_spe_evlwhos
4242 || icode == CODE_FOR_spe_evlwhou
4243 || icode == CODE_FOR_spe_evlwhsplat
4244 || icode == CODE_FOR_spe_evlwwsplat
4245 || icode == CODE_FOR_spe_evrlwi
4246 || icode == CODE_FOR_spe_evslwi
4247 || icode == CODE_FOR_spe_evsrwis
4248 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4249 {
4250 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4251 if (TREE_CODE (arg1) != INTEGER_CST
4252 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4253 {
4254 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4255 return const0_rtx;
b44140e7 4256 }
b44140e7
AH
4257 }
4258
c62f2db5 4259 if (target == 0
0ac081f6
AH
4260 || GET_MODE (target) != tmode
4261 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4262 target = gen_reg_rtx (tmode);
4263
4264 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4265 op0 = copy_to_mode_reg (mode0, op0);
4266 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4267 op1 = copy_to_mode_reg (mode1, op1);
4268
4269 pat = GEN_FCN (icode) (target, op0, op1);
4270 if (! pat)
4271 return 0;
4272 emit_insn (pat);
4273
4274 return target;
4275}
6525c0e7 4276
ae4b4a02
AH
4277static rtx
4278altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4279 enum insn_code icode;
4280 const char *opcode;
4281 tree arglist;
4282 rtx target;
4283{
4284 rtx pat, scratch;
4285 tree cr6_form = TREE_VALUE (arglist);
4286 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4287 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4288 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4289 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4290 enum machine_mode tmode = SImode;
4291 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4292 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4293 int cr6_form_int;
4294
4295 if (TREE_CODE (cr6_form) != INTEGER_CST)
4296 {
4297 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4298 return const0_rtx;
ae4b4a02
AH
4299 }
4300 else
4301 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4302
4303 if (mode0 != mode1)
4304 abort ();
4305
4306 /* If we have invalid arguments, bail out before generating bad rtl. */
4307 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4308 return const0_rtx;
ae4b4a02
AH
4309
4310 if (target == 0
4311 || GET_MODE (target) != tmode
4312 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4313 target = gen_reg_rtx (tmode);
4314
4315 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4316 op0 = copy_to_mode_reg (mode0, op0);
4317 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4318 op1 = copy_to_mode_reg (mode1, op1);
4319
4320 scratch = gen_reg_rtx (mode0);
4321
4322 pat = GEN_FCN (icode) (scratch, op0, op1,
4323 gen_rtx (SYMBOL_REF, Pmode, opcode));
4324 if (! pat)
4325 return 0;
4326 emit_insn (pat);
4327
4328 /* The vec_any* and vec_all* predicates use the same opcodes for two
4329 different operations, but the bits in CR6 will be different
4330 depending on what information we want. So we have to play tricks
4331 with CR6 to get the right bits out.
4332
4333 If you think this is disgusting, look at the specs for the
4334 AltiVec predicates. */
4335
4336 switch (cr6_form_int)
4337 {
4338 case 0:
4339 emit_insn (gen_cr6_test_for_zero (target));
4340 break;
4341 case 1:
4342 emit_insn (gen_cr6_test_for_zero_reverse (target));
4343 break;
4344 case 2:
4345 emit_insn (gen_cr6_test_for_lt (target));
4346 break;
4347 case 3:
4348 emit_insn (gen_cr6_test_for_lt_reverse (target));
4349 break;
4350 default:
4351 error ("argument 1 of __builtin_altivec_predicate is out of range");
4352 break;
4353 }
4354
4355 return target;
4356}
4357
6525c0e7
AH
4358static rtx
4359altivec_expand_stv_builtin (icode, arglist)
4360 enum insn_code icode;
4361 tree arglist;
4362{
4363 tree arg0 = TREE_VALUE (arglist);
4364 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4365 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4366 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4367 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4368 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4369 rtx pat;
4370 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4371 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4372 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4373
4374 /* Invalid arguments. Bail before doing anything stoopid! */
4375 if (arg0 == error_mark_node
4376 || arg1 == error_mark_node
4377 || arg2 == error_mark_node)
9a171fcd 4378 return const0_rtx;
6525c0e7
AH
4379
4380 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4381 op0 = copy_to_mode_reg (mode2, op0);
4382 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4383 op1 = copy_to_mode_reg (mode0, op1);
4384 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4385 op2 = copy_to_mode_reg (mode1, op2);
4386
4387 pat = GEN_FCN (icode) (op1, op2, op0);
4388 if (pat)
4389 emit_insn (pat);
4390 return NULL_RTX;
4391}
4392
2212663f 4393static rtx
92898235 4394rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4395 enum insn_code icode;
4396 tree arglist;
4397 rtx target;
4398{
4399 rtx pat;
4400 tree arg0 = TREE_VALUE (arglist);
4401 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4402 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4403 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4404 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4405 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4406 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4407 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4408 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4409 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4410
774b5662
DE
4411 if (icode == CODE_FOR_nothing)
4412 /* Builtin not supported on this processor. */
4413 return 0;
4414
20e26713
AH
4415 /* If we got invalid arguments bail out before generating bad rtl. */
4416 if (arg0 == error_mark_node
4417 || arg1 == error_mark_node
4418 || arg2 == error_mark_node)
9a171fcd 4419 return const0_rtx;
20e26713 4420
774b5662
DE
4421 if (icode == CODE_FOR_altivec_vsldoi_4sf
4422 || icode == CODE_FOR_altivec_vsldoi_4si
4423 || icode == CODE_FOR_altivec_vsldoi_8hi
4424 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4425 {
4426 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4427 if (TREE_CODE (arg2) != INTEGER_CST
4428 || TREE_INT_CST_LOW (arg2) & ~0xf)
4429 {
4430 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4431 return const0_rtx;
b44140e7 4432 }
b44140e7
AH
4433 }
4434
c62f2db5 4435 if (target == 0
2212663f
DB
4436 || GET_MODE (target) != tmode
4437 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4438 target = gen_reg_rtx (tmode);
4439
4440 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4441 op0 = copy_to_mode_reg (mode0, op0);
4442 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4443 op1 = copy_to_mode_reg (mode1, op1);
4444 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4445 op2 = copy_to_mode_reg (mode2, op2);
4446
4447 pat = GEN_FCN (icode) (target, op0, op1, op2);
4448 if (! pat)
4449 return 0;
4450 emit_insn (pat);
4451
4452 return target;
4453}
92898235 4454
3a9b8c7e 4455/* Expand the lvx builtins. */
0ac081f6 4456static rtx
3a9b8c7e 4457altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4458 tree exp;
4459 rtx target;
92898235 4460 bool *expandedp;
0ac081f6 4461{
0ac081f6
AH
4462 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4463 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4464 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4465 tree arg0;
4466 enum machine_mode tmode, mode0;
7c3abc73 4467 rtx pat, op0;
3a9b8c7e 4468 enum insn_code icode;
92898235 4469
0ac081f6
AH
4470 switch (fcode)
4471 {
f18c054f
DB
4472 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4473 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4474 break;
f18c054f
DB
4475 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4476 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4477 break;
4478 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4479 icode = CODE_FOR_altivec_lvx_4si;
4480 break;
4481 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4482 icode = CODE_FOR_altivec_lvx_4sf;
4483 break;
4484 default:
4485 *expandedp = false;
4486 return NULL_RTX;
4487 }
0ac081f6 4488
3a9b8c7e 4489 *expandedp = true;
f18c054f 4490
3a9b8c7e
AH
4491 arg0 = TREE_VALUE (arglist);
4492 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4493 tmode = insn_data[icode].operand[0].mode;
4494 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4495
3a9b8c7e
AH
4496 if (target == 0
4497 || GET_MODE (target) != tmode
4498 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4499 target = gen_reg_rtx (tmode);
24408032 4500
3a9b8c7e
AH
4501 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4502 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4503
3a9b8c7e
AH
4504 pat = GEN_FCN (icode) (target, op0);
4505 if (! pat)
4506 return 0;
4507 emit_insn (pat);
4508 return target;
4509}
f18c054f 4510
3a9b8c7e
AH
4511/* Expand the stvx builtins. */
4512static rtx
4513altivec_expand_st_builtin (exp, target, expandedp)
4514 tree exp;
7c3abc73 4515 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4516 bool *expandedp;
4517{
4518 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4519 tree arglist = TREE_OPERAND (exp, 1);
4520 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4521 tree arg0, arg1;
4522 enum machine_mode mode0, mode1;
7c3abc73 4523 rtx pat, op0, op1;
3a9b8c7e 4524 enum insn_code icode;
f18c054f 4525
3a9b8c7e
AH
4526 switch (fcode)
4527 {
4528 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4529 icode = CODE_FOR_altivec_stvx_16qi;
4530 break;
4531 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4532 icode = CODE_FOR_altivec_stvx_8hi;
4533 break;
4534 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4535 icode = CODE_FOR_altivec_stvx_4si;
4536 break;
4537 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4538 icode = CODE_FOR_altivec_stvx_4sf;
4539 break;
4540 default:
4541 *expandedp = false;
4542 return NULL_RTX;
4543 }
24408032 4544
3a9b8c7e
AH
4545 arg0 = TREE_VALUE (arglist);
4546 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4547 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4548 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4549 mode0 = insn_data[icode].operand[0].mode;
4550 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4551
3a9b8c7e
AH
4552 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4553 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4554 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4555 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4556
3a9b8c7e
AH
4557 pat = GEN_FCN (icode) (op0, op1);
4558 if (pat)
4559 emit_insn (pat);
f18c054f 4560
3a9b8c7e
AH
4561 *expandedp = true;
4562 return NULL_RTX;
4563}
f18c054f 4564
3a9b8c7e
AH
4565/* Expand the dst builtins. */
4566static rtx
4567altivec_expand_dst_builtin (exp, target, expandedp)
4568 tree exp;
7c3abc73 4569 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4570 bool *expandedp;
4571{
4572 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4573 tree arglist = TREE_OPERAND (exp, 1);
4574 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4575 tree arg0, arg1, arg2;
4576 enum machine_mode mode0, mode1, mode2;
7c3abc73 4577 rtx pat, op0, op1, op2;
3a9b8c7e 4578 struct builtin_description *d;
a3170dc6 4579 size_t i;
f18c054f 4580
3a9b8c7e 4581 *expandedp = false;
f18c054f 4582
3a9b8c7e
AH
4583 /* Handle DST variants. */
4584 d = (struct builtin_description *) bdesc_dst;
4585 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4586 if (d->code == fcode)
4587 {
4588 arg0 = TREE_VALUE (arglist);
4589 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4590 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4591 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4592 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4593 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4594 mode0 = insn_data[d->icode].operand[0].mode;
4595 mode1 = insn_data[d->icode].operand[1].mode;
4596 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4597
3a9b8c7e
AH
4598 /* Invalid arguments, bail out before generating bad rtl. */
4599 if (arg0 == error_mark_node
4600 || arg1 == error_mark_node
4601 || arg2 == error_mark_node)
4602 return const0_rtx;
f18c054f 4603
3a9b8c7e
AH
4604 if (TREE_CODE (arg2) != INTEGER_CST
4605 || TREE_INT_CST_LOW (arg2) & ~0x3)
4606 {
4607 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4608 return const0_rtx;
4609 }
f18c054f 4610
3a9b8c7e
AH
4611 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4612 op0 = copy_to_mode_reg (mode0, op0);
4613 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4614 op1 = copy_to_mode_reg (mode1, op1);
24408032 4615
3a9b8c7e
AH
4616 pat = GEN_FCN (d->icode) (op0, op1, op2);
4617 if (pat != 0)
4618 emit_insn (pat);
f18c054f 4619
3a9b8c7e
AH
4620 *expandedp = true;
4621 return NULL_RTX;
4622 }
f18c054f 4623
3a9b8c7e
AH
4624 return NULL_RTX;
4625}
24408032 4626
3a9b8c7e
AH
4627/* Expand the builtin in EXP and store the result in TARGET. Store
4628 true in *EXPANDEDP if we found a builtin to expand. */
4629static rtx
4630altivec_expand_builtin (exp, target, expandedp)
4631 tree exp;
4632 rtx target;
4633 bool *expandedp;
4634{
4635 struct builtin_description *d;
4636 struct builtin_description_predicates *dp;
4637 size_t i;
4638 enum insn_code icode;
4639 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4640 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4641 tree arg0;
4642 rtx op0, pat;
4643 enum machine_mode tmode, mode0;
3a9b8c7e 4644 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4645
3a9b8c7e
AH
4646 target = altivec_expand_ld_builtin (exp, target, expandedp);
4647 if (*expandedp)
4648 return target;
0ac081f6 4649
3a9b8c7e
AH
4650 target = altivec_expand_st_builtin (exp, target, expandedp);
4651 if (*expandedp)
4652 return target;
4653
4654 target = altivec_expand_dst_builtin (exp, target, expandedp);
4655 if (*expandedp)
4656 return target;
4657
4658 *expandedp = true;
95385cbb 4659
3a9b8c7e
AH
4660 switch (fcode)
4661 {
6525c0e7
AH
4662 case ALTIVEC_BUILTIN_STVX:
4663 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4664 case ALTIVEC_BUILTIN_STVEBX:
4665 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4666 case ALTIVEC_BUILTIN_STVEHX:
4667 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4668 case ALTIVEC_BUILTIN_STVEWX:
4669 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4670 case ALTIVEC_BUILTIN_STVXL:
4671 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4672
95385cbb
AH
4673 case ALTIVEC_BUILTIN_MFVSCR:
4674 icode = CODE_FOR_altivec_mfvscr;
4675 tmode = insn_data[icode].operand[0].mode;
4676
4677 if (target == 0
4678 || GET_MODE (target) != tmode
4679 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4680 target = gen_reg_rtx (tmode);
4681
4682 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4683 if (! pat)
4684 return 0;
4685 emit_insn (pat);
95385cbb
AH
4686 return target;
4687
4688 case ALTIVEC_BUILTIN_MTVSCR:
4689 icode = CODE_FOR_altivec_mtvscr;
4690 arg0 = TREE_VALUE (arglist);
4691 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4692 mode0 = insn_data[icode].operand[0].mode;
4693
4694 /* If we got invalid arguments bail out before generating bad rtl. */
4695 if (arg0 == error_mark_node)
9a171fcd 4696 return const0_rtx;
95385cbb
AH
4697
4698 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4699 op0 = copy_to_mode_reg (mode0, op0);
4700
4701 pat = GEN_FCN (icode) (op0);
4702 if (pat)
4703 emit_insn (pat);
4704 return NULL_RTX;
3a9b8c7e 4705
95385cbb
AH
4706 case ALTIVEC_BUILTIN_DSSALL:
4707 emit_insn (gen_altivec_dssall ());
4708 return NULL_RTX;
4709
4710 case ALTIVEC_BUILTIN_DSS:
4711 icode = CODE_FOR_altivec_dss;
4712 arg0 = TREE_VALUE (arglist);
4713 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4714 mode0 = insn_data[icode].operand[0].mode;
4715
4716 /* If we got invalid arguments bail out before generating bad rtl. */
4717 if (arg0 == error_mark_node)
9a171fcd 4718 return const0_rtx;
95385cbb 4719
b44140e7
AH
4720 if (TREE_CODE (arg0) != INTEGER_CST
4721 || TREE_INT_CST_LOW (arg0) & ~0x3)
4722 {
4723 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4724 return const0_rtx;
b44140e7
AH
4725 }
4726
95385cbb
AH
4727 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4728 op0 = copy_to_mode_reg (mode0, op0);
4729
4730 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4731 return NULL_RTX;
4732 }
24408032 4733
100c4561
AH
4734 /* Expand abs* operations. */
4735 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4736 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4737 if (d->code == fcode)
4738 return altivec_expand_abs_builtin (d->icode, arglist, target);
4739
ae4b4a02
AH
4740 /* Expand the AltiVec predicates. */
4741 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4742 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4743 if (dp->code == fcode)
4744 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4745
6525c0e7
AH
4746 /* LV* are funky. We initialized them differently. */
4747 switch (fcode)
4748 {
4749 case ALTIVEC_BUILTIN_LVSL:
92898235 4750 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
4751 arglist, target);
4752 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
4753 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4754 arglist, target);
6525c0e7 4755 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
4756 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4757 arglist, target);
6525c0e7 4758 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
4759 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4760 arglist, target);
6525c0e7 4761 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
4762 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4763 arglist, target);
6525c0e7 4764 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
4765 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4766 arglist, target);
6525c0e7 4767 case ALTIVEC_BUILTIN_LVX:
92898235
AH
4768 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4769 arglist, target);
6525c0e7
AH
4770 default:
4771 break;
4772 /* Fall through. */
4773 }
95385cbb 4774
92898235 4775 *expandedp = false;
0ac081f6
AH
4776 return NULL_RTX;
4777}
4778
a3170dc6
AH
4779/* Binops that need to be initialized manually, but can be expanded
4780 automagically by rs6000_expand_binop_builtin. */
4781static struct builtin_description bdesc_2arg_spe[] =
4782{
4783 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4784 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4785 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4786 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4787 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4788 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4789 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4790 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4791 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4792 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4793 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4794 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4795 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4796 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4797 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4798 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4799 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4800 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4801 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4802 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4803 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4804 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4805};
4806
4807/* Expand the builtin in EXP and store the result in TARGET. Store
4808 true in *EXPANDEDP if we found a builtin to expand.
4809
4810 This expands the SPE builtins that are not simple unary and binary
4811 operations. */
4812static rtx
4813spe_expand_builtin (exp, target, expandedp)
4814 tree exp;
4815 rtx target;
4816 bool *expandedp;
4817{
4818 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4819 tree arglist = TREE_OPERAND (exp, 1);
4820 tree arg1, arg0;
4821 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4822 enum insn_code icode;
4823 enum machine_mode tmode, mode0;
4824 rtx pat, op0;
4825 struct builtin_description *d;
4826 size_t i;
4827
4828 *expandedp = true;
4829
4830 /* Syntax check for a 5-bit unsigned immediate. */
4831 switch (fcode)
4832 {
4833 case SPE_BUILTIN_EVSTDD:
4834 case SPE_BUILTIN_EVSTDH:
4835 case SPE_BUILTIN_EVSTDW:
4836 case SPE_BUILTIN_EVSTWHE:
4837 case SPE_BUILTIN_EVSTWHO:
4838 case SPE_BUILTIN_EVSTWWE:
4839 case SPE_BUILTIN_EVSTWWO:
4840 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4841 if (TREE_CODE (arg1) != INTEGER_CST
4842 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4843 {
4844 error ("argument 2 must be a 5-bit unsigned literal");
4845 return const0_rtx;
4846 }
4847 break;
4848 default:
4849 break;
4850 }
4851
4852 d = (struct builtin_description *) bdesc_2arg_spe;
4853 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4854 if (d->code == fcode)
4855 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4856
4857 d = (struct builtin_description *) bdesc_spe_predicates;
4858 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4859 if (d->code == fcode)
4860 return spe_expand_predicate_builtin (d->icode, arglist, target);
4861
4862 d = (struct builtin_description *) bdesc_spe_evsel;
4863 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4864 if (d->code == fcode)
4865 return spe_expand_evsel_builtin (d->icode, arglist, target);
4866
4867 switch (fcode)
4868 {
4869 case SPE_BUILTIN_EVSTDDX:
4870 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4871 case SPE_BUILTIN_EVSTDHX:
4872 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4873 case SPE_BUILTIN_EVSTDWX:
4874 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
4875 case SPE_BUILTIN_EVSTWHEX:
4876 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
4877 case SPE_BUILTIN_EVSTWHOX:
4878 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
4879 case SPE_BUILTIN_EVSTWWEX:
4880 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
4881 case SPE_BUILTIN_EVSTWWOX:
4882 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
4883 case SPE_BUILTIN_EVSTDD:
4884 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
4885 case SPE_BUILTIN_EVSTDH:
4886 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
4887 case SPE_BUILTIN_EVSTDW:
4888 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
4889 case SPE_BUILTIN_EVSTWHE:
4890 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
4891 case SPE_BUILTIN_EVSTWHO:
4892 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
4893 case SPE_BUILTIN_EVSTWWE:
4894 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
4895 case SPE_BUILTIN_EVSTWWO:
4896 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
4897 case SPE_BUILTIN_MFSPEFSCR:
4898 icode = CODE_FOR_spe_mfspefscr;
4899 tmode = insn_data[icode].operand[0].mode;
4900
4901 if (target == 0
4902 || GET_MODE (target) != tmode
4903 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4904 target = gen_reg_rtx (tmode);
4905
4906 pat = GEN_FCN (icode) (target);
4907 if (! pat)
4908 return 0;
4909 emit_insn (pat);
4910 return target;
4911 case SPE_BUILTIN_MTSPEFSCR:
4912 icode = CODE_FOR_spe_mtspefscr;
4913 arg0 = TREE_VALUE (arglist);
4914 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4915 mode0 = insn_data[icode].operand[0].mode;
4916
4917 if (arg0 == error_mark_node)
4918 return const0_rtx;
4919
4920 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4921 op0 = copy_to_mode_reg (mode0, op0);
4922
4923 pat = GEN_FCN (icode) (op0);
4924 if (pat)
4925 emit_insn (pat);
4926 return NULL_RTX;
4927 default:
4928 break;
4929 }
4930
4931 *expandedp = false;
4932 return NULL_RTX;
4933}
4934
4935static rtx
4936spe_expand_predicate_builtin (icode, arglist, target)
4937 enum insn_code icode;
4938 tree arglist;
4939 rtx target;
4940{
4941 rtx pat, scratch, tmp;
4942 tree form = TREE_VALUE (arglist);
4943 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4944 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4945 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4946 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4947 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4948 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4949 int form_int;
4950 enum rtx_code code;
4951
4952 if (TREE_CODE (form) != INTEGER_CST)
4953 {
4954 error ("argument 1 of __builtin_spe_predicate must be a constant");
4955 return const0_rtx;
4956 }
4957 else
4958 form_int = TREE_INT_CST_LOW (form);
4959
4960 if (mode0 != mode1)
4961 abort ();
4962
4963 if (arg0 == error_mark_node || arg1 == error_mark_node)
4964 return const0_rtx;
4965
4966 if (target == 0
4967 || GET_MODE (target) != SImode
4968 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
4969 target = gen_reg_rtx (SImode);
4970
4971 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4972 op0 = copy_to_mode_reg (mode0, op0);
4973 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4974 op1 = copy_to_mode_reg (mode1, op1);
4975
4976 scratch = gen_reg_rtx (CCmode);
4977
4978 pat = GEN_FCN (icode) (scratch, op0, op1);
4979 if (! pat)
4980 return const0_rtx;
4981 emit_insn (pat);
4982
4983 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
4984 _lower_. We use one compare, but look in different bits of the
4985 CR for each variant.
4986
4987 There are 2 elements in each SPE simd type (upper/lower). The CR
4988 bits are set as follows:
4989
4990 BIT0 | BIT 1 | BIT 2 | BIT 3
4991 U | L | (U | L) | (U & L)
4992
4993 So, for an "all" relationship, BIT 3 would be set.
4994 For an "any" relationship, BIT 2 would be set. Etc.
4995
4996 Following traditional nomenclature, these bits map to:
4997
4998 BIT0 | BIT 1 | BIT 2 | BIT 3
4999 LT | GT | EQ | OV
5000
5001 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
5002 */
5003
5004 switch (form_int)
5005 {
5006 /* All variant. OV bit. */
5007 case 0:
5008 /* We need to get to the OV bit, which is the ORDERED bit. We
5009 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
5010 that's ugly and will trigger a validate_condition_mode abort.
5011 So let's just use another pattern. */
5012 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
5013 return target;
5014 /* Any variant. EQ bit. */
5015 case 1:
5016 code = EQ;
5017 break;
5018 /* Upper variant. LT bit. */
5019 case 2:
5020 code = LT;
5021 break;
5022 /* Lower variant. GT bit. */
5023 case 3:
5024 code = GT;
5025 break;
5026 default:
5027 error ("argument 1 of __builtin_spe_predicate is out of range");
5028 return const0_rtx;
5029 }
5030
5031 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5032 emit_move_insn (target, tmp);
5033
5034 return target;
5035}
5036
5037/* The evsel builtins look like this:
5038
5039 e = __builtin_spe_evsel_OP (a, b, c, d);
5040
5041 and work like this:
5042
5043 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5044 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5045*/
5046
5047static rtx
5048spe_expand_evsel_builtin (icode, arglist, target)
5049 enum insn_code icode;
5050 tree arglist;
5051 rtx target;
5052{
5053 rtx pat, scratch;
5054 tree arg0 = TREE_VALUE (arglist);
5055 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5056 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5057 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5058 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5059 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5060 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5061 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5062 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5063 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5064
5065 if (mode0 != mode1)
5066 abort ();
5067
5068 if (arg0 == error_mark_node || arg1 == error_mark_node
5069 || arg2 == error_mark_node || arg3 == error_mark_node)
5070 return const0_rtx;
5071
5072 if (target == 0
5073 || GET_MODE (target) != mode0
5074 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5075 target = gen_reg_rtx (mode0);
5076
5077 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5078 op0 = copy_to_mode_reg (mode0, op0);
5079 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5080 op1 = copy_to_mode_reg (mode0, op1);
5081 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5082 op2 = copy_to_mode_reg (mode0, op2);
5083 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5084 op3 = copy_to_mode_reg (mode0, op3);
5085
5086 /* Generate the compare. */
5087 scratch = gen_reg_rtx (CCmode);
5088 pat = GEN_FCN (icode) (scratch, op0, op1);
5089 if (! pat)
5090 return const0_rtx;
5091 emit_insn (pat);
5092
5093 if (mode0 == V2SImode)
5094 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5095 else
5096 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5097
5098 return target;
5099}
5100
0ac081f6
AH
5101/* Expand an expression EXP that calls a built-in function,
5102 with result going to TARGET if that's convenient
5103 (and in mode MODE if that's convenient).
5104 SUBTARGET may be used as the target for computing one of EXP's operands.
5105 IGNORE is nonzero if the value is to be ignored. */
5106
5107static rtx
5108rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5109 tree exp;
5110 rtx target;
00b960c7
AH
5111 rtx subtarget ATTRIBUTE_UNUSED;
5112 enum machine_mode mode ATTRIBUTE_UNUSED;
5113 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5114{
92898235
AH
5115 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5116 tree arglist = TREE_OPERAND (exp, 1);
5117 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5118 struct builtin_description *d;
5119 size_t i;
5120 rtx ret;
5121 bool success;
5122
0ac081f6 5123 if (TARGET_ALTIVEC)
92898235
AH
5124 {
5125 ret = altivec_expand_builtin (exp, target, &success);
5126
a3170dc6
AH
5127 if (success)
5128 return ret;
5129 }
5130 if (TARGET_SPE)
5131 {
5132 ret = spe_expand_builtin (exp, target, &success);
5133
92898235
AH
5134 if (success)
5135 return ret;
5136 }
5137
0559cc77
DE
5138 if (TARGET_ALTIVEC || TARGET_SPE)
5139 {
5140 /* Handle simple unary operations. */
5141 d = (struct builtin_description *) bdesc_1arg;
5142 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5143 if (d->code == fcode)
5144 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5145
5146 /* Handle simple binary operations. */
5147 d = (struct builtin_description *) bdesc_2arg;
5148 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5149 if (d->code == fcode)
5150 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5151
5152 /* Handle simple ternary operations. */
5153 d = (struct builtin_description *) bdesc_3arg;
5154 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5155 if (d->code == fcode)
5156 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5157 }
0ac081f6
AH
5158
5159 abort ();
92898235 5160 return NULL_RTX;
0ac081f6
AH
5161}
5162
5163static void
6fa3f289 5164rs6000_init_builtins ()
0ac081f6 5165{
a3170dc6
AH
5166 if (TARGET_SPE)
5167 spe_init_builtins ();
0ac081f6
AH
5168 if (TARGET_ALTIVEC)
5169 altivec_init_builtins ();
0559cc77
DE
5170 if (TARGET_ALTIVEC || TARGET_SPE)
5171 rs6000_common_init_builtins ();
0ac081f6
AH
5172}
5173
a3170dc6
AH
5174/* Search through a set of builtins and enable the mask bits.
5175 DESC is an array of builtins.
5176 SIZE is the totaly number of builtins.
5177 START is the builtin enum at which to start.
5178 END is the builtin enum at which to end. */
0ac081f6 5179static void
a3170dc6
AH
5180enable_mask_for_builtins (desc, size, start, end)
5181 struct builtin_description *desc;
5182 int size;
5183 enum rs6000_builtins start, end;
5184{
5185 int i;
5186
5187 for (i = 0; i < size; ++i)
5188 if (desc[i].code == start)
5189 break;
5190
5191 if (i == size)
5192 return;
5193
5194 for (; i < size; ++i)
5195 {
5196 /* Flip all the bits on. */
5197 desc[i].mask = target_flags;
5198 if (desc[i].code == end)
5199 break;
5200 }
5201}
5202
5203static void
b24c9d35 5204spe_init_builtins ()
0ac081f6 5205{
a3170dc6
AH
5206 tree endlink = void_list_node;
5207 tree puint_type_node = build_pointer_type (unsigned_type_node);
5208 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5209 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5210 struct builtin_description *d;
0ac081f6
AH
5211 size_t i;
5212
a3170dc6
AH
5213 tree v2si_ftype_4_v2si
5214 = build_function_type
5215 (V2SI_type_node,
5216 tree_cons (NULL_TREE, V2SI_type_node,
5217 tree_cons (NULL_TREE, V2SI_type_node,
5218 tree_cons (NULL_TREE, V2SI_type_node,
5219 tree_cons (NULL_TREE, V2SI_type_node,
5220 endlink)))));
5221
5222 tree v2sf_ftype_4_v2sf
5223 = build_function_type
5224 (V2SF_type_node,
5225 tree_cons (NULL_TREE, V2SF_type_node,
5226 tree_cons (NULL_TREE, V2SF_type_node,
5227 tree_cons (NULL_TREE, V2SF_type_node,
5228 tree_cons (NULL_TREE, V2SF_type_node,
5229 endlink)))));
5230
5231 tree int_ftype_int_v2si_v2si
5232 = build_function_type
5233 (integer_type_node,
5234 tree_cons (NULL_TREE, integer_type_node,
5235 tree_cons (NULL_TREE, V2SI_type_node,
5236 tree_cons (NULL_TREE, V2SI_type_node,
5237 endlink))));
5238
5239 tree int_ftype_int_v2sf_v2sf
5240 = build_function_type
5241 (integer_type_node,
5242 tree_cons (NULL_TREE, integer_type_node,
5243 tree_cons (NULL_TREE, V2SF_type_node,
5244 tree_cons (NULL_TREE, V2SF_type_node,
5245 endlink))));
5246
5247 tree void_ftype_v2si_puint_int
5248 = build_function_type (void_type_node,
5249 tree_cons (NULL_TREE, V2SI_type_node,
5250 tree_cons (NULL_TREE, puint_type_node,
5251 tree_cons (NULL_TREE,
5252 integer_type_node,
5253 endlink))));
5254
5255 tree void_ftype_v2si_puint_char
5256 = build_function_type (void_type_node,
5257 tree_cons (NULL_TREE, V2SI_type_node,
5258 tree_cons (NULL_TREE, puint_type_node,
5259 tree_cons (NULL_TREE,
5260 char_type_node,
5261 endlink))));
5262
5263 tree void_ftype_v2si_pv2si_int
5264 = build_function_type (void_type_node,
5265 tree_cons (NULL_TREE, V2SI_type_node,
5266 tree_cons (NULL_TREE, pv2si_type_node,
5267 tree_cons (NULL_TREE,
5268 integer_type_node,
5269 endlink))));
5270
5271 tree void_ftype_v2si_pv2si_char
5272 = build_function_type (void_type_node,
5273 tree_cons (NULL_TREE, V2SI_type_node,
5274 tree_cons (NULL_TREE, pv2si_type_node,
5275 tree_cons (NULL_TREE,
5276 char_type_node,
5277 endlink))));
5278
5279 tree void_ftype_int
5280 = build_function_type (void_type_node,
5281 tree_cons (NULL_TREE, integer_type_node, endlink));
5282
5283 tree int_ftype_void
5284 = build_function_type (integer_type_node,
5285 tree_cons (NULL_TREE, void_type_node, endlink));
5286
5287 tree v2si_ftype_pv2si_int
5288 = build_function_type (V2SI_type_node,
5289 tree_cons (NULL_TREE, pv2si_type_node,
5290 tree_cons (NULL_TREE, integer_type_node,
5291 endlink)));
5292
5293 tree v2si_ftype_puint_int
5294 = build_function_type (V2SI_type_node,
5295 tree_cons (NULL_TREE, puint_type_node,
5296 tree_cons (NULL_TREE, integer_type_node,
5297 endlink)));
5298
5299 tree v2si_ftype_pushort_int
5300 = build_function_type (V2SI_type_node,
5301 tree_cons (NULL_TREE, pushort_type_node,
5302 tree_cons (NULL_TREE, integer_type_node,
5303 endlink)));
5304
5305 /* The initialization of the simple binary and unary builtins is
5306 done in rs6000_common_init_builtins, but we have to enable the
5307 mask bits here manually because we have run out of `target_flags'
5308 bits. We really need to redesign this mask business. */
5309
5310 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5311 ARRAY_SIZE (bdesc_2arg),
5312 SPE_BUILTIN_EVADDW,
5313 SPE_BUILTIN_EVXOR);
5314 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5315 ARRAY_SIZE (bdesc_1arg),
5316 SPE_BUILTIN_EVABS,
5317 SPE_BUILTIN_EVSUBFUSIAAW);
5318 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5319 ARRAY_SIZE (bdesc_spe_predicates),
5320 SPE_BUILTIN_EVCMPEQ,
5321 SPE_BUILTIN_EVFSTSTLT);
5322 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5323 ARRAY_SIZE (bdesc_spe_evsel),
5324 SPE_BUILTIN_EVSEL_CMPGTS,
5325 SPE_BUILTIN_EVSEL_FSTSTEQ);
5326
5327 /* Initialize irregular SPE builtins. */
5328
5329 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5330 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5331 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5332 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5333 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5334 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5335 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5336 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5337 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5338 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5339 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5340 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5341 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5342 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5343 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5344 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5345
5346 /* Loads. */
5347 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5348 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5349 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5350 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5351 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5352 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5353 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5354 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5355 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5356 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5357 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5358 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5359 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5360 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5361 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5362 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5363 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5364 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5365 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5366 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5367 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5368 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5369
5370 /* Predicates. */
5371 d = (struct builtin_description *) bdesc_spe_predicates;
5372 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5373 {
5374 tree type;
5375
5376 switch (insn_data[d->icode].operand[1].mode)
5377 {
5378 case V2SImode:
5379 type = int_ftype_int_v2si_v2si;
5380 break;
5381 case V2SFmode:
5382 type = int_ftype_int_v2sf_v2sf;
5383 break;
5384 default:
5385 abort ();
5386 }
5387
5388 def_builtin (d->mask, d->name, type, d->code);
5389 }
5390
5391 /* Evsel predicates. */
5392 d = (struct builtin_description *) bdesc_spe_evsel;
5393 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5394 {
5395 tree type;
5396
5397 switch (insn_data[d->icode].operand[1].mode)
5398 {
5399 case V2SImode:
5400 type = v2si_ftype_4_v2si;
5401 break;
5402 case V2SFmode:
5403 type = v2sf_ftype_4_v2sf;
5404 break;
5405 default:
5406 abort ();
5407 }
5408
5409 def_builtin (d->mask, d->name, type, d->code);
5410 }
5411}
5412
5413static void
b24c9d35 5414altivec_init_builtins ()
a3170dc6
AH
5415{
5416 struct builtin_description *d;
5417 struct builtin_description_predicates *dp;
5418 size_t i;
5419 tree pfloat_type_node = build_pointer_type (float_type_node);
5420 tree pint_type_node = build_pointer_type (integer_type_node);
5421 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5422 tree pchar_type_node = build_pointer_type (char_type_node);
5423
5424 tree pvoid_type_node = build_pointer_type (void_type_node);
5425
5426 tree int_ftype_int_v4si_v4si
5427 = build_function_type_list (integer_type_node,
5428 integer_type_node, V4SI_type_node,
5429 V4SI_type_node, NULL_TREE);
f18c054f 5430 tree v4sf_ftype_pfloat
b4de2f7d 5431 = build_function_type_list (V4SF_type_node, pfloat_type_node, NULL_TREE);
a3170dc6 5432 tree void_ftype_pfloat_v4sf
b4de2f7d 5433 = build_function_type_list (void_type_node,
a3170dc6
AH
5434 pfloat_type_node, V4SF_type_node, NULL_TREE);
5435 tree v4si_ftype_pint
5436 = build_function_type_list (V4SI_type_node, pint_type_node, NULL_TREE); tree void_ftype_pint_v4si
b4de2f7d
AH
5437 = build_function_type_list (void_type_node,
5438 pint_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5439 tree v8hi_ftype_pshort
5440 = build_function_type_list (V8HI_type_node, pshort_type_node, NULL_TREE);
f18c054f 5441 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5442 = build_function_type_list (void_type_node,
5443 pshort_type_node, V8HI_type_node, NULL_TREE);
a3170dc6
AH
5444 tree v16qi_ftype_pchar
5445 = build_function_type_list (V16QI_type_node, pchar_type_node, NULL_TREE);
f18c054f 5446 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5447 = build_function_type_list (void_type_node,
5448 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5449 tree void_ftype_v4si
b4de2f7d 5450 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5451 tree v8hi_ftype_void
5452 = build_function_type (V8HI_type_node, void_list_node);
5453 tree void_ftype_void
5454 = build_function_type (void_type_node, void_list_node);
5455 tree void_ftype_qi
5456 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
5457 tree v16qi_ftype_int_pvoid
5458 = build_function_type_list (V16QI_type_node,
5459 integer_type_node, pvoid_type_node, NULL_TREE);
5460 tree v8hi_ftype_int_pvoid
5461 = build_function_type_list (V8HI_type_node,
5462 integer_type_node, pvoid_type_node, NULL_TREE);
5463 tree v4si_ftype_int_pvoid
5464 = build_function_type_list (V4SI_type_node,
5465 integer_type_node, pvoid_type_node, NULL_TREE);
14b32f4e 5466 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5467 = build_function_type_list (void_type_node,
5468 V4SI_type_node, integer_type_node,
5469 pvoid_type_node, NULL_TREE);
6525c0e7 5470 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5471 = build_function_type_list (void_type_node,
5472 V16QI_type_node, integer_type_node,
5473 pvoid_type_node, NULL_TREE);
6525c0e7 5474 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5475 = build_function_type_list (void_type_node,
5476 V8HI_type_node, integer_type_node,
5477 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5478 tree int_ftype_int_v8hi_v8hi
5479 = build_function_type_list (integer_type_node,
5480 integer_type_node, V8HI_type_node,
5481 V8HI_type_node, NULL_TREE);
5482 tree int_ftype_int_v16qi_v16qi
5483 = build_function_type_list (integer_type_node,
5484 integer_type_node, V16QI_type_node,
5485 V16QI_type_node, NULL_TREE);
5486 tree int_ftype_int_v4sf_v4sf
5487 = build_function_type_list (integer_type_node,
5488 integer_type_node, V4SF_type_node,
5489 V4SF_type_node, NULL_TREE);
5490 tree v4si_ftype_v4si
5491 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5492 tree v8hi_ftype_v8hi
5493 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5494 tree v16qi_ftype_v16qi
5495 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5496 tree v4sf_ftype_v4sf
5497 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5498 tree void_ftype_pvoid_int_char
5499 = build_function_type_list (void_type_node,
5500 pvoid_type_node, integer_type_node,
5501 char_type_node, NULL_TREE);
5502
5503 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pfloat, ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5504 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf, ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5505 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5506 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5507 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pshort, ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5508 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi, ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5509 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pchar, ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5510 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi, ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
5511 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5512 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5513 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5514 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
5515 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
5516 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
5517 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEBX);
5518 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEHX);
5519 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEWX);
5520 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVXL);
5521 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVX);
5522 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5523 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5524 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5525 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5526 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5527
5528 /* Add the DST variants. */
5529 d = (struct builtin_description *) bdesc_dst;
5530 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
5531 def_builtin (d->mask, d->name, void_ftype_pvoid_int_char, d->code);
5532
5533 /* Initialize the predicates. */
5534 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5535 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5536 {
5537 enum machine_mode mode1;
5538 tree type;
5539
5540 mode1 = insn_data[dp->icode].operand[1].mode;
5541
5542 switch (mode1)
5543 {
5544 case V4SImode:
5545 type = int_ftype_int_v4si_v4si;
5546 break;
5547 case V8HImode:
5548 type = int_ftype_int_v8hi_v8hi;
5549 break;
5550 case V16QImode:
5551 type = int_ftype_int_v16qi_v16qi;
5552 break;
5553 case V4SFmode:
5554 type = int_ftype_int_v4sf_v4sf;
5555 break;
5556 default:
5557 abort ();
5558 }
5559
5560 def_builtin (dp->mask, dp->name, type, dp->code);
5561 }
5562
5563 /* Initialize the abs* operators. */
5564 d = (struct builtin_description *) bdesc_abs;
5565 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5566 {
5567 enum machine_mode mode0;
5568 tree type;
5569
5570 mode0 = insn_data[d->icode].operand[0].mode;
5571
5572 switch (mode0)
5573 {
5574 case V4SImode:
5575 type = v4si_ftype_v4si;
5576 break;
5577 case V8HImode:
5578 type = v8hi_ftype_v8hi;
5579 break;
5580 case V16QImode:
5581 type = v16qi_ftype_v16qi;
5582 break;
5583 case V4SFmode:
5584 type = v4sf_ftype_v4sf;
5585 break;
5586 default:
5587 abort ();
5588 }
5589
5590 def_builtin (d->mask, d->name, type, d->code);
5591 }
5592}
5593
5594static void
b24c9d35 5595rs6000_common_init_builtins ()
a3170dc6
AH
5596{
5597 struct builtin_description *d;
5598 size_t i;
5599
5600 tree v4sf_ftype_v4sf_v4sf_v16qi
5601 = build_function_type_list (V4SF_type_node,
5602 V4SF_type_node, V4SF_type_node,
5603 V16QI_type_node, NULL_TREE);
5604 tree v4si_ftype_v4si_v4si_v16qi
5605 = build_function_type_list (V4SI_type_node,
5606 V4SI_type_node, V4SI_type_node,
5607 V16QI_type_node, NULL_TREE);
5608 tree v8hi_ftype_v8hi_v8hi_v16qi
5609 = build_function_type_list (V8HI_type_node,
5610 V8HI_type_node, V8HI_type_node,
5611 V16QI_type_node, NULL_TREE);
5612 tree v16qi_ftype_v16qi_v16qi_v16qi
5613 = build_function_type_list (V16QI_type_node,
5614 V16QI_type_node, V16QI_type_node,
5615 V16QI_type_node, NULL_TREE);
5616 tree v4si_ftype_char
5617 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5618 tree v8hi_ftype_char
5619 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5620 tree v16qi_ftype_char
5621 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5622 tree v8hi_ftype_v16qi
5623 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5624 tree v4sf_ftype_v4sf
5625 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5626
5627 tree v2si_ftype_v2si_v2si
5628 = build_function_type_list (V2SI_type_node,
5629 V2SI_type_node, V2SI_type_node, NULL_TREE);
5630
5631 tree v2sf_ftype_v2sf_v2sf
5632 = build_function_type_list (V2SF_type_node,
5633 V2SF_type_node, V2SF_type_node, NULL_TREE);
5634
5635 tree v2si_ftype_int_int
5636 = build_function_type_list (V2SI_type_node,
5637 integer_type_node, integer_type_node,
5638 NULL_TREE);
5639
5640 tree v2si_ftype_v2si
5641 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5642
5643 tree v2sf_ftype_v2sf
5644 = build_function_type_list (V2SF_type_node,
5645 V2SF_type_node, NULL_TREE);
5646
5647 tree v2sf_ftype_v2si
5648 = build_function_type_list (V2SF_type_node,
5649 V2SI_type_node, NULL_TREE);
5650
5651 tree v2si_ftype_v2sf
5652 = build_function_type_list (V2SI_type_node,
5653 V2SF_type_node, NULL_TREE);
5654
5655 tree v2si_ftype_v2si_char
5656 = build_function_type_list (V2SI_type_node,
5657 V2SI_type_node, char_type_node, NULL_TREE);
5658
5659 tree v2si_ftype_int_char
5660 = build_function_type_list (V2SI_type_node,
5661 integer_type_node, char_type_node, NULL_TREE);
5662
5663 tree v2si_ftype_char
5664 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5665
5666 tree int_ftype_int_int
5667 = build_function_type_list (integer_type_node,
5668 integer_type_node, integer_type_node,
5669 NULL_TREE);
95385cbb 5670
0ac081f6 5671 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5672 = build_function_type_list (V4SI_type_node,
5673 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5674 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5675 = build_function_type_list (V4SF_type_node,
5676 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5677 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5678 = build_function_type_list (V4SI_type_node,
5679 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5680 tree v4si_ftype_v4si_char
b4de2f7d
AH
5681 = build_function_type_list (V4SI_type_node,
5682 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5683 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5684 = build_function_type_list (V8HI_type_node,
5685 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5686 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5687 = build_function_type_list (V16QI_type_node,
5688 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5689 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5690 = build_function_type_list (V16QI_type_node,
5691 V16QI_type_node, V16QI_type_node,
5692 char_type_node, NULL_TREE);
24408032 5693 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5694 = build_function_type_list (V8HI_type_node,
5695 V8HI_type_node, V8HI_type_node,
5696 char_type_node, NULL_TREE);
24408032 5697 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5698 = build_function_type_list (V4SI_type_node,
5699 V4SI_type_node, V4SI_type_node,
5700 char_type_node, NULL_TREE);
24408032 5701 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5702 = build_function_type_list (V4SF_type_node,
5703 V4SF_type_node, V4SF_type_node,
5704 char_type_node, NULL_TREE);
0ac081f6 5705 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5706 = build_function_type_list (V4SF_type_node,
5707 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5708 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5709 = build_function_type_list (V4SF_type_node,
5710 V4SF_type_node, V4SF_type_node,
5711 V4SI_type_node, NULL_TREE);
2212663f 5712 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5713 = build_function_type_list (V4SF_type_node,
5714 V4SF_type_node, V4SF_type_node,
5715 V4SF_type_node, NULL_TREE);
617e0e1d 5716 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
5717 = build_function_type_list (V4SI_type_node,
5718 V4SI_type_node, V4SI_type_node,
5719 V4SI_type_node, NULL_TREE);
0ac081f6 5720 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
5721 = build_function_type_list (V8HI_type_node,
5722 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 5723 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
5724 = build_function_type_list (V8HI_type_node,
5725 V8HI_type_node, V8HI_type_node,
5726 V8HI_type_node, NULL_TREE);
2212663f 5727 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
5728 = build_function_type_list (V4SI_type_node,
5729 V8HI_type_node, V8HI_type_node,
5730 V4SI_type_node, NULL_TREE);
2212663f 5731 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
5732 = build_function_type_list (V4SI_type_node,
5733 V16QI_type_node, V16QI_type_node,
5734 V4SI_type_node, NULL_TREE);
0ac081f6 5735 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
5736 = build_function_type_list (V16QI_type_node,
5737 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5738 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
5739 = build_function_type_list (V4SI_type_node,
5740 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 5741 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
5742 = build_function_type_list (V8HI_type_node,
5743 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5744 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
5745 = build_function_type_list (V4SI_type_node,
5746 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5747 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
5748 = build_function_type_list (V8HI_type_node,
5749 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 5750 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
5751 = build_function_type_list (V16QI_type_node,
5752 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5753 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
5754 = build_function_type_list (V4SI_type_node,
5755 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 5756 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
5757 = build_function_type_list (V4SI_type_node,
5758 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5759 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
5760 = build_function_type_list (V4SI_type_node,
5761 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5762 tree v4si_ftype_v8hi
5763 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5764 tree int_ftype_v4si_v4si
5765 = build_function_type_list (integer_type_node,
5766 V4SI_type_node, V4SI_type_node, NULL_TREE);
5767 tree int_ftype_v4sf_v4sf
5768 = build_function_type_list (integer_type_node,
5769 V4SF_type_node, V4SF_type_node, NULL_TREE);
5770 tree int_ftype_v16qi_v16qi
5771 = build_function_type_list (integer_type_node,
5772 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5773 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
5774 = build_function_type_list (integer_type_node,
5775 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5776
6f317ef3 5777 /* Add the simple ternary operators. */
2212663f 5778 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 5779 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
5780 {
5781
5782 enum machine_mode mode0, mode1, mode2, mode3;
5783 tree type;
5784
0559cc77 5785 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5786 continue;
5787
5788 mode0 = insn_data[d->icode].operand[0].mode;
5789 mode1 = insn_data[d->icode].operand[1].mode;
5790 mode2 = insn_data[d->icode].operand[2].mode;
5791 mode3 = insn_data[d->icode].operand[3].mode;
5792
5793 /* When all four are of the same mode. */
5794 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5795 {
5796 switch (mode0)
5797 {
617e0e1d
DB
5798 case V4SImode:
5799 type = v4si_ftype_v4si_v4si_v4si;
5800 break;
2212663f
DB
5801 case V4SFmode:
5802 type = v4sf_ftype_v4sf_v4sf_v4sf;
5803 break;
5804 case V8HImode:
5805 type = v8hi_ftype_v8hi_v8hi_v8hi;
5806 break;
5807 case V16QImode:
5808 type = v16qi_ftype_v16qi_v16qi_v16qi;
5809 break;
5810 default:
5811 abort();
5812 }
5813 }
5814 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5815 {
5816 switch (mode0)
5817 {
5818 case V4SImode:
5819 type = v4si_ftype_v4si_v4si_v16qi;
5820 break;
5821 case V4SFmode:
5822 type = v4sf_ftype_v4sf_v4sf_v16qi;
5823 break;
5824 case V8HImode:
5825 type = v8hi_ftype_v8hi_v8hi_v16qi;
5826 break;
5827 case V16QImode:
5828 type = v16qi_ftype_v16qi_v16qi_v16qi;
5829 break;
5830 default:
5831 abort();
5832 }
5833 }
5834 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5835 && mode3 == V4SImode)
24408032 5836 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
5837 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5838 && mode3 == V4SImode)
24408032 5839 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
5840 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5841 && mode3 == V4SImode)
24408032
AH
5842 type = v4sf_ftype_v4sf_v4sf_v4si;
5843
5844 /* vchar, vchar, vchar, 4 bit literal. */
5845 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5846 && mode3 == QImode)
5847 type = v16qi_ftype_v16qi_v16qi_char;
5848
5849 /* vshort, vshort, vshort, 4 bit literal. */
5850 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5851 && mode3 == QImode)
5852 type = v8hi_ftype_v8hi_v8hi_char;
5853
5854 /* vint, vint, vint, 4 bit literal. */
5855 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
5856 && mode3 == QImode)
5857 type = v4si_ftype_v4si_v4si_char;
5858
5859 /* vfloat, vfloat, vfloat, 4 bit literal. */
5860 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
5861 && mode3 == QImode)
5862 type = v4sf_ftype_v4sf_v4sf_char;
5863
2212663f
DB
5864 else
5865 abort ();
5866
5867 def_builtin (d->mask, d->name, type, d->code);
5868 }
5869
0ac081f6 5870 /* Add the simple binary operators. */
00b960c7 5871 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 5872 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
5873 {
5874 enum machine_mode mode0, mode1, mode2;
5875 tree type;
5876
0559cc77 5877 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
5878 continue;
5879
5880 mode0 = insn_data[d->icode].operand[0].mode;
5881 mode1 = insn_data[d->icode].operand[1].mode;
5882 mode2 = insn_data[d->icode].operand[2].mode;
5883
5884 /* When all three operands are of the same mode. */
5885 if (mode0 == mode1 && mode1 == mode2)
5886 {
5887 switch (mode0)
5888 {
5889 case V4SFmode:
5890 type = v4sf_ftype_v4sf_v4sf;
5891 break;
5892 case V4SImode:
5893 type = v4si_ftype_v4si_v4si;
5894 break;
5895 case V16QImode:
5896 type = v16qi_ftype_v16qi_v16qi;
5897 break;
5898 case V8HImode:
5899 type = v8hi_ftype_v8hi_v8hi;
5900 break;
a3170dc6
AH
5901 case V2SImode:
5902 type = v2si_ftype_v2si_v2si;
5903 break;
5904 case V2SFmode:
5905 type = v2sf_ftype_v2sf_v2sf;
5906 break;
5907 case SImode:
5908 type = int_ftype_int_int;
5909 break;
0ac081f6
AH
5910 default:
5911 abort ();
5912 }
5913 }
5914
5915 /* A few other combos we really don't want to do manually. */
5916
5917 /* vint, vfloat, vfloat. */
5918 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
5919 type = v4si_ftype_v4sf_v4sf;
5920
5921 /* vshort, vchar, vchar. */
5922 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
5923 type = v8hi_ftype_v16qi_v16qi;
5924
5925 /* vint, vshort, vshort. */
5926 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
5927 type = v4si_ftype_v8hi_v8hi;
5928
5929 /* vshort, vint, vint. */
5930 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
5931 type = v8hi_ftype_v4si_v4si;
5932
5933 /* vchar, vshort, vshort. */
5934 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
5935 type = v16qi_ftype_v8hi_v8hi;
5936
5937 /* vint, vchar, vint. */
5938 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
5939 type = v4si_ftype_v16qi_v4si;
5940
fa066a23
AH
5941 /* vint, vchar, vchar. */
5942 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
5943 type = v4si_ftype_v16qi_v16qi;
5944
0ac081f6
AH
5945 /* vint, vshort, vint. */
5946 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
5947 type = v4si_ftype_v8hi_v4si;
2212663f
DB
5948
5949 /* vint, vint, 5 bit literal. */
5950 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
5951 type = v4si_ftype_v4si_char;
5952
5953 /* vshort, vshort, 5 bit literal. */
5954 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
5955 type = v8hi_ftype_v8hi_char;
5956
5957 /* vchar, vchar, 5 bit literal. */
5958 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
5959 type = v16qi_ftype_v16qi_char;
0ac081f6 5960
617e0e1d
DB
5961 /* vfloat, vint, 5 bit literal. */
5962 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
5963 type = v4sf_ftype_v4si_char;
5964
5965 /* vint, vfloat, 5 bit literal. */
5966 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
5967 type = v4si_ftype_v4sf_char;
5968
a3170dc6
AH
5969 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
5970 type = v2si_ftype_int_int;
5971
5972 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
5973 type = v2si_ftype_v2si_char;
5974
5975 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
5976 type = v2si_ftype_int_char;
5977
0ac081f6
AH
5978 /* int, x, x. */
5979 else if (mode0 == SImode)
5980 {
5981 switch (mode1)
5982 {
5983 case V4SImode:
5984 type = int_ftype_v4si_v4si;
5985 break;
5986 case V4SFmode:
5987 type = int_ftype_v4sf_v4sf;
5988 break;
5989 case V16QImode:
5990 type = int_ftype_v16qi_v16qi;
5991 break;
5992 case V8HImode:
5993 type = int_ftype_v8hi_v8hi;
5994 break;
5995 default:
5996 abort ();
5997 }
5998 }
5999
6000 else
6001 abort ();
6002
2212663f
DB
6003 def_builtin (d->mask, d->name, type, d->code);
6004 }
24408032 6005
2212663f
DB
6006 /* Add the simple unary operators. */
6007 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 6008 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
6009 {
6010 enum machine_mode mode0, mode1;
6011 tree type;
6012
0559cc77 6013 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
6014 continue;
6015
6016 mode0 = insn_data[d->icode].operand[0].mode;
6017 mode1 = insn_data[d->icode].operand[1].mode;
6018
6019 if (mode0 == V4SImode && mode1 == QImode)
6020 type = v4si_ftype_char;
6021 else if (mode0 == V8HImode && mode1 == QImode)
6022 type = v8hi_ftype_char;
6023 else if (mode0 == V16QImode && mode1 == QImode)
6024 type = v16qi_ftype_char;
617e0e1d
DB
6025 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6026 type = v4sf_ftype_v4sf;
20e26713
AH
6027 else if (mode0 == V8HImode && mode1 == V16QImode)
6028 type = v8hi_ftype_v16qi;
6029 else if (mode0 == V4SImode && mode1 == V8HImode)
6030 type = v4si_ftype_v8hi;
a3170dc6
AH
6031 else if (mode0 == V2SImode && mode1 == V2SImode)
6032 type = v2si_ftype_v2si;
6033 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6034 type = v2sf_ftype_v2sf;
6035 else if (mode0 == V2SFmode && mode1 == V2SImode)
6036 type = v2sf_ftype_v2si;
6037 else if (mode0 == V2SImode && mode1 == V2SFmode)
6038 type = v2si_ftype_v2sf;
6039 else if (mode0 == V2SImode && mode1 == QImode)
6040 type = v2si_ftype_char;
2212663f
DB
6041 else
6042 abort ();
6043
0ac081f6
AH
6044 def_builtin (d->mask, d->name, type, d->code);
6045 }
6046}
6047
35aff10b 6048\f
7e69e155
MM
6049/* Expand a block move operation, and return 1 if successful. Return 0
6050 if we should let the compiler generate normal code.
6051
6052 operands[0] is the destination
6053 operands[1] is the source
6054 operands[2] is the length
6055 operands[3] is the alignment */
6056
3933e0e1
MM
6057#define MAX_MOVE_REG 4
6058
7e69e155
MM
6059int
6060expand_block_move (operands)
6061 rtx operands[];
6062{
b6c9286a
MM
6063 rtx orig_dest = operands[0];
6064 rtx orig_src = operands[1];
7e69e155 6065 rtx bytes_rtx = operands[2];
7e69e155 6066 rtx align_rtx = operands[3];
3933e0e1 6067 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6068 int align;
3933e0e1
MM
6069 int bytes;
6070 int offset;
7e69e155
MM
6071 int move_bytes;
6072
3933e0e1 6073 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6074 if (! constp)
3933e0e1
MM
6075 return 0;
6076
5ee95df6
FS
6077 /* If this is not a fixed size alignment, abort */
6078 if (GET_CODE (align_rtx) != CONST_INT)
6079 abort ();
6080 align = INTVAL (align_rtx);
6081
7e69e155 6082 /* Anything to move? */
3933e0e1
MM
6083 bytes = INTVAL (bytes_rtx);
6084 if (bytes <= 0)
7e69e155
MM
6085 return 1;
6086
ea9982a8 6087 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6088 reg_parm_stack_space. */
ea9982a8 6089 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6090 return 0;
6091
3933e0e1 6092 if (TARGET_STRING) /* string instructions are available */
7e69e155 6093 {
35aff10b 6094 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6095 {
35aff10b
AM
6096 union {
6097 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
6098 rtx (*mov) PARAMS ((rtx, rtx));
6099 } gen_func;
6100 enum machine_mode mode = BLKmode;
6101 rtx src, dest;
6102
3933e0e1 6103 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6104 && ! fixed_regs[5]
6105 && ! fixed_regs[6]
6106 && ! fixed_regs[7]
6107 && ! fixed_regs[8]
6108 && ! fixed_regs[9]
6109 && ! fixed_regs[10]
6110 && ! fixed_regs[11]
6111 && ! fixed_regs[12])
3933e0e1
MM
6112 {
6113 move_bytes = (bytes > 32) ? 32 : bytes;
35aff10b 6114 gen_func.movstrsi = gen_movstrsi_8reg;
3933e0e1
MM
6115 }
6116 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6117 && ! fixed_regs[5]
6118 && ! fixed_regs[6]
cc0d9ba8
DE
6119 && ! fixed_regs[7]
6120 && ! fixed_regs[8]
6121 && ! fixed_regs[9]
f9562f27 6122 && ! fixed_regs[10])
3933e0e1
MM
6123 {
6124 move_bytes = (bytes > 24) ? 24 : bytes;
35aff10b 6125 gen_func.movstrsi = gen_movstrsi_6reg;
3933e0e1
MM
6126 }
6127 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6128 && ! fixed_regs[5]
6129 && ! fixed_regs[6]
6130 && ! fixed_regs[7]
6131 && ! fixed_regs[8])
3933e0e1
MM
6132 {
6133 move_bytes = (bytes > 16) ? 16 : bytes;
35aff10b 6134 gen_func.movstrsi = gen_movstrsi_4reg;
3933e0e1 6135 }
acad7ed3 6136 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6137 /* 64-bit loads and stores require word-aligned
82e41834 6138 displacements. */
a4f6c312 6139 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6140 {
6141 move_bytes = 8;
35aff10b
AM
6142 mode = DImode;
6143 gen_func.mov = gen_movdi;
acad7ed3 6144 }
09a625f7 6145 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6146 { /* move up to 8 bytes at a time */
6147 move_bytes = (bytes > 8) ? 8 : bytes;
35aff10b 6148 gen_func.movstrsi = gen_movstrsi_2reg;
3933e0e1 6149 }
cc0d9ba8 6150 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6151 { /* move 4 bytes */
6152 move_bytes = 4;
35aff10b
AM
6153 mode = SImode;
6154 gen_func.mov = gen_movsi;
3933e0e1 6155 }
cc0d9ba8 6156 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6157 { /* move 2 bytes */
6158 move_bytes = 2;
35aff10b
AM
6159 mode = HImode;
6160 gen_func.mov = gen_movhi;
3933e0e1
MM
6161 }
6162 else if (bytes == 1) /* move 1 byte */
6163 {
6164 move_bytes = 1;
35aff10b
AM
6165 mode = QImode;
6166 gen_func.mov = gen_movqi;
3933e0e1
MM
6167 }
6168 else
6169 { /* move up to 4 bytes at a time */
6170 move_bytes = (bytes > 4) ? 4 : bytes;
35aff10b 6171 gen_func.movstrsi = gen_movstrsi_1reg;
3933e0e1 6172 }
4c64a852 6173
35aff10b
AM
6174 src = adjust_address (orig_src, mode, offset);
6175 dest = adjust_address (orig_dest, mode, offset);
6176
6177 if (mode == BLKmode)
015892ee 6178 {
35aff10b
AM
6179 /* Move the address into scratch registers. The movstrsi
6180 patterns require zero offset. */
6181 if (!REG_P (XEXP (src, 0)))
cc0d9ba8 6182 {
35aff10b
AM
6183 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
6184 src = replace_equiv_address (src, src_reg);
cc0d9ba8 6185 }
35aff10b
AM
6186 set_mem_size (src, GEN_INT (move_bytes));
6187
6188 if (!REG_P (XEXP (dest, 0)))
cc0d9ba8 6189 {
35aff10b
AM
6190 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
6191 dest = replace_equiv_address (dest, dest_reg);
cc0d9ba8 6192 }
35aff10b
AM
6193 set_mem_size (dest, GEN_INT (move_bytes));
6194
6195 emit_insn ((*gen_func.movstrsi) (dest, src,
6196 GEN_INT (move_bytes & 31),
6197 align_rtx));
6198 }
6199 else
6200 {
6201 rtx tmp_reg = gen_reg_rtx (mode);
6202
6203 emit_insn ((*gen_func.mov) (tmp_reg, src));
6204 emit_insn ((*gen_func.mov) (dest, tmp_reg));
015892ee 6205 }
4c64a852 6206 }
3933e0e1
MM
6207 }
6208
6209 else /* string instructions not available */
6210 {
35aff10b
AM
6211 rtx stores[MAX_MOVE_REG];
6212 int num_reg = 0;
6213 int i;
6214
6215 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6216 {
35aff10b
AM
6217 rtx (*gen_mov_func) PARAMS ((rtx, rtx));
6218 enum machine_mode mode;
6219 rtx src, dest, tmp_reg;
3933e0e1 6220
cc0d9ba8
DE
6221 /* Generate the appropriate load and store, saving the stores
6222 for later. */
6223 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6224 /* 64-bit loads and stores require word-aligned
6225 displacements. */
cc0d9ba8 6226 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6227 {
6228 move_bytes = 8;
35aff10b
AM
6229 mode = DImode;
6230 gen_mov_func = gen_movdi;
b6c9286a 6231 }
cc0d9ba8 6232 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6233 {
6234 move_bytes = 4;
35aff10b
AM
6235 mode = SImode;
6236 gen_mov_func = gen_movsi;
3933e0e1 6237 }
cc0d9ba8 6238 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6239 {
6240 move_bytes = 2;
35aff10b
AM
6241 mode = HImode;
6242 gen_mov_func = gen_movhi;
3933e0e1
MM
6243 }
6244 else
6245 {
6246 move_bytes = 1;
35aff10b
AM
6247 mode = QImode;
6248 gen_mov_func = gen_movqi;
3933e0e1
MM
6249 }
6250
35aff10b
AM
6251 src = adjust_address (orig_src, mode, offset);
6252 dest = adjust_address (orig_dest, mode, offset);
6253 tmp_reg = gen_reg_rtx (mode);
6254
6255 emit_insn ((*gen_mov_func) (tmp_reg, src));
6256 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
6257
3933e0e1
MM
6258 if (num_reg >= MAX_MOVE_REG)
6259 {
6260 for (i = 0; i < num_reg; i++)
6261 emit_insn (stores[i]);
6262 num_reg = 0;
7e69e155
MM
6263 }
6264 }
3933e0e1 6265
b6c9286a
MM
6266 for (i = 0; i < num_reg; i++)
6267 emit_insn (stores[i]);
7e69e155
MM
6268 }
6269
6270 return 1;
6271}
6272
9878760c
RK
6273\f
6274/* Return 1 if OP is a load multiple operation. It is known to be a
6275 PARALLEL and the first section will be tested. */
6276
6277int
6278load_multiple_operation (op, mode)
6279 rtx op;
296b8152 6280 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6281{
6282 int count = XVECLEN (op, 0);
e2c953b6 6283 unsigned int dest_regno;
9878760c
RK
6284 rtx src_addr;
6285 int i;
6286
6287 /* Perform a quick check so we don't blow up below. */
6288 if (count <= 1
6289 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6290 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6291 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6292 return 0;
6293
6294 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6295 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6296
6297 for (i = 1; i < count; i++)
6298 {
6299 rtx elt = XVECEXP (op, 0, i);
6300
6301 if (GET_CODE (elt) != SET
6302 || GET_CODE (SET_DEST (elt)) != REG
6303 || GET_MODE (SET_DEST (elt)) != SImode
6304 || REGNO (SET_DEST (elt)) != dest_regno + i
6305 || GET_CODE (SET_SRC (elt)) != MEM
6306 || GET_MODE (SET_SRC (elt)) != SImode
6307 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6308 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6309 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6310 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6311 return 0;
6312 }
6313
6314 return 1;
6315}
6316
6317/* Similar, but tests for store multiple. Here, the second vector element
6318 is a CLOBBER. It will be tested later. */
6319
6320int
6321store_multiple_operation (op, mode)
6322 rtx op;
296b8152 6323 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6324{
6325 int count = XVECLEN (op, 0) - 1;
e2c953b6 6326 unsigned int src_regno;
9878760c
RK
6327 rtx dest_addr;
6328 int i;
6329
6330 /* Perform a quick check so we don't blow up below. */
6331 if (count <= 1
6332 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6333 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6334 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6335 return 0;
6336
6337 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6338 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6339
6340 for (i = 1; i < count; i++)
6341 {
6342 rtx elt = XVECEXP (op, 0, i + 1);
6343
6344 if (GET_CODE (elt) != SET
6345 || GET_CODE (SET_SRC (elt)) != REG
6346 || GET_MODE (SET_SRC (elt)) != SImode
6347 || REGNO (SET_SRC (elt)) != src_regno + i
6348 || GET_CODE (SET_DEST (elt)) != MEM
6349 || GET_MODE (SET_DEST (elt)) != SImode
6350 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6351 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6352 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6353 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6354 return 0;
6355 }
6356
6357 return 1;
6358}
9ebbca7d 6359
00b960c7
AH
6360/* Return 1 for a parallel vrsave operation. */
6361
6362int
6363vrsave_operation (op, mode)
6364 rtx op;
6365 enum machine_mode mode ATTRIBUTE_UNUSED;
6366{
6367 int count = XVECLEN (op, 0);
6368 unsigned int dest_regno, src_regno;
6369 int i;
6370
6371 if (count <= 1
6372 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6373 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6374 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6375 return 0;
6376
6377 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6378 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6379
6380 if (dest_regno != VRSAVE_REGNO
6381 && src_regno != VRSAVE_REGNO)
6382 return 0;
6383
6384 for (i = 1; i < count; i++)
6385 {
6386 rtx elt = XVECEXP (op, 0, i);
6387
9aa86737
AH
6388 if (GET_CODE (elt) != CLOBBER
6389 && GET_CODE (elt) != SET)
00b960c7
AH
6390 return 0;
6391 }
6392
6393 return 1;
6394}
6395
a4f6c312 6396/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6397
6398int
6399mtcrf_operation (op, mode)
6400 rtx op;
6401 enum machine_mode mode ATTRIBUTE_UNUSED;
6402{
6403 int count = XVECLEN (op, 0);
6404 int i;
9ebbca7d
GK
6405 rtx src_reg;
6406
6407 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6408 if (count < 1
6409 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6410 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6411 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6412 return 0;
e35b9579 6413 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6414
6415 if (GET_CODE (src_reg) != REG
6416 || GET_MODE (src_reg) != SImode
6417 || ! INT_REGNO_P (REGNO (src_reg)))
6418 return 0;
6419
e35b9579 6420 for (i = 0; i < count; i++)
9ebbca7d
GK
6421 {
6422 rtx exp = XVECEXP (op, 0, i);
6423 rtx unspec;
6424 int maskval;
6425
6426 if (GET_CODE (exp) != SET
6427 || GET_CODE (SET_DEST (exp)) != REG
6428 || GET_MODE (SET_DEST (exp)) != CCmode
6429 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6430 return 0;
6431 unspec = SET_SRC (exp);
6432 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6433
6434 if (GET_CODE (unspec) != UNSPEC
6435 || XINT (unspec, 1) != 20
6436 || XVECLEN (unspec, 0) != 2
6437 || XVECEXP (unspec, 0, 0) != src_reg
6438 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6439 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6440 return 0;
6441 }
e35b9579 6442 return 1;
9ebbca7d
GK
6443}
6444
a4f6c312 6445/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6446
6447int
6448lmw_operation (op, mode)
6449 rtx op;
6450 enum machine_mode mode ATTRIBUTE_UNUSED;
6451{
6452 int count = XVECLEN (op, 0);
e2c953b6 6453 unsigned int dest_regno;
9ebbca7d 6454 rtx src_addr;
e2c953b6 6455 unsigned int base_regno;
9ebbca7d
GK
6456 HOST_WIDE_INT offset;
6457 int i;
6458
6459 /* Perform a quick check so we don't blow up below. */
6460 if (count <= 1
6461 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6462 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6463 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6464 return 0;
6465
6466 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6467 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6468
6469 if (dest_regno > 31
e2c953b6 6470 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6471 return 0;
6472
258bfae2 6473 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6474 {
6475 offset = 0;
6476 base_regno = REGNO (src_addr);
6477 if (base_regno == 0)
6478 return 0;
6479 }
258bfae2 6480 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6481 {
6482 offset = INTVAL (XEXP (src_addr, 1));
6483 base_regno = REGNO (XEXP (src_addr, 0));
6484 }
6485 else
6486 return 0;
6487
6488 for (i = 0; i < count; i++)
6489 {
6490 rtx elt = XVECEXP (op, 0, i);
6491 rtx newaddr;
6492 rtx addr_reg;
6493 HOST_WIDE_INT newoffset;
6494
6495 if (GET_CODE (elt) != SET
6496 || GET_CODE (SET_DEST (elt)) != REG
6497 || GET_MODE (SET_DEST (elt)) != SImode
6498 || REGNO (SET_DEST (elt)) != dest_regno + i
6499 || GET_CODE (SET_SRC (elt)) != MEM
6500 || GET_MODE (SET_SRC (elt)) != SImode)
6501 return 0;
6502 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6503 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6504 {
6505 newoffset = 0;
6506 addr_reg = newaddr;
6507 }
258bfae2 6508 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6509 {
6510 addr_reg = XEXP (newaddr, 0);
6511 newoffset = INTVAL (XEXP (newaddr, 1));
6512 }
6513 else
6514 return 0;
6515 if (REGNO (addr_reg) != base_regno
6516 || newoffset != offset + 4 * i)
6517 return 0;
6518 }
6519
6520 return 1;
6521}
6522
a4f6c312 6523/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6524
6525int
6526stmw_operation (op, mode)
6527 rtx op;
6528 enum machine_mode mode ATTRIBUTE_UNUSED;
6529{
6530 int count = XVECLEN (op, 0);
e2c953b6 6531 unsigned int src_regno;
9ebbca7d 6532 rtx dest_addr;
e2c953b6 6533 unsigned int base_regno;
9ebbca7d
GK
6534 HOST_WIDE_INT offset;
6535 int i;
6536
6537 /* Perform a quick check so we don't blow up below. */
6538 if (count <= 1
6539 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6540 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6541 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6542 return 0;
6543
6544 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6545 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6546
6547 if (src_regno > 31
e2c953b6 6548 || count != 32 - (int) src_regno)
9ebbca7d
GK
6549 return 0;
6550
258bfae2 6551 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6552 {
6553 offset = 0;
6554 base_regno = REGNO (dest_addr);
6555 if (base_regno == 0)
6556 return 0;
6557 }
258bfae2 6558 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6559 {
6560 offset = INTVAL (XEXP (dest_addr, 1));
6561 base_regno = REGNO (XEXP (dest_addr, 0));
6562 }
6563 else
6564 return 0;
6565
6566 for (i = 0; i < count; i++)
6567 {
6568 rtx elt = XVECEXP (op, 0, i);
6569 rtx newaddr;
6570 rtx addr_reg;
6571 HOST_WIDE_INT newoffset;
6572
6573 if (GET_CODE (elt) != SET
6574 || GET_CODE (SET_SRC (elt)) != REG
6575 || GET_MODE (SET_SRC (elt)) != SImode
6576 || REGNO (SET_SRC (elt)) != src_regno + i
6577 || GET_CODE (SET_DEST (elt)) != MEM
6578 || GET_MODE (SET_DEST (elt)) != SImode)
6579 return 0;
6580 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6581 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6582 {
6583 newoffset = 0;
6584 addr_reg = newaddr;
6585 }
258bfae2 6586 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6587 {
6588 addr_reg = XEXP (newaddr, 0);
6589 newoffset = INTVAL (XEXP (newaddr, 1));
6590 }
6591 else
6592 return 0;
6593 if (REGNO (addr_reg) != base_regno
6594 || newoffset != offset + 4 * i)
6595 return 0;
6596 }
6597
6598 return 1;
6599}
9878760c 6600\f
a4f6c312
SS
6601/* A validation routine: say whether CODE, a condition code, and MODE
6602 match. The other alternatives either don't make sense or should
6603 never be generated. */
39a10a29 6604
39a10a29
GK
6605static void
6606validate_condition_mode (code, mode)
6607 enum rtx_code code;
6608 enum machine_mode mode;
6609{
6610 if (GET_RTX_CLASS (code) != '<'
6611 || GET_MODE_CLASS (mode) != MODE_CC)
6612 abort ();
6613
6614 /* These don't make sense. */
6615 if ((code == GT || code == LT || code == GE || code == LE)
6616 && mode == CCUNSmode)
6617 abort ();
6618
6619 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6620 && mode != CCUNSmode)
6621 abort ();
6622
6623 if (mode != CCFPmode
6624 && (code == ORDERED || code == UNORDERED
6625 || code == UNEQ || code == LTGT
6626 || code == UNGT || code == UNLT
6627 || code == UNGE || code == UNLE))
a4f6c312 6628 abort ();
39a10a29 6629
de6c5979 6630 /* These should never be generated except for
ad72b533 6631 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6632 if (mode == CCFPmode
de6c5979 6633 && ! flag_unsafe_math_optimizations
ad72b533 6634 && ! flag_finite_math_only
39a10a29
GK
6635 && (code == LE || code == GE
6636 || code == UNEQ || code == LTGT
6637 || code == UNGT || code == UNLT))
6638 abort ();
6639
6640 /* These are invalid; the information is not there. */
6641 if (mode == CCEQmode
6642 && code != EQ && code != NE)
6643 abort ();
6644}
6645
9878760c
RK
6646/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6647 We only check the opcode against the mode of the CC value here. */
6648
6649int
6650branch_comparison_operator (op, mode)
592696dd 6651 rtx op;
296b8152 6652 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6653{
6654 enum rtx_code code = GET_CODE (op);
6655 enum machine_mode cc_mode;
6656
6657 if (GET_RTX_CLASS (code) != '<')
6658 return 0;
6659
6660 cc_mode = GET_MODE (XEXP (op, 0));
6661 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6662 return 0;
6663
39a10a29 6664 validate_condition_mode (code, cc_mode);
9878760c 6665
39a10a29
GK
6666 return 1;
6667}
6668
6669/* Return 1 if OP is a comparison operation that is valid for a branch
6670 insn and which is true if the corresponding bit in the CC register
6671 is set. */
6672
6673int
6674branch_positive_comparison_operator (op, mode)
592696dd 6675 rtx op;
39a10a29
GK
6676 enum machine_mode mode;
6677{
6678 enum rtx_code code;
6679
6680 if (! branch_comparison_operator (op, mode))
9878760c
RK
6681 return 0;
6682
39a10a29
GK
6683 code = GET_CODE (op);
6684 return (code == EQ || code == LT || code == GT
a3170dc6 6685 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
6686 || code == LTU || code == GTU
6687 || code == UNORDERED);
9878760c
RK
6688}
6689
6690/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6691 We check the opcode against the mode of the CC value and disallow EQ or
6692 NE comparisons for integers. */
6693
6694int
6695scc_comparison_operator (op, mode)
592696dd 6696 rtx op;
9878760c
RK
6697 enum machine_mode mode;
6698{
6699 enum rtx_code code = GET_CODE (op);
6700 enum machine_mode cc_mode;
6701
6702 if (GET_MODE (op) != mode && mode != VOIDmode)
6703 return 0;
6704
6705 if (GET_RTX_CLASS (code) != '<')
6706 return 0;
6707
6708 cc_mode = GET_MODE (XEXP (op, 0));
6709 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6710 return 0;
6711
39a10a29 6712 validate_condition_mode (code, cc_mode);
9878760c 6713
39a10a29 6714 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
6715 return 0;
6716
9878760c
RK
6717 return 1;
6718}
e0cd0770
JC
6719
6720int
6721trap_comparison_operator (op, mode)
6722 rtx op;
6723 enum machine_mode mode;
6724{
6725 if (mode != VOIDmode && mode != GET_MODE (op))
6726 return 0;
39a10a29 6727 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 6728}
dfbdccdb
GK
6729
6730int
6731boolean_operator (op, mode)
6732 rtx op;
6733 enum machine_mode mode ATTRIBUTE_UNUSED;
6734{
6735 enum rtx_code code = GET_CODE (op);
6736 return (code == AND || code == IOR || code == XOR);
6737}
1d328b19
GK
6738
6739int
6740boolean_or_operator (op, mode)
6741 rtx op;
6742 enum machine_mode mode ATTRIBUTE_UNUSED;
6743{
6744 enum rtx_code code = GET_CODE (op);
6745 return (code == IOR || code == XOR);
6746}
50a0b056
GK
6747
6748int
6749min_max_operator (op, mode)
6750 rtx op;
6751 enum machine_mode mode ATTRIBUTE_UNUSED;
6752{
6753 enum rtx_code code = GET_CODE (op);
6754 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6755}
9878760c
RK
6756\f
6757/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6758 mask required to convert the result of a rotate insn into a shift
b1765bde 6759 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
6760
6761int
6762includes_lshift_p (shiftop, andop)
592696dd
SS
6763 rtx shiftop;
6764 rtx andop;
9878760c 6765{
e2c953b6
DE
6766 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6767
6768 shift_mask <<= INTVAL (shiftop);
9878760c 6769
b1765bde 6770 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
6771}
6772
6773/* Similar, but for right shift. */
6774
6775int
6776includes_rshift_p (shiftop, andop)
592696dd
SS
6777 rtx shiftop;
6778 rtx andop;
9878760c 6779{
a7653a2c 6780 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
6781
6782 shift_mask >>= INTVAL (shiftop);
6783
b1765bde 6784 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
6785}
6786
c5059423
AM
6787/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6788 to perform a left shift. It must have exactly SHIFTOP least
6789 signifigant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
6790
6791int
c5059423 6792includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
6793 rtx shiftop;
6794 rtx andop;
e2c953b6 6795{
c5059423
AM
6796 if (GET_CODE (andop) == CONST_INT)
6797 {
02071907 6798 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 6799
c5059423 6800 c = INTVAL (andop);
02071907 6801 if (c == 0 || c == ~0)
c5059423 6802 return 0;
e2c953b6 6803
02071907 6804 shift_mask = ~0;
c5059423
AM
6805 shift_mask <<= INTVAL (shiftop);
6806
6807 /* Find the least signifigant one bit. */
6808 lsb = c & -c;
6809
6810 /* It must coincide with the LSB of the shift mask. */
6811 if (-lsb != shift_mask)
6812 return 0;
e2c953b6 6813
c5059423
AM
6814 /* Invert to look for the next transition (if any). */
6815 c = ~c;
6816
6817 /* Remove the low group of ones (originally low group of zeros). */
6818 c &= -lsb;
6819
6820 /* Again find the lsb, and check we have all 1's above. */
6821 lsb = c & -c;
6822 return c == -lsb;
6823 }
6824 else if (GET_CODE (andop) == CONST_DOUBLE
6825 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6826 {
02071907
AM
6827 HOST_WIDE_INT low, high, lsb;
6828 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
6829
6830 low = CONST_DOUBLE_LOW (andop);
6831 if (HOST_BITS_PER_WIDE_INT < 64)
6832 high = CONST_DOUBLE_HIGH (andop);
6833
6834 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 6835 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
6836 return 0;
6837
6838 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6839 {
02071907 6840 shift_mask_high = ~0;
c5059423
AM
6841 if (INTVAL (shiftop) > 32)
6842 shift_mask_high <<= INTVAL (shiftop) - 32;
6843
6844 lsb = high & -high;
6845
6846 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
6847 return 0;
6848
6849 high = ~high;
6850 high &= -lsb;
6851
6852 lsb = high & -high;
6853 return high == -lsb;
6854 }
6855
02071907 6856 shift_mask_low = ~0;
c5059423
AM
6857 shift_mask_low <<= INTVAL (shiftop);
6858
6859 lsb = low & -low;
6860
6861 if (-lsb != shift_mask_low)
6862 return 0;
6863
6864 if (HOST_BITS_PER_WIDE_INT < 64)
6865 high = ~high;
6866 low = ~low;
6867 low &= -lsb;
6868
6869 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6870 {
6871 lsb = high & -high;
6872 return high == -lsb;
6873 }
6874
6875 lsb = low & -low;
6876 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
6877 }
6878 else
6879 return 0;
6880}
e2c953b6 6881
c5059423
AM
6882/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
6883 to perform a left shift. It must have SHIFTOP or more least
6884 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 6885
c5059423
AM
6886int
6887includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
6888 rtx shiftop;
6889 rtx andop;
c5059423 6890{
e2c953b6 6891 if (GET_CODE (andop) == CONST_INT)
c5059423 6892 {
02071907 6893 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 6894
02071907 6895 shift_mask = ~0;
c5059423
AM
6896 shift_mask <<= INTVAL (shiftop);
6897 c = INTVAL (andop);
6898
6899 /* Find the least signifigant one bit. */
6900 lsb = c & -c;
6901
6902 /* It must be covered by the shift mask.
a4f6c312 6903 This test also rejects c == 0. */
c5059423
AM
6904 if ((lsb & shift_mask) == 0)
6905 return 0;
6906
6907 /* Check we have all 1's above the transition, and reject all 1's. */
6908 return c == -lsb && lsb != 1;
6909 }
6910 else if (GET_CODE (andop) == CONST_DOUBLE
6911 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6912 {
02071907 6913 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
6914
6915 low = CONST_DOUBLE_LOW (andop);
6916
6917 if (HOST_BITS_PER_WIDE_INT < 64)
6918 {
02071907 6919 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
6920
6921 high = CONST_DOUBLE_HIGH (andop);
6922
6923 if (low == 0)
6924 {
02071907 6925 shift_mask_high = ~0;
c5059423
AM
6926 if (INTVAL (shiftop) > 32)
6927 shift_mask_high <<= INTVAL (shiftop) - 32;
6928
6929 lsb = high & -high;
6930
6931 if ((lsb & shift_mask_high) == 0)
6932 return 0;
6933
6934 return high == -lsb;
6935 }
6936 if (high != ~0)
6937 return 0;
6938 }
6939
02071907 6940 shift_mask_low = ~0;
c5059423
AM
6941 shift_mask_low <<= INTVAL (shiftop);
6942
6943 lsb = low & -low;
6944
6945 if ((lsb & shift_mask_low) == 0)
6946 return 0;
6947
6948 return low == -lsb && lsb != 1;
6949 }
e2c953b6 6950 else
c5059423 6951 return 0;
9878760c 6952}
35068b43
RK
6953
6954/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
6955 for lfq and stfq insns.
6956
6957 Note reg1 and reg2 *must* be hard registers. To be sure we will
6958 abort if we are passed pseudo registers. */
6959
6960int
6961registers_ok_for_quad_peep (reg1, reg2)
6962 rtx reg1, reg2;
6963{
6964 /* We might have been passed a SUBREG. */
6965 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
6966 return 0;
6967
6968 return (REGNO (reg1) == REGNO (reg2) - 1);
6969}
6970
a4f6c312
SS
6971/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
6972 addr1 and addr2 must be in consecutive memory locations
6973 (addr2 == addr1 + 8). */
35068b43
RK
6974
6975int
6976addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
6977 rtx addr1;
6978 rtx addr2;
35068b43 6979{
e2c953b6 6980 unsigned int reg1;
35068b43
RK
6981 int offset1;
6982
6983 /* Extract an offset (if used) from the first addr. */
6984 if (GET_CODE (addr1) == PLUS)
6985 {
6986 /* If not a REG, return zero. */
6987 if (GET_CODE (XEXP (addr1, 0)) != REG)
6988 return 0;
6989 else
6990 {
6991 reg1 = REGNO (XEXP (addr1, 0));
6992 /* The offset must be constant! */
6993 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
6994 return 0;
6995 offset1 = INTVAL (XEXP (addr1, 1));
6996 }
6997 }
6998 else if (GET_CODE (addr1) != REG)
6999 return 0;
7000 else
7001 {
7002 reg1 = REGNO (addr1);
7003 /* This was a simple (mem (reg)) expression. Offset is 0. */
7004 offset1 = 0;
7005 }
7006
acad7ed3 7007 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
7008 if (GET_CODE (addr2) != PLUS)
7009 return 0;
7010
7011 if (GET_CODE (XEXP (addr2, 0)) != REG
7012 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7013 return 0;
7014
7015 if (reg1 != REGNO (XEXP (addr2, 0)))
7016 return 0;
7017
7018 /* The offset for the second addr must be 8 more than the first addr. */
7019 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7020 return 0;
7021
7022 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7023 instructions. */
7024 return 1;
7025}
9878760c
RK
7026\f
7027/* Return the register class of a scratch register needed to copy IN into
7028 or out of a register in CLASS in MODE. If it can be done directly,
7029 NO_REGS is returned. */
7030
7031enum reg_class
7032secondary_reload_class (class, mode, in)
7033 enum reg_class class;
296b8152 7034 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7035 rtx in;
7036{
5accd822 7037 int regno;
9878760c 7038
46fad5b7
DJ
7039 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
7040 {
7041 /* We cannot copy a symbolic operand directly into anything
7042 other than BASE_REGS for TARGET_ELF. So indicate that a
7043 register from BASE_REGS is needed as an intermediate
7044 register.
7045
7046 On Darwin, pic addresses require a load from memory, which
7047 needs a base register. */
7048 if (class != BASE_REGS
7049 && (GET_CODE (in) == SYMBOL_REF
7050 || GET_CODE (in) == HIGH
7051 || GET_CODE (in) == LABEL_REF
7052 || GET_CODE (in) == CONST))
7053 return BASE_REGS;
7054 }
e7b7998a 7055
5accd822
DE
7056 if (GET_CODE (in) == REG)
7057 {
7058 regno = REGNO (in);
7059 if (regno >= FIRST_PSEUDO_REGISTER)
7060 {
7061 regno = true_regnum (in);
7062 if (regno >= FIRST_PSEUDO_REGISTER)
7063 regno = -1;
7064 }
7065 }
7066 else if (GET_CODE (in) == SUBREG)
7067 {
7068 regno = true_regnum (in);
7069 if (regno >= FIRST_PSEUDO_REGISTER)
7070 regno = -1;
7071 }
7072 else
7073 regno = -1;
7074
9878760c
RK
7075 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7076 into anything. */
7077 if (class == GENERAL_REGS || class == BASE_REGS
7078 || (regno >= 0 && INT_REGNO_P (regno)))
7079 return NO_REGS;
7080
7081 /* Constants, memory, and FP registers can go into FP registers. */
7082 if ((regno == -1 || FP_REGNO_P (regno))
7083 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7084 return NO_REGS;
7085
0ac081f6
AH
7086 /* Memory, and AltiVec registers can go into AltiVec registers. */
7087 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7088 && class == ALTIVEC_REGS)
7089 return NO_REGS;
7090
9878760c
RK
7091 /* We can copy among the CR registers. */
7092 if ((class == CR_REGS || class == CR0_REGS)
7093 && regno >= 0 && CR_REGNO_P (regno))
7094 return NO_REGS;
7095
7096 /* Otherwise, we need GENERAL_REGS. */
7097 return GENERAL_REGS;
7098}
7099\f
7100/* Given a comparison operation, return the bit number in CCR to test. We
7101 know this is a valid comparison.
7102
7103 SCC_P is 1 if this is for an scc. That means that %D will have been
7104 used instead of %C, so the bits will be in different places.
7105
b4ac57ab 7106 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7107
7108int
7109ccr_bit (op, scc_p)
592696dd 7110 rtx op;
9878760c
RK
7111 int scc_p;
7112{
7113 enum rtx_code code = GET_CODE (op);
7114 enum machine_mode cc_mode;
7115 int cc_regnum;
7116 int base_bit;
9ebbca7d 7117 rtx reg;
9878760c
RK
7118
7119 if (GET_RTX_CLASS (code) != '<')
7120 return -1;
7121
9ebbca7d
GK
7122 reg = XEXP (op, 0);
7123
7124 if (GET_CODE (reg) != REG
7125 || ! CR_REGNO_P (REGNO (reg)))
7126 abort ();
7127
7128 cc_mode = GET_MODE (reg);
7129 cc_regnum = REGNO (reg);
7130 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7131
39a10a29 7132 validate_condition_mode (code, cc_mode);
c5defebb 7133
9878760c
RK
7134 switch (code)
7135 {
7136 case NE:
a3170dc6
AH
7137 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7138 return base_bit + 1;
9878760c
RK
7139 return scc_p ? base_bit + 3 : base_bit + 2;
7140 case EQ:
a3170dc6
AH
7141 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7142 return base_bit + 1;
9878760c 7143 return base_bit + 2;
1c882ea4 7144 case GT: case GTU: case UNLE:
9878760c 7145 return base_bit + 1;
1c882ea4 7146 case LT: case LTU: case UNGE:
9878760c 7147 return base_bit;
1c882ea4
GK
7148 case ORDERED: case UNORDERED:
7149 return base_bit + 3;
9878760c
RK
7150
7151 case GE: case GEU:
39a10a29 7152 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7153 unordered position. So test that bit. For integer, this is ! LT
7154 unless this is an scc insn. */
39a10a29 7155 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7156
7157 case LE: case LEU:
39a10a29 7158 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7159
9878760c
RK
7160 default:
7161 abort ();
7162 }
7163}
1ff7789b 7164\f
8d30c4ee 7165/* Return the GOT register. */
1ff7789b
MM
7166
7167struct rtx_def *
7168rs6000_got_register (value)
5f59ecb7 7169 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7170{
a4f6c312
SS
7171 /* The second flow pass currently (June 1999) can't update
7172 regs_ever_live without disturbing other parts of the compiler, so
7173 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7174 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7175 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7176
8d30c4ee 7177 current_function_uses_pic_offset_table = 1;
3cb999d8 7178
1ff7789b
MM
7179 return pic_offset_table_rtx;
7180}
a7df97e6 7181\f
e2500fed
GK
7182/* Function to init struct machine_function.
7183 This will be called, via a pointer variable,
7184 from push_function_context. */
a7df97e6 7185
e2500fed
GK
7186static struct machine_function *
7187rs6000_init_machine_status ()
a7df97e6 7188{
e2500fed 7189 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7190}
9878760c 7191\f
0ba1b2ff
AM
7192/* These macros test for integers and extract the low-order bits. */
7193#define INT_P(X) \
7194((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7195 && GET_MODE (X) == VOIDmode)
7196
7197#define INT_LOWPART(X) \
7198 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7199
7200int
7201extract_MB (op)
7202 rtx op;
7203{
7204 int i;
7205 unsigned long val = INT_LOWPART (op);
7206
7207 /* If the high bit is zero, the value is the first 1 bit we find
7208 from the left. */
7209 if ((val & 0x80000000) == 0)
7210 {
7211 if ((val & 0xffffffff) == 0)
7212 abort ();
7213
7214 i = 1;
7215 while (((val <<= 1) & 0x80000000) == 0)
7216 ++i;
7217 return i;
7218 }
7219
7220 /* If the high bit is set and the low bit is not, or the mask is all
7221 1's, the value is zero. */
7222 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7223 return 0;
7224
7225 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7226 from the right. */
7227 i = 31;
7228 while (((val >>= 1) & 1) != 0)
7229 --i;
7230
7231 return i;
7232}
7233
7234int
7235extract_ME (op)
7236 rtx op;
7237{
7238 int i;
7239 unsigned long val = INT_LOWPART (op);
7240
7241 /* If the low bit is zero, the value is the first 1 bit we find from
7242 the right. */
7243 if ((val & 1) == 0)
7244 {
7245 if ((val & 0xffffffff) == 0)
7246 abort ();
7247
7248 i = 30;
7249 while (((val >>= 1) & 1) == 0)
7250 --i;
7251
7252 return i;
7253 }
7254
7255 /* If the low bit is set and the high bit is not, or the mask is all
7256 1's, the value is 31. */
7257 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7258 return 31;
7259
7260 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7261 from the left. */
7262 i = 0;
7263 while (((val <<= 1) & 0x80000000) != 0)
7264 ++i;
7265
7266 return i;
7267}
7268
9878760c
RK
7269/* Print an operand. Recognize special options, documented below. */
7270
38c1f2d7 7271#if TARGET_ELF
d9407988 7272#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7273#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7274#else
7275#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7276#define SMALL_DATA_REG 0
ba5e43aa
MM
7277#endif
7278
9878760c
RK
7279void
7280print_operand (file, x, code)
7281 FILE *file;
7282 rtx x;
9ebbca7d 7283 int code;
9878760c
RK
7284{
7285 int i;
a260abc9 7286 HOST_WIDE_INT val;
0ba1b2ff 7287 unsigned HOST_WIDE_INT uval;
9878760c
RK
7288
7289 switch (code)
7290 {
a8b3aeda 7291 case '.':
a85d226b
RK
7292 /* Write out an instruction after the call which may be replaced
7293 with glue code by the loader. This depends on the AIX version. */
7294 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7295 return;
7296
81eace42
GK
7297 /* %a is output_address. */
7298
9854d9ed
RK
7299 case 'A':
7300 /* If X is a constant integer whose low-order 5 bits are zero,
7301 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7302 in the AIX assembler where "sri" with a zero shift count
20e26713 7303 writes a trash instruction. */
9854d9ed 7304 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7305 putc ('l', file);
9854d9ed 7306 else
76229ac8 7307 putc ('r', file);
9854d9ed
RK
7308 return;
7309
7310 case 'b':
e2c953b6
DE
7311 /* If constant, low-order 16 bits of constant, unsigned.
7312 Otherwise, write normally. */
7313 if (INT_P (x))
7314 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7315 else
7316 print_operand (file, x, 0);
cad12a8d
RK
7317 return;
7318
a260abc9
DE
7319 case 'B':
7320 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7321 for 64-bit mask direction. */
296b8152 7322 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7323 return;
a260abc9 7324
81eace42
GK
7325 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7326 output_operand. */
7327
9854d9ed 7328 case 'D':
39a10a29
GK
7329 /* There used to be a comment for 'C' reading "This is an
7330 optional cror needed for certain floating-point
7331 comparisons. Otherwise write nothing." */
7332
9854d9ed
RK
7333 /* Similar, except that this is for an scc, so we must be able to
7334 encode the test in a single bit that is one. We do the above
7335 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7336 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7337 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7338 {
9ebbca7d 7339 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7340
7341 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7342 base_bit + 2,
7343 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7344 }
7345
7346 else if (GET_CODE (x) == NE)
7347 {
9ebbca7d 7348 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7349
7350 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7351 base_bit + 2, base_bit + 2);
7352 }
a3170dc6
AH
7353 else if (TARGET_SPE && TARGET_HARD_FLOAT
7354 && GET_CODE (x) == EQ
7355 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7356 {
7357 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7358
7359 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7360 base_bit + 1, base_bit + 1);
7361 }
9854d9ed
RK
7362 return;
7363
7364 case 'E':
39a10a29 7365 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7366 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7367 output_operand_lossage ("invalid %%E value");
78fbdbf7 7368 else
39a10a29 7369 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7370 return;
9854d9ed
RK
7371
7372 case 'f':
7373 /* X is a CR register. Print the shift count needed to move it
7374 to the high-order four bits. */
7375 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7376 output_operand_lossage ("invalid %%f value");
7377 else
9ebbca7d 7378 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7379 return;
7380
7381 case 'F':
7382 /* Similar, but print the count for the rotate in the opposite
7383 direction. */
7384 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7385 output_operand_lossage ("invalid %%F value");
7386 else
9ebbca7d 7387 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7388 return;
7389
7390 case 'G':
7391 /* X is a constant integer. If it is negative, print "m",
7392 otherwise print "z". This is to make a aze or ame insn. */
7393 if (GET_CODE (x) != CONST_INT)
7394 output_operand_lossage ("invalid %%G value");
7395 else if (INTVAL (x) >= 0)
76229ac8 7396 putc ('z', file);
9854d9ed 7397 else
76229ac8 7398 putc ('m', file);
9854d9ed 7399 return;
e2c953b6 7400
9878760c 7401 case 'h':
a4f6c312
SS
7402 /* If constant, output low-order five bits. Otherwise, write
7403 normally. */
9878760c 7404 if (INT_P (x))
5f59ecb7 7405 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7406 else
7407 print_operand (file, x, 0);
7408 return;
7409
64305719 7410 case 'H':
a4f6c312
SS
7411 /* If constant, output low-order six bits. Otherwise, write
7412 normally. */
64305719 7413 if (INT_P (x))
5f59ecb7 7414 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7415 else
7416 print_operand (file, x, 0);
7417 return;
7418
9854d9ed
RK
7419 case 'I':
7420 /* Print `i' if this is a constant, else nothing. */
9878760c 7421 if (INT_P (x))
76229ac8 7422 putc ('i', file);
9878760c
RK
7423 return;
7424
9854d9ed
RK
7425 case 'j':
7426 /* Write the bit number in CCR for jump. */
7427 i = ccr_bit (x, 0);
7428 if (i == -1)
7429 output_operand_lossage ("invalid %%j code");
9878760c 7430 else
9854d9ed 7431 fprintf (file, "%d", i);
9878760c
RK
7432 return;
7433
9854d9ed
RK
7434 case 'J':
7435 /* Similar, but add one for shift count in rlinm for scc and pass
7436 scc flag to `ccr_bit'. */
7437 i = ccr_bit (x, 1);
7438 if (i == -1)
7439 output_operand_lossage ("invalid %%J code");
7440 else
a0466a68
RK
7441 /* If we want bit 31, write a shift count of zero, not 32. */
7442 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7443 return;
7444
9854d9ed
RK
7445 case 'k':
7446 /* X must be a constant. Write the 1's complement of the
7447 constant. */
9878760c 7448 if (! INT_P (x))
9854d9ed 7449 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7450 else
7451 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7452 return;
7453
81eace42 7454 case 'K':
9ebbca7d
GK
7455 /* X must be a symbolic constant on ELF. Write an
7456 expression suitable for an 'addi' that adds in the low 16
7457 bits of the MEM. */
7458 if (GET_CODE (x) != CONST)
7459 {
7460 print_operand_address (file, x);
7461 fputs ("@l", file);
7462 }
7463 else
7464 {
7465 if (GET_CODE (XEXP (x, 0)) != PLUS
7466 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7467 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7468 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7469 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7470 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7471 fputs ("@l", file);
ed8d2920
MM
7472 /* For GNU as, there must be a non-alphanumeric character
7473 between 'l' and the number. The '-' is added by
7474 print_operand() already. */
7475 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7476 fputs ("+", file);
9ebbca7d
GK
7477 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7478 }
81eace42
GK
7479 return;
7480
7481 /* %l is output_asm_label. */
9ebbca7d 7482
9854d9ed
RK
7483 case 'L':
7484 /* Write second word of DImode or DFmode reference. Works on register
7485 or non-indexed memory only. */
7486 if (GET_CODE (x) == REG)
5ebfb2ba 7487 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7488 else if (GET_CODE (x) == MEM)
7489 {
7490 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7491 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7492 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7493 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7494 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7495 UNITS_PER_WORD));
9854d9ed 7496 else
d7624dc0
RK
7497 output_address (XEXP (adjust_address_nv (x, SImode,
7498 UNITS_PER_WORD),
7499 0));
ed8908e7 7500
ba5e43aa 7501 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7502 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7503 reg_names[SMALL_DATA_REG]);
9854d9ed 7504 }
9878760c 7505 return;
9854d9ed 7506
9878760c
RK
7507 case 'm':
7508 /* MB value for a mask operand. */
b1765bde 7509 if (! mask_operand (x, SImode))
9878760c
RK
7510 output_operand_lossage ("invalid %%m value");
7511
0ba1b2ff 7512 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7513 return;
7514
7515 case 'M':
7516 /* ME value for a mask operand. */
b1765bde 7517 if (! mask_operand (x, SImode))
a260abc9 7518 output_operand_lossage ("invalid %%M value");
9878760c 7519
0ba1b2ff 7520 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7521 return;
7522
81eace42
GK
7523 /* %n outputs the negative of its operand. */
7524
9878760c
RK
7525 case 'N':
7526 /* Write the number of elements in the vector times 4. */
7527 if (GET_CODE (x) != PARALLEL)
7528 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7529 else
7530 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7531 return;
7532
7533 case 'O':
7534 /* Similar, but subtract 1 first. */
7535 if (GET_CODE (x) != PARALLEL)
1427100a 7536 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7537 else
7538 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7539 return;
7540
9854d9ed
RK
7541 case 'p':
7542 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7543 if (! INT_P (x)
2bfcf297 7544 || INT_LOWPART (x) < 0
9854d9ed
RK
7545 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7546 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7547 else
7548 fprintf (file, "%d", i);
9854d9ed
RK
7549 return;
7550
9878760c
RK
7551 case 'P':
7552 /* The operand must be an indirect memory reference. The result
a4f6c312 7553 is the register number. */
9878760c
RK
7554 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7555 || REGNO (XEXP (x, 0)) >= 32)
7556 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7557 else
7558 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7559 return;
7560
dfbdccdb
GK
7561 case 'q':
7562 /* This outputs the logical code corresponding to a boolean
7563 expression. The expression may have one or both operands
39a10a29
GK
7564 negated (if one, only the first one). For condition register
7565 logical operations, it will also treat the negated
7566 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7567 {
63bc1d05 7568 const char *const *t = 0;
dfbdccdb
GK
7569 const char *s;
7570 enum rtx_code code = GET_CODE (x);
7571 static const char * const tbl[3][3] = {
7572 { "and", "andc", "nor" },
7573 { "or", "orc", "nand" },
7574 { "xor", "eqv", "xor" } };
7575
7576 if (code == AND)
7577 t = tbl[0];
7578 else if (code == IOR)
7579 t = tbl[1];
7580 else if (code == XOR)
7581 t = tbl[2];
7582 else
7583 output_operand_lossage ("invalid %%q value");
7584
7585 if (GET_CODE (XEXP (x, 0)) != NOT)
7586 s = t[0];
7587 else
7588 {
7589 if (GET_CODE (XEXP (x, 1)) == NOT)
7590 s = t[2];
7591 else
7592 s = t[1];
7593 }
7594
7595 fputs (s, file);
7596 }
7597 return;
7598
9854d9ed
RK
7599 case 'R':
7600 /* X is a CR register. Print the mask for `mtcrf'. */
7601 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7602 output_operand_lossage ("invalid %%R value");
7603 else
9ebbca7d 7604 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7605 return;
9854d9ed
RK
7606
7607 case 's':
7608 /* Low 5 bits of 32 - value */
7609 if (! INT_P (x))
7610 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7611 else
7612 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7613 return;
9854d9ed 7614
a260abc9 7615 case 'S':
0ba1b2ff 7616 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7617 CONST_INT 32-bit mask is considered sign-extended so any
7618 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7619 if (! mask64_operand (x, DImode))
a260abc9
DE
7620 output_operand_lossage ("invalid %%S value");
7621
0ba1b2ff 7622 uval = INT_LOWPART (x);
a260abc9 7623
0ba1b2ff 7624 if (uval & 1) /* Clear Left */
a260abc9 7625 {
0ba1b2ff
AM
7626 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7627 i = 64;
a260abc9 7628 }
0ba1b2ff 7629 else /* Clear Right */
a260abc9 7630 {
0ba1b2ff
AM
7631 uval = ~uval;
7632 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7633 i = 63;
a260abc9 7634 }
0ba1b2ff
AM
7635 while (uval != 0)
7636 --i, uval >>= 1;
7637 if (i < 0)
7638 abort ();
7639 fprintf (file, "%d", i);
7640 return;
a260abc9 7641
a3170dc6
AH
7642 case 't':
7643 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7644 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7645 abort ();
7646
7647 /* Bit 3 is OV bit. */
7648 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7649
7650 /* If we want bit 31, write a shift count of zero, not 32. */
7651 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7652 return;
7653
cccf3bdc
DE
7654 case 'T':
7655 /* Print the symbolic name of a branch target register. */
7656 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7657 && REGNO (x) != COUNT_REGISTER_REGNUM))
7658 output_operand_lossage ("invalid %%T value");
e2c953b6 7659 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
7660 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7661 else
7662 fputs ("ctr", file);
7663 return;
7664
9854d9ed 7665 case 'u':
802a0058 7666 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
7667 if (! INT_P (x))
7668 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
7669 else
7670 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7671 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
7672 return;
7673
802a0058
MM
7674 case 'v':
7675 /* High-order 16 bits of constant for use in signed operand. */
7676 if (! INT_P (x))
7677 output_operand_lossage ("invalid %%v value");
e2c953b6 7678 else
134c32f6
DE
7679 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7680 (INT_LOWPART (x) >> 16) & 0xffff);
7681 return;
802a0058 7682
9854d9ed
RK
7683 case 'U':
7684 /* Print `u' if this has an auto-increment or auto-decrement. */
7685 if (GET_CODE (x) == MEM
7686 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7687 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 7688 putc ('u', file);
9854d9ed 7689 return;
9878760c 7690
e0cd0770
JC
7691 case 'V':
7692 /* Print the trap code for this operand. */
7693 switch (GET_CODE (x))
7694 {
7695 case EQ:
7696 fputs ("eq", file); /* 4 */
7697 break;
7698 case NE:
7699 fputs ("ne", file); /* 24 */
7700 break;
7701 case LT:
7702 fputs ("lt", file); /* 16 */
7703 break;
7704 case LE:
7705 fputs ("le", file); /* 20 */
7706 break;
7707 case GT:
7708 fputs ("gt", file); /* 8 */
7709 break;
7710 case GE:
7711 fputs ("ge", file); /* 12 */
7712 break;
7713 case LTU:
7714 fputs ("llt", file); /* 2 */
7715 break;
7716 case LEU:
7717 fputs ("lle", file); /* 6 */
7718 break;
7719 case GTU:
7720 fputs ("lgt", file); /* 1 */
7721 break;
7722 case GEU:
7723 fputs ("lge", file); /* 5 */
7724 break;
7725 default:
7726 abort ();
7727 }
7728 break;
7729
9854d9ed
RK
7730 case 'w':
7731 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7732 normally. */
7733 if (INT_P (x))
5f59ecb7
DE
7734 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7735 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
7736 else
7737 print_operand (file, x, 0);
9878760c
RK
7738 return;
7739
9854d9ed 7740 case 'W':
e2c953b6 7741 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
7742 val = (GET_CODE (x) == CONST_INT
7743 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7744
7745 if (val < 0)
7746 i = -1;
9854d9ed 7747 else
e2c953b6
DE
7748 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7749 if ((val <<= 1) < 0)
7750 break;
7751
7752#if HOST_BITS_PER_WIDE_INT == 32
7753 if (GET_CODE (x) == CONST_INT && i >= 0)
7754 i += 32; /* zero-extend high-part was all 0's */
7755 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7756 {
7757 val = CONST_DOUBLE_LOW (x);
7758
7759 if (val == 0)
a4f6c312 7760 abort ();
e2c953b6
DE
7761 else if (val < 0)
7762 --i;
7763 else
7764 for ( ; i < 64; i++)
7765 if ((val <<= 1) < 0)
7766 break;
7767 }
7768#endif
7769
7770 fprintf (file, "%d", i + 1);
9854d9ed 7771 return;
9878760c 7772
9854d9ed
RK
7773 case 'X':
7774 if (GET_CODE (x) == MEM
258bfae2 7775 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 7776 putc ('x', file);
9854d9ed 7777 return;
9878760c 7778
9854d9ed
RK
7779 case 'Y':
7780 /* Like 'L', for third word of TImode */
7781 if (GET_CODE (x) == REG)
5ebfb2ba 7782 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 7783 else if (GET_CODE (x) == MEM)
9878760c 7784 {
9854d9ed
RK
7785 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7786 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7787 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 7788 else
d7624dc0 7789 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 7790 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7791 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7792 reg_names[SMALL_DATA_REG]);
9878760c
RK
7793 }
7794 return;
9854d9ed 7795
9878760c 7796 case 'z':
b4ac57ab
RS
7797 /* X is a SYMBOL_REF. Write out the name preceded by a
7798 period and without any trailing data in brackets. Used for function
4d30c363
MM
7799 names. If we are configured for System V (or the embedded ABI) on
7800 the PowerPC, do not emit the period, since those systems do not use
7801 TOCs and the like. */
9878760c
RK
7802 if (GET_CODE (x) != SYMBOL_REF)
7803 abort ();
7804
b6c9286a
MM
7805 if (XSTR (x, 0)[0] != '.')
7806 {
7807 switch (DEFAULT_ABI)
7808 {
7809 default:
7810 abort ();
7811
7812 case ABI_AIX:
7813 putc ('.', file);
7814 break;
7815
7816 case ABI_V4:
7817 case ABI_AIX_NODESC:
ee890fe2 7818 case ABI_DARWIN:
b6c9286a 7819 break;
b6c9286a
MM
7820 }
7821 }
54ee9799
DE
7822#if TARGET_AIX
7823 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
7824#else
9ebbca7d 7825 assemble_name (file, XSTR (x, 0));
54ee9799 7826#endif
9878760c
RK
7827 return;
7828
9854d9ed
RK
7829 case 'Z':
7830 /* Like 'L', for last word of TImode. */
7831 if (GET_CODE (x) == REG)
5ebfb2ba 7832 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
7833 else if (GET_CODE (x) == MEM)
7834 {
7835 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7836 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7837 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 7838 else
d7624dc0 7839 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 7840 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7841 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7842 reg_names[SMALL_DATA_REG]);
9854d9ed 7843 }
5c23c401 7844 return;
0ac081f6 7845
a3170dc6 7846 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
7847 case 'y':
7848 {
7849 rtx tmp;
7850
7851 if (GET_CODE (x) != MEM)
7852 abort ();
7853
7854 tmp = XEXP (x, 0);
7855
a3170dc6
AH
7856 if (TARGET_SPE)
7857 {
7858 /* Handle [reg]. */
7859 if (GET_CODE (tmp) == REG)
7860 {
7861 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
7862 break;
7863 }
7864 /* Handle [reg+UIMM]. */
7865 else if (GET_CODE (tmp) == PLUS &&
7866 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
7867 {
7868 int x;
7869
7870 if (GET_CODE (XEXP (tmp, 0)) != REG)
7871 abort ();
7872
7873 x = INTVAL (XEXP (tmp, 1));
7874 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
7875 break;
7876 }
7877
7878 /* Fall through. Must be [reg+reg]. */
7879 }
0ac081f6 7880 if (GET_CODE (tmp) == REG)
c62f2db5 7881 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
7882 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
7883 {
7884 if (REGNO (XEXP (tmp, 0)) == 0)
7885 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
7886 reg_names[ REGNO (XEXP (tmp, 0)) ]);
7887 else
7888 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
7889 reg_names[ REGNO (XEXP (tmp, 1)) ]);
7890 }
7891 else
7892 abort ();
7893 break;
7894 }
9854d9ed 7895
9878760c
RK
7896 case 0:
7897 if (GET_CODE (x) == REG)
7898 fprintf (file, "%s", reg_names[REGNO (x)]);
7899 else if (GET_CODE (x) == MEM)
7900 {
7901 /* We need to handle PRE_INC and PRE_DEC here, since we need to
7902 know the width from the mode. */
7903 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
7904 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
7905 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7906 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
7907 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
7908 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7909 else
a54d04b7 7910 output_address (XEXP (x, 0));
9878760c
RK
7911 }
7912 else
a54d04b7 7913 output_addr_const (file, x);
a85d226b 7914 return;
9878760c
RK
7915
7916 default:
7917 output_operand_lossage ("invalid %%xn code");
7918 }
7919}
7920\f
7921/* Print the address of an operand. */
7922
7923void
7924print_operand_address (file, x)
7925 FILE *file;
592696dd 7926 rtx x;
9878760c
RK
7927{
7928 if (GET_CODE (x) == REG)
4697a36c 7929 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
7930 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
7931 || GET_CODE (x) == LABEL_REF)
9878760c
RK
7932 {
7933 output_addr_const (file, x);
ba5e43aa 7934 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7935 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7936 reg_names[SMALL_DATA_REG]);
9ebbca7d 7937 else if (TARGET_TOC)
a4f6c312 7938 abort ();
9878760c
RK
7939 }
7940 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
7941 {
7942 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
7943 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
7944 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 7945 else
4697a36c
MM
7946 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
7947 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
7948 }
7949 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
7950 {
7951 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
7952 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7953 }
3cb999d8
DE
7954#if TARGET_ELF
7955 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
7956 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
7957 {
7958 output_addr_const (file, XEXP (x, 1));
7959 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7960 }
c859cda6
DJ
7961#endif
7962#if TARGET_MACHO
7963 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
7964 && CONSTANT_P (XEXP (x, 1)))
7965 {
7966 fprintf (file, "lo16(");
7967 output_addr_const (file, XEXP (x, 1));
7968 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7969 }
3cb999d8 7970#endif
9ebbca7d
GK
7971 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
7972 {
2bfcf297 7973 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 7974 {
2bfcf297
DB
7975 rtx contains_minus = XEXP (x, 1);
7976 rtx minus, symref;
7977 const char *name;
9ebbca7d
GK
7978
7979 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 7980 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
7981 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
7982 contains_minus = XEXP (contains_minus, 0);
7983
2bfcf297
DB
7984 minus = XEXP (contains_minus, 0);
7985 symref = XEXP (minus, 0);
7986 XEXP (contains_minus, 0) = symref;
7987 if (TARGET_ELF)
7988 {
7989 char *newname;
7990
7991 name = XSTR (symref, 0);
7992 newname = alloca (strlen (name) + sizeof ("@toc"));
7993 strcpy (newname, name);
7994 strcat (newname, "@toc");
7995 XSTR (symref, 0) = newname;
7996 }
7997 output_addr_const (file, XEXP (x, 1));
7998 if (TARGET_ELF)
7999 XSTR (symref, 0) = name;
9ebbca7d
GK
8000 XEXP (contains_minus, 0) = minus;
8001 }
8002 else
8003 output_addr_const (file, XEXP (x, 1));
8004
8005 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8006 }
9878760c
RK
8007 else
8008 abort ();
8009}
8010\f
88cad84b 8011/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
8012 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8013 is defined. It also needs to handle DI-mode objects on 64-bit
8014 targets. */
8015
8016static bool
8017rs6000_assemble_integer (x, size, aligned_p)
8018 rtx x;
8019 unsigned int size;
8020 int aligned_p;
8021{
8022#ifdef RELOCATABLE_NEEDS_FIXUP
8023 /* Special handling for SI values. */
8024 if (size == 4 && aligned_p)
8025 {
8026 extern int in_toc_section PARAMS ((void));
8027 static int recurse = 0;
8028
8029 /* For -mrelocatable, we mark all addresses that need to be fixed up
8030 in the .fixup section. */
8031 if (TARGET_RELOCATABLE
8032 && !in_toc_section ()
8033 && !in_text_section ()
8034 && !recurse
8035 && GET_CODE (x) != CONST_INT
8036 && GET_CODE (x) != CONST_DOUBLE
8037 && CONSTANT_P (x))
8038 {
8039 char buf[256];
8040
8041 recurse = 1;
8042 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8043 fixuplabelno++;
8044 ASM_OUTPUT_LABEL (asm_out_file, buf);
8045 fprintf (asm_out_file, "\t.long\t(");
8046 output_addr_const (asm_out_file, x);
8047 fprintf (asm_out_file, ")@fixup\n");
8048 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8049 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8050 fprintf (asm_out_file, "\t.long\t");
8051 assemble_name (asm_out_file, buf);
8052 fprintf (asm_out_file, "\n\t.previous\n");
8053 recurse = 0;
8054 return true;
8055 }
8056 /* Remove initial .'s to turn a -mcall-aixdesc function
8057 address into the address of the descriptor, not the function
8058 itself. */
8059 else if (GET_CODE (x) == SYMBOL_REF
8060 && XSTR (x, 0)[0] == '.'
8061 && DEFAULT_ABI == ABI_AIX)
8062 {
8063 const char *name = XSTR (x, 0);
8064 while (*name == '.')
8065 name++;
8066
8067 fprintf (asm_out_file, "\t.long\t%s\n", name);
8068 return true;
8069 }
8070 }
8071#endif /* RELOCATABLE_NEEDS_FIXUP */
8072 return default_assemble_integer (x, size, aligned_p);
8073}
93638d7a
AM
8074
8075#ifdef HAVE_GAS_HIDDEN
8076/* Emit an assembler directive to set symbol visibility for DECL to
8077 VISIBILITY_TYPE. */
8078
5add3202 8079static void
93638d7a
AM
8080rs6000_assemble_visibility (decl, visibility_type)
8081 tree decl;
8082 const char *visibility_type;
8083{
bd79540a 8084 default_assemble_visibility (decl, visibility_type);
93638d7a
AM
8085
8086 /* Functions need to have their entry point symbol visibility set as
8087 well as their descriptor symbol visibility. */
8088 if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
8089 {
8090 const char *name;
8091
8092 name = ((* targetm.strip_name_encoding)
8093 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
8094
8095 fprintf (asm_out_file, "\t.%s\t.%s\n", visibility_type, name);
8096 }
8097}
8098#endif
301d03af 8099\f
39a10a29
GK
8100enum rtx_code
8101rs6000_reverse_condition (mode, code)
8102 enum machine_mode mode;
8103 enum rtx_code code;
8104{
8105 /* Reversal of FP compares takes care -- an ordered compare
8106 becomes an unordered compare and vice versa. */
8107 if (mode == CCFPmode)
bab6226b 8108 return reverse_condition_maybe_unordered (code);
39a10a29 8109 else
bab6226b 8110 return reverse_condition (code);
39a10a29
GK
8111}
8112
39a10a29
GK
8113/* Generate a compare for CODE. Return a brand-new rtx that
8114 represents the result of the compare. */
a4f6c312 8115
39a10a29
GK
8116static rtx
8117rs6000_generate_compare (code)
8118 enum rtx_code code;
8119{
8120 enum machine_mode comp_mode;
8121 rtx compare_result;
8122
8123 if (rs6000_compare_fp_p)
8124 comp_mode = CCFPmode;
8125 else if (code == GTU || code == LTU
8126 || code == GEU || code == LEU)
8127 comp_mode = CCUNSmode;
8128 else
8129 comp_mode = CCmode;
8130
8131 /* First, the compare. */
8132 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
8133
8134 /* SPE FP compare instructions on the GPRs. Yuck! */
8135 if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
8136 {
8137 rtx cmp, or1, or2, or_result, compare_result2;
8138
8139 switch (code)
8140 {
8141 case EQ:
8142 case UNEQ:
8143 case NE:
8144 case LTGT:
8145 cmp = flag_unsafe_math_optimizations
8146 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8147 rs6000_compare_op1)
8148 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8149 rs6000_compare_op1);
8150 break;
8151 case GT:
8152 case GTU:
8153 case UNGT:
8154 case UNGE:
8155 case GE:
8156 case GEU:
8157 cmp = flag_unsafe_math_optimizations
8158 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8159 rs6000_compare_op1)
8160 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8161 rs6000_compare_op1);
8162 break;
8163 case LT:
8164 case LTU:
8165 case UNLT:
8166 case UNLE:
8167 case LE:
8168 case LEU:
8169 cmp = flag_unsafe_math_optimizations
8170 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8171 rs6000_compare_op1)
8172 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8173 rs6000_compare_op1);
8174 break;
8175 default:
8176 abort ();
8177 }
8178
8179 /* Synthesize LE and GE from LT/GT || EQ. */
8180 if (code == LE || code == GE || code == LEU || code == GEU)
8181 {
8182 /* Synthesize GE/LE frome GT/LT || EQ. */
8183
8184 emit_insn (cmp);
8185
8186 switch (code)
8187 {
8188 case LE: code = LT; break;
8189 case GE: code = GT; break;
8190 case LEU: code = LT; break;
8191 case GEU: code = GT; break;
8192 default: abort ();
8193 }
8194
8195 or1 = gen_reg_rtx (SImode);
8196 or2 = gen_reg_rtx (SImode);
8197 or_result = gen_reg_rtx (CCEQmode);
8198 compare_result2 = gen_reg_rtx (CCFPmode);
8199
8200 /* Do the EQ. */
8201 cmp = flag_unsafe_math_optimizations
8202 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8203 rs6000_compare_op1)
8204 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8205 rs6000_compare_op1);
8206 emit_insn (cmp);
8207
8208 /* The MC8540 FP compare instructions set the CR bits
8209 differently than other PPC compare instructions. For
8210 that matter, there is no generic test instruction, but a
8211 testgt, testlt, and testeq. For a true condition, bit 2
8212 is set (x1xx) in the CR. Following the traditional CR
8213 values:
8214
8215 LT GT EQ OV
8216 bit3 bit2 bit1 bit0
8217
8218 ... bit 2 would be a GT CR alias, so later on we
8219 look in the GT bits for the branch instructins.
8220 However, we must be careful to emit correct RTL in
8221 the meantime, so optimizations don't get confused. */
8222
8223 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8224 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8225
8226 /* OR them together. */
8227 cmp = gen_rtx_SET (VOIDmode, or_result,
8228 gen_rtx_COMPARE (CCEQmode,
8229 gen_rtx_IOR (SImode, or1, or2),
8230 const_true_rtx));
8231 compare_result = or_result;
8232 code = EQ;
8233 }
8234 else
8235 {
8236 /* We only care about 1 bit (x1xx), so map everything to NE to
8237 maintain rtl sanity. We'll get to the right bit (x1xx) at
8238 code output time. */
8239 if (code == NE || code == LTGT)
8240 /* Do the inverse here because we have no cmpne
8241 instruction. We use the cmpeq instruction and expect
8242 to get a 0 instead. */
8243 code = EQ;
8244 else
8245 code = NE;
8246 }
8247
8248 emit_insn (cmp);
8249 }
8250 else
8251 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8252 gen_rtx_COMPARE (comp_mode,
8253 rs6000_compare_op0,
8254 rs6000_compare_op1)));
39a10a29 8255
ca5adc63 8256 /* Some kinds of FP comparisons need an OR operation;
de6c5979 8257 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 8258 if (rs6000_compare_fp_p
de6c5979 8259 && ! flag_unsafe_math_optimizations
a3170dc6 8260 && ! (TARGET_HARD_FLOAT && TARGET_SPE)
39a10a29
GK
8261 && (code == LE || code == GE
8262 || code == UNEQ || code == LTGT
8263 || code == UNGT || code == UNLT))
8264 {
8265 enum rtx_code or1, or2;
8266 rtx or1_rtx, or2_rtx, compare2_rtx;
8267 rtx or_result = gen_reg_rtx (CCEQmode);
8268
8269 switch (code)
8270 {
8271 case LE: or1 = LT; or2 = EQ; break;
8272 case GE: or1 = GT; or2 = EQ; break;
8273 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8274 case LTGT: or1 = LT; or2 = GT; break;
8275 case UNGT: or1 = UNORDERED; or2 = GT; break;
8276 case UNLT: or1 = UNORDERED; or2 = LT; break;
8277 default: abort ();
8278 }
8279 validate_condition_mode (or1, comp_mode);
8280 validate_condition_mode (or2, comp_mode);
8281 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8282 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8283 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8284 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8285 const_true_rtx);
8286 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8287
8288 compare_result = or_result;
8289 code = EQ;
8290 }
8291
8292 validate_condition_mode (code, GET_MODE (compare_result));
8293
8294 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8295}
8296
8297
8298/* Emit the RTL for an sCOND pattern. */
8299
8300void
8301rs6000_emit_sCOND (code, result)
8302 enum rtx_code code;
8303 rtx result;
8304{
8305 rtx condition_rtx;
8306 enum machine_mode op_mode;
8307
8308 condition_rtx = rs6000_generate_compare (code);
8309
8310 op_mode = GET_MODE (rs6000_compare_op0);
8311 if (op_mode == VOIDmode)
8312 op_mode = GET_MODE (rs6000_compare_op1);
8313
8314 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8315 {
8316 PUT_MODE (condition_rtx, DImode);
8317 convert_move (result, condition_rtx, 0);
8318 }
8319 else
8320 {
8321 PUT_MODE (condition_rtx, SImode);
8322 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8323 }
8324}
8325
39a10a29
GK
8326/* Emit a branch of kind CODE to location LOC. */
8327
8328void
8329rs6000_emit_cbranch (code, loc)
8330 enum rtx_code code;
8331 rtx loc;
8332{
8333 rtx condition_rtx, loc_ref;
8334
8335 condition_rtx = rs6000_generate_compare (code);
8336 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8337 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8338 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8339 loc_ref, pc_rtx)));
8340}
8341
12a4e8c5
GK
8342/* Return the string to output a conditional branch to LABEL, which is
8343 the operand number of the label, or -1 if the branch is really a
8344 conditional return.
8345
8346 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8347 condition code register and its mode specifies what kind of
8348 comparison we made.
8349
8350 REVERSED is non-zero if we should reverse the sense of the comparison.
8351
8352 INSN is the insn. */
8353
8354char *
8355output_cbranch (op, label, reversed, insn)
8356 rtx op;
8357 const char * label;
8358 int reversed;
8359 rtx insn;
8360{
8361 static char string[64];
8362 enum rtx_code code = GET_CODE (op);
8363 rtx cc_reg = XEXP (op, 0);
8364 enum machine_mode mode = GET_MODE (cc_reg);
8365 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 8366 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
8367 int really_reversed = reversed ^ need_longbranch;
8368 char *s = string;
8369 const char *ccode;
8370 const char *pred;
8371 rtx note;
8372
39a10a29
GK
8373 validate_condition_mode (code, mode);
8374
8375 /* Work out which way this really branches. We could use
8376 reverse_condition_maybe_unordered here always but this
8377 makes the resulting assembler clearer. */
12a4e8c5 8378 if (really_reversed)
39a10a29 8379 code = rs6000_reverse_condition (mode, code);
12a4e8c5 8380
a3170dc6
AH
8381 if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
8382 {
8383 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8384 to the GT bit. */
8385 if (code == EQ)
8386 /* Opposite of GT. */
8387 code = UNLE;
8388 else if (code == NE)
8389 code = GT;
8390 else
8391 abort ();
8392 }
8393
39a10a29 8394 switch (code)
12a4e8c5
GK
8395 {
8396 /* Not all of these are actually distinct opcodes, but
8397 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
8398 case NE: case LTGT:
8399 ccode = "ne"; break;
8400 case EQ: case UNEQ:
8401 ccode = "eq"; break;
8402 case GE: case GEU:
8403 ccode = "ge"; break;
8404 case GT: case GTU: case UNGT:
8405 ccode = "gt"; break;
8406 case LE: case LEU:
8407 ccode = "le"; break;
8408 case LT: case LTU: case UNLT:
8409 ccode = "lt"; break;
12a4e8c5
GK
8410 case UNORDERED: ccode = "un"; break;
8411 case ORDERED: ccode = "nu"; break;
8412 case UNGE: ccode = "nl"; break;
8413 case UNLE: ccode = "ng"; break;
8414 default:
a4f6c312 8415 abort ();
12a4e8c5
GK
8416 }
8417
94a54f47
GK
8418 /* Maybe we have a guess as to how likely the branch is.
8419 The old mnemonics don't have a way to specify this information. */
f4857b9b 8420 pred = "";
12a4e8c5
GK
8421 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8422 if (note != NULL_RTX)
8423 {
8424 /* PROB is the difference from 50%. */
8425 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
8426 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8427
8428 /* Only hint for highly probable/improbable branches on newer
8429 cpus as static prediction overrides processor dynamic
8430 prediction. For older cpus we may as well always hint, but
8431 assume not taken for branches that are very close to 50% as a
8432 mispredicted taken branch is more expensive than a
8433 mispredicted not-taken branch. */
8434 if (always_hint
8435 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8436 {
8437 if (abs (prob) > REG_BR_PROB_BASE / 20
8438 && ((prob > 0) ^ need_longbranch))
8439 pred = "+";
8440 else
8441 pred = "-";
8442 }
12a4e8c5 8443 }
12a4e8c5
GK
8444
8445 if (label == NULL)
94a54f47 8446 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 8447 else
94a54f47 8448 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 8449
37c67319
GK
8450 /* We need to escape any '%' characters in the reg_names string.
8451 Assume they'd only be the first character... */
8452 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8453 *s++ = '%';
94a54f47 8454 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
8455
8456 if (label != NULL)
8457 {
8458 /* If the branch distance was too far, we may have to use an
8459 unconditional branch to go the distance. */
8460 if (need_longbranch)
44518ddd 8461 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
8462 else
8463 s += sprintf (s, ",%s", label);
8464 }
8465
8466 return string;
8467}
50a0b056
GK
8468
8469/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8470 operands of the last comparison is nonzero/true, FALSE_COND if it
8471 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 8472
50a0b056
GK
8473int
8474rs6000_emit_cmove (dest, op, true_cond, false_cond)
8475 rtx dest;
8476 rtx op;
8477 rtx true_cond;
8478 rtx false_cond;
8479{
8480 enum rtx_code code = GET_CODE (op);
8481 rtx op0 = rs6000_compare_op0;
8482 rtx op1 = rs6000_compare_op1;
8483 REAL_VALUE_TYPE c1;
3148ad6d
DJ
8484 enum machine_mode compare_mode = GET_MODE (op0);
8485 enum machine_mode result_mode = GET_MODE (dest);
50a0b056
GK
8486 rtx temp;
8487
3148ad6d 8488 /* These modes should always match. */
a3170dc6
AH
8489 if (GET_MODE (op1) != compare_mode
8490 /* In the isel case however, we can use a compare immediate, so
8491 op1 may be a small constant. */
8492 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 8493 return 0;
178c3eff 8494 if (GET_MODE (true_cond) != result_mode)
3148ad6d 8495 return 0;
178c3eff 8496 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
8497 return 0;
8498
50a0b056
GK
8499 /* First, work out if the hardware can do this at all, or
8500 if it's too slow... */
50a0b056 8501 if (! rs6000_compare_fp_p)
a3170dc6
AH
8502 {
8503 if (TARGET_ISEL)
8504 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8505 return 0;
8506 }
50a0b056
GK
8507
8508 /* Eliminate half of the comparisons by switching operands, this
8509 makes the remaining code simpler. */
8510 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8511 || code == LTGT || code == LT)
8512 {
8513 code = reverse_condition_maybe_unordered (code);
8514 temp = true_cond;
8515 true_cond = false_cond;
8516 false_cond = temp;
8517 }
8518
8519 /* UNEQ and LTGT take four instructions for a comparison with zero,
8520 it'll probably be faster to use a branch here too. */
8521 if (code == UNEQ)
8522 return 0;
8523
8524 if (GET_CODE (op1) == CONST_DOUBLE)
8525 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8526
8527 /* We're going to try to implement comparions by performing
8528 a subtract, then comparing against zero. Unfortunately,
8529 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 8530 know that the operand is finite and the comparison
50a0b056
GK
8531 would treat EQ different to UNORDERED, we can't do it. */
8532 if (! flag_unsafe_math_optimizations
8533 && code != GT && code != UNGE
045572c7 8534 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
8535 /* Constructs of the form (a OP b ? a : b) are safe. */
8536 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8537 || (! rtx_equal_p (op0, true_cond)
8538 && ! rtx_equal_p (op1, true_cond))))
8539 return 0;
8540 /* At this point we know we can use fsel. */
8541
8542 /* Reduce the comparison to a comparison against zero. */
3148ad6d 8543 temp = gen_reg_rtx (compare_mode);
50a0b056 8544 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8545 gen_rtx_MINUS (compare_mode, op0, op1)));
50a0b056 8546 op0 = temp;
3148ad6d 8547 op1 = CONST0_RTX (compare_mode);
50a0b056
GK
8548
8549 /* If we don't care about NaNs we can reduce some of the comparisons
8550 down to faster ones. */
8551 if (flag_unsafe_math_optimizations)
8552 switch (code)
8553 {
8554 case GT:
8555 code = LE;
8556 temp = true_cond;
8557 true_cond = false_cond;
8558 false_cond = temp;
8559 break;
8560 case UNGE:
8561 code = GE;
8562 break;
8563 case UNEQ:
8564 code = EQ;
8565 break;
8566 default:
8567 break;
8568 }
8569
8570 /* Now, reduce everything down to a GE. */
8571 switch (code)
8572 {
8573 case GE:
8574 break;
8575
8576 case LE:
3148ad6d
DJ
8577 temp = gen_reg_rtx (compare_mode);
8578 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8579 op0 = temp;
8580 break;
8581
8582 case ORDERED:
3148ad6d
DJ
8583 temp = gen_reg_rtx (compare_mode);
8584 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
8585 op0 = temp;
8586 break;
8587
8588 case EQ:
3148ad6d 8589 temp = gen_reg_rtx (compare_mode);
50a0b056 8590 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
8591 gen_rtx_NEG (compare_mode,
8592 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
8593 op0 = temp;
8594 break;
8595
8596 case UNGE:
3148ad6d 8597 temp = gen_reg_rtx (result_mode);
50a0b056 8598 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8599 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8600 gen_rtx_GE (VOIDmode,
8601 op0, op1),
8602 true_cond, false_cond)));
8603 false_cond = temp;
8604 true_cond = false_cond;
8605
3148ad6d
DJ
8606 temp = gen_reg_rtx (compare_mode);
8607 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8608 op0 = temp;
8609 break;
8610
8611 case GT:
3148ad6d 8612 temp = gen_reg_rtx (result_mode);
50a0b056 8613 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8614 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8615 gen_rtx_GE (VOIDmode,
8616 op0, op1),
8617 true_cond, false_cond)));
8618 true_cond = temp;
8619 false_cond = true_cond;
8620
3148ad6d
DJ
8621 temp = gen_reg_rtx (compare_mode);
8622 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8623 op0 = temp;
8624 break;
8625
8626 default:
8627 abort ();
8628 }
8629
8630 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 8631 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8632 gen_rtx_GE (VOIDmode,
8633 op0, op1),
8634 true_cond, false_cond)));
8635 return 1;
8636}
8637
a3170dc6
AH
8638/* Same as above, but for ints (isel). */
8639
8640static int
8641rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
8642 rtx dest;
8643 rtx op;
8644 rtx true_cond;
8645 rtx false_cond;
8646{
8647 rtx condition_rtx, cr;
8648
8649 /* All isel implementations thus far are 32-bits. */
8650 if (GET_MODE (rs6000_compare_op0) != SImode)
8651 return 0;
8652
8653 /* We still have to do the compare, because isel doesn't do a
8654 compare, it just looks at the CRx bits set by a previous compare
8655 instruction. */
8656 condition_rtx = rs6000_generate_compare (GET_CODE (op));
8657 cr = XEXP (condition_rtx, 0);
8658
8659 if (GET_MODE (cr) == CCmode)
8660 emit_insn (gen_isel_signed (dest, condition_rtx,
8661 true_cond, false_cond, cr));
8662 else
8663 emit_insn (gen_isel_unsigned (dest, condition_rtx,
8664 true_cond, false_cond, cr));
8665
8666 return 1;
8667}
8668
8669const char *
8670output_isel (operands)
8671 rtx *operands;
8672{
8673 enum rtx_code code;
8674
8675 code = GET_CODE (operands[1]);
8676 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
8677 {
8678 PUT_CODE (operands[1], reverse_condition (code));
8679 return "isel %0,%3,%2,%j1";
8680 }
8681 else
8682 return "isel %0,%2,%3,%j1";
8683}
8684
50a0b056
GK
8685void
8686rs6000_emit_minmax (dest, code, op0, op1)
8687 rtx dest;
8688 enum rtx_code code;
8689 rtx op0;
8690 rtx op1;
8691{
8692 enum machine_mode mode = GET_MODE (op0);
5dc8d536 8693 enum rtx_code c;
50a0b056 8694 rtx target;
5dc8d536
AH
8695
8696 if (code == SMAX || code == SMIN)
8697 c = GE;
8698 else
8699 c = GEU;
8700
50a0b056 8701 if (code == SMAX || code == UMAX)
5dc8d536 8702 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8703 op0, op1, mode, 0);
8704 else
5dc8d536 8705 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8706 op1, op0, mode, 0);
8707 if (target == NULL_RTX)
8708 abort ();
8709 if (target != dest)
8710 emit_move_insn (dest, target);
8711}
12a4e8c5 8712\f
a4f6c312
SS
8713/* This page contains routines that are used to determine what the
8714 function prologue and epilogue code will do and write them out. */
9878760c 8715
a4f6c312
SS
8716/* Return the first fixed-point register that is required to be
8717 saved. 32 if none. */
9878760c
RK
8718
8719int
8720first_reg_to_save ()
8721{
8722 int first_reg;
8723
8724 /* Find lowest numbered live register. */
8725 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
8726 if (regs_ever_live[first_reg]
8727 && (! call_used_regs[first_reg]
1db02437 8728 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
8729 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
8730 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
8731 break;
8732
ee890fe2 8733#if TARGET_MACHO
93638d7a
AM
8734 if (flag_pic
8735 && current_function_uses_pic_offset_table
8736 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 8737 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
8738#endif
8739
9878760c
RK
8740 return first_reg;
8741}
8742
8743/* Similar, for FP regs. */
8744
8745int
8746first_fp_reg_to_save ()
8747{
8748 int first_reg;
8749
8750 /* Find lowest numbered live register. */
8751 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8752 if (regs_ever_live[first_reg])
8753 break;
8754
8755 return first_reg;
8756}
00b960c7
AH
8757
8758/* Similar, for AltiVec regs. */
8759
8760static int
8761first_altivec_reg_to_save ()
8762{
8763 int i;
8764
8765 /* Stack frame remains as is unless we are in AltiVec ABI. */
8766 if (! TARGET_ALTIVEC_ABI)
8767 return LAST_ALTIVEC_REGNO + 1;
8768
8769 /* Find lowest numbered live register. */
8770 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8771 if (regs_ever_live[i])
8772 break;
8773
8774 return i;
8775}
8776
8777/* Return a 32-bit mask of the AltiVec registers we need to set in
8778 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
8779 the 32-bit word is 0. */
8780
8781static unsigned int
8782compute_vrsave_mask ()
8783{
8784 unsigned int i, mask = 0;
8785
8786 /* First, find out if we use _any_ altivec registers. */
8787 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8788 if (regs_ever_live[i])
8789 mask |= ALTIVEC_REG_BIT (i);
8790
8791 if (mask == 0)
8792 return mask;
8793
8794 /* Next, add all registers that are call-clobbered. We do this
8795 because post-reload register optimizers such as regrename_optimize
8796 may choose to use them. They never change the register class
8797 chosen by reload, so cannot create new uses of altivec registers
8798 if there were none before, so the early exit above is safe. */
8799 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
8800 altivec registers not saved in the mask, which might well make the
8801 adjustments below more effective in eliding the save/restore of
8802 VRSAVE in small functions. */
8803 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8804 if (call_used_regs[i])
8805 mask |= ALTIVEC_REG_BIT (i);
8806
8807 /* Next, remove the argument registers from the set. These must
8808 be in the VRSAVE mask set by the caller, so we don't need to add
8809 them in again. More importantly, the mask we compute here is
8810 used to generate CLOBBERs in the set_vrsave insn, and we do not
8811 wish the argument registers to die. */
8812 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
8813 mask &= ~ALTIVEC_REG_BIT (i);
8814
8815 /* Similarly, remove the return value from the set. */
8816 {
8817 bool yes = false;
8818 diddle_return_value (is_altivec_return_reg, &yes);
8819 if (yes)
8820 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
8821 }
8822
8823 return mask;
8824}
8825
8826static void
8827is_altivec_return_reg (reg, xyes)
8828 rtx reg;
8829 void *xyes;
8830{
8831 bool *yes = (bool *) xyes;
8832 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
8833 *yes = true;
8834}
8835
4697a36c
MM
8836\f
8837/* Calculate the stack information for the current function. This is
8838 complicated by having two separate calling sequences, the AIX calling
8839 sequence and the V.4 calling sequence.
8840
592696dd 8841 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 8842 32-bit 64-bit
4697a36c 8843 SP----> +---------------------------------------+
a260abc9 8844 | back chain to caller | 0 0
4697a36c 8845 +---------------------------------------+
a260abc9 8846 | saved CR | 4 8 (8-11)
4697a36c 8847 +---------------------------------------+
a260abc9 8848 | saved LR | 8 16
4697a36c 8849 +---------------------------------------+
a260abc9 8850 | reserved for compilers | 12 24
4697a36c 8851 +---------------------------------------+
a260abc9 8852 | reserved for binders | 16 32
4697a36c 8853 +---------------------------------------+
a260abc9 8854 | saved TOC pointer | 20 40
4697a36c 8855 +---------------------------------------+
a260abc9 8856 | Parameter save area (P) | 24 48
4697a36c 8857 +---------------------------------------+
a260abc9 8858 | Alloca space (A) | 24+P etc.
802a0058 8859 +---------------------------------------+
a7df97e6 8860 | Local variable space (L) | 24+P+A
4697a36c 8861 +---------------------------------------+
a7df97e6 8862 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 8863 +---------------------------------------+
00b960c7
AH
8864 | Save area for AltiVec registers (W) | 24+P+A+L+X
8865 +---------------------------------------+
8866 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
8867 +---------------------------------------+
8868 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 8869 +---------------------------------------+
00b960c7
AH
8870 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
8871 +---------------------------------------+
8872 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
8873 +---------------------------------------+
8874 old SP->| back chain to caller's caller |
8875 +---------------------------------------+
8876
5376a30c
KR
8877 The required alignment for AIX configurations is two words (i.e., 8
8878 or 16 bytes).
8879
8880
4697a36c
MM
8881 V.4 stack frames look like:
8882
8883 SP----> +---------------------------------------+
8884 | back chain to caller | 0
8885 +---------------------------------------+
5eb387b8 8886 | caller's saved LR | 4
4697a36c
MM
8887 +---------------------------------------+
8888 | Parameter save area (P) | 8
8889 +---------------------------------------+
a7df97e6
MM
8890 | Alloca space (A) | 8+P
8891 +---------------------------------------+
8892 | Varargs save area (V) | 8+P+A
8893 +---------------------------------------+
8894 | Local variable space (L) | 8+P+A+V
8895 +---------------------------------------+
8896 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 8897 +---------------------------------------+
00b960c7
AH
8898 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
8899 +---------------------------------------+
8900 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
8901 +---------------------------------------+
8902 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
8903 +---------------------------------------+
a3170dc6
AH
8904 | SPE: area for 64-bit GP registers |
8905 +---------------------------------------+
8906 | SPE alignment padding |
8907 +---------------------------------------+
00b960c7 8908 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 8909 +---------------------------------------+
00b960c7 8910 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 8911 +---------------------------------------+
00b960c7 8912 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
8913 +---------------------------------------+
8914 old SP->| back chain to caller's caller |
8915 +---------------------------------------+
b6c9286a 8916
5376a30c
KR
8917 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
8918 given. (But note below and in sysv4.h that we require only 8 and
8919 may round up the size of our stack frame anyways. The historical
8920 reason is early versions of powerpc-linux which didn't properly
8921 align the stack at program startup. A happy side-effect is that
8922 -mno-eabi libraries can be used with -meabi programs.)
8923
5376a30c
KR
8924 The EABI configuration defaults to the V.4 layout, unless
8925 -mcall-aix is used, in which case the AIX layout is used. However,
8926 the stack alignment requirements may differ. If -mno-eabi is not
8927 given, the required stack alignment is 8 bytes; if -mno-eabi is
8928 given, the required alignment is 16 bytes. (But see V.4 comment
8929 above.) */
4697a36c 8930
61b2fbe7
MM
8931#ifndef ABI_STACK_BOUNDARY
8932#define ABI_STACK_BOUNDARY STACK_BOUNDARY
8933#endif
8934
4697a36c
MM
8935rs6000_stack_t *
8936rs6000_stack_info ()
8937{
8938 static rs6000_stack_t info, zero_info;
8939 rs6000_stack_t *info_ptr = &info;
9ebbca7d 8940 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 8941 enum rs6000_abi abi;
83720594 8942 int ehrd_size;
b6c9286a 8943 int total_raw_size;
4697a36c 8944
a4f6c312 8945 /* Zero all fields portably. */
4697a36c
MM
8946 info = zero_info;
8947
a4f6c312 8948 /* Select which calling sequence. */
b6c9286a 8949 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 8950
a4f6c312 8951 /* Calculate which registers need to be saved & save area size. */
4697a36c 8952 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 8953 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 8954 even if it currently looks like we won't. */
2bfcf297 8955 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
8956 || (flag_pic == 1 && abi == ABI_V4)
8957 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
8958 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
8959 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
8960 else
8961 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 8962
a3170dc6
AH
8963 /* For the SPE, we have an additional upper 32-bits on each GPR.
8964 Ideally we should save the entire 64-bits only when the upper
8965 half is used in SIMD instructions. Since we only record
8966 registers live (not the size they are used in), this proves
8967 difficult because we'd have to traverse the instruction chain at
8968 the right time, taking reload into account. This is a real pain,
8969 so we opt to save the GPRs in 64-bits always. Anyone overly
8970 concerned with frame size can fix this. ;-).
8971
8972 So... since we save all GPRs (except the SP) in 64-bits, the
8973 traditional GP save area will be empty. */
8974 if (TARGET_SPE_ABI)
8975 info_ptr->gp_size = 0;
8976
4697a36c
MM
8977 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
8978 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
8979
00b960c7
AH
8980 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
8981 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
8982 - info_ptr->first_altivec_reg_save);
8983
592696dd 8984 /* Does this function call anything? */
71f123ca
FS
8985 info_ptr->calls_p = (! current_function_is_leaf
8986 || cfun->machine->ra_needs_full_frame);
b6c9286a 8987
a4f6c312 8988 /* Determine if we need to save the link register. */
71f123ca 8989 if (rs6000_ra_ever_killed ()
70f4f91c 8990 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
8991#ifdef TARGET_RELOCATABLE
8992 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
8993#endif
8994 || (info_ptr->first_fp_reg_save != 64
8995 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 8996 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 8997 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
8998 || (DEFAULT_ABI == ABI_DARWIN
8999 && flag_pic
9000 && current_function_uses_pic_offset_table)
4697a36c
MM
9001 || info_ptr->calls_p)
9002 {
9003 info_ptr->lr_save_p = 1;
9ebbca7d 9004 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9005 }
9006
9ebbca7d
GK
9007 /* Determine if we need to save the condition code registers. */
9008 if (regs_ever_live[CR2_REGNO]
9009 || regs_ever_live[CR3_REGNO]
9010 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9011 {
9012 info_ptr->cr_save_p = 1;
f607bc57 9013 if (abi == ABI_V4)
4697a36c
MM
9014 info_ptr->cr_size = reg_size;
9015 }
9016
83720594
RH
9017 /* If the current function calls __builtin_eh_return, then we need
9018 to allocate stack space for registers that will hold data for
9019 the exception handler. */
9020 if (current_function_calls_eh_return)
9021 {
9022 unsigned int i;
9023 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9024 continue;
a3170dc6
AH
9025
9026 /* SPE saves EH registers in 64-bits. */
9027 ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9028 }
9029 else
9030 ehrd_size = 0;
9031
592696dd 9032 /* Determine various sizes. */
4697a36c
MM
9033 info_ptr->reg_size = reg_size;
9034 info_ptr->fixed_size = RS6000_SAVE_AREA;
9035 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9036 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9037 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9038 8);
00b960c7 9039
a3170dc6
AH
9040 if (TARGET_SPE_ABI)
9041 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9042 else
9043 info_ptr->spe_gp_size = 0;
9044
08b57fb3 9045 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9046 {
9047 info_ptr->vrsave_mask = compute_vrsave_mask ();
9048 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9049 }
9050 else
9051 {
9052 info_ptr->vrsave_mask = 0;
9053 info_ptr->vrsave_size = 0;
9054 }
b6c9286a 9055
592696dd 9056 /* Calculate the offsets. */
24d304eb 9057 switch (abi)
4697a36c 9058 {
b6c9286a 9059 case ABI_NONE:
24d304eb 9060 default:
b6c9286a
MM
9061 abort ();
9062
9063 case ABI_AIX:
9064 case ABI_AIX_NODESC:
ee890fe2 9065 case ABI_DARWIN:
b6c9286a
MM
9066 info_ptr->fp_save_offset = - info_ptr->fp_size;
9067 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9068
9069 if (TARGET_ALTIVEC_ABI)
9070 {
9071 info_ptr->vrsave_save_offset
9072 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9073
9074 /* Align stack so vector save area is on a quadword boundary. */
9075 if (info_ptr->altivec_size != 0)
9076 info_ptr->altivec_padding_size
9077 = 16 - (-info_ptr->vrsave_save_offset % 16);
9078 else
9079 info_ptr->altivec_padding_size = 0;
9080
9081 info_ptr->altivec_save_offset
9082 = info_ptr->vrsave_save_offset
9083 - info_ptr->altivec_padding_size
9084 - info_ptr->altivec_size;
9085
9086 /* Adjust for AltiVec case. */
9087 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9088 }
9089 else
9090 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9091 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9092 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9093 break;
9094
9095 case ABI_V4:
b6c9286a
MM
9096 info_ptr->fp_save_offset = - info_ptr->fp_size;
9097 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9098 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9099
a3170dc6
AH
9100 if (TARGET_SPE_ABI)
9101 {
9102 /* Align stack so SPE GPR save area is aligned on a
9103 double-word boundary. */
9104 if (info_ptr->spe_gp_size != 0)
9105 info_ptr->spe_padding_size
9106 = 8 - (-info_ptr->cr_save_offset % 8);
9107 else
9108 info_ptr->spe_padding_size = 0;
9109
9110 info_ptr->spe_gp_save_offset
9111 = info_ptr->cr_save_offset
9112 - info_ptr->spe_padding_size
9113 - info_ptr->spe_gp_size;
9114
9115 /* Adjust for SPE case. */
9116 info_ptr->toc_save_offset
9117 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9118 }
9119 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9120 {
9121 info_ptr->vrsave_save_offset
9122 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9123
9124 /* Align stack so vector save area is on a quadword boundary. */
9125 if (info_ptr->altivec_size != 0)
9126 info_ptr->altivec_padding_size
9127 = 16 - (-info_ptr->vrsave_save_offset % 16);
9128 else
9129 info_ptr->altivec_padding_size = 0;
9130
9131 info_ptr->altivec_save_offset
9132 = info_ptr->vrsave_save_offset
9133 - info_ptr->altivec_padding_size
9134 - info_ptr->altivec_size;
9135
9136 /* Adjust for AltiVec case. */
9137 info_ptr->toc_save_offset
9138 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9139 }
9140 else
9141 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9142 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9143 info_ptr->lr_save_offset = reg_size;
9144 break;
4697a36c
MM
9145 }
9146
00b960c7
AH
9147 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9148 + info_ptr->gp_size
9149 + info_ptr->altivec_size
9150 + info_ptr->altivec_padding_size
9151 + info_ptr->vrsave_size
a3170dc6
AH
9152 + info_ptr->spe_gp_size
9153 + info_ptr->spe_padding_size
00b960c7
AH
9154 + ehrd_size
9155 + info_ptr->cr_size
9156 + info_ptr->lr_size
9157 + info_ptr->vrsave_size
9158 + info_ptr->toc_size,
9159 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9160 ? 16 : 8);
9161
ff381587
MM
9162 total_raw_size = (info_ptr->vars_size
9163 + info_ptr->parm_size
ff381587
MM
9164 + info_ptr->save_size
9165 + info_ptr->varargs_size
9166 + info_ptr->fixed_size);
9167
a4f6c312
SS
9168 info_ptr->total_size =
9169 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9170
9171 /* Determine if we need to allocate any stack frame:
9172
a4f6c312
SS
9173 For AIX we need to push the stack if a frame pointer is needed
9174 (because the stack might be dynamically adjusted), if we are
9175 debugging, if we make calls, or if the sum of fp_save, gp_save,
9176 and local variables are more than the space needed to save all
9177 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9178 + 18*8 = 288 (GPR13 reserved).
ff381587 9179
a4f6c312
SS
9180 For V.4 we don't have the stack cushion that AIX uses, but assume
9181 that the debugger can handle stackless frames. */
ff381587
MM
9182
9183 if (info_ptr->calls_p)
9184 info_ptr->push_p = 1;
9185
f607bc57 9186 else if (abi == ABI_V4)
e72247f4 9187 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
9188
9189 else
9190 info_ptr->push_p = (frame_pointer_needed
ee890fe2 9191 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 9192 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 9193 > (TARGET_32BIT ? 220 : 288)));
ff381587 9194
a4f6c312 9195 /* Zero offsets if we're not saving those registers. */
8dda1a21 9196 if (info_ptr->fp_size == 0)
4697a36c
MM
9197 info_ptr->fp_save_offset = 0;
9198
8dda1a21 9199 if (info_ptr->gp_size == 0)
4697a36c
MM
9200 info_ptr->gp_save_offset = 0;
9201
00b960c7
AH
9202 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9203 info_ptr->altivec_save_offset = 0;
9204
9205 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9206 info_ptr->vrsave_save_offset = 0;
9207
a3170dc6
AH
9208 if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
9209 info_ptr->spe_gp_save_offset = 0;
9210
c81fc13e 9211 if (! info_ptr->lr_save_p)
4697a36c
MM
9212 info_ptr->lr_save_offset = 0;
9213
c81fc13e 9214 if (! info_ptr->cr_save_p)
4697a36c
MM
9215 info_ptr->cr_save_offset = 0;
9216
c81fc13e 9217 if (! info_ptr->toc_save_p)
b6c9286a
MM
9218 info_ptr->toc_save_offset = 0;
9219
4697a36c
MM
9220 return info_ptr;
9221}
9222
9223void
9224debug_stack_info (info)
9225 rs6000_stack_t *info;
9878760c 9226{
d330fd93 9227 const char *abi_string;
24d304eb 9228
c81fc13e 9229 if (! info)
4697a36c
MM
9230 info = rs6000_stack_info ();
9231
9232 fprintf (stderr, "\nStack information for function %s:\n",
9233 ((current_function_decl && DECL_NAME (current_function_decl))
9234 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9235 : "<unknown>"));
9236
24d304eb
RK
9237 switch (info->abi)
9238 {
b6c9286a
MM
9239 default: abi_string = "Unknown"; break;
9240 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9241 case ABI_AIX:
b6c9286a 9242 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9243 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9244 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9245 }
9246
9247 fprintf (stderr, "\tABI = %5s\n", abi_string);
9248
00b960c7
AH
9249 if (TARGET_ALTIVEC_ABI)
9250 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9251
a3170dc6
AH
9252 if (TARGET_SPE_ABI)
9253 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9254
4697a36c
MM
9255 if (info->first_gp_reg_save != 32)
9256 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9257
9258 if (info->first_fp_reg_save != 64)
9259 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9260
00b960c7
AH
9261 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9262 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9263 info->first_altivec_reg_save);
9264
4697a36c
MM
9265 if (info->lr_save_p)
9266 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9267
4697a36c
MM
9268 if (info->cr_save_p)
9269 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9270
b6c9286a
MM
9271 if (info->toc_save_p)
9272 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9273
00b960c7
AH
9274 if (info->vrsave_mask)
9275 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9276
4697a36c
MM
9277 if (info->push_p)
9278 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9279
9280 if (info->calls_p)
9281 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9282
4697a36c
MM
9283 if (info->gp_save_offset)
9284 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9285
9286 if (info->fp_save_offset)
9287 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9288
00b960c7
AH
9289 if (info->altivec_save_offset)
9290 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9291 info->altivec_save_offset);
9292
a3170dc6
AH
9293 if (info->spe_gp_save_offset)
9294 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9295 info->spe_gp_save_offset);
9296
00b960c7
AH
9297 if (info->vrsave_save_offset)
9298 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9299 info->vrsave_save_offset);
9300
4697a36c
MM
9301 if (info->lr_save_offset)
9302 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9303
9304 if (info->cr_save_offset)
9305 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9306
b6c9286a
MM
9307 if (info->toc_save_offset)
9308 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9309
4697a36c
MM
9310 if (info->varargs_save_offset)
9311 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9312
9313 if (info->total_size)
9314 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9315
9316 if (info->varargs_size)
9317 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9318
9319 if (info->vars_size)
9320 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9321
9322 if (info->parm_size)
9323 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9324
9325 if (info->fixed_size)
9326 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9327
9328 if (info->gp_size)
9329 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9330
a3170dc6
AH
9331 if (info->spe_gp_size)
9332 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9333
4697a36c
MM
9334 if (info->fp_size)
9335 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9336
00b960c7
AH
9337 if (info->altivec_size)
9338 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9339
9340 if (info->vrsave_size)
9341 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9342
9343 if (info->altivec_padding_size)
9344 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9345 info->altivec_padding_size);
9346
a3170dc6
AH
9347 if (info->spe_padding_size)
9348 fprintf (stderr, "\tspe_padding_size = %5d\n",
9349 info->spe_padding_size);
9350
a4f6c312 9351 if (info->lr_size)
ed947a96 9352 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9353
4697a36c
MM
9354 if (info->cr_size)
9355 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9356
a4f6c312 9357 if (info->toc_size)
b6c9286a
MM
9358 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9359
4697a36c
MM
9360 if (info->save_size)
9361 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9362
9363 if (info->reg_size != 4)
9364 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9365
9366 fprintf (stderr, "\n");
9878760c 9367}
71f123ca
FS
9368
9369rtx
9370rs6000_return_addr (count, frame)
9371 int count;
9372 rtx frame;
9373{
a4f6c312
SS
9374 /* Currently we don't optimize very well between prolog and body
9375 code and for PIC code the code can be actually quite bad, so
9376 don't try to be too clever here. */
f585a356 9377 if (count != 0 || flag_pic != 0)
71f123ca
FS
9378 {
9379 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9380
9381 return
9382 gen_rtx_MEM
9383 (Pmode,
9384 memory_address
9385 (Pmode,
9386 plus_constant (copy_to_reg
9387 (gen_rtx_MEM (Pmode,
9388 memory_address (Pmode, frame))),
9389 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9390 }
9391
9e2f7ec7 9392 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9393}
9394
5e1bf043
DJ
9395/* Say whether a function is a candidate for sibcall handling or not.
9396 We do not allow indirect calls to be optimized into sibling calls.
9397 Also, we can't do it if there are any vector parameters; there's
9398 nowhere to put the VRsave code so it works; note that functions with
9399 vector parameters are required to have a prototype, so the argument
9400 type info must be available here. (The tail recursion case can work
9401 with vector parameters, but there's no way to distinguish here.) */
9402int
9403function_ok_for_sibcall (fndecl)
9404 tree fndecl;
9405{
9406 tree type;
9407 if (fndecl)
9408 {
9409 if (TARGET_ALTIVEC_VRSAVE)
9410 {
9411 for (type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
9412 type; type = TREE_CHAIN (type))
9413 {
c15b529f 9414 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
5e1bf043
DJ
9415 return 0;
9416 }
9417 }
9418 if (DEFAULT_ABI == ABI_DARWIN
2bcc50d0
AM
9419 || (*targetm.binds_local_p) (fndecl))
9420 {
9421 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
9422
9423 if (!lookup_attribute ("longcall", attr_list)
9424 || lookup_attribute ("shortcall", attr_list))
9425 return 1;
9426 }
5e1bf043
DJ
9427 }
9428 return 0;
9429}
9430
9431/* function rewritten to handle sibcalls */
71f123ca
FS
9432static int
9433rs6000_ra_ever_killed ()
9434{
9435 rtx top;
5e1bf043
DJ
9436 rtx reg;
9437 rtx insn;
71f123ca
FS
9438
9439#ifdef ASM_OUTPUT_MI_THUNK
9440 if (current_function_is_thunk)
9441 return 0;
9442#endif
5e1bf043
DJ
9443 /* regs_ever_live has LR marked as used if any sibcalls
9444 are present. Which it is, but this should not force
9445 saving and restoring in the prologue/epilog. Likewise,
9446 reg_set_between_p thinks a sibcall clobbers LR, so
9447 that is inappropriate. */
9448 /* Also, the prologue can generate a store into LR that
9449 doesn't really count, like this:
9450 move LR->R0
9451 bcl to set PIC register
9452 move LR->R31
9453 move R0->LR
9454 When we're called from the epilog, we need to avoid counting
9455 this as a store; thus we ignore any insns with a REG_MAYBE_DEAD note. */
9456
71f123ca
FS
9457 push_topmost_sequence ();
9458 top = get_insns ();
9459 pop_topmost_sequence ();
5e1bf043 9460 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9461
5e1bf043
DJ
9462 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9463 {
9464 if (INSN_P (insn))
9465 {
9466 if (FIND_REG_INC_NOTE (insn, reg))
9467 return 1;
9468 else if (GET_CODE (insn) == CALL_INSN
c15b529f 9469 && !SIBLING_CALL_P (insn))
5e1bf043
DJ
9470 return 1;
9471 else if (set_of (reg, insn) != NULL_RTX
c15b529f 9472 && find_reg_note (insn, REG_MAYBE_DEAD, NULL_RTX) == 0)
5e1bf043
DJ
9473 return 1;
9474 }
9475 }
9476 return 0;
71f123ca 9477}
4697a36c 9478\f
8cd8f856
GK
9479/* Add a REG_MAYBE_DEAD note to the insn. */
9480static void
9481rs6000_maybe_dead (insn)
9482 rtx insn;
9483{
9484 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9485 const0_rtx,
9486 REG_NOTES (insn));
9487}
9488
9ebbca7d 9489/* Emit instructions needed to load the TOC register.
c7ca610e 9490 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9491 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9492
9493void
9ebbca7d
GK
9494rs6000_emit_load_toc_table (fromprolog)
9495 int fromprolog;
c7ca610e 9496{
9ebbca7d 9497 rtx dest;
1db02437 9498 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9499
20b71b17
AM
9500 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9501 {
9502 rtx temp = (fromprolog
9503 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9504 : gen_reg_rtx (Pmode));
9505 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
9506 rs6000_maybe_dead (emit_move_insn (dest, temp));
9507 }
9508 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
9509 {
9510 char buf[30];
9511 rtx tempLR = (fromprolog
9512 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9513 : gen_reg_rtx (Pmode));
9514 rtx temp0 = (fromprolog
9515 ? gen_rtx_REG (Pmode, 0)
9516 : gen_reg_rtx (Pmode));
9517 rtx symF;
9518
9519 /* possibly create the toc section */
9520 if (! toc_initialized)
38c1f2d7 9521 {
20b71b17
AM
9522 toc_section ();
9523 function_section (current_function_decl);
38c1f2d7 9524 }
9ebbca7d 9525
20b71b17
AM
9526 if (fromprolog)
9527 {
9528 rtx symL;
38c1f2d7 9529
20b71b17
AM
9530 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
9531 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9532
20b71b17
AM
9533 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
9534 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9535
9536 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9537 symF)));
9538 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9539 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9540 symL,
9541 symF)));
9ebbca7d
GK
9542 }
9543 else
20b71b17
AM
9544 {
9545 rtx tocsym;
9546 static int reload_toc_labelno = 0;
9547
9548 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
9549
9550 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
9551 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9552
9553 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9554 symF,
9555 tocsym)));
9556 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9557 rs6000_maybe_dead (emit_move_insn (temp0,
9558 gen_rtx_MEM (Pmode, dest)));
9559 }
9560 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d 9561 }
20b71b17
AM
9562 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
9563 {
9564 /* This is for AIX code running in non-PIC ELF32. */
9565 char buf[30];
9566 rtx realsym;
9567 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9568 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9569
9570 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9571 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9572 }
9573 else if (DEFAULT_ABI == ABI_AIX)
9ebbca7d
GK
9574 {
9575 if (TARGET_32BIT)
20b71b17 9576 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 9577 else
20b71b17 9578 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d 9579 }
20b71b17
AM
9580 else
9581 abort ();
9ebbca7d
GK
9582}
9583
9584int
9585get_TOC_alias_set ()
9586{
9587 static int set = -1;
9588 if (set == -1)
9589 set = new_alias_set ();
9590 return set;
9591}
9592
9593/* This retuns nonzero if the current function uses the TOC. This is
9594 determined by the presence of (unspec ... 7), which is generated by
9595 the various load_toc_* patterns. */
a4f6c312 9596
9ebbca7d
GK
9597int
9598uses_TOC ()
9599{
9600 rtx insn;
38c1f2d7 9601
9ebbca7d 9602 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 9603 if (INSN_P (insn))
9ebbca7d
GK
9604 {
9605 rtx pat = PATTERN (insn);
9606 int i;
9607
8cd8f856 9608 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
9609 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9610 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9611 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9612 return 1;
38c1f2d7 9613 }
9ebbca7d
GK
9614 return 0;
9615}
38c1f2d7 9616
9ebbca7d 9617rtx
a4f6c312 9618create_TOC_reference (symbol)
9ebbca7d
GK
9619 rtx symbol;
9620{
a8a05998
ZW
9621 return gen_rtx_PLUS (Pmode,
9622 gen_rtx_REG (Pmode, TOC_REGISTER),
9623 gen_rtx_CONST (Pmode,
9624 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 9625 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 9626}
38c1f2d7 9627
9ebbca7d
GK
9628#if TARGET_AIX
9629/* __throw will restore its own return address to be the same as the
9630 return address of the function that the throw is being made to.
9631 This is unfortunate, because we want to check the original
9632 return address to see if we need to restore the TOC.
9633 So we have to squirrel it away here.
9634 This is used only in compiling __throw and __rethrow.
c7ca610e 9635
9ebbca7d
GK
9636 Most of this code should be removed by CSE. */
9637static rtx insn_after_throw;
c7ca610e 9638
a4f6c312 9639/* This does the saving... */
9ebbca7d
GK
9640void
9641rs6000_aix_emit_builtin_unwind_init ()
9642{
9643 rtx mem;
9644 rtx stack_top = gen_reg_rtx (Pmode);
9645 rtx opcode_addr = gen_reg_rtx (Pmode);
9646
9647 insn_after_throw = gen_reg_rtx (SImode);
9648
9649 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9650 emit_move_insn (stack_top, mem);
9651
9652 mem = gen_rtx_MEM (Pmode,
9653 gen_rtx_PLUS (Pmode, stack_top,
9654 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9655 emit_move_insn (opcode_addr, mem);
9656 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
9657}
9658
a4f6c312
SS
9659/* Emit insns to _restore_ the TOC register, at runtime (specifically
9660 in _eh.o). Only used on AIX.
9ebbca7d
GK
9661
9662 The idea is that on AIX, function calls look like this:
9663 bl somefunction-trampoline
9664 lwz r2,20(sp)
9665
a4f6c312 9666 and later,
9ebbca7d
GK
9667 somefunction-trampoline:
9668 stw r2,20(sp)
9669 ... load function address in the count register ...
9670 bctr
9671 or like this, if the linker determines that this is not a cross-module call
9672 and so the TOC need not be restored:
9673 bl somefunction
9674 nop
9675 or like this, if the compiler could determine that this is not a
9676 cross-module call:
9677 bl somefunction
9678 now, the tricky bit here is that register 2 is saved and restored
9679 by the _linker_, so we can't readily generate debugging information
9680 for it. So we need to go back up the call chain looking at the
9681 insns at return addresses to see which calls saved the TOC register
9682 and so see where it gets restored from.
9683
9684 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9685 just before the actual epilogue.
9686
9687 On the bright side, this incurs no space or time overhead unless an
9688 exception is thrown, except for the extra code in libgcc.a.
9689
9690 The parameter STACKSIZE is a register containing (at runtime)
9691 the amount to be popped off the stack in addition to the stack frame
9692 of this routine (which will be __throw or __rethrow, and so is
9693 guaranteed to have a stack frame). */
a4f6c312 9694
9ebbca7d
GK
9695void
9696rs6000_emit_eh_toc_restore (stacksize)
9697 rtx stacksize;
9698{
9699 rtx top_of_stack;
9700 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9701 rtx tocompare = gen_reg_rtx (SImode);
9702 rtx opcode = gen_reg_rtx (SImode);
9703 rtx opcode_addr = gen_reg_rtx (Pmode);
9704 rtx mem;
9705 rtx loop_start = gen_label_rtx ();
9706 rtx no_toc_restore_needed = gen_label_rtx ();
9707 rtx loop_exit = gen_label_rtx ();
9708
9709 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 9710 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9711 emit_move_insn (bottom_of_stack, mem);
9712
9713 top_of_stack = expand_binop (Pmode, add_optab,
9714 bottom_of_stack, stacksize,
9715 NULL_RTX, 1, OPTAB_WIDEN);
9716
2496c7bd
LB
9717 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9718 : 0xE8410028, SImode));
9ebbca7d
GK
9719
9720 if (insn_after_throw == NULL_RTX)
a4f6c312 9721 abort ();
9ebbca7d
GK
9722 emit_move_insn (opcode, insn_after_throw);
9723
6496a589 9724 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
9725 emit_label (loop_start);
9726
9727 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 9728 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9729 no_toc_restore_needed);
9730
9731 mem = gen_rtx_MEM (Pmode,
9732 gen_rtx_PLUS (Pmode, bottom_of_stack,
9733 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
9734 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
9735
9736 emit_label (no_toc_restore_needed);
9737 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 9738 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9739 loop_exit);
9740
9741 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 9742 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9743 emit_move_insn (bottom_of_stack, mem);
9744
9745 mem = gen_rtx_MEM (Pmode,
9746 gen_rtx_PLUS (Pmode, bottom_of_stack,
9747 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9748 emit_move_insn (opcode_addr, mem);
9749 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
9750
6496a589 9751 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 9752 emit_jump (loop_start);
6496a589 9753 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
9754 emit_label (loop_exit);
9755}
9756#endif /* TARGET_AIX */
38c1f2d7 9757\f
ba4828e0
RK
9758/* This ties together stack memory (MEM with an alias set of
9759 rs6000_sr_alias_set) and the change to the stack pointer. */
9760
9ebbca7d
GK
9761static void
9762rs6000_emit_stack_tie ()
9763{
ba4828e0
RK
9764 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
9765
9766 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9767 emit_insn (gen_stack_tie (mem));
9768}
38c1f2d7 9769
9ebbca7d
GK
9770/* Emit the correct code for allocating stack space, as insns.
9771 If COPY_R12, make sure a copy of the old frame is left in r12.
9772 The generated code may use hard register 0 as a temporary. */
9773
9774static void
9775rs6000_emit_allocate_stack (size, copy_r12)
9776 HOST_WIDE_INT size;
38c1f2d7
MM
9777 int copy_r12;
9778{
9ebbca7d
GK
9779 rtx insn;
9780 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9781 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
9782 rtx todec = GEN_INT (-size);
a157febd
GK
9783
9784 if (current_function_limit_stack)
9785 {
9786 if (REG_P (stack_limit_rtx)
9787 && REGNO (stack_limit_rtx) > 1
9788 && REGNO (stack_limit_rtx) <= 31)
9789 {
9ebbca7d
GK
9790 emit_insn (Pmode == SImode
9791 ? gen_addsi3 (tmp_reg,
9792 stack_limit_rtx,
9793 GEN_INT (size))
9794 : gen_adddi3 (tmp_reg,
9795 stack_limit_rtx,
9796 GEN_INT (size)));
9797
9798 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9799 const0_rtx));
a157febd
GK
9800 }
9801 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 9802 && TARGET_32BIT
f607bc57 9803 && DEFAULT_ABI == ABI_V4)
a157febd 9804 {
9ebbca7d
GK
9805 rtx toload = gen_rtx_CONST (VOIDmode,
9806 gen_rtx_PLUS (Pmode,
9807 stack_limit_rtx,
9808 GEN_INT (size)));
9809
9810 emit_insn (gen_elf_high (tmp_reg, toload));
9811 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
9812 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9813 const0_rtx));
a157febd
GK
9814 }
9815 else
9816 warning ("stack limit expression is not supported");
9817 }
9818
9ebbca7d
GK
9819 if (copy_r12 || ! TARGET_UPDATE)
9820 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
9821
38c1f2d7
MM
9822 if (TARGET_UPDATE)
9823 {
9ebbca7d 9824 if (size > 32767)
38c1f2d7 9825 {
9ebbca7d
GK
9826 /* Need a note here so that try_split doesn't get confused. */
9827 if (get_last_insn() == NULL_RTX)
9828 emit_note (0, NOTE_INSN_DELETED);
9829 insn = emit_move_insn (tmp_reg, todec);
9830 try_split (PATTERN (insn), insn, 0);
9831 todec = tmp_reg;
38c1f2d7 9832 }
9ebbca7d
GK
9833
9834 if (Pmode == SImode)
9835 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
9836 todec, stack_reg));
9837 else
9838 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
9839 todec, stack_reg));
38c1f2d7
MM
9840 }
9841 else
9842 {
9ebbca7d
GK
9843 if (Pmode == SImode)
9844 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
38c1f2d7 9845 else
9ebbca7d
GK
9846 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
9847 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
9848 gen_rtx_REG (Pmode, 12));
9849 }
9850
9851 RTX_FRAME_RELATED_P (insn) = 1;
9852 REG_NOTES (insn) =
9853 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9854 gen_rtx_SET (VOIDmode, stack_reg,
9855 gen_rtx_PLUS (Pmode, stack_reg,
9856 GEN_INT (-size))),
9857 REG_NOTES (insn));
9858}
9859
9aa86737
AH
9860/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
9861 knows that:
9862
9863 (mem (plus (blah) (regXX)))
9864
9865 is really:
9866
9867 (mem (plus (blah) (const VALUE_OF_REGXX))). */
9868
9869static void
9870altivec_frame_fixup (insn, reg, val)
9871 rtx insn, reg;
9872 HOST_WIDE_INT val;
9873{
9874 rtx real;
9875
9876 real = copy_rtx (PATTERN (insn));
9877
9878 real = replace_rtx (real, reg, GEN_INT (val));
9879
9880 RTX_FRAME_RELATED_P (insn) = 1;
9881 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9882 real,
9883 REG_NOTES (insn));
9884}
9885
a4f6c312
SS
9886/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
9887 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
9888 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
9889 deduce these equivalences by itself so it wasn't necessary to hold
9890 its hand so much. */
9ebbca7d
GK
9891
9892static void
9893rs6000_frame_related (insn, reg, val, reg2, rreg)
9894 rtx insn;
9895 rtx reg;
9896 HOST_WIDE_INT val;
9897 rtx reg2;
9898 rtx rreg;
9899{
9900 rtx real, temp;
9901
e56c4463
JL
9902 /* copy_rtx will not make unique copies of registers, so we need to
9903 ensure we don't have unwanted sharing here. */
9904 if (reg == reg2)
9905 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9906
9907 if (reg == rreg)
9908 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9909
9ebbca7d
GK
9910 real = copy_rtx (PATTERN (insn));
9911
89e7058f
AH
9912 if (reg2 != NULL_RTX)
9913 real = replace_rtx (real, reg2, rreg);
9914
9ebbca7d
GK
9915 real = replace_rtx (real, reg,
9916 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
9917 STACK_POINTER_REGNUM),
9918 GEN_INT (val)));
9919
9920 /* We expect that 'real' is either a SET or a PARALLEL containing
9921 SETs (and possibly other stuff). In a PARALLEL, all the SETs
9922 are important so they all have to be marked RTX_FRAME_RELATED_P. */
9923
9924 if (GET_CODE (real) == SET)
9925 {
9926 rtx set = real;
9927
9928 temp = simplify_rtx (SET_SRC (set));
9929 if (temp)
9930 SET_SRC (set) = temp;
9931 temp = simplify_rtx (SET_DEST (set));
9932 if (temp)
9933 SET_DEST (set) = temp;
9934 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 9935 {
9ebbca7d
GK
9936 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9937 if (temp)
9938 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 9939 }
38c1f2d7 9940 }
9ebbca7d
GK
9941 else if (GET_CODE (real) == PARALLEL)
9942 {
9943 int i;
9944 for (i = 0; i < XVECLEN (real, 0); i++)
9945 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
9946 {
9947 rtx set = XVECEXP (real, 0, i);
9948
9949 temp = simplify_rtx (SET_SRC (set));
9950 if (temp)
9951 SET_SRC (set) = temp;
9952 temp = simplify_rtx (SET_DEST (set));
9953 if (temp)
9954 SET_DEST (set) = temp;
9955 if (GET_CODE (SET_DEST (set)) == MEM)
9956 {
9957 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9958 if (temp)
9959 XEXP (SET_DEST (set), 0) = temp;
9960 }
9961 RTX_FRAME_RELATED_P (set) = 1;
9962 }
9963 }
9964 else
a4f6c312 9965 abort ();
9ebbca7d 9966
9ebbca7d
GK
9967 RTX_FRAME_RELATED_P (insn) = 1;
9968 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9969 real,
9970 REG_NOTES (insn));
38c1f2d7
MM
9971}
9972
00b960c7
AH
9973/* Returns an insn that has a vrsave set operation with the
9974 appropriate CLOBBERs. */
9975
9976static rtx
9aa86737 9977generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
9978 rtx reg;
9979 rs6000_stack_t *info;
9aa86737 9980 int epiloguep;
00b960c7
AH
9981{
9982 int nclobs, i;
9983 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 9984 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 9985
a004eb82
AH
9986 clobs[0]
9987 = gen_rtx_SET (VOIDmode,
9988 vrsave,
9989 gen_rtx_UNSPEC_VOLATILE (SImode,
9990 gen_rtvec (2, reg, vrsave),
9991 30));
00b960c7
AH
9992
9993 nclobs = 1;
9994
9aa86737
AH
9995 /* We need to clobber the registers in the mask so the scheduler
9996 does not move sets to VRSAVE before sets of AltiVec registers.
9997
9998 However, if the function receives nonlocal gotos, reload will set
9999 all call saved registers live. We will end up with:
10000
10001 (set (reg 999) (mem))
10002 (parallel [ (set (reg vrsave) (unspec blah))
10003 (clobber (reg 999))])
10004
10005 The clobber will cause the store into reg 999 to be dead, and
10006 flow will attempt to delete an epilogue insn. In this case, we
10007 need an unspec use/set of the register. */
00b960c7
AH
10008
10009 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10010 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10011 {
10012 if (!epiloguep || call_used_regs [i])
10013 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10014 gen_rtx_REG (V4SImode, i));
10015 else
10016 {
10017 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10018
10019 clobs[nclobs++]
a004eb82
AH
10020 = gen_rtx_SET (VOIDmode,
10021 reg,
10022 gen_rtx_UNSPEC (V4SImode,
10023 gen_rtvec (1, reg), 27));
9aa86737
AH
10024 }
10025 }
00b960c7
AH
10026
10027 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10028
10029 for (i = 0; i < nclobs; ++i)
10030 XVECEXP (insn, 0, i) = clobs[i];
10031
10032 return insn;
10033}
10034
89e7058f
AH
10035/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10036 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10037
10038static void
10039emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10040 rtx frame_reg;
10041 rtx frame_ptr;
10042 enum machine_mode mode;
10043 unsigned int regno;
10044 int offset;
10045 int total_size;
10046{
10047 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10048 rtx replacea, replaceb;
10049
10050 int_rtx = GEN_INT (offset);
10051
10052 /* Some cases that need register indexed addressing. */
10053 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10054 || (TARGET_SPE_ABI
10055 && SPE_VECTOR_MODE (mode)
10056 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10057 {
10058 /* Whomever calls us must make sure r11 is available in the
10059 flow path of instructions in the prologue. */
10060 offset_rtx = gen_rtx_REG (Pmode, 11);
10061 emit_move_insn (offset_rtx, int_rtx);
10062
10063 replacea = offset_rtx;
10064 replaceb = int_rtx;
10065 }
10066 else
10067 {
10068 offset_rtx = int_rtx;
10069 replacea = NULL_RTX;
10070 replaceb = NULL_RTX;
10071 }
10072
10073 reg = gen_rtx_REG (mode, regno);
10074 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10075 mem = gen_rtx_MEM (mode, addr);
10076 set_mem_alias_set (mem, rs6000_sr_alias_set);
10077
10078 insn = emit_move_insn (mem, reg);
10079
10080 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10081}
10082
a3170dc6
AH
10083/* Emit an offset memory reference suitable for a frame store, while
10084 converting to a valid addressing mode. */
10085
10086static rtx
10087gen_frame_mem_offset (mode, reg, offset)
10088 enum machine_mode mode;
10089 rtx reg;
10090 int offset;
10091{
10092 rtx int_rtx, offset_rtx;
10093
10094 int_rtx = GEN_INT (offset);
10095
10096 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10097 {
10098 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10099 emit_move_insn (offset_rtx, int_rtx);
10100 }
10101 else
10102 offset_rtx = int_rtx;
10103
10104 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10105}
10106
9ebbca7d
GK
10107/* Emit function prologue as insns. */
10108
9878760c 10109void
83720594 10110rs6000_emit_prologue ()
9878760c 10111{
4697a36c 10112 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10113 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10114 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10115 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10116 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10117 rtx frame_reg_rtx = sp_reg_rtx;
10118 rtx cr_save_rtx = NULL;
10119 rtx insn;
10120 int saving_FPRs_inline;
10121 int using_store_multiple;
10122 HOST_WIDE_INT sp_offset = 0;
10123
a3170dc6
AH
10124 if (TARGET_SPE_ABI)
10125 {
10126 reg_mode = V2SImode;
10127 reg_size = 8;
10128 }
10129
9ebbca7d 10130 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10131 && !TARGET_SPE_ABI
9ebbca7d
GK
10132 && info->first_gp_reg_save < 31);
10133 saving_FPRs_inline = (info->first_fp_reg_save == 64
10134 || FP_SAVE_INLINE (info->first_fp_reg_save));
10135
10136 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10137 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10138 {
10139 if (info->total_size < 32767)
10140 sp_offset = info->total_size;
10141 else
10142 frame_reg_rtx = frame_ptr_rtx;
10143 rs6000_emit_allocate_stack (info->total_size,
10144 (frame_reg_rtx != sp_reg_rtx
10145 && (info->cr_save_p
10146 || info->lr_save_p
10147 || info->first_fp_reg_save < 64
10148 || info->first_gp_reg_save < 32
10149 )));
10150 if (frame_reg_rtx != sp_reg_rtx)
10151 rs6000_emit_stack_tie ();
10152 }
10153
9aa86737
AH
10154 /* Save AltiVec registers if needed. */
10155 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10156 {
10157 int i;
10158
10159 /* There should be a non inline version of this, for when we
10160 are saving lots of vector registers. */
10161 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10162 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10163 {
10164 rtx areg, savereg, mem;
10165 int offset;
10166
10167 offset = info->altivec_save_offset + sp_offset
10168 + 16 * (i - info->first_altivec_reg_save);
10169
10170 savereg = gen_rtx_REG (V4SImode, i);
10171
10172 areg = gen_rtx_REG (Pmode, 0);
10173 emit_move_insn (areg, GEN_INT (offset));
10174
10175 /* AltiVec addressing mode is [reg+reg]. */
10176 mem = gen_rtx_MEM (V4SImode,
10177 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10178
10179 set_mem_alias_set (mem, rs6000_sr_alias_set);
10180
10181 insn = emit_move_insn (mem, savereg);
10182
10183 altivec_frame_fixup (insn, areg, offset);
10184 }
10185 }
10186
10187 /* VRSAVE is a bit vector representing which AltiVec registers
10188 are used. The OS uses this to determine which vector
10189 registers to save on a context switch. We need to save
10190 VRSAVE on the stack frame, add whatever AltiVec registers we
10191 used in this function, and do the corresponding magic in the
10192 epilogue. */
10193
10194 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10195 {
a004eb82 10196 rtx reg, mem, vrsave;
9aa86737
AH
10197 int offset;
10198
10199 /* Get VRSAVE onto a GPR. */
10200 reg = gen_rtx_REG (SImode, 12);
a004eb82 10201 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10202 if (TARGET_MACHO)
10203 emit_insn (gen_get_vrsave_internal (reg));
10204 else
10205 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10206
10207 /* Save VRSAVE. */
10208 offset = info->vrsave_save_offset + sp_offset;
10209 mem
10210 = gen_rtx_MEM (SImode,
10211 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10212 set_mem_alias_set (mem, rs6000_sr_alias_set);
10213 insn = emit_move_insn (mem, reg);
10214
10215 /* Include the registers in the mask. */
10216 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10217
10218 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10219 }
10220
9ebbca7d
GK
10221 /* If we use the link register, get it into r0. */
10222 if (info->lr_save_p)
71f123ca 10223 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10224 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10225
10226 /* If we need to save CR, put it into r12. */
10227 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10228 {
10229 cr_save_rtx = gen_rtx_REG (SImode, 12);
10230 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10231 }
10232
a4f6c312
SS
10233 /* Do any required saving of fpr's. If only one or two to save, do
10234 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10235 if (saving_FPRs_inline)
10236 {
10237 int i;
10238 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10239 if ((regs_ever_live[info->first_fp_reg_save+i]
10240 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10241 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10242 info->first_fp_reg_save + i,
10243 info->fp_save_offset + sp_offset + 8 * i,
10244 info->total_size);
9ebbca7d
GK
10245 }
10246 else if (info->first_fp_reg_save != 64)
10247 {
10248 int i;
10249 char rname[30];
520a57c8 10250 const char *alloc_rname;
9ebbca7d
GK
10251 rtvec p;
10252 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10253
10254 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10255 gen_rtx_REG (Pmode,
10256 LINK_REGISTER_REGNUM));
10257 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10258 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10259 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10260 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10261 gen_rtx_SYMBOL_REF (Pmode,
10262 alloc_rname));
10263 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10264 {
10265 rtx addr, reg, mem;
10266 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10267 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10268 GEN_INT (info->fp_save_offset
10269 + sp_offset + 8*i));
10270 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10271 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10272
10273 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10274 }
10275 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10276 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10277 NULL_RTX, NULL_RTX);
10278 }
b6c9286a 10279
9ebbca7d
GK
10280 /* Save GPRs. This is done as a PARALLEL if we are using
10281 the store-multiple instructions. */
10282 if (using_store_multiple)
b6c9286a 10283 {
308c142a 10284 rtvec p;
9ebbca7d
GK
10285 int i;
10286 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10287 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10288 {
10289 rtx addr, reg, mem;
10290 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10291 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10292 GEN_INT (info->gp_save_offset
10293 + sp_offset
10294 + reg_size * i));
10295 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10296 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10297
10298 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10299 }
10300 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10301 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10302 NULL_RTX, NULL_RTX);
b6c9286a
MM
10303 }
10304 else
10305 {
9ebbca7d
GK
10306 int i;
10307 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10308 if ((regs_ever_live[info->first_gp_reg_save+i]
10309 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10310 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10311 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10312 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10313 {
10314 rtx addr, reg, mem;
10315 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10316
10317 if (TARGET_SPE_ABI)
10318 {
10319 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10320 rtx b;
10321
10322 if (!SPE_CONST_OFFSET_OK (offset))
10323 {
10324 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10325 emit_move_insn (b, GEN_INT (offset));
10326 }
10327 else
10328 b = GEN_INT (offset);
10329
10330 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10331 mem = gen_rtx_MEM (V2SImode, addr);
10332 set_mem_alias_set (mem, rs6000_sr_alias_set);
10333 insn = emit_move_insn (mem, reg);
10334
10335 if (GET_CODE (b) == CONST_INT)
10336 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10337 NULL_RTX, NULL_RTX);
10338 else
10339 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10340 b, GEN_INT (offset));
10341 }
10342 else
10343 {
10344 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10345 GEN_INT (info->gp_save_offset
10346 + sp_offset
10347 + reg_size * i));
10348 mem = gen_rtx_MEM (reg_mode, addr);
10349 set_mem_alias_set (mem, rs6000_sr_alias_set);
10350
10351 insn = emit_move_insn (mem, reg);
10352 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10353 NULL_RTX, NULL_RTX);
10354 }
10355 }
9ebbca7d
GK
10356 }
10357
83720594
RH
10358 /* ??? There's no need to emit actual instructions here, but it's the
10359 easiest way to get the frame unwind information emitted. */
10360 if (current_function_calls_eh_return)
10361 {
78e1b90d
DE
10362 unsigned int i, regno;
10363
83720594
RH
10364 for (i = 0; ; ++i)
10365 {
83720594
RH
10366 regno = EH_RETURN_DATA_REGNO (i);
10367 if (regno == INVALID_REGNUM)
10368 break;
10369
89e7058f
AH
10370 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10371 info->ehrd_offset + sp_offset
10372 + reg_size * (int) i,
10373 info->total_size);
83720594
RH
10374 }
10375 }
10376
9ebbca7d
GK
10377 /* Save lr if we used it. */
10378 if (info->lr_save_p)
10379 {
10380 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10381 GEN_INT (info->lr_save_offset + sp_offset));
10382 rtx reg = gen_rtx_REG (Pmode, 0);
10383 rtx mem = gen_rtx_MEM (Pmode, addr);
10384 /* This should not be of rs6000_sr_alias_set, because of
10385 __builtin_return_address. */
10386
10387 insn = emit_move_insn (mem, reg);
10388 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10389 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10390 }
10391
10392 /* Save CR if we use any that must be preserved. */
10393 if (info->cr_save_p)
10394 {
10395 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10396 GEN_INT (info->cr_save_offset + sp_offset));
10397 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10398
10399 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10400
10401 /* If r12 was used to hold the original sp, copy cr into r0 now
10402 that it's free. */
10403 if (REGNO (frame_reg_rtx) == 12)
10404 {
10405 cr_save_rtx = gen_rtx_REG (SImode, 0);
10406 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10407 }
10408 insn = emit_move_insn (mem, cr_save_rtx);
10409
10410 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10411 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10412 OK. All we have to do is specify that _one_ condition code
10413 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10414 will then restore all the call-saved registers.
10415 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10416 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10417 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10418 }
10419
10420 /* Update stack and set back pointer unless this is V.4,
10421 for which it was done previously. */
f607bc57 10422 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10423 rs6000_emit_allocate_stack (info->total_size, FALSE);
10424
10425 /* Set frame pointer, if needed. */
10426 if (frame_pointer_needed)
10427 {
a3170dc6 10428 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10429 sp_reg_rtx);
10430 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10431 }
9878760c 10432
1db02437 10433 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10434 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10435 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10436 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10437 {
10438 /* If emit_load_toc_table will use the link register, we need to save
10439 it. We use R11 for this purpose because emit_load_toc_table
10440 can use register 0. This allows us to use a plain 'blr' to return
10441 from the procedure more often. */
d5fa86ba
GK
10442 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10443 && ! info->lr_save_p
10444 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10445 if (save_LR_around_toc_setup)
10446 emit_move_insn (gen_rtx_REG (Pmode, 11),
10447 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10448
10449 rs6000_emit_load_toc_table (TRUE);
10450
10451 if (save_LR_around_toc_setup)
10452 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10453 gen_rtx_REG (Pmode, 11));
10454 }
ee890fe2
SS
10455
10456 if (DEFAULT_ABI == ABI_DARWIN
10457 && flag_pic && current_function_uses_pic_offset_table)
10458 {
10459 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
10460
10461 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest)));
10462
10463 rs6000_maybe_dead (
1db02437 10464 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10465 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10466 }
9ebbca7d
GK
10467}
10468
9ebbca7d 10469/* Write function prologue. */
a4f6c312 10470
08c148a8
NB
10471static void
10472rs6000_output_function_prologue (file, size)
9ebbca7d 10473 FILE *file;
08c148a8 10474 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10475{
10476 rs6000_stack_t *info = rs6000_stack_info ();
10477
4697a36c
MM
10478 if (TARGET_DEBUG_STACK)
10479 debug_stack_info (info);
9878760c 10480
a4f6c312
SS
10481 /* Write .extern for any function we will call to save and restore
10482 fp values. */
10483 if (info->first_fp_reg_save < 64
10484 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10485 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10486 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10487 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10488 RESTORE_FP_SUFFIX);
9878760c 10489
c764f757
RK
10490 /* Write .extern for AIX common mode routines, if needed. */
10491 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10492 {
f6709c70
JW
10493 fputs ("\t.extern __mulh\n", file);
10494 fputs ("\t.extern __mull\n", file);
10495 fputs ("\t.extern __divss\n", file);
10496 fputs ("\t.extern __divus\n", file);
10497 fputs ("\t.extern __quoss\n", file);
10498 fputs ("\t.extern __quous\n", file);
c764f757
RK
10499 common_mode_defined = 1;
10500 }
9878760c 10501
9ebbca7d 10502 if (! HAVE_prologue)
979721f8 10503 {
9ebbca7d 10504 start_sequence ();
9dda4cc8 10505
a4f6c312
SS
10506 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10507 the "toplevel" insn chain. */
9ebbca7d
GK
10508 emit_note (0, NOTE_INSN_DELETED);
10509 rs6000_emit_prologue ();
10510 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10511
10512 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10513 {
10514 rtx insn;
10515 unsigned addr = 0;
10516 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10517 {
10518 INSN_ADDRESSES_NEW (insn, addr);
10519 addr += 4;
10520 }
10521 }
9dda4cc8 10522
9ebbca7d 10523 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10524 debug_rtx_list (get_insns (), 100);
10525 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10526 end_sequence ();
979721f8
MM
10527 }
10528
9ebbca7d
GK
10529 rs6000_pic_labelno++;
10530}
10531
10532/* Emit function epilogue as insns.
9878760c 10533
9ebbca7d
GK
10534 At present, dwarf2out_frame_debug_expr doesn't understand
10535 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10536 anywhere in the epilogue. Most of the insns below would in any case
10537 need special notes to explain where r11 is in relation to the stack. */
9878760c 10538
9ebbca7d 10539void
83720594 10540rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
10541 int sibcall;
10542{
10543 rs6000_stack_t *info;
10544 int restoring_FPRs_inline;
10545 int using_load_multiple;
10546 int using_mfcr_multiple;
10547 int use_backchain_to_restore_sp;
10548 int sp_offset = 0;
10549 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10550 rtx frame_reg_rtx = sp_reg_rtx;
10551 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10552 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10553 int i;
10554
a3170dc6
AH
10555 if (TARGET_SPE_ABI)
10556 {
10557 reg_mode = V2SImode;
10558 reg_size = 8;
10559 }
10560
9ebbca7d
GK
10561 info = rs6000_stack_info ();
10562 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10563 && !TARGET_SPE_ABI
9ebbca7d
GK
10564 && info->first_gp_reg_save < 31);
10565 restoring_FPRs_inline = (sibcall
83720594 10566 || current_function_calls_eh_return
9ebbca7d
GK
10567 || info->first_fp_reg_save == 64
10568 || FP_SAVE_INLINE (info->first_fp_reg_save));
10569 use_backchain_to_restore_sp = (frame_pointer_needed
10570 || current_function_calls_alloca
10571 || info->total_size > 32767);
10572 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10573 || rs6000_cpu == PROCESSOR_PPC603
10574 || rs6000_cpu == PROCESSOR_PPC750
10575 || optimize_size);
10576
10577 /* If we have a frame pointer, a call to alloca, or a large stack
10578 frame, restore the old stack pointer using the backchain. Otherwise,
10579 we know what size to update it with. */
10580 if (use_backchain_to_restore_sp)
bacbde18 10581 {
9ebbca7d
GK
10582 /* Under V.4, don't reset the stack pointer until after we're done
10583 loading the saved registers. */
f607bc57 10584 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 10585 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 10586
9ebbca7d
GK
10587 emit_move_insn (frame_reg_rtx,
10588 gen_rtx_MEM (Pmode, sp_reg_rtx));
10589
bacbde18 10590 }
9ebbca7d 10591 else if (info->push_p)
85638c0d 10592 {
f607bc57 10593 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10594 sp_offset = info->total_size;
10595 else
10596 {
10597 emit_insn (TARGET_32BIT
10598 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10599 GEN_INT (info->total_size))
10600 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10601 GEN_INT (info->total_size)));
10602 }
85638c0d 10603 }
9ebbca7d 10604
9aa86737
AH
10605 /* Restore AltiVec registers if needed. */
10606 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10607 {
10608 int i;
10609
10610 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10611 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10612 {
10613 rtx addr, areg, mem;
10614
10615 areg = gen_rtx_REG (Pmode, 0);
10616 emit_move_insn
10617 (areg, GEN_INT (info->altivec_save_offset
10618 + sp_offset
10619 + 16 * (i - info->first_altivec_reg_save)));
10620
10621 /* AltiVec addressing mode is [reg+reg]. */
10622 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10623 mem = gen_rtx_MEM (V4SImode, addr);
10624 set_mem_alias_set (mem, rs6000_sr_alias_set);
10625
10626 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10627 }
10628 }
10629
10630 /* Restore VRSAVE if needed. */
10631 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10632 {
10633 rtx addr, mem, reg;
10634
10635 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10636 GEN_INT (info->vrsave_save_offset + sp_offset));
10637 mem = gen_rtx_MEM (SImode, addr);
10638 set_mem_alias_set (mem, rs6000_sr_alias_set);
10639 reg = gen_rtx_REG (SImode, 12);
10640 emit_move_insn (reg, mem);
10641
10642 emit_insn (generate_set_vrsave (reg, info, 1));
10643 }
10644
9ebbca7d
GK
10645 /* Get the old lr if we saved it. */
10646 if (info->lr_save_p)
b6c9286a 10647 {
a3170dc6
AH
10648 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10649 info->lr_save_offset + sp_offset);
ba4828e0
RK
10650
10651 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10652
9ebbca7d 10653 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 10654 }
9ebbca7d
GK
10655
10656 /* Get the old cr if we saved it. */
10657 if (info->cr_save_p)
10658 {
10659 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10660 GEN_INT (info->cr_save_offset + sp_offset));
10661 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10662
10663 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10664
9ebbca7d
GK
10665 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10666 }
10667
10668 /* Set LR here to try to overlap restores below. */
4697a36c 10669 if (info->lr_save_p)
9ebbca7d
GK
10670 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10671 gen_rtx_REG (Pmode, 0));
10672
83720594
RH
10673 /* Load exception handler data registers, if needed. */
10674 if (current_function_calls_eh_return)
10675 {
78e1b90d
DE
10676 unsigned int i, regno;
10677
83720594
RH
10678 for (i = 0; ; ++i)
10679 {
a3170dc6 10680 rtx mem;
83720594
RH
10681
10682 regno = EH_RETURN_DATA_REGNO (i);
10683 if (regno == INVALID_REGNUM)
10684 break;
10685
a3170dc6
AH
10686 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
10687 info->ehrd_offset + sp_offset
10688 + reg_size * (int) i);
ba4828e0 10689 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
10690
10691 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
10692 }
10693 }
9ebbca7d
GK
10694
10695 /* Restore GPRs. This is done as a PARALLEL if we are using
10696 the load-multiple instructions. */
10697 if (using_load_multiple)
979721f8 10698 {
9ebbca7d
GK
10699 rtvec p;
10700 p = rtvec_alloc (32 - info->first_gp_reg_save);
10701 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 10702 {
9ebbca7d
GK
10703 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10704 GEN_INT (info->gp_save_offset
10705 + sp_offset
10706 + reg_size * i));
10707 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
10708
10709 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10710
10711 RTVEC_ELT (p, i) =
10712 gen_rtx_SET (VOIDmode,
10713 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
10714 mem);
979721f8 10715 }
9ebbca7d 10716 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 10717 }
9ebbca7d
GK
10718 else
10719 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10720 if ((regs_ever_live[info->first_gp_reg_save+i]
10721 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10722 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10723 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10724 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
10725 {
10726 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10727 GEN_INT (info->gp_save_offset
10728 + sp_offset
10729 + reg_size * i));
10730 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10731
a3170dc6
AH
10732 /* Restore 64-bit quantities for SPE. */
10733 if (TARGET_SPE_ABI)
10734 {
10735 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10736 rtx b;
10737
10738 if (!SPE_CONST_OFFSET_OK (offset))
10739 {
10740 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10741 emit_move_insn (b, GEN_INT (offset));
10742 }
10743 else
10744 b = GEN_INT (offset);
10745
10746 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10747 mem = gen_rtx_MEM (V2SImode, addr);
10748 }
10749
ba4828e0 10750 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10751
10752 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 10753 info->first_gp_reg_save + i), mem);
9ebbca7d 10754 }
9878760c 10755
9ebbca7d
GK
10756 /* Restore fpr's if we need to do it without calling a function. */
10757 if (restoring_FPRs_inline)
10758 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10759 if ((regs_ever_live[info->first_fp_reg_save+i]
10760 && ! call_used_regs[info->first_fp_reg_save+i]))
10761 {
10762 rtx addr, mem;
10763 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10764 GEN_INT (info->fp_save_offset
10765 + sp_offset
a4f6c312 10766 + 8 * i));
9ebbca7d 10767 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10768 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10769
10770 emit_move_insn (gen_rtx_REG (DFmode,
10771 info->first_fp_reg_save + i),
10772 mem);
10773 }
8d30c4ee 10774
9ebbca7d
GK
10775 /* If we saved cr, restore it here. Just those that were used. */
10776 if (info->cr_save_p)
979721f8 10777 {
9ebbca7d 10778 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 10779 int count = 0;
9ebbca7d
GK
10780
10781 if (using_mfcr_multiple)
979721f8 10782 {
9ebbca7d
GK
10783 for (i = 0; i < 8; i++)
10784 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 10785 count++;
9ebbca7d 10786 if (count == 0)
e35b9579
GK
10787 abort ();
10788 }
10789
10790 if (using_mfcr_multiple && count > 1)
10791 {
10792 rtvec p;
10793 int ndx;
9ebbca7d 10794
e35b9579 10795 p = rtvec_alloc (count);
9ebbca7d 10796
e35b9579 10797 ndx = 0;
9ebbca7d
GK
10798 for (i = 0; i < 8; i++)
10799 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
10800 {
10801 rtvec r = rtvec_alloc (2);
10802 RTVEC_ELT (r, 0) = r12_rtx;
10803 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 10804 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
10805 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
10806 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 10807 ndx++;
9ebbca7d
GK
10808 }
10809 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
10810 if (ndx != count)
10811 abort ();
979721f8
MM
10812 }
10813 else
9ebbca7d
GK
10814 for (i = 0; i < 8; i++)
10815 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 10816 {
9ebbca7d
GK
10817 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
10818 CR0_REGNO+i),
10819 r12_rtx));
979721f8 10820 }
979721f8
MM
10821 }
10822
9ebbca7d
GK
10823 /* If this is V.4, unwind the stack pointer after all of the loads
10824 have been done. We need to emit a block here so that sched
10825 doesn't decide to move the sp change before the register restores
10826 (which may not have any obvious dependency on the stack). This
10827 doesn't hurt performance, because there is no scheduling that can
10828 be done after this point. */
f607bc57 10829 if (DEFAULT_ABI == ABI_V4)
b6c9286a 10830 {
9ebbca7d
GK
10831 if (frame_reg_rtx != sp_reg_rtx)
10832 rs6000_emit_stack_tie ();
b6c9286a 10833
9ebbca7d 10834 if (use_backchain_to_restore_sp)
b6c9286a 10835 {
9ebbca7d 10836 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 10837 }
9ebbca7d 10838 else if (sp_offset != 0)
13f1623b 10839 {
9ebbca7d
GK
10840 emit_insn (Pmode == SImode
10841 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10842 GEN_INT (sp_offset))
10843 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10844 GEN_INT (sp_offset)));
13f1623b 10845 }
9ebbca7d 10846 }
b6c9286a 10847
83720594
RH
10848 if (current_function_calls_eh_return)
10849 {
10850 rtx sa = EH_RETURN_STACKADJ_RTX;
10851 emit_insn (Pmode == SImode
10852 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
10853 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
10854 }
10855
9ebbca7d
GK
10856 if (!sibcall)
10857 {
10858 rtvec p;
10859 if (! restoring_FPRs_inline)
10860 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
10861 else
10862 p = rtvec_alloc (2);
b6c9286a 10863
e35b9579
GK
10864 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
10865 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
10866 gen_rtx_REG (Pmode,
10867 LINK_REGISTER_REGNUM));
9ebbca7d
GK
10868
10869 /* If we have to restore more than two FP registers, branch to the
10870 restore function. It will return to our caller. */
10871 if (! restoring_FPRs_inline)
10872 {
10873 int i;
10874 char rname[30];
520a57c8 10875 const char *alloc_rname;
979721f8 10876
9ebbca7d
GK
10877 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
10878 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 10879 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10880 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
10881 gen_rtx_SYMBOL_REF (Pmode,
10882 alloc_rname));
b6c9286a 10883
9ebbca7d
GK
10884 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10885 {
10886 rtx addr, mem;
10887 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
10888 GEN_INT (info->fp_save_offset + 8*i));
10889 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10890 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10891
10892 RTVEC_ELT (p, i+3) =
10893 gen_rtx_SET (VOIDmode,
10894 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
10895 mem);
b6c9286a
MM
10896 }
10897 }
9ebbca7d
GK
10898
10899 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 10900 }
9878760c
RK
10901}
10902
10903/* Write function epilogue. */
10904
08c148a8
NB
10905static void
10906rs6000_output_function_epilogue (file, size)
9878760c 10907 FILE *file;
08c148a8 10908 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 10909{
4697a36c 10910 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 10911
9ebbca7d 10912 if (! HAVE_epilogue)
9878760c 10913 {
9ebbca7d
GK
10914 rtx insn = get_last_insn ();
10915 /* If the last insn was a BARRIER, we don't have to write anything except
10916 the trace table. */
10917 if (GET_CODE (insn) == NOTE)
10918 insn = prev_nonnote_insn (insn);
10919 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 10920 {
9ebbca7d
GK
10921 /* This is slightly ugly, but at least we don't have two
10922 copies of the epilogue-emitting code. */
10923 start_sequence ();
10924
10925 /* A NOTE_INSN_DELETED is supposed to be at the start
10926 and end of the "toplevel" insn chain. */
10927 emit_note (0, NOTE_INSN_DELETED);
10928 rs6000_emit_epilogue (FALSE);
10929 emit_note (0, NOTE_INSN_DELETED);
10930
178c3eff
DJ
10931 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10932 {
10933 rtx insn;
10934 unsigned addr = 0;
10935 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10936 {
10937 INSN_ADDRESSES_NEW (insn, addr);
10938 addr += 4;
10939 }
10940 }
10941
9ebbca7d 10942 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10943 debug_rtx_list (get_insns (), 100);
10944 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10945 end_sequence ();
4697a36c 10946 }
9878760c 10947 }
b4ac57ab 10948
9b30bae2 10949 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
10950 on its format.
10951
10952 We don't output a traceback table if -finhibit-size-directive was
10953 used. The documentation for -finhibit-size-directive reads
10954 ``don't output a @code{.size} assembler directive, or anything
10955 else that would cause trouble if the function is split in the
10956 middle, and the two halves are placed at locations far apart in
10957 memory.'' The traceback table has this property, since it
10958 includes the offset from the start of the function to the
4d30c363
MM
10959 traceback table itself.
10960
10961 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 10962 different traceback table. */
57ac7be9
AM
10963 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
10964 && rs6000_traceback != traceback_none)
9b30bae2 10965 {
3cce094d 10966 const char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
3ac88239 10967 const char *language_string = lang_hooks.name;
6041bf2f 10968 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 10969 int i;
57ac7be9
AM
10970 int optional_tbtab;
10971
10972 if (rs6000_traceback == traceback_full)
10973 optional_tbtab = 1;
10974 else if (rs6000_traceback == traceback_part)
10975 optional_tbtab = 0;
10976 else
10977 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 10978
b6c9286a
MM
10979 while (*fname == '.') /* V.4 encodes . in the name */
10980 fname++;
10981
314fc5a9
ILT
10982 /* Need label immediately before tbtab, so we can compute its offset
10983 from the function start. */
10984 if (*fname == '*')
10985 ++fname;
10986 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
10987 ASM_OUTPUT_LABEL (file, fname);
10988
10989 /* The .tbtab pseudo-op can only be used for the first eight
10990 expressions, since it can't handle the possibly variable
10991 length fields that follow. However, if you omit the optional
10992 fields, the assembler outputs zeros for all optional fields
10993 anyways, giving each variable length field is minimum length
10994 (as defined in sys/debug.h). Thus we can not use the .tbtab
10995 pseudo-op at all. */
10996
10997 /* An all-zero word flags the start of the tbtab, for debuggers
10998 that have to find it by searching forward from the entry
10999 point or from the current pc. */
19d2d16f 11000 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11001
11002 /* Tbtab format type. Use format type 0. */
19d2d16f 11003 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11004
11005 /* Language type. Unfortunately, there doesn't seem to be any
11006 official way to get this info, so we use language_string. C
11007 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11008 value for C for now. There is no official value for Java,
6f573ff9 11009 although IBM appears to be using 13. There is no official value
f710504c 11010 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11011 if (! strcmp (language_string, "GNU C")
e2c953b6 11012 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11013 i = 0;
11014 else if (! strcmp (language_string, "GNU F77"))
11015 i = 1;
11016 else if (! strcmp (language_string, "GNU Ada"))
11017 i = 3;
8b83775b 11018 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11019 i = 2;
11020 else if (! strcmp (language_string, "GNU C++"))
11021 i = 9;
9517ead8
AG
11022 else if (! strcmp (language_string, "GNU Java"))
11023 i = 13;
6f573ff9
JL
11024 else if (! strcmp (language_string, "GNU CHILL"))
11025 i = 44;
314fc5a9
ILT
11026 else
11027 abort ();
11028 fprintf (file, "%d,", i);
11029
11030 /* 8 single bit fields: global linkage (not set for C extern linkage,
11031 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11032 from start of procedure stored in tbtab, internal function, function
11033 has controlled storage, function has no toc, function uses fp,
11034 function logs/aborts fp operations. */
11035 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11036 fprintf (file, "%d,",
11037 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11038
11039 /* 6 bitfields: function is interrupt handler, name present in
11040 proc table, function calls alloca, on condition directives
11041 (controls stack walks, 3 bits), saves condition reg, saves
11042 link reg. */
11043 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11044 set up as a frame pointer, even when there is no alloca call. */
11045 fprintf (file, "%d,",
6041bf2f
DE
11046 ((optional_tbtab << 6)
11047 | ((optional_tbtab & frame_pointer_needed) << 5)
11048 | (info->cr_save_p << 1)
11049 | (info->lr_save_p)));
314fc5a9 11050
6041bf2f 11051 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11052 (6 bits). */
11053 fprintf (file, "%d,",
4697a36c 11054 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11055
11056 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11057 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11058
6041bf2f
DE
11059 if (optional_tbtab)
11060 {
11061 /* Compute the parameter info from the function decl argument
11062 list. */
11063 tree decl;
11064 int next_parm_info_bit = 31;
314fc5a9 11065
6041bf2f
DE
11066 for (decl = DECL_ARGUMENTS (current_function_decl);
11067 decl; decl = TREE_CHAIN (decl))
11068 {
11069 rtx parameter = DECL_INCOMING_RTL (decl);
11070 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11071
6041bf2f
DE
11072 if (GET_CODE (parameter) == REG)
11073 {
11074 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11075 {
11076 int bits;
11077
11078 float_parms++;
11079
11080 if (mode == SFmode)
11081 bits = 0x2;
11082 else if (mode == DFmode)
11083 bits = 0x3;
11084 else
11085 abort ();
11086
11087 /* If only one bit will fit, don't or in this entry. */
11088 if (next_parm_info_bit > 0)
11089 parm_info |= (bits << (next_parm_info_bit - 1));
11090 next_parm_info_bit -= 2;
11091 }
11092 else
11093 {
11094 fixed_parms += ((GET_MODE_SIZE (mode)
11095 + (UNITS_PER_WORD - 1))
11096 / UNITS_PER_WORD);
11097 next_parm_info_bit -= 1;
11098 }
11099 }
11100 }
11101 }
314fc5a9
ILT
11102
11103 /* Number of fixed point parameters. */
11104 /* This is actually the number of words of fixed point parameters; thus
11105 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11106 fprintf (file, "%d,", fixed_parms);
11107
11108 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11109 all on stack. */
11110 /* This is actually the number of fp registers that hold parameters;
11111 and thus the maximum value is 13. */
11112 /* Set parameters on stack bit if parameters are not in their original
11113 registers, regardless of whether they are on the stack? Xlc
11114 seems to set the bit when not optimizing. */
11115 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11116
6041bf2f
DE
11117 if (! optional_tbtab)
11118 return;
11119
314fc5a9
ILT
11120 /* Optional fields follow. Some are variable length. */
11121
11122 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11123 11 double float. */
11124 /* There is an entry for each parameter in a register, in the order that
11125 they occur in the parameter list. Any intervening arguments on the
11126 stack are ignored. If the list overflows a long (max possible length
11127 34 bits) then completely leave off all elements that don't fit. */
11128 /* Only emit this long if there was at least one parameter. */
11129 if (fixed_parms || float_parms)
11130 fprintf (file, "\t.long %d\n", parm_info);
11131
11132 /* Offset from start of code to tb table. */
19d2d16f 11133 fputs ("\t.long ", file);
314fc5a9 11134 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11135#if TARGET_AIX
11136 RS6000_OUTPUT_BASENAME (file, fname);
11137#else
9ebbca7d 11138 assemble_name (file, fname);
54ee9799 11139#endif
19d2d16f 11140 fputs ("-.", file);
54ee9799
DE
11141#if TARGET_AIX
11142 RS6000_OUTPUT_BASENAME (file, fname);
11143#else
9ebbca7d 11144 assemble_name (file, fname);
54ee9799 11145#endif
19d2d16f 11146 putc ('\n', file);
314fc5a9
ILT
11147
11148 /* Interrupt handler mask. */
11149 /* Omit this long, since we never set the interrupt handler bit
11150 above. */
11151
11152 /* Number of CTL (controlled storage) anchors. */
11153 /* Omit this long, since the has_ctl bit is never set above. */
11154
11155 /* Displacement into stack of each CTL anchor. */
11156 /* Omit this list of longs, because there are no CTL anchors. */
11157
11158 /* Length of function name. */
296b8152 11159 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11160
11161 /* Function name. */
11162 assemble_string (fname, strlen (fname));
11163
11164 /* Register for alloca automatic storage; this is always reg 31.
11165 Only emit this if the alloca bit was set above. */
11166 if (frame_pointer_needed)
19d2d16f 11167 fputs ("\t.byte 31\n", file);
b1765bde
DE
11168
11169 fputs ("\t.align 2\n", file);
9b30bae2 11170 }
9878760c 11171}
17167fd8 11172\f
a4f6c312
SS
11173/* A C compound statement that outputs the assembler code for a thunk
11174 function, used to implement C++ virtual function calls with
11175 multiple inheritance. The thunk acts as a wrapper around a virtual
11176 function, adjusting the implicit object parameter before handing
11177 control off to the real function.
11178
11179 First, emit code to add the integer DELTA to the location that
11180 contains the incoming first argument. Assume that this argument
11181 contains a pointer, and is the one used to pass the `this' pointer
11182 in C++. This is the incoming argument *before* the function
11183 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11184 values of all other incoming arguments.
17167fd8
MM
11185
11186 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11187 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11188 not touch the return address. Hence returning from FUNCTION will
11189 return to whoever called the current `thunk'.
17167fd8 11190
a4f6c312
SS
11191 The effect must be as if FUNCTION had been called directly with the
11192 adjusted first argument. This macro is responsible for emitting
11193 all of the code for a thunk function; output_function_prologue()
11194 and output_function_epilogue() are not invoked.
17167fd8 11195
a4f6c312
SS
11196 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11197 been extracted from it.) It might possibly be useful on some
11198 targets, but probably not.
17167fd8 11199
a4f6c312
SS
11200 If you do not define this macro, the target-independent code in the
11201 C++ frontend will generate a less efficient heavyweight thunk that
11202 calls FUNCTION instead of jumping to it. The generic approach does
11203 not support varargs. */
17167fd8
MM
11204
11205void
11206output_mi_thunk (file, thunk_fndecl, delta, function)
11207 FILE *file;
d330fd93 11208 tree thunk_fndecl ATTRIBUTE_UNUSED;
17167fd8
MM
11209 int delta;
11210 tree function;
11211{
a4f6c312
SS
11212 const char *this_reg =
11213 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
d330fd93 11214 const char *prefix;
3cce094d 11215 const char *fname;
d330fd93 11216 const char *r0 = reg_names[0];
d330fd93
KG
11217 const char *toc = reg_names[2];
11218 const char *schain = reg_names[11];
11219 const char *r12 = reg_names[12];
17167fd8
MM
11220 char buf[512];
11221 static int labelno = 0;
11222
a4f6c312 11223 /* Small constants that can be done by one add instruction. */
17167fd8
MM
11224 if (delta >= -32768 && delta <= 32767)
11225 {
22b4a3b0 11226 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11227 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta, this_reg);
11228 else
11229 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
11230 }
11231
56a7189a
AM
11232 /* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
11233 else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
11234 abort ();
11235
a4f6c312 11236 /* Large constants that can be done by one addis instruction. */
56a7189a 11237 else if ((delta & 0xffff) == 0)
17167fd8
MM
11238 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11239 delta >> 16);
11240
11241 /* 32-bit constants that can be done by an add and addis instruction. */
56a7189a 11242 else
17167fd8 11243 {
a4f6c312
SS
11244 /* Break into two pieces, propagating the sign bit from the low
11245 word to the upper word. */
56a7189a
AM
11246 int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
11247 int delta_high = (delta - delta_low) >> 16;
17167fd8
MM
11248
11249 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11250 delta_high);
11251
22b4a3b0 11252 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11253 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
11254 else
11255 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
11256 }
11257
17167fd8
MM
11258 /* Get the prefix in front of the names. */
11259 switch (DEFAULT_ABI)
11260 {
11261 default:
11262 abort ();
11263
11264 case ABI_AIX:
11265 prefix = ".";
11266 break;
11267
11268 case ABI_V4:
11269 case ABI_AIX_NODESC:
17167fd8
MM
11270 prefix = "";
11271 break;
17167fd8
MM
11272 }
11273
11274 /* If the function is compiled in this module, jump to it directly.
11275 Otherwise, load up its address and jump to it. */
11276
11277 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
42820a49 11278
9ebbca7d 11279 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
a5c76ee6
ZW
11280 && (! lookup_attribute ("longcall",
11281 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11282 || lookup_attribute ("shortcall",
11283 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
11284
17167fd8
MM
11285 {
11286 fprintf (file, "\tb %s", prefix);
11287 assemble_name (file, fname);
22b4a3b0 11288 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
949ea356 11289 putc ('\n', file);
17167fd8
MM
11290 }
11291
11292 else
11293 {
11294 switch (DEFAULT_ABI)
11295 {
11296 default:
17167fd8
MM
11297 abort ();
11298
11299 case ABI_AIX:
11300 /* Set up a TOC entry for the function. */
11301 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
11302 toc_section ();
11303 ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
11304 labelno++;
11305
fa9b5c6b
DE
11306 if (TARGET_MINIMAL_TOC)
11307 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
11308 else
11309 {
11310 fputs ("\t.tc ", file);
11311 assemble_name (file, fname);
11312 fputs ("[TC],", file);
11313 }
11314 assemble_name (file, fname);
17167fd8 11315 putc ('\n', file);
b4d330e1
DE
11316 if (TARGET_ELF)
11317 function_section (current_function_decl);
11318 else
11319 text_section();
468e8dba
DE
11320 if (TARGET_MINIMAL_TOC)
11321 asm_fprintf (file, (TARGET_32BIT)
11322 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
11323 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
d2574c50 11324 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
17167fd8 11325 assemble_name (file, buf);
468e8dba
DE
11326 if (TARGET_ELF && TARGET_MINIMAL_TOC)
11327 fputs ("-(.LCTOC1)", file);
11328 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
17167fd8
MM
11329 asm_fprintf (file,
11330 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
11331 r0, r12);
11332
11333 asm_fprintf (file,
11334 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
11335 toc, r12);
11336
11337 asm_fprintf (file, "\tmtctr %s\n", r0);
11338 asm_fprintf (file,
11339 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
11340 schain, r12);
11341
11342 asm_fprintf (file, "\tbctr\n");
11343 break;
11344
9ebbca7d 11345 case ABI_AIX_NODESC:
17167fd8 11346 case ABI_V4:
22b4a3b0
FS
11347 fprintf (file, "\tb %s", prefix);
11348 assemble_name (file, fname);
11349 if (flag_pic) fputs ("@plt", file);
949ea356 11350 putc ('\n', file);
22b4a3b0 11351 break;
ee890fe2
SS
11352
11353#if TARGET_MACHO
11354 case ABI_DARWIN:
11355 fprintf (file, "\tb %s", prefix);
11356 if (flag_pic && !machopic_name_defined_p (fname))
11357 assemble_name (file, machopic_stub_name (fname));
11358 else
11359 assemble_name (file, fname);
11360 putc ('\n', file);
11361 break;
11362#endif
9ebbca7d
GK
11363 }
11364 }
11365}
42820a49 11366
9ebbca7d
GK
11367\f
11368/* A quick summary of the various types of 'constant-pool tables'
11369 under PowerPC:
11370
11371 Target Flags Name One table per
11372 AIX (none) AIX TOC object file
11373 AIX -mfull-toc AIX TOC object file
11374 AIX -mminimal-toc AIX minimal TOC translation unit
11375 SVR4/EABI (none) SVR4 SDATA object file
11376 SVR4/EABI -fpic SVR4 pic object file
11377 SVR4/EABI -fPIC SVR4 PIC translation unit
11378 SVR4/EABI -mrelocatable EABI TOC function
11379 SVR4/EABI -maix AIX TOC object file
11380 SVR4/EABI -maix -mminimal-toc
11381 AIX minimal TOC translation unit
11382
11383 Name Reg. Set by entries contains:
11384 made by addrs? fp? sum?
11385
11386 AIX TOC 2 crt0 as Y option option
11387 AIX minimal TOC 30 prolog gcc Y Y option
11388 SVR4 SDATA 13 crt0 gcc N Y N
11389 SVR4 pic 30 prolog ld Y not yet N
11390 SVR4 PIC 30 prolog gcc Y option option
11391 EABI TOC 30 prolog gcc Y option option
11392
11393*/
11394
11395/* Hash table stuff for keeping track of TOC entries. */
11396
11397struct toc_hash_struct
11398{
11399 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
11400 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
11401 rtx key;
a9098fd0 11402 enum machine_mode key_mode;
9ebbca7d
GK
11403 int labelno;
11404};
17167fd8 11405
9ebbca7d
GK
11406static htab_t toc_hash_table;
11407
11408/* Hash functions for the hash table. */
11409
11410static unsigned
11411rs6000_hash_constant (k)
11412 rtx k;
11413{
a9098fd0 11414 unsigned result = (GET_CODE (k) << 3) ^ GET_MODE (k);
9ebbca7d
GK
11415 const char *format = GET_RTX_FORMAT (GET_CODE (k));
11416 int flen = strlen (format);
11417 int fidx;
11418
11419 if (GET_CODE (k) == LABEL_REF)
b3a646eb 11420 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
9ebbca7d 11421
5692c7bc 11422 if (GET_CODE (k) == CODE_LABEL)
9ebbca7d
GK
11423 fidx = 3;
11424 else
11425 fidx = 0;
11426
11427 for (; fidx < flen; fidx++)
11428 switch (format[fidx])
11429 {
11430 case 's':
11431 {
11432 unsigned i, len;
11433 const char *str = XSTR (k, fidx);
11434 len = strlen (str);
11435 result = result * 613 + len;
11436 for (i = 0; i < len; i++)
11437 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11438 break;
11439 }
9ebbca7d
GK
11440 case 'u':
11441 case 'e':
11442 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11443 break;
11444 case 'i':
11445 case 'n':
11446 result = result * 613 + (unsigned) XINT (k, fidx);
11447 break;
11448 case 'w':
11449 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11450 result = result * 613 + (unsigned) XWINT (k, fidx);
11451 else
11452 {
11453 size_t i;
11454 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11455 result = result * 613 + (unsigned) (XWINT (k, fidx)
11456 >> CHAR_BIT * i);
11457 }
11458 break;
11459 default:
a4f6c312 11460 abort ();
9ebbca7d
GK
11461 }
11462 return result;
11463}
11464
11465static unsigned
11466toc_hash_function (hash_entry)
11467 const void * hash_entry;
11468{
a9098fd0
GK
11469 const struct toc_hash_struct *thc =
11470 (const struct toc_hash_struct *) hash_entry;
11471 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11472}
11473
11474/* Compare H1 and H2 for equivalence. */
11475
11476static int
11477toc_hash_eq (h1, h2)
11478 const void * h1;
11479 const void * h2;
11480{
11481 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11482 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11483
a9098fd0
GK
11484 if (((const struct toc_hash_struct *) h1)->key_mode
11485 != ((const struct toc_hash_struct *) h2)->key_mode)
11486 return 0;
11487
5692c7bc 11488 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11489}
11490
11491/* Mark the hash table-entry HASH_ENTRY. */
11492
11493static int
11494toc_hash_mark_entry (hash_slot, unused)
2eba1afa 11495 void ** hash_slot;
9ebbca7d
GK
11496 void * unused ATTRIBUTE_UNUSED;
11497{
11498 const struct toc_hash_struct * hash_entry =
11499 *(const struct toc_hash_struct **) hash_slot;
11500 rtx r = hash_entry->key;
11501 ggc_set_mark (hash_entry);
a4f6c312 11502 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
9ebbca7d
GK
11503 if (GET_CODE (r) == LABEL_REF)
11504 {
11505 ggc_set_mark (r);
11506 ggc_set_mark (XEXP (r, 0));
11507 }
11508 else
11509 ggc_mark_rtx (r);
11510 return 1;
11511}
11512
11513/* Mark all the elements of the TOC hash-table *HT. */
11514
11515static void
11516toc_hash_mark_table (vht)
11517 void *vht;
11518{
11519 htab_t *ht = vht;
11520
11521 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
17167fd8
MM
11522}
11523
28e510bd
MM
11524/* These are the names given by the C++ front-end to vtables, and
11525 vtable-like objects. Ideally, this logic should not be here;
11526 instead, there should be some programmatic way of inquiring as
11527 to whether or not an object is a vtable. */
11528
11529#define VTABLE_NAME_P(NAME) \
11530 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11531 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11532 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11533 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11534
11535void
11536rs6000_output_symbol_ref (file, x)
11537 FILE *file;
11538 rtx x;
11539{
11540 /* Currently C++ toc references to vtables can be emitted before it
11541 is decided whether the vtable is public or private. If this is
11542 the case, then the linker will eventually complain that there is
11543 a reference to an unknown section. Thus, for vtables only,
11544 we emit the TOC reference to reference the symbol and not the
11545 section. */
11546 const char *name = XSTR (x, 0);
54ee9799
DE
11547
11548 if (VTABLE_NAME_P (name))
11549 {
11550 RS6000_OUTPUT_BASENAME (file, name);
11551 }
11552 else
11553 assemble_name (file, name);
28e510bd
MM
11554}
11555
a4f6c312
SS
11556/* Output a TOC entry. We derive the entry name from what is being
11557 written. */
9878760c
RK
11558
11559void
a9098fd0 11560output_toc (file, x, labelno, mode)
9878760c
RK
11561 FILE *file;
11562 rtx x;
11563 int labelno;
a9098fd0 11564 enum machine_mode mode;
9878760c
RK
11565{
11566 char buf[256];
3cce094d 11567 const char *name = buf;
ec940faa 11568 const char *real_name;
9878760c
RK
11569 rtx base = x;
11570 int offset = 0;
11571
4697a36c
MM
11572 if (TARGET_NO_TOC)
11573 abort ();
11574
9ebbca7d
GK
11575 /* When the linker won't eliminate them, don't output duplicate
11576 TOC entries (this happens on AIX if there is any kind of TOC,
1f8f4a0b
MM
11577 and on SVR4 under -fPIC or -mrelocatable). */
11578 if (TARGET_TOC)
9ebbca7d
GK
11579 {
11580 struct toc_hash_struct *h;
11581 void * * found;
11582
11583 h = ggc_alloc (sizeof (*h));
11584 h->key = x;
a9098fd0 11585 h->key_mode = mode;
9ebbca7d
GK
11586 h->labelno = labelno;
11587
11588 found = htab_find_slot (toc_hash_table, h, 1);
11589 if (*found == NULL)
11590 *found = h;
11591 else /* This is indeed a duplicate.
11592 Set this label equal to that label. */
11593 {
11594 fputs ("\t.set ", file);
11595 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11596 fprintf (file, "%d,", labelno);
11597 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11598 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11599 found)->labelno));
11600 return;
11601 }
11602 }
11603
11604 /* If we're going to put a double constant in the TOC, make sure it's
11605 aligned properly when strict alignment is on. */
ff1720ed
RK
11606 if (GET_CODE (x) == CONST_DOUBLE
11607 && STRICT_ALIGNMENT
a9098fd0 11608 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
11609 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11610 ASM_OUTPUT_ALIGN (file, 3);
11611 }
11612
9ebbca7d 11613 ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
9878760c 11614
37c37a57
RK
11615 /* Handle FP constants specially. Note that if we have a minimal
11616 TOC, things we put here aren't actually in the TOC, so we can allow
11617 FP constants. */
a9098fd0 11618 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 11619 {
042259f2
DE
11620 REAL_VALUE_TYPE rv;
11621 long k[2];
0adc764e 11622
042259f2
DE
11623 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11624 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 11625
13ded975
DE
11626 if (TARGET_64BIT)
11627 {
11628 if (TARGET_MINIMAL_TOC)
2bfcf297 11629 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11630 else
2f0552b6
AM
11631 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11632 k[0] & 0xffffffff, k[1] & 0xffffffff);
11633 fprintf (file, "0x%lx%08lx\n",
11634 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11635 return;
11636 }
1875cc88 11637 else
13ded975
DE
11638 {
11639 if (TARGET_MINIMAL_TOC)
2bfcf297 11640 fputs ("\t.long ", file);
13ded975 11641 else
2f0552b6
AM
11642 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11643 k[0] & 0xffffffff, k[1] & 0xffffffff);
11644 fprintf (file, "0x%lx,0x%lx\n",
11645 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11646 return;
11647 }
9878760c 11648 }
a9098fd0 11649 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 11650 {
042259f2
DE
11651 REAL_VALUE_TYPE rv;
11652 long l;
9878760c 11653
042259f2
DE
11654 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11655 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11656
31bfaa0b
DE
11657 if (TARGET_64BIT)
11658 {
11659 if (TARGET_MINIMAL_TOC)
2bfcf297 11660 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 11661 else
2f0552b6
AM
11662 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11663 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
11664 return;
11665 }
042259f2 11666 else
31bfaa0b
DE
11667 {
11668 if (TARGET_MINIMAL_TOC)
2bfcf297 11669 fputs ("\t.long ", file);
31bfaa0b 11670 else
2f0552b6
AM
11671 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11672 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
11673 return;
11674 }
042259f2 11675 }
f176e826 11676 else if (GET_MODE (x) == VOIDmode
a9098fd0 11677 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 11678 {
e2c953b6 11679 unsigned HOST_WIDE_INT low;
042259f2
DE
11680 HOST_WIDE_INT high;
11681
11682 if (GET_CODE (x) == CONST_DOUBLE)
11683 {
11684 low = CONST_DOUBLE_LOW (x);
11685 high = CONST_DOUBLE_HIGH (x);
11686 }
11687 else
11688#if HOST_BITS_PER_WIDE_INT == 32
11689 {
11690 low = INTVAL (x);
0858c623 11691 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
11692 }
11693#else
11694 {
0858c623 11695 low = INTVAL (x) & 0xffffffff;
042259f2
DE
11696 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11697 }
11698#endif
9878760c 11699
a9098fd0
GK
11700 /* TOC entries are always Pmode-sized, but since this
11701 is a bigendian machine then if we're putting smaller
11702 integer constants in the TOC we have to pad them.
11703 (This is still a win over putting the constants in
11704 a separate constant pool, because then we'd have
02a4ec28
FS
11705 to have both a TOC entry _and_ the actual constant.)
11706
11707 For a 32-bit target, CONST_INT values are loaded and shifted
11708 entirely within `low' and can be stored in one TOC entry. */
11709
11710 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 11711 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
11712
11713 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
11714 {
11715#if HOST_BITS_PER_WIDE_INT == 32
11716 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11717 POINTER_SIZE, &low, &high, 0);
11718#else
11719 low |= high << 32;
11720 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11721 high = (HOST_WIDE_INT) low >> 32;
11722 low &= 0xffffffff;
11723#endif
11724 }
a9098fd0 11725
13ded975
DE
11726 if (TARGET_64BIT)
11727 {
11728 if (TARGET_MINIMAL_TOC)
2bfcf297 11729 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11730 else
2f0552b6
AM
11731 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
11732 (long) high & 0xffffffff, (long) low & 0xffffffff);
11733 fprintf (file, "0x%lx%08lx\n",
11734 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
11735 return;
11736 }
1875cc88 11737 else
13ded975 11738 {
02a4ec28
FS
11739 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
11740 {
11741 if (TARGET_MINIMAL_TOC)
2bfcf297 11742 fputs ("\t.long ", file);
02a4ec28 11743 else
2bfcf297 11744 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
11745 (long) high & 0xffffffff, (long) low & 0xffffffff);
11746 fprintf (file, "0x%lx,0x%lx\n",
11747 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 11748 }
13ded975 11749 else
02a4ec28
FS
11750 {
11751 if (TARGET_MINIMAL_TOC)
2bfcf297 11752 fputs ("\t.long ", file);
02a4ec28 11753 else
2f0552b6
AM
11754 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
11755 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 11756 }
13ded975
DE
11757 return;
11758 }
9878760c
RK
11759 }
11760
11761 if (GET_CODE (x) == CONST)
11762 {
2bfcf297
DB
11763 if (GET_CODE (XEXP (x, 0)) != PLUS)
11764 abort ();
11765
9878760c
RK
11766 base = XEXP (XEXP (x, 0), 0);
11767 offset = INTVAL (XEXP (XEXP (x, 0), 1));
11768 }
11769
11770 if (GET_CODE (base) == SYMBOL_REF)
11771 name = XSTR (base, 0);
11772 else if (GET_CODE (base) == LABEL_REF)
11773 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
11774 else if (GET_CODE (base) == CODE_LABEL)
11775 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
11776 else
11777 abort ();
11778
772c5265 11779 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 11780 if (TARGET_MINIMAL_TOC)
2bfcf297 11781 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
11782 else
11783 {
b6c9286a 11784 fprintf (file, "\t.tc %s", real_name);
9878760c 11785
1875cc88
JW
11786 if (offset < 0)
11787 fprintf (file, ".N%d", - offset);
11788 else if (offset)
11789 fprintf (file, ".P%d", offset);
9878760c 11790
19d2d16f 11791 fputs ("[TC],", file);
1875cc88 11792 }
581bc4de
MM
11793
11794 /* Currently C++ toc references to vtables can be emitted before it
11795 is decided whether the vtable is public or private. If this is
11796 the case, then the linker will eventually complain that there is
11797 a TOC reference to an unknown section. Thus, for vtables only,
11798 we emit the TOC reference to reference the symbol and not the
11799 section. */
28e510bd 11800 if (VTABLE_NAME_P (name))
581bc4de 11801 {
54ee9799 11802 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
11803 if (offset < 0)
11804 fprintf (file, "%d", offset);
11805 else if (offset > 0)
11806 fprintf (file, "+%d", offset);
11807 }
11808 else
11809 output_addr_const (file, x);
19d2d16f 11810 putc ('\n', file);
9878760c
RK
11811}
11812\f
11813/* Output an assembler pseudo-op to write an ASCII string of N characters
11814 starting at P to FILE.
11815
11816 On the RS/6000, we have to do this using the .byte operation and
11817 write out special characters outside the quoted string.
11818 Also, the assembler is broken; very long strings are truncated,
a4f6c312 11819 so we must artificially break them up early. */
9878760c
RK
11820
11821void
11822output_ascii (file, p, n)
11823 FILE *file;
d330fd93 11824 const char *p;
9878760c
RK
11825 int n;
11826{
11827 char c;
11828 int i, count_string;
d330fd93
KG
11829 const char *for_string = "\t.byte \"";
11830 const char *for_decimal = "\t.byte ";
11831 const char *to_close = NULL;
9878760c
RK
11832
11833 count_string = 0;
11834 for (i = 0; i < n; i++)
11835 {
11836 c = *p++;
11837 if (c >= ' ' && c < 0177)
11838 {
11839 if (for_string)
11840 fputs (for_string, file);
11841 putc (c, file);
11842
11843 /* Write two quotes to get one. */
11844 if (c == '"')
11845 {
11846 putc (c, file);
11847 ++count_string;
11848 }
11849
11850 for_string = NULL;
11851 for_decimal = "\"\n\t.byte ";
11852 to_close = "\"\n";
11853 ++count_string;
11854
11855 if (count_string >= 512)
11856 {
11857 fputs (to_close, file);
11858
11859 for_string = "\t.byte \"";
11860 for_decimal = "\t.byte ";
11861 to_close = NULL;
11862 count_string = 0;
11863 }
11864 }
11865 else
11866 {
11867 if (for_decimal)
11868 fputs (for_decimal, file);
11869 fprintf (file, "%d", c);
11870
11871 for_string = "\n\t.byte \"";
11872 for_decimal = ", ";
11873 to_close = "\n";
11874 count_string = 0;
11875 }
11876 }
11877
11878 /* Now close the string if we have written one. Then end the line. */
11879 if (to_close)
9ebbca7d 11880 fputs (to_close, file);
9878760c
RK
11881}
11882\f
11883/* Generate a unique section name for FILENAME for a section type
11884 represented by SECTION_DESC. Output goes into BUF.
11885
11886 SECTION_DESC can be any string, as long as it is different for each
11887 possible section type.
11888
11889 We name the section in the same manner as xlc. The name begins with an
11890 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
11891 names) with the last period replaced by the string SECTION_DESC. If
11892 FILENAME does not contain a period, SECTION_DESC is appended to the end of
11893 the name. */
9878760c
RK
11894
11895void
11896rs6000_gen_section_name (buf, filename, section_desc)
11897 char **buf;
9ebbca7d
GK
11898 const char *filename;
11899 const char *section_desc;
9878760c 11900{
9ebbca7d 11901 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
11902 char *p;
11903 int len;
9878760c
RK
11904
11905 after_last_slash = filename;
11906 for (q = filename; *q; q++)
11e5fe42
RK
11907 {
11908 if (*q == '/')
11909 after_last_slash = q + 1;
11910 else if (*q == '.')
11911 last_period = q;
11912 }
9878760c 11913
11e5fe42 11914 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 11915 *buf = (char *) xmalloc (len);
9878760c
RK
11916
11917 p = *buf;
11918 *p++ = '_';
11919
11920 for (q = after_last_slash; *q; q++)
11921 {
11e5fe42 11922 if (q == last_period)
9878760c
RK
11923 {
11924 strcpy (p, section_desc);
11925 p += strlen (section_desc);
9878760c
RK
11926 }
11927
e9a780ec 11928 else if (ISALNUM (*q))
9878760c
RK
11929 *p++ = *q;
11930 }
11931
11e5fe42 11932 if (last_period == 0)
9878760c
RK
11933 strcpy (p, section_desc);
11934 else
11935 *p = '\0';
11936}
e165f3f0 11937\f
a4f6c312 11938/* Emit profile function. */
411707f4 11939
411707f4
CC
11940void
11941output_profile_hook (labelno)
57ac7be9 11942 int labelno ATTRIBUTE_UNUSED;
411707f4 11943{
8480e480
CC
11944 if (DEFAULT_ABI == ABI_AIX)
11945 {
57ac7be9
AM
11946#ifdef NO_PROFILE_COUNTERS
11947 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
11948#else
8480e480 11949 char buf[30];
40501e5f 11950 const char *label_name;
8480e480 11951 rtx fun;
411707f4 11952
8480e480 11953 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 11954 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 11955 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 11956
8480e480
CC
11957 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
11958 fun, Pmode);
57ac7be9 11959#endif
8480e480 11960 }
ee890fe2
SS
11961 else if (DEFAULT_ABI == ABI_DARWIN)
11962 {
d5fa86ba 11963 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
11964 int caller_addr_regno = LINK_REGISTER_REGNUM;
11965
11966 /* Be conservative and always set this, at least for now. */
11967 current_function_uses_pic_offset_table = 1;
11968
11969#if TARGET_MACHO
11970 /* For PIC code, set up a stub and collect the caller's address
11971 from r0, which is where the prologue puts it. */
11972 if (flag_pic)
11973 {
11974 mcount_name = machopic_stub_name (mcount_name);
11975 if (current_function_uses_pic_offset_table)
11976 caller_addr_regno = 0;
11977 }
11978#endif
11979 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
11980 0, VOIDmode, 1,
11981 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
11982 }
411707f4
CC
11983}
11984
a4f6c312 11985/* Write function profiler code. */
e165f3f0
RK
11986
11987void
11988output_function_profiler (file, labelno)
11989 FILE *file;
11990 int labelno;
11991{
3daf36a4 11992 char buf[100];
09eeeacb 11993 int save_lr = 8;
e165f3f0 11994
3daf36a4 11995 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 11996 switch (DEFAULT_ABI)
3daf36a4 11997 {
38c1f2d7
MM
11998 default:
11999 abort ();
12000
12001 case ABI_V4:
09eeeacb
AM
12002 save_lr = 4;
12003 /* Fall through. */
12004
38c1f2d7 12005 case ABI_AIX_NODESC:
09eeeacb
AM
12006 if (!TARGET_32BIT)
12007 {
12008 warning ("no profiling of 64-bit code for this ABI");
12009 return;
12010 }
38c1f2d7
MM
12011 fprintf (file, "\tmflr %s\n", reg_names[0]);
12012 if (flag_pic == 1)
12013 {
dfdfa60f 12014 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12015 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12016 reg_names[0], save_lr, reg_names[1]);
17167fd8 12017 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12018 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12019 assemble_name (file, buf);
17167fd8 12020 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12021 }
9ebbca7d 12022 else if (flag_pic > 1)
38c1f2d7 12023 {
09eeeacb
AM
12024 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12025 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12026 /* Now, we need to get the address of the label. */
12027 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12028 assemble_name (file, buf);
9ebbca7d
GK
12029 fputs ("-.\n1:", file);
12030 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12031 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12032 reg_names[0], reg_names[11]);
12033 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12034 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12035 }
38c1f2d7
MM
12036 else
12037 {
17167fd8 12038 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12039 assemble_name (file, buf);
dfdfa60f 12040 fputs ("@ha\n", file);
09eeeacb
AM
12041 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12042 reg_names[0], save_lr, reg_names[1]);
a260abc9 12043 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12044 assemble_name (file, buf);
17167fd8 12045 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12046 }
12047
09eeeacb
AM
12048 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12049 {
12050 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12051 reg_names[STATIC_CHAIN_REGNUM],
12052 12, reg_names[1]);
12053 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12054 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12055 reg_names[STATIC_CHAIN_REGNUM],
12056 12, reg_names[1]);
12057 }
12058 else
12059 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12060 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12061 break;
12062
12063 case ABI_AIX:
ee890fe2 12064 case ABI_DARWIN:
a4f6c312 12065 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7
MM
12066 break;
12067 }
e165f3f0 12068}
a251ffd0
TG
12069
12070/* Adjust the cost of a scheduling dependency. Return the new cost of
12071 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12072
c237e94a 12073static int
a06faf84 12074rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12075 rtx insn;
12076 rtx link;
296b8152 12077 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12078 int cost;
12079{
12080 if (! recog_memoized (insn))
12081 return 0;
12082
12083 if (REG_NOTE_KIND (link) != 0)
12084 return 0;
12085
12086 if (REG_NOTE_KIND (link) == 0)
12087 {
ed947a96
DJ
12088 /* Data dependency; DEP_INSN writes a register that INSN reads
12089 some cycles later. */
12090 switch (get_attr_type (insn))
12091 {
12092 case TYPE_JMPREG:
309323c2 12093 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12094 a mtctr and bctr (and mtlr and br/blr). The first
12095 scheduling pass will not know about this latency since
12096 the mtctr instruction, which has the latency associated
12097 to it, will be generated by reload. */
309323c2 12098 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12099 case TYPE_BRANCH:
12100 /* Leave some extra cycles between a compare and its
12101 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12102 if ((rs6000_cpu_attr == CPU_PPC603
12103 || rs6000_cpu_attr == CPU_PPC604
12104 || rs6000_cpu_attr == CPU_PPC604E
12105 || rs6000_cpu_attr == CPU_PPC620
12106 || rs6000_cpu_attr == CPU_PPC630
12107 || rs6000_cpu_attr == CPU_PPC750
12108 || rs6000_cpu_attr == CPU_PPC7400
12109 || rs6000_cpu_attr == CPU_PPC7450
12110 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12111 && recog_memoized (dep_insn)
12112 && (INSN_CODE (dep_insn) >= 0)
12113 && (get_attr_type (dep_insn) == TYPE_COMPARE
12114 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12115 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
12116 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
12117 return cost + 2;
12118 default:
12119 break;
12120 }
a251ffd0
TG
12121 /* Fall out to return default cost. */
12122 }
12123
12124 return cost;
12125}
b6c9286a 12126
a4f6c312
SS
12127/* A C statement (sans semicolon) to update the integer scheduling
12128 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12129 INSN earlier, increase the priority to execute INSN later. Do not
12130 define this macro if you do not need to adjust the scheduling
12131 priorities of insns. */
bef84347 12132
c237e94a 12133static int
bef84347 12134rs6000_adjust_priority (insn, priority)
d330fd93 12135 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12136 int priority;
12137{
a4f6c312
SS
12138 /* On machines (like the 750) which have asymmetric integer units,
12139 where one integer unit can do multiply and divides and the other
12140 can't, reduce the priority of multiply/divide so it is scheduled
12141 before other integer operations. */
bef84347
VM
12142
12143#if 0
2c3c49de 12144 if (! INSN_P (insn))
bef84347
VM
12145 return priority;
12146
12147 if (GET_CODE (PATTERN (insn)) == USE)
12148 return priority;
12149
12150 switch (rs6000_cpu_attr) {
12151 case CPU_PPC750:
12152 switch (get_attr_type (insn))
12153 {
12154 default:
12155 break;
12156
12157 case TYPE_IMUL:
12158 case TYPE_IDIV:
3cb999d8
DE
12159 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12160 priority, priority);
bef84347
VM
12161 if (priority >= 0 && priority < 0x01000000)
12162 priority >>= 3;
12163 break;
12164 }
12165 }
12166#endif
12167
12168 return priority;
12169}
12170
a4f6c312
SS
12171/* Return how many instructions the machine can issue per cycle. */
12172
c237e94a
ZW
12173static int
12174rs6000_issue_rate ()
b6c9286a
MM
12175{
12176 switch (rs6000_cpu_attr) {
3cb999d8
DE
12177 case CPU_RIOS1: /* ? */
12178 case CPU_RS64A:
12179 case CPU_PPC601: /* ? */
ed947a96 12180 case CPU_PPC7450:
3cb999d8 12181 return 3;
b6c9286a 12182 case CPU_PPC603:
bef84347 12183 case CPU_PPC750:
ed947a96 12184 case CPU_PPC7400:
bef84347 12185 return 2;
3cb999d8 12186 case CPU_RIOS2:
b6c9286a 12187 case CPU_PPC604:
19684119 12188 case CPU_PPC604E:
b6c9286a 12189 case CPU_PPC620:
3cb999d8 12190 case CPU_PPC630:
309323c2 12191 case CPU_POWER4:
b6c9286a
MM
12192 return 4;
12193 default:
12194 return 1;
12195 }
12196}
12197
b6c9286a 12198\f
b6c9286a
MM
12199/* Length in units of the trampoline for entering a nested function. */
12200
12201int
12202rs6000_trampoline_size ()
12203{
12204 int ret = 0;
12205
12206 switch (DEFAULT_ABI)
12207 {
12208 default:
12209 abort ();
12210
12211 case ABI_AIX:
8f802bfb 12212 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12213 break;
12214
4dabc42d 12215 case ABI_DARWIN:
b6c9286a
MM
12216 case ABI_V4:
12217 case ABI_AIX_NODESC:
03a7e1a5 12218 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12219 break;
b6c9286a
MM
12220 }
12221
12222 return ret;
12223}
12224
12225/* Emit RTL insns to initialize the variable parts of a trampoline.
12226 FNADDR is an RTX for the address of the function's pure code.
12227 CXT is an RTX for the static chain value for the function. */
12228
12229void
12230rs6000_initialize_trampoline (addr, fnaddr, cxt)
12231 rtx addr;
12232 rtx fnaddr;
12233 rtx cxt;
12234{
ac2a93a1 12235 enum machine_mode pmode = Pmode;
8bd04c56
MM
12236 int regsize = (TARGET_32BIT) ? 4 : 8;
12237 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12238
12239 switch (DEFAULT_ABI)
12240 {
12241 default:
12242 abort ();
12243
8bd04c56 12244/* Macros to shorten the code expansions below. */
39403d82 12245#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12246#define MEM_PLUS(addr,offset) \
12247 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12248
b6c9286a
MM
12249 /* Under AIX, just build the 3 word function descriptor */
12250 case ABI_AIX:
8bd04c56
MM
12251 {
12252 rtx fn_reg = gen_reg_rtx (pmode);
12253 rtx toc_reg = gen_reg_rtx (pmode);
12254 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12255 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12256 emit_move_insn (MEM_DEREF (addr), fn_reg);
12257 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12258 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12259 }
b6c9286a
MM
12260 break;
12261
4dabc42d
TC
12262 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12263 case ABI_DARWIN:
b6c9286a
MM
12264 case ABI_V4:
12265 case ABI_AIX_NODESC:
39403d82 12266 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12267 FALSE, VOIDmode, 4,
12268 addr, pmode,
12269 GEN_INT (rs6000_trampoline_size ()), SImode,
12270 fnaddr, pmode,
12271 ctx_reg, pmode);
b6c9286a 12272 break;
b6c9286a
MM
12273 }
12274
12275 return;
12276}
7509c759
MM
12277
12278\f
91d231cb 12279/* Table of valid machine attributes. */
a4f6c312 12280
91d231cb 12281const struct attribute_spec rs6000_attribute_table[] =
7509c759 12282{
91d231cb 12283 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12284 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12285 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12286 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12287};
7509c759 12288
a5c76ee6
ZW
12289/* Handle a "longcall" or "shortcall" attribute; arguments as in
12290 struct attribute_spec.handler. */
a4f6c312 12291
91d231cb
JM
12292static tree
12293rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12294 tree *node;
12295 tree name;
12296 tree args ATTRIBUTE_UNUSED;
12297 int flags ATTRIBUTE_UNUSED;
12298 bool *no_add_attrs;
12299{
12300 if (TREE_CODE (*node) != FUNCTION_TYPE
12301 && TREE_CODE (*node) != FIELD_DECL
12302 && TREE_CODE (*node) != TYPE_DECL)
12303 {
12304 warning ("`%s' attribute only applies to functions",
12305 IDENTIFIER_POINTER (name));
12306 *no_add_attrs = true;
12307 }
6a4cee5f 12308
91d231cb 12309 return NULL_TREE;
7509c759
MM
12310}
12311
a5c76ee6
ZW
12312/* Set longcall attributes on all functions declared when
12313 rs6000_default_long_calls is true. */
12314static void
12315rs6000_set_default_type_attributes (type)
12316 tree type;
12317{
12318 if (rs6000_default_long_calls
12319 && (TREE_CODE (type) == FUNCTION_TYPE
12320 || TREE_CODE (type) == METHOD_TYPE))
12321 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12322 NULL_TREE,
12323 TYPE_ATTRIBUTES (type));
12324}
12325
3cb999d8
DE
12326/* Return a reference suitable for calling a function with the
12327 longcall attribute. */
a4f6c312 12328
6a4cee5f
MM
12329struct rtx_def *
12330rs6000_longcall_ref (call_ref)
12331 rtx call_ref;
12332{
d330fd93 12333 const char *call_name;
6a4cee5f
MM
12334 tree node;
12335
12336 if (GET_CODE (call_ref) != SYMBOL_REF)
12337 return call_ref;
12338
12339 /* System V adds '.' to the internal name, so skip them. */
12340 call_name = XSTR (call_ref, 0);
12341 if (*call_name == '.')
12342 {
12343 while (*call_name == '.')
12344 call_name++;
12345
12346 node = get_identifier (call_name);
39403d82 12347 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12348 }
12349
12350 return force_reg (Pmode, call_ref);
12351}
12352
7509c759 12353\f
b64a1b53
RH
12354#ifdef USING_ELFOS_H
12355
7509c759
MM
12356/* A C statement or statements to switch to the appropriate section
12357 for output of RTX in mode MODE. You can assume that RTX is some
12358 kind of constant in RTL. The argument MODE is redundant except in
12359 the case of a `const_int' rtx. Select the section by calling
12360 `text_section' or one of the alternatives for other sections.
12361
12362 Do not define this macro if you put all constants in the read-only
12363 data section. */
12364
b64a1b53
RH
12365static void
12366rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12367 enum machine_mode mode;
7509c759 12368 rtx x;
b64a1b53 12369 unsigned HOST_WIDE_INT align;
7509c759 12370{
a9098fd0 12371 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12372 toc_section ();
7509c759 12373 else
b64a1b53 12374 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12375}
12376
12377/* A C statement or statements to switch to the appropriate
12378 section for output of DECL. DECL is either a `VAR_DECL' node
12379 or a constant of some sort. RELOC indicates whether forming
12380 the initial value of DECL requires link-time relocations. */
12381
ae46c4e0
RH
12382static void
12383rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12384 tree decl;
12385 int reloc;
0e5dbd9b 12386 unsigned HOST_WIDE_INT align;
7509c759 12387{
0e5dbd9b
DE
12388 default_elf_select_section_1 (decl, reloc, align,
12389 flag_pic || DEFAULT_ABI == ABI_AIX);
63019373
GK
12390}
12391
12392/* A C statement to build up a unique section name, expressed as a
12393 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12394 RELOC indicates whether the initial value of EXP requires
12395 link-time relocations. If you do not define this macro, GCC will use
12396 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12397 macro can now be called for uninitialized data items as well as
4912a07c 12398 initialized data and functions. */
63019373 12399
ae46c4e0
RH
12400static void
12401rs6000_elf_unique_section (decl, reloc)
63019373
GK
12402 tree decl;
12403 int reloc;
12404{
0e5dbd9b
DE
12405 default_unique_section_1 (decl, reloc,
12406 flag_pic || DEFAULT_ABI == ABI_AIX);
7509c759 12407}
d9407988
MM
12408
12409\f
d9407988
MM
12410/* If we are referencing a function that is static or is known to be
12411 in this file, make the SYMBOL_REF special. We can use this to indicate
12412 that we can branch to this function without emitting a no-op after the
9ebbca7d 12413 call. For real AIX calling sequences, we also replace the
d9407988
MM
12414 function name with the real name (1 or 2 leading .'s), rather than
12415 the function descriptor name. This saves a lot of overriding code
a260abc9 12416 to read the prefixes. */
d9407988 12417
fb49053f
RH
12418static void
12419rs6000_elf_encode_section_info (decl, first)
d9407988 12420 tree decl;
b2003250 12421 int first;
d9407988 12422{
b2003250
RH
12423 if (!first)
12424 return;
12425
d9407988
MM
12426 if (TREE_CODE (decl) == FUNCTION_DECL)
12427 {
12428 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
b629ba0c 12429 if ((*targetm.binds_local_p) (decl))
d9407988
MM
12430 SYMBOL_REF_FLAG (sym_ref) = 1;
12431
9ebbca7d 12432 if (DEFAULT_ABI == ABI_AIX)
d9407988 12433 {
ff669a6c
RH
12434 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12435 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12436 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12437 str[0] = '.';
12438 str[1] = '.';
12439 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12440
520a57c8 12441 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12442 }
12443 }
12444 else if (rs6000_sdata != SDATA_NONE
f607bc57 12445 && DEFAULT_ABI == ABI_V4
d9407988
MM
12446 && TREE_CODE (decl) == VAR_DECL)
12447 {
12448 int size = int_size_in_bytes (TREE_TYPE (decl));
12449 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12450 const char *name = (char *)0;
d9407988
MM
12451 int len = 0;
12452
12453 if (section_name)
12454 {
12455 if (TREE_CODE (section_name) == STRING_CST)
12456 {
12457 name = TREE_STRING_POINTER (section_name);
12458 len = TREE_STRING_LENGTH (section_name);
12459 }
12460 else
12461 abort ();
12462 }
12463
12464 if ((size > 0 && size <= g_switch_value)
12465 || (name
5f59ecb7 12466 && ((len == sizeof (".sdata") - 1
3cb999d8 12467 && strcmp (name, ".sdata") == 0)
5f59ecb7 12468 || (len == sizeof (".sdata2") - 1
3cb999d8 12469 && strcmp (name, ".sdata2") == 0)
5f59ecb7 12470 || (len == sizeof (".sbss") - 1
3cb999d8 12471 && strcmp (name, ".sbss") == 0)
5f59ecb7 12472 || (len == sizeof (".sbss2") - 1
3cb999d8 12473 && strcmp (name, ".sbss2") == 0)
5f59ecb7 12474 || (len == sizeof (".PPC.EMB.sdata0") - 1
3cb999d8 12475 && strcmp (name, ".PPC.EMB.sdata0") == 0)
5f59ecb7 12476 || (len == sizeof (".PPC.EMB.sbss0") - 1
3cb999d8 12477 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d9407988
MM
12478 {
12479 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
ff669a6c 12480 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 12481 char *str = alloca (len + 2);
ff669a6c 12482
ff669a6c
RH
12483 str[0] = '@';
12484 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 12485 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
12486 }
12487 }
12488}
12489
772c5265
RH
12490static const char *
12491rs6000_elf_strip_name_encoding (str)
12492 const char *str;
12493{
12494 while (*str == '*' || *str == '@')
12495 str++;
12496 return str;
12497}
12498
0e5dbd9b
DE
12499static bool
12500rs6000_elf_in_small_data_p (decl)
12501 tree decl;
12502{
12503 if (rs6000_sdata == SDATA_NONE)
12504 return false;
12505
12506 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
12507 {
12508 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
12509 if (strcmp (section, ".sdata") == 0
12510 || strcmp (section, ".sdata2") == 0
12511 || strcmp (section, ".sbss") == 0)
12512 return true;
12513 }
12514 else
12515 {
12516 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
12517
12518 if (size > 0
12519 && size <= g_switch_value
12520 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
12521 return true;
12522 }
12523
12524 return false;
12525}
12526
b91da81f 12527#endif /* USING_ELFOS_H */
000034eb 12528
a6c2a102 12529\f
000034eb 12530/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
12531 ADDR can be effectively incremented by incrementing REG.
12532
12533 r0 is special and we must not select it as an address
12534 register by this routine since our caller will try to
12535 increment the returned register via an "la" instruction. */
000034eb
DE
12536
12537struct rtx_def *
12538find_addr_reg (addr)
12539 rtx addr;
12540{
12541 while (GET_CODE (addr) == PLUS)
12542 {
02441cd6
JL
12543 if (GET_CODE (XEXP (addr, 0)) == REG
12544 && REGNO (XEXP (addr, 0)) != 0)
000034eb 12545 addr = XEXP (addr, 0);
02441cd6
JL
12546 else if (GET_CODE (XEXP (addr, 1)) == REG
12547 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
12548 addr = XEXP (addr, 1);
12549 else if (CONSTANT_P (XEXP (addr, 0)))
12550 addr = XEXP (addr, 1);
12551 else if (CONSTANT_P (XEXP (addr, 1)))
12552 addr = XEXP (addr, 0);
12553 else
12554 abort ();
12555 }
02441cd6 12556 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
12557 return addr;
12558 abort ();
12559}
12560
a6c2a102
DE
12561void
12562rs6000_fatal_bad_address (op)
12563 rtx op;
12564{
12565 fatal_insn ("bad address", op);
12566}
c8023011
MM
12567
12568/* Called to register all of our global variables with the garbage
12569 collector. */
12570
12571static void
12572rs6000_add_gc_roots ()
12573{
9ebbca7d
GK
12574 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
12575 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
12576 toc_hash_mark_table);
ee890fe2
SS
12577}
12578
12579#if TARGET_MACHO
12580
12581#if 0
12582/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12583 reference and a constant. */
12584
12585int
12586symbolic_operand (op)
592696dd 12587 rtx op;
ee890fe2
SS
12588{
12589 switch (GET_CODE (op))
12590 {
12591 case SYMBOL_REF:
12592 case LABEL_REF:
12593 return 1;
12594 case CONST:
12595 op = XEXP (op, 0);
12596 return (GET_CODE (op) == SYMBOL_REF ||
12597 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12598 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12599 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12600 default:
12601 return 0;
12602 }
c8023011 12603}
ee890fe2
SS
12604#endif
12605
12606#ifdef RS6000_LONG_BRANCH
12607
12608static tree stub_list = 0;
12609
12610/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12611 procedure calls to the linked list. */
12612
12613void
12614add_compiler_stub (label_name, function_name, line_number)
12615 tree label_name;
12616 tree function_name;
12617 int line_number;
12618{
12619 tree stub = build_tree_list (function_name, label_name);
12620 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12621 TREE_CHAIN (stub) = stub_list;
12622 stub_list = stub;
12623}
12624
12625#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12626#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12627#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12628
a4f6c312
SS
12629/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12630 handling procedure calls from the linked list and initializes the
12631 linked list. */
ee890fe2 12632
a4f6c312
SS
12633void
12634output_compiler_stub ()
ee890fe2
SS
12635{
12636 char tmp_buf[256];
12637 char label_buf[256];
308c142a 12638 tree stub;
ee890fe2
SS
12639
12640 if (!flag_pic)
12641 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12642 {
12643 fprintf (asm_out_file,
12644 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12645
12646#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12647 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12648 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12649#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12650
12651 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12652 strcpy (label_buf,
12653 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12654 else
12655 {
12656 label_buf[0] = '_';
12657 strcpy (label_buf+1,
12658 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12659 }
12660
12661 strcpy (tmp_buf, "lis r12,hi16(");
12662 strcat (tmp_buf, label_buf);
12663 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12664 strcat (tmp_buf, label_buf);
12665 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12666 output_asm_insn (tmp_buf, 0);
12667
12668#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12669 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12670 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12671#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12672 }
12673
12674 stub_list = 0;
12675}
12676
12677/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12678 already there or not. */
12679
a4f6c312
SS
12680int
12681no_previous_def (function_name)
ee890fe2
SS
12682 tree function_name;
12683{
12684 tree stub;
12685 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12686 if (function_name == STUB_FUNCTION_NAME (stub))
12687 return 0;
12688 return 1;
12689}
12690
12691/* GET_PREV_LABEL gets the label name from the previous definition of
12692 the function. */
12693
a4f6c312
SS
12694tree
12695get_prev_label (function_name)
ee890fe2
SS
12696 tree function_name;
12697{
12698 tree stub;
12699 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12700 if (function_name == STUB_FUNCTION_NAME (stub))
12701 return STUB_LABEL_NAME (stub);
12702 return 0;
12703}
12704
12705/* INSN is either a function call or a millicode call. It may have an
12706 unconditional jump in its delay slot.
12707
12708 CALL_DEST is the routine we are calling. */
12709
12710char *
12711output_call (insn, call_dest, operand_number)
12712 rtx insn;
12713 rtx call_dest;
12714 int operand_number;
12715{
12716 static char buf[256];
12717 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
12718 {
12719 tree labelname;
12720 tree funname = get_identifier (XSTR (call_dest, 0));
12721
12722 if (no_previous_def (funname))
12723 {
308c142a 12724 int line_number = 0;
ee890fe2
SS
12725 rtx label_rtx = gen_label_rtx ();
12726 char *label_buf, temp_buf[256];
12727 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
12728 CODE_LABEL_NUMBER (label_rtx));
12729 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
12730 labelname = get_identifier (label_buf);
12731 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
12732 if (insn)
12733 line_number = NOTE_LINE_NUMBER (insn);
12734 add_compiler_stub (labelname, funname, line_number);
12735 }
12736 else
12737 labelname = get_prev_label (funname);
12738
12739 sprintf (buf, "jbsr %%z%d,%.246s",
12740 operand_number, IDENTIFIER_POINTER (labelname));
12741 return buf;
12742 }
12743 else
12744 {
12745 sprintf (buf, "bl %%z%d", operand_number);
12746 return buf;
12747 }
12748}
12749
12750#endif /* RS6000_LONG_BRANCH */
12751
12752#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
12753 do { \
83182544 12754 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
12755 char *buffer_ = (BUF); \
12756 if (symbol_[0] == '"') \
12757 { \
12758 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
12759 } \
12760 else if (name_needs_quotes(symbol_)) \
12761 { \
12762 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
12763 } \
12764 else \
12765 { \
12766 sprintf(buffer_, "L%d$%s", (N), symbol_); \
12767 } \
12768 } while (0)
12769
12770
12771/* Generate PIC and indirect symbol stubs. */
12772
12773void
12774machopic_output_stub (file, symb, stub)
12775 FILE *file;
12776 const char *symb, *stub;
12777{
12778 unsigned int length;
a4f6c312
SS
12779 char *symbol_name, *lazy_ptr_name;
12780 char *local_label_0;
ee890fe2
SS
12781 static int label = 0;
12782
df56a27f 12783 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 12784 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 12785
ee890fe2
SS
12786 label += 1;
12787
ee890fe2
SS
12788 length = strlen (symb);
12789 symbol_name = alloca (length + 32);
12790 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
12791
12792 lazy_ptr_name = alloca (length + 32);
12793 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
12794
12795 local_label_0 = alloca (length + 32);
12796 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
12797
ee890fe2
SS
12798 if (flag_pic == 2)
12799 machopic_picsymbol_stub_section ();
12800 else
12801 machopic_symbol_stub_section ();
12802
12803 fprintf (file, "%s:\n", stub);
12804 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12805
12806 if (flag_pic == 2)
12807 {
12808 fprintf (file, "\tmflr r0\n");
12809 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
12810 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
12811 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
12812 lazy_ptr_name, local_label_0);
12813 fprintf (file, "\tmtlr r0\n");
12814 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
12815 lazy_ptr_name, local_label_0);
12816 fprintf (file, "\tmtctr r12\n");
12817 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
12818 lazy_ptr_name, local_label_0);
12819 fprintf (file, "\tbctr\n");
12820 }
12821 else
12822 fprintf (file, "non-pure not supported\n");
12823
12824 machopic_lazy_symbol_ptr_section ();
12825 fprintf (file, "%s:\n", lazy_ptr_name);
12826 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12827 fprintf (file, "\t.long dyld_stub_binding_helper\n");
12828}
12829
12830/* Legitimize PIC addresses. If the address is already
12831 position-independent, we return ORIG. Newly generated
12832 position-independent addresses go into a reg. This is REG if non
12833 zero, otherwise we allocate register(s) as necessary. */
12834
c859cda6 12835#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
12836
12837rtx
12838rs6000_machopic_legitimize_pic_address (orig, mode, reg)
12839 rtx orig;
12840 enum machine_mode mode;
12841 rtx reg;
12842{
12843 rtx base, offset;
12844
12845 if (reg == NULL && ! reload_in_progress && ! reload_completed)
12846 reg = gen_reg_rtx (Pmode);
12847
12848 if (GET_CODE (orig) == CONST)
12849 {
12850 if (GET_CODE (XEXP (orig, 0)) == PLUS
12851 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
12852 return orig;
12853
12854 if (GET_CODE (XEXP (orig, 0)) == PLUS)
12855 {
a4f6c312
SS
12856 base =
12857 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
12858 Pmode, reg);
12859 offset =
12860 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
12861 Pmode, reg);
ee890fe2
SS
12862 }
12863 else
12864 abort ();
12865
12866 if (GET_CODE (offset) == CONST_INT)
12867 {
12868 if (SMALL_INT (offset))
ed8908e7 12869 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
12870 else if (! reload_in_progress && ! reload_completed)
12871 offset = force_reg (Pmode, offset);
12872 else
c859cda6
DJ
12873 {
12874 rtx mem = force_const_mem (Pmode, orig);
12875 return machopic_legitimize_pic_address (mem, Pmode, reg);
12876 }
ee890fe2
SS
12877 }
12878 return gen_rtx (PLUS, Pmode, base, offset);
12879 }
12880
12881 /* Fall back on generic machopic code. */
12882 return machopic_legitimize_pic_address (orig, mode, reg);
12883}
12884
12885/* This is just a placeholder to make linking work without having to
12886 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
12887 ever needed for Darwin (not too likely!) this would have to get a
12888 real definition. */
12889
12890void
12891toc_section ()
12892{
12893}
12894
12895#endif /* TARGET_MACHO */
7c262518
RH
12896
12897#if TARGET_ELF
12898static unsigned int
12899rs6000_elf_section_type_flags (decl, name, reloc)
12900 tree decl;
12901 const char *name;
12902 int reloc;
12903{
5add3202
DE
12904 unsigned int flags
12905 = default_section_type_flags_1 (decl, name, reloc,
12906 flag_pic || DEFAULT_ABI == ABI_AIX);
7c262518 12907
270fc29b
RH
12908 if (TARGET_RELOCATABLE)
12909 flags |= SECTION_WRITE;
7c262518 12910
d0101753 12911 return flags;
7c262518 12912}
d9f6800d
RH
12913
12914/* Record an element in the table of global constructors. SYMBOL is
12915 a SYMBOL_REF of the function to be called; PRIORITY is a number
12916 between 0 and MAX_INIT_PRIORITY.
12917
12918 This differs from default_named_section_asm_out_constructor in
12919 that we have special handling for -mrelocatable. */
12920
12921static void
12922rs6000_elf_asm_out_constructor (symbol, priority)
12923 rtx symbol;
12924 int priority;
12925{
12926 const char *section = ".ctors";
12927 char buf[16];
12928
12929 if (priority != DEFAULT_INIT_PRIORITY)
12930 {
12931 sprintf (buf, ".ctors.%.5u",
12932 /* Invert the numbering so the linker puts us in the proper
12933 order; constructors are run from right to left, and the
12934 linker sorts in increasing order. */
12935 MAX_INIT_PRIORITY - priority);
12936 section = buf;
12937 }
12938
715bdd29
RH
12939 named_section_flags (section, SECTION_WRITE);
12940 assemble_align (POINTER_SIZE);
d9f6800d
RH
12941
12942 if (TARGET_RELOCATABLE)
12943 {
12944 fputs ("\t.long (", asm_out_file);
12945 output_addr_const (asm_out_file, symbol);
12946 fputs (")@fixup\n", asm_out_file);
12947 }
12948 else
c8af3574 12949 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
12950}
12951
12952static void
12953rs6000_elf_asm_out_destructor (symbol, priority)
12954 rtx symbol;
12955 int priority;
12956{
12957 const char *section = ".dtors";
12958 char buf[16];
12959
12960 if (priority != DEFAULT_INIT_PRIORITY)
12961 {
12962 sprintf (buf, ".dtors.%.5u",
12963 /* Invert the numbering so the linker puts us in the proper
12964 order; constructors are run from right to left, and the
12965 linker sorts in increasing order. */
12966 MAX_INIT_PRIORITY - priority);
12967 section = buf;
12968 }
12969
715bdd29
RH
12970 named_section_flags (section, SECTION_WRITE);
12971 assemble_align (POINTER_SIZE);
d9f6800d
RH
12972
12973 if (TARGET_RELOCATABLE)
12974 {
12975 fputs ("\t.long (", asm_out_file);
12976 output_addr_const (asm_out_file, symbol);
12977 fputs (")@fixup\n", asm_out_file);
12978 }
12979 else
c8af3574 12980 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 12981}
7c262518
RH
12982#endif
12983
cbaaba19 12984#if TARGET_XCOFF
7c262518 12985static void
b275d088
DE
12986rs6000_xcoff_asm_globalize_label (stream, name)
12987 FILE *stream;
12988 const char *name;
12989{
12990 fputs (GLOBAL_ASM_OP, stream);
12991 RS6000_OUTPUT_BASENAME (stream, name);
12992 putc ('\n', stream);
12993}
12994
12995static void
12996rs6000_xcoff_asm_named_section (name, flags)
7c262518 12997 const char *name;
0e5dbd9b 12998 unsigned int flags;
7c262518 12999{
0e5dbd9b
DE
13000 int smclass;
13001 static const char * const suffix[3] = { "PR", "RO", "RW" };
13002
13003 if (flags & SECTION_CODE)
13004 smclass = 0;
13005 else if (flags & SECTION_WRITE)
13006 smclass = 2;
13007 else
13008 smclass = 1;
13009
5b5198f7 13010 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 13011 (flags & SECTION_CODE) ? "." : "",
5b5198f7 13012 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 13013}
ae46c4e0
RH
13014
13015static void
0e5dbd9b
DE
13016rs6000_xcoff_select_section (decl, reloc, align)
13017 tree decl;
ae46c4e0
RH
13018 int reloc;
13019 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13020{
5add3202 13021 if (decl_readonly_section_1 (decl, reloc, 1))
ae46c4e0 13022 {
0e5dbd9b 13023 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13024 read_only_data_section ();
13025 else
13026 read_only_private_data_section ();
13027 }
13028 else
13029 {
0e5dbd9b 13030 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13031 data_section ();
13032 else
13033 private_data_section ();
13034 }
13035}
13036
13037static void
13038rs6000_xcoff_unique_section (decl, reloc)
13039 tree decl;
772c5265 13040 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13041{
13042 const char *name;
ae46c4e0 13043
5b5198f7
DE
13044 /* Use select_section for private and uninitialized data. */
13045 if (!TREE_PUBLIC (decl)
13046 || DECL_COMMON (decl)
0e5dbd9b
DE
13047 || DECL_INITIAL (decl) == NULL_TREE
13048 || DECL_INITIAL (decl) == error_mark_node
13049 || (flag_zero_initialized_in_bss
13050 && initializer_zerop (DECL_INITIAL (decl))))
13051 return;
13052
13053 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13054 name = (*targetm.strip_name_encoding) (name);
13055 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 13056}
b64a1b53 13057
fb49053f
RH
13058/* Select section for constant in constant pool.
13059
13060 On RS/6000, all constants are in the private read-only data area.
13061 However, if this is being placed in the TOC it must be output as a
13062 toc entry. */
13063
b64a1b53
RH
13064static void
13065rs6000_xcoff_select_rtx_section (mode, x, align)
13066 enum machine_mode mode;
13067 rtx x;
13068 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13069{
13070 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13071 toc_section ();
13072 else
13073 read_only_private_data_section ();
13074}
772c5265
RH
13075
13076/* Remove any trailing [DS] or the like from the symbol name. */
13077
13078static const char *
13079rs6000_xcoff_strip_name_encoding (name)
13080 const char *name;
13081{
13082 size_t len;
13083 if (*name == '*')
13084 name++;
13085 len = strlen (name);
13086 if (name[len - 1] == ']')
13087 return ggc_alloc_string (name, len - 4);
13088 else
13089 return name;
13090}
13091
5add3202
DE
13092/* Section attributes. AIX is always PIC. */
13093
13094static unsigned int
13095rs6000_xcoff_section_type_flags (decl, name, reloc)
13096 tree decl;
13097 const char *name;
13098 int reloc;
13099{
5b5198f7
DE
13100 unsigned int align;
13101 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
13102
13103 /* Align to at least UNIT size. */
13104 if (flags & SECTION_CODE)
13105 align = MIN_UNITS_PER_WORD;
13106 else
13107 /* Increase alignment of large objects if not already stricter. */
13108 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
13109 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
13110 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
13111
13112 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202
DE
13113}
13114
cbaaba19 13115#endif /* TARGET_XCOFF */
fb49053f 13116
0e5dbd9b 13117/* Note that this is also used for PPC64 Linux. */
fb49053f
RH
13118
13119static void
13120rs6000_xcoff_encode_section_info (decl, first)
13121 tree decl;
13122 int first ATTRIBUTE_UNUSED;
13123{
13124 if (TREE_CODE (decl) == FUNCTION_DECL
b629ba0c 13125 && (*targetm.binds_local_p) (decl))
fb49053f
RH
13126 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13127}
0e5dbd9b
DE
13128
13129/* Cross-module name binding. For AIX and PPC64 Linux, which always are
13130 PIC, use private copy of flag_pic. */
13131
2bcc50d0 13132static bool
0e5dbd9b
DE
13133rs6000_binds_local_p (decl)
13134 tree decl;
13135{
5add3202 13136 return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
0e5dbd9b 13137}