]> 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
a0ab749a 95/* Set to nonzero once AIX common-mode calls have been defined. */
c764f757 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
c72bfda7
SS
593 /* For Darwin, always silently make -fpic and -fPIC identical. */
594 if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN)
595 flag_pic = 2;
596
38c1f2d7
MM
597 /* Set debug flags */
598 if (rs6000_debug_name)
599 {
bfc79d3b 600 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 601 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 602 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 603 rs6000_debug_stack = 1;
bfc79d3b 604 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
605 rs6000_debug_arg = 1;
606 else
c725bd79 607 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
608 }
609
57ac7be9
AM
610 if (rs6000_traceback_name)
611 {
612 if (! strncmp (rs6000_traceback_name, "full", 4))
613 rs6000_traceback = traceback_full;
614 else if (! strncmp (rs6000_traceback_name, "part", 4))
615 rs6000_traceback = traceback_part;
616 else if (! strncmp (rs6000_traceback_name, "no", 2))
617 rs6000_traceback = traceback_none;
618 else
619 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
620 rs6000_traceback_name);
621 }
622
6fa3f289
ZW
623 /* Set size of long double */
624 rs6000_long_double_type_size = 64;
625 if (rs6000_long_double_size_string)
626 {
627 char *tail;
628 int size = strtol (rs6000_long_double_size_string, &tail, 10);
629 if (*tail != '\0' || (size != 64 && size != 128))
630 error ("Unknown switch -mlong-double-%s",
631 rs6000_long_double_size_string);
632 else
633 rs6000_long_double_type_size = size;
634 }
635
0ac081f6
AH
636 /* Handle -mabi= options. */
637 rs6000_parse_abi_options ();
638
08b57fb3
AH
639 /* Handle -mvrsave= option. */
640 rs6000_parse_vrsave_option ();
641
a3170dc6
AH
642 /* Handle -misel= option. */
643 rs6000_parse_isel_option ();
644
a7ae18e2
AH
645#ifdef SUBTARGET_OVERRIDE_OPTIONS
646 SUBTARGET_OVERRIDE_OPTIONS;
647#endif
648#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
649 SUBSUBTARGET_OVERRIDE_OPTIONS;
650#endif
651
a5c76ee6
ZW
652 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
653 using TARGET_OPTIONS to handle a toggle switch, but we're out of
654 bits in target_flags so TARGET_SWITCHES cannot be used.
655 Assumption here is that rs6000_longcall_switch points into the
656 text of the complete option, rather than being a copy, so we can
657 scan back for the presence or absence of the no- modifier. */
658 if (rs6000_longcall_switch)
659 {
660 const char *base = rs6000_longcall_switch;
661 while (base[-1] != 'm') base--;
662
663 if (*rs6000_longcall_switch != '\0')
664 error ("invalid option `%s'", base);
665 rs6000_default_long_calls = (base[0] != 'n');
666 }
667
c81bebd7 668#ifdef TARGET_REGNAMES
a4f6c312
SS
669 /* If the user desires alternate register names, copy in the
670 alternate names now. */
c81bebd7 671 if (TARGET_REGNAMES)
4e135bdd 672 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
673#endif
674
6fa3f289
ZW
675 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
676 If -maix-struct-return or -msvr4-struct-return was explicitly
677 used, don't override with the ABI default. */
678 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
679 {
680 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
681 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
682 else
683 target_flags |= MASK_AIX_STRUCT_RET;
684 }
685
fcce224d
DE
686 if (TARGET_LONG_DOUBLE_128
687 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
688 real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
689
c8023011
MM
690 /* Register global variables with the garbage collector. */
691 rs6000_add_gc_roots ();
9ebbca7d
GK
692
693 /* Allocate an alias set for register saves & restores from stack. */
694 rs6000_sr_alias_set = new_alias_set ();
695
696 if (TARGET_TOC)
697 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 698
301d03af
RS
699 /* We can only guarantee the availability of DI pseudo-ops when
700 assembling for 64-bit targets. */
ae6c1efd 701 if (!TARGET_64BIT)
301d03af
RS
702 {
703 targetm.asm_out.aligned_op.di = NULL;
704 targetm.asm_out.unaligned_op.di = NULL;
705 }
706
71f123ca
FS
707 /* Arrange to save and restore machine status around nested functions. */
708 init_machine_status = rs6000_init_machine_status;
5248c961 709}
5accd822 710
a3170dc6
AH
711/* Handle -misel= option. */
712static void
713rs6000_parse_isel_option ()
714{
715 if (rs6000_isel_string == 0)
716 return;
717 else if (! strcmp (rs6000_isel_string, "yes"))
718 rs6000_isel = 1;
719 else if (! strcmp (rs6000_isel_string, "no"))
720 rs6000_isel = 0;
721 else
722 error ("unknown -misel= option specified: '%s'",
723 rs6000_isel_string);
724}
725
08b57fb3
AH
726/* Handle -mvrsave= options. */
727static void
728rs6000_parse_vrsave_option ()
729{
730 /* Generate VRSAVE instructions by default. */
731 if (rs6000_altivec_vrsave_string == 0
732 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
733 rs6000_altivec_vrsave = 1;
734 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
735 rs6000_altivec_vrsave = 0;
736 else
737 error ("unknown -mvrsave= option specified: '%s'",
738 rs6000_altivec_vrsave_string);
739}
740
0ac081f6 741/* Handle -mabi= options. */
00b960c7
AH
742static void
743rs6000_parse_abi_options ()
0ac081f6
AH
744{
745 if (rs6000_abi_string == 0)
746 return;
747 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 748 rs6000_altivec_abi = 1;
76a773f3
AH
749 else if (! strcmp (rs6000_abi_string, "no-altivec"))
750 rs6000_altivec_abi = 0;
a3170dc6
AH
751 else if (! strcmp (rs6000_abi_string, "spe"))
752 rs6000_spe_abi = 1;
753 else if (! strcmp (rs6000_abi_string, "no-spe"))
754 rs6000_spe_abi = 0;
0ac081f6 755 else
c725bd79 756 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
757}
758
5accd822
DE
759void
760optimization_options (level, size)
e2c953b6 761 int level ATTRIBUTE_UNUSED;
5accd822
DE
762 int size ATTRIBUTE_UNUSED;
763{
5accd822 764}
3cfa4909
MM
765\f
766/* Do anything needed at the start of the asm file. */
767
768void
769rs6000_file_start (file, default_cpu)
770 FILE *file;
d330fd93 771 const char *default_cpu;
3cfa4909 772{
c4d38ccb 773 size_t i;
3cfa4909 774 char buffer[80];
d330fd93 775 const char *start = buffer;
3cfa4909
MM
776 struct rs6000_cpu_select *ptr;
777
778 if (flag_verbose_asm)
779 {
780 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
781 rs6000_select[0].string = default_cpu;
782
b6a1cbae 783 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
784 {
785 ptr = &rs6000_select[i];
786 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
787 {
788 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
789 start = "";
790 }
791 }
792
b91da81f 793#ifdef USING_ELFOS_H
3cfa4909
MM
794 switch (rs6000_sdata)
795 {
796 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
797 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
798 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
799 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
800 }
801
802 if (rs6000_sdata && g_switch_value)
803 {
804 fprintf (file, "%s -G %d", start, g_switch_value);
805 start = "";
806 }
807#endif
808
809 if (*start == '\0')
949ea356 810 putc ('\n', file);
3cfa4909
MM
811 }
812}
5248c961 813\f
a0ab749a 814/* Return nonzero if this function is known to have a null epilogue. */
9878760c
RK
815
816int
817direct_return ()
818{
4697a36c
MM
819 if (reload_completed)
820 {
821 rs6000_stack_t *info = rs6000_stack_info ();
822
823 if (info->first_gp_reg_save == 32
824 && info->first_fp_reg_save == 64
00b960c7 825 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
826 && ! info->lr_save_p
827 && ! info->cr_save_p
00b960c7 828 && info->vrsave_mask == 0
c81fc13e 829 && ! info->push_p)
4697a36c
MM
830 return 1;
831 }
832
833 return 0;
9878760c
RK
834}
835
836/* Returns 1 always. */
837
838int
839any_operand (op, mode)
592696dd 840 rtx op ATTRIBUTE_UNUSED;
296b8152 841 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
842{
843 return 1;
844}
845
a4f6c312 846/* Returns 1 if op is the count register. */
38c1f2d7 847int
a4f6c312 848count_register_operand (op, mode)
592696dd 849 rtx op;
296b8152 850 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
851{
852 if (GET_CODE (op) != REG)
853 return 0;
854
855 if (REGNO (op) == COUNT_REGISTER_REGNUM)
856 return 1;
857
858 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
859 return 1;
860
861 return 0;
862}
863
0ec4e2a8
AH
864/* Returns 1 if op is an altivec register. */
865int
866altivec_register_operand (op, mode)
867 rtx op;
868 enum machine_mode mode ATTRIBUTE_UNUSED;
869{
870
871 return (register_operand (op, mode)
872 && (GET_CODE (op) != REG
873 || REGNO (op) > FIRST_PSEUDO_REGISTER
874 || ALTIVEC_REGNO_P (REGNO (op))));
875}
876
38c1f2d7 877int
a4f6c312 878xer_operand (op, mode)
592696dd 879 rtx op;
296b8152 880 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
881{
882 if (GET_CODE (op) != REG)
883 return 0;
884
9ebbca7d 885 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
886 return 1;
887
802a0058
MM
888 return 0;
889}
890
c859cda6 891/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 892 by such constants completes more quickly. */
c859cda6
DJ
893
894int
895s8bit_cint_operand (op, mode)
896 rtx op;
897 enum machine_mode mode ATTRIBUTE_UNUSED;
898{
899 return ( GET_CODE (op) == CONST_INT
900 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
901}
902
9878760c
RK
903/* Return 1 if OP is a constant that can fit in a D field. */
904
905int
906short_cint_operand (op, mode)
592696dd 907 rtx op;
296b8152 908 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 909{
5f59ecb7
DE
910 return (GET_CODE (op) == CONST_INT
911 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
912}
913
5519a4f9 914/* Similar for an unsigned D field. */
9878760c
RK
915
916int
917u_short_cint_operand (op, mode)
592696dd 918 rtx op;
296b8152 919 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 920{
19684119 921 return (GET_CODE (op) == CONST_INT
c1f11548 922 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
923}
924
dcfedcd0
RK
925/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
926
927int
928non_short_cint_operand (op, mode)
592696dd 929 rtx op;
296b8152 930 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
931{
932 return (GET_CODE (op) == CONST_INT
a7653a2c 933 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
934}
935
2bfcf297
DB
936/* Returns 1 if OP is a CONST_INT that is a positive value
937 and an exact power of 2. */
938
939int
940exact_log2_cint_operand (op, mode)
592696dd 941 rtx op;
2bfcf297
DB
942 enum machine_mode mode ATTRIBUTE_UNUSED;
943{
944 return (GET_CODE (op) == CONST_INT
945 && INTVAL (op) > 0
946 && exact_log2 (INTVAL (op)) >= 0);
947}
948
9878760c
RK
949/* Returns 1 if OP is a register that is not special (i.e., not MQ,
950 ctr, or lr). */
951
952int
cd2b37d9 953gpc_reg_operand (op, mode)
592696dd 954 rtx op;
9878760c
RK
955 enum machine_mode mode;
956{
957 return (register_operand (op, mode)
802a0058 958 && (GET_CODE (op) != REG
9ebbca7d
GK
959 || (REGNO (op) >= ARG_POINTER_REGNUM
960 && !XER_REGNO_P (REGNO (op)))
961 || REGNO (op) < MQ_REGNO));
9878760c
RK
962}
963
964/* Returns 1 if OP is either a pseudo-register or a register denoting a
965 CR field. */
966
967int
968cc_reg_operand (op, mode)
592696dd 969 rtx op;
9878760c
RK
970 enum machine_mode mode;
971{
972 return (register_operand (op, mode)
973 && (GET_CODE (op) != REG
974 || REGNO (op) >= FIRST_PSEUDO_REGISTER
975 || CR_REGNO_P (REGNO (op))));
976}
977
815cdc52
MM
978/* Returns 1 if OP is either a pseudo-register or a register denoting a
979 CR field that isn't CR0. */
980
981int
982cc_reg_not_cr0_operand (op, mode)
592696dd 983 rtx op;
815cdc52
MM
984 enum machine_mode mode;
985{
986 return (register_operand (op, mode)
987 && (GET_CODE (op) != REG
988 || REGNO (op) >= FIRST_PSEUDO_REGISTER
989 || CR_REGNO_NOT_CR0_P (REGNO (op))));
990}
991
a4f6c312
SS
992/* Returns 1 if OP is either a constant integer valid for a D-field or
993 a non-special register. If a register, it must be in the proper
994 mode unless MODE is VOIDmode. */
9878760c
RK
995
996int
997reg_or_short_operand (op, mode)
592696dd 998 rtx op;
9878760c
RK
999 enum machine_mode mode;
1000{
f5a28898 1001 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1002}
1003
a4f6c312
SS
1004/* Similar, except check if the negation of the constant would be
1005 valid for a D-field. */
9878760c
RK
1006
1007int
1008reg_or_neg_short_operand (op, mode)
592696dd 1009 rtx op;
9878760c
RK
1010 enum machine_mode mode;
1011{
1012 if (GET_CODE (op) == CONST_INT)
1013 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1014
cd2b37d9 1015 return gpc_reg_operand (op, mode);
9878760c
RK
1016}
1017
768070a0
TR
1018/* Returns 1 if OP is either a constant integer valid for a DS-field or
1019 a non-special register. If a register, it must be in the proper
1020 mode unless MODE is VOIDmode. */
1021
1022int
1023reg_or_aligned_short_operand (op, mode)
1024 rtx op;
1025 enum machine_mode mode;
1026{
1027 if (gpc_reg_operand (op, mode))
1028 return 1;
1029 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1030 return 1;
1031
1032 return 0;
1033}
1034
1035
a4f6c312
SS
1036/* Return 1 if the operand is either a register or an integer whose
1037 high-order 16 bits are zero. */
9878760c
RK
1038
1039int
1040reg_or_u_short_operand (op, mode)
592696dd 1041 rtx op;
9878760c
RK
1042 enum machine_mode mode;
1043{
e675f625 1044 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1045}
1046
1047/* Return 1 is the operand is either a non-special register or ANY
1048 constant integer. */
1049
1050int
1051reg_or_cint_operand (op, mode)
592696dd 1052 rtx op;
9878760c
RK
1053 enum machine_mode mode;
1054{
a4f6c312 1055 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1056}
1057
1058/* Return 1 is the operand is either a non-special register or ANY
1059 32-bit signed constant integer. */
1060
1061int
1062reg_or_arith_cint_operand (op, mode)
592696dd 1063 rtx op;
f6bf7de2
DE
1064 enum machine_mode mode;
1065{
a4f6c312
SS
1066 return (gpc_reg_operand (op, mode)
1067 || (GET_CODE (op) == CONST_INT
f6bf7de2 1068#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1069 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1070 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1071#endif
a4f6c312 1072 ));
9878760c
RK
1073}
1074
2bfcf297
DB
1075/* Return 1 is the operand is either a non-special register or a 32-bit
1076 signed constant integer valid for 64-bit addition. */
1077
1078int
1079reg_or_add_cint64_operand (op, mode)
592696dd 1080 rtx op;
2bfcf297
DB
1081 enum machine_mode mode;
1082{
a4f6c312
SS
1083 return (gpc_reg_operand (op, mode)
1084 || (GET_CODE (op) == CONST_INT
a65c591c 1085#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1086 && INTVAL (op) < 0x7fff8000
a65c591c 1087#else
a4f6c312
SS
1088 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1089 < 0x100000000ll)
2bfcf297 1090#endif
a4f6c312 1091 ));
2bfcf297
DB
1092}
1093
1094/* Return 1 is the operand is either a non-special register or a 32-bit
1095 signed constant integer valid for 64-bit subtraction. */
1096
1097int
1098reg_or_sub_cint64_operand (op, mode)
592696dd 1099 rtx op;
2bfcf297
DB
1100 enum machine_mode mode;
1101{
a4f6c312
SS
1102 return (gpc_reg_operand (op, mode)
1103 || (GET_CODE (op) == CONST_INT
a65c591c 1104#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1105 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1106#else
a4f6c312
SS
1107 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1108 < 0x100000000ll)
2bfcf297 1109#endif
a4f6c312 1110 ));
2bfcf297
DB
1111}
1112
9ebbca7d
GK
1113/* Return 1 is the operand is either a non-special register or ANY
1114 32-bit unsigned constant integer. */
1115
1116int
1d328b19 1117reg_or_logical_cint_operand (op, mode)
592696dd 1118 rtx op;
9ebbca7d
GK
1119 enum machine_mode mode;
1120{
1d328b19
GK
1121 if (GET_CODE (op) == CONST_INT)
1122 {
1123 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1124 {
1125 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1126 abort ();
1d328b19
GK
1127
1128 if (INTVAL (op) < 0)
1129 return 0;
1130 }
1131
1132 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1133 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1134 }
1135 else if (GET_CODE (op) == CONST_DOUBLE)
1136 {
1137 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1138 || mode != DImode)
a4f6c312 1139 abort ();
1d328b19
GK
1140
1141 return CONST_DOUBLE_HIGH (op) == 0;
1142 }
1143 else
1144 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1145}
1146
51d3e7d6 1147/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1148
1149int
1150got_operand (op, mode)
592696dd 1151 rtx op;
296b8152 1152 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1153{
1154 return (GET_CODE (op) == SYMBOL_REF
1155 || GET_CODE (op) == CONST
1156 || GET_CODE (op) == LABEL_REF);
1157}
1158
38c1f2d7
MM
1159/* Return 1 if the operand is a simple references that can be loaded via
1160 the GOT (labels involving addition aren't allowed). */
1161
1162int
1163got_no_const_operand (op, mode)
592696dd 1164 rtx op;
296b8152 1165 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1166{
1167 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1168}
1169
4e74d8ec
MM
1170/* Return the number of instructions it takes to form a constant in an
1171 integer register. */
1172
1173static int
1174num_insns_constant_wide (value)
1175 HOST_WIDE_INT value;
1176{
1177 /* signed constant loadable with {cal|addi} */
5f59ecb7 1178 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1179 return 1;
1180
4e74d8ec 1181 /* constant loadable with {cau|addis} */
5f59ecb7 1182 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1183 return 1;
1184
5f59ecb7 1185#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1186 else if (TARGET_POWERPC64)
4e74d8ec 1187 {
a65c591c
DE
1188 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1189 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1190
a65c591c 1191 if (high == 0 || high == -1)
4e74d8ec
MM
1192 return 2;
1193
a65c591c 1194 high >>= 1;
4e74d8ec 1195
a65c591c 1196 if (low == 0)
4e74d8ec 1197 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1198 else
1199 return (num_insns_constant_wide (high)
e396202a 1200 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1201 }
1202#endif
1203
1204 else
1205 return 2;
1206}
1207
1208int
1209num_insns_constant (op, mode)
1210 rtx op;
1211 enum machine_mode mode;
1212{
4e74d8ec 1213 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1214 {
1215#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1216 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1217 && mask64_operand (op, mode))
0d30d435
DE
1218 return 2;
1219 else
1220#endif
1221 return num_insns_constant_wide (INTVAL (op));
1222 }
4e74d8ec 1223
6fc48950
MM
1224 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1225 {
1226 long l;
1227 REAL_VALUE_TYPE rv;
1228
1229 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1230 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1231 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1232 }
1233
47ad8c61 1234 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1235 {
47ad8c61
MM
1236 HOST_WIDE_INT low;
1237 HOST_WIDE_INT high;
1238 long l[2];
1239 REAL_VALUE_TYPE rv;
1240 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1241
47ad8c61
MM
1242 if (mode == VOIDmode || mode == DImode)
1243 {
1244 high = CONST_DOUBLE_HIGH (op);
1245 low = CONST_DOUBLE_LOW (op);
1246 }
1247 else
1248 {
1249 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1250 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1251 high = l[endian];
1252 low = l[1 - endian];
1253 }
4e74d8ec 1254
47ad8c61
MM
1255 if (TARGET_32BIT)
1256 return (num_insns_constant_wide (low)
1257 + num_insns_constant_wide (high));
4e74d8ec
MM
1258
1259 else
47ad8c61 1260 {
e72247f4 1261 if (high == 0 && low >= 0)
47ad8c61
MM
1262 return num_insns_constant_wide (low);
1263
e72247f4 1264 else if (high == -1 && low < 0)
47ad8c61
MM
1265 return num_insns_constant_wide (low);
1266
a260abc9
DE
1267 else if (mask64_operand (op, mode))
1268 return 2;
1269
47ad8c61
MM
1270 else if (low == 0)
1271 return num_insns_constant_wide (high) + 1;
1272
1273 else
1274 return (num_insns_constant_wide (high)
1275 + num_insns_constant_wide (low) + 1);
1276 }
4e74d8ec
MM
1277 }
1278
1279 else
1280 abort ();
1281}
1282
a4f6c312
SS
1283/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1284 register with one instruction per word. We only do this if we can
1285 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1286
1287int
1288easy_fp_constant (op, mode)
592696dd
SS
1289 rtx op;
1290 enum machine_mode mode;
9878760c 1291{
9878760c
RK
1292 if (GET_CODE (op) != CONST_DOUBLE
1293 || GET_MODE (op) != mode
4e74d8ec 1294 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1295 return 0;
1296
a4f6c312 1297 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1298 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1299 && mode != DImode)
b6c9286a
MM
1300 return 1;
1301
a4f6c312 1302 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1303 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1304 return 0;
1305
5ae4759c 1306#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1307 /* Similarly if we are using -mrelocatable, consider all constants
1308 to be hard. */
5ae4759c
MM
1309 if (TARGET_RELOCATABLE)
1310 return 0;
1311#endif
1312
fcce224d
DE
1313 if (mode == TFmode)
1314 {
1315 long k[4];
1316 REAL_VALUE_TYPE rv;
1317
1318 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1319 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
1320
1321 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1322 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
1323 && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
1324 && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
1325 }
1326
1327 else if (mode == DFmode)
042259f2
DE
1328 {
1329 long k[2];
1330 REAL_VALUE_TYPE rv;
1331
1332 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1333 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1334
a65c591c
DE
1335 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1336 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1337 }
4e74d8ec
MM
1338
1339 else if (mode == SFmode)
042259f2
DE
1340 {
1341 long l;
1342 REAL_VALUE_TYPE rv;
1343
1344 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1345 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1346
4e74d8ec 1347 return num_insns_constant_wide (l) == 1;
042259f2 1348 }
4e74d8ec 1349
a260abc9 1350 else if (mode == DImode)
c81fc13e 1351 return ((TARGET_POWERPC64
a260abc9
DE
1352 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1353 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1354
a9098fd0
GK
1355 else if (mode == SImode)
1356 return 1;
4e74d8ec
MM
1357 else
1358 abort ();
9878760c 1359}
8f75773e 1360
69ef87e2
AH
1361/* Return 1 if the operand is a CONST_INT and can be put into a
1362 register with one instruction. */
1363
1364static int
1365easy_vector_constant (op)
1366 rtx op;
1367{
1368 rtx elt;
1369 int units, i;
1370
1371 if (GET_CODE (op) != CONST_VECTOR)
1372 return 0;
1373
1374 units = CONST_VECTOR_NUNITS (op);
1375
1376 /* We can generate 0 easily. Look for that. */
1377 for (i = 0; i < units; ++i)
1378 {
1379 elt = CONST_VECTOR_ELT (op, i);
1380
1381 /* We could probably simplify this by just checking for equality
1382 with CONST0_RTX for the current mode, but let's be safe
1383 instead. */
1384
98ef3137
JJ
1385 switch (GET_CODE (elt))
1386 {
1387 case CONST_INT:
1388 if (INTVAL (elt) != 0)
1389 return 0;
1390 break;
1391 case CONST_DOUBLE:
1392 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1393 return 0;
1394 break;
1395 default:
1396 return 0;
1397 }
69ef87e2
AH
1398 }
1399
1400 /* We could probably generate a few other constants trivially, but
1401 gcc doesn't generate them yet. FIXME later. */
98ef3137 1402 return 1;
69ef87e2
AH
1403}
1404
1405/* Return 1 if the operand is the constant 0. This works for scalars
1406 as well as vectors. */
1407int
1408zero_constant (op, mode)
1409 rtx op;
1410 enum machine_mode mode;
1411{
1412 return op == CONST0_RTX (mode);
1413}
1414
50a0b056
GK
1415/* Return 1 if the operand is 0.0. */
1416int
1417zero_fp_constant (op, mode)
592696dd
SS
1418 rtx op;
1419 enum machine_mode mode;
50a0b056
GK
1420{
1421 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1422}
1423
a4f6c312
SS
1424/* Return 1 if the operand is in volatile memory. Note that during
1425 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1426 volatile memory references. So this function allows us to
1427 recognize volatile references where its safe. */
1428
1429int
1430volatile_mem_operand (op, mode)
592696dd 1431 rtx op;
b6c9286a
MM
1432 enum machine_mode mode;
1433{
1434 if (GET_CODE (op) != MEM)
1435 return 0;
1436
1437 if (!MEM_VOLATILE_P (op))
1438 return 0;
1439
1440 if (mode != GET_MODE (op))
1441 return 0;
1442
1443 if (reload_completed)
1444 return memory_operand (op, mode);
1445
1446 if (reload_in_progress)
1447 return strict_memory_address_p (mode, XEXP (op, 0));
1448
1449 return memory_address_p (mode, XEXP (op, 0));
1450}
1451
97f6e72f 1452/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1453
1454int
97f6e72f 1455offsettable_mem_operand (op, mode)
592696dd 1456 rtx op;
914c2e77
RK
1457 enum machine_mode mode;
1458{
97f6e72f 1459 return ((GET_CODE (op) == MEM)
677a9668 1460 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1461 mode, XEXP (op, 0)));
914c2e77
RK
1462}
1463
9878760c
RK
1464/* Return 1 if the operand is either an easy FP constant (see above) or
1465 memory. */
1466
1467int
1468mem_or_easy_const_operand (op, mode)
592696dd 1469 rtx op;
9878760c
RK
1470 enum machine_mode mode;
1471{
1472 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1473}
1474
1475/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1476 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1477
1478int
1479add_operand (op, mode)
592696dd 1480 rtx op;
9878760c
RK
1481 enum machine_mode mode;
1482{
2bfcf297 1483 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1484 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1485 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1486
1487 return gpc_reg_operand (op, mode);
9878760c
RK
1488}
1489
dcfedcd0
RK
1490/* Return 1 if OP is a constant but not a valid add_operand. */
1491
1492int
1493non_add_cint_operand (op, mode)
592696dd 1494 rtx op;
296b8152 1495 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1496{
1497 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1498 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1499 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1500}
1501
9878760c
RK
1502/* Return 1 if the operand is a non-special register or a constant that
1503 can be used as the operand of an OR or XOR insn on the RS/6000. */
1504
1505int
1506logical_operand (op, mode)
592696dd 1507 rtx op;
9878760c
RK
1508 enum machine_mode mode;
1509{
40501e5f 1510 HOST_WIDE_INT opl, oph;
1d328b19 1511
dfbdccdb
GK
1512 if (gpc_reg_operand (op, mode))
1513 return 1;
1d328b19 1514
dfbdccdb 1515 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1516 {
1517 opl = INTVAL (op) & GET_MODE_MASK (mode);
1518
1519#if HOST_BITS_PER_WIDE_INT <= 32
1520 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1521 return 0;
1522#endif
1523 }
dfbdccdb
GK
1524 else if (GET_CODE (op) == CONST_DOUBLE)
1525 {
1d328b19 1526 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1527 abort ();
1d328b19
GK
1528
1529 opl = CONST_DOUBLE_LOW (op);
1530 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1531 if (oph != 0)
38886f37 1532 return 0;
dfbdccdb
GK
1533 }
1534 else
1535 return 0;
1d328b19 1536
40501e5f
AM
1537 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1538 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1539}
1540
dcfedcd0 1541/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1542 above), but could be split into one. */
dcfedcd0
RK
1543
1544int
1545non_logical_cint_operand (op, mode)
592696dd 1546 rtx op;
5f59ecb7 1547 enum machine_mode mode;
dcfedcd0 1548{
dfbdccdb 1549 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1550 && ! logical_operand (op, mode)
1551 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1552}
1553
19ba8161 1554/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1555 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1556 Reject all ones and all zeros, since these should have been optimized
1557 away and confuse the making of MB and ME. */
1558
1559int
19ba8161 1560mask_operand (op, mode)
592696dd 1561 rtx op;
19ba8161 1562 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1563{
02071907 1564 HOST_WIDE_INT c, lsb;
9878760c 1565
19ba8161
DE
1566 if (GET_CODE (op) != CONST_INT)
1567 return 0;
1568
1569 c = INTVAL (op);
1570
57deb3a1
AM
1571 /* Fail in 64-bit mode if the mask wraps around because the upper
1572 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1573 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1574 return 0;
1575
c5059423
AM
1576 /* We don't change the number of transitions by inverting,
1577 so make sure we start with the LS bit zero. */
1578 if (c & 1)
1579 c = ~c;
1580
1581 /* Reject all zeros or all ones. */
1582 if (c == 0)
9878760c
RK
1583 return 0;
1584
c5059423
AM
1585 /* Find the first transition. */
1586 lsb = c & -c;
1587
1588 /* Invert to look for a second transition. */
1589 c = ~c;
9878760c 1590
c5059423
AM
1591 /* Erase first transition. */
1592 c &= -lsb;
9878760c 1593
c5059423
AM
1594 /* Find the second transition (if any). */
1595 lsb = c & -c;
1596
1597 /* Match if all the bits above are 1's (or c is zero). */
1598 return c == -lsb;
9878760c
RK
1599}
1600
0ba1b2ff
AM
1601/* Return 1 for the PowerPC64 rlwinm corner case. */
1602
1603int
1604mask_operand_wrap (op, mode)
1605 rtx op;
1606 enum machine_mode mode ATTRIBUTE_UNUSED;
1607{
1608 HOST_WIDE_INT c, lsb;
1609
1610 if (GET_CODE (op) != CONST_INT)
1611 return 0;
1612
1613 c = INTVAL (op);
1614
1615 if ((c & 0x80000001) != 0x80000001)
1616 return 0;
1617
1618 c = ~c;
1619 if (c == 0)
1620 return 0;
1621
1622 lsb = c & -c;
1623 c = ~c;
1624 c &= -lsb;
1625 lsb = c & -c;
1626 return c == -lsb;
1627}
1628
a260abc9
DE
1629/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1630 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1631 Reject all zeros, since zero should have been optimized away and
1632 confuses the making of MB and ME. */
9878760c
RK
1633
1634int
a260abc9 1635mask64_operand (op, mode)
592696dd 1636 rtx op;
0ba1b2ff 1637 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1638{
1639 if (GET_CODE (op) == CONST_INT)
1640 {
02071907 1641 HOST_WIDE_INT c, lsb;
a260abc9 1642
c5059423 1643 c = INTVAL (op);
a260abc9 1644
0ba1b2ff 1645 /* Reject all zeros. */
c5059423 1646 if (c == 0)
e2c953b6
DE
1647 return 0;
1648
0ba1b2ff
AM
1649 /* We don't change the number of transitions by inverting,
1650 so make sure we start with the LS bit zero. */
1651 if (c & 1)
1652 c = ~c;
1653
c5059423
AM
1654 /* Find the transition, and check that all bits above are 1's. */
1655 lsb = c & -c;
1656 return c == -lsb;
e2c953b6 1657 }
0ba1b2ff
AM
1658 return 0;
1659}
1660
1661/* Like mask64_operand, but allow up to three transitions. This
1662 predicate is used by insn patterns that generate two rldicl or
1663 rldicr machine insns. */
1664
1665int
1666mask64_2_operand (op, mode)
1667 rtx op;
1668 enum machine_mode mode ATTRIBUTE_UNUSED;
1669{
1670 if (GET_CODE (op) == CONST_INT)
a260abc9 1671 {
0ba1b2ff 1672 HOST_WIDE_INT c, lsb;
a260abc9 1673
0ba1b2ff 1674 c = INTVAL (op);
a260abc9 1675
0ba1b2ff
AM
1676 /* Disallow all zeros. */
1677 if (c == 0)
1678 return 0;
a260abc9 1679
0ba1b2ff
AM
1680 /* We don't change the number of transitions by inverting,
1681 so make sure we start with the LS bit zero. */
1682 if (c & 1)
1683 c = ~c;
a260abc9 1684
0ba1b2ff
AM
1685 /* Find the first transition. */
1686 lsb = c & -c;
a260abc9 1687
0ba1b2ff
AM
1688 /* Invert to look for a second transition. */
1689 c = ~c;
1690
1691 /* Erase first transition. */
1692 c &= -lsb;
1693
1694 /* Find the second transition. */
1695 lsb = c & -c;
1696
1697 /* Invert to look for a third transition. */
1698 c = ~c;
1699
1700 /* Erase second transition. */
1701 c &= -lsb;
1702
1703 /* Find the third transition (if any). */
1704 lsb = c & -c;
1705
1706 /* Match if all the bits above are 1's (or c is zero). */
1707 return c == -lsb;
1708 }
1709 return 0;
1710}
1711
1712/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1713 implement ANDing by the mask IN. */
1714void
1715build_mask64_2_operands (in, out)
1716 rtx in;
1717 rtx *out;
1718{
1719#if HOST_BITS_PER_WIDE_INT >= 64
1720 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1721 int shift;
1722
1723 if (GET_CODE (in) != CONST_INT)
1724 abort ();
1725
1726 c = INTVAL (in);
1727 if (c & 1)
1728 {
1729 /* Assume c initially something like 0x00fff000000fffff. The idea
1730 is to rotate the word so that the middle ^^^^^^ group of zeros
1731 is at the MS end and can be cleared with an rldicl mask. We then
1732 rotate back and clear off the MS ^^ group of zeros with a
1733 second rldicl. */
1734 c = ~c; /* c == 0xff000ffffff00000 */
1735 lsb = c & -c; /* lsb == 0x0000000000100000 */
1736 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1737 c = ~c; /* c == 0x00fff000000fffff */
1738 c &= -lsb; /* c == 0x00fff00000000000 */
1739 lsb = c & -c; /* lsb == 0x0000100000000000 */
1740 c = ~c; /* c == 0xff000fffffffffff */
1741 c &= -lsb; /* c == 0xff00000000000000 */
1742 shift = 0;
1743 while ((lsb >>= 1) != 0)
1744 shift++; /* shift == 44 on exit from loop */
1745 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1746 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1747 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1748 }
1749 else
0ba1b2ff
AM
1750 {
1751 /* Assume c initially something like 0xff000f0000000000. The idea
1752 is to rotate the word so that the ^^^ middle group of zeros
1753 is at the LS end and can be cleared with an rldicr mask. We then
1754 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1755 a second rldicr. */
1756 lsb = c & -c; /* lsb == 0x0000010000000000 */
1757 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1758 c = ~c; /* c == 0x00fff0ffffffffff */
1759 c &= -lsb; /* c == 0x00fff00000000000 */
1760 lsb = c & -c; /* lsb == 0x0000100000000000 */
1761 c = ~c; /* c == 0xff000fffffffffff */
1762 c &= -lsb; /* c == 0xff00000000000000 */
1763 shift = 0;
1764 while ((lsb >>= 1) != 0)
1765 shift++; /* shift == 44 on exit from loop */
1766 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1767 m1 >>= shift; /* m1 == 0x0000000000000fff */
1768 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1769 }
1770
1771 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1772 masks will be all 1's. We are guaranteed more than one transition. */
1773 out[0] = GEN_INT (64 - shift);
1774 out[1] = GEN_INT (m1);
1775 out[2] = GEN_INT (shift);
1776 out[3] = GEN_INT (m2);
1777#else
045572c7
GK
1778 (void)in;
1779 (void)out;
0ba1b2ff
AM
1780 abort ();
1781#endif
a260abc9
DE
1782}
1783
1784/* Return 1 if the operand is either a non-special register or a constant
1785 that can be used as the operand of a PowerPC64 logical AND insn. */
1786
1787int
1788and64_operand (op, mode)
592696dd 1789 rtx op;
9878760c
RK
1790 enum machine_mode mode;
1791{
a4f6c312 1792 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1793 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1794
1795 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1796}
1797
0ba1b2ff
AM
1798/* Like the above, but also match constants that can be implemented
1799 with two rldicl or rldicr insns. */
1800
1801int
1802and64_2_operand (op, mode)
1803 rtx op;
1804 enum machine_mode mode;
1805{
1806 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1807 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1808
1809 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1810}
1811
a260abc9
DE
1812/* Return 1 if the operand is either a non-special register or a
1813 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1814
1815int
a260abc9 1816and_operand (op, mode)
592696dd 1817 rtx op;
a260abc9 1818 enum machine_mode mode;
dcfedcd0 1819{
a4f6c312 1820 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1821 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1822
1823 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1824}
1825
9878760c
RK
1826/* Return 1 if the operand is a general register or memory operand. */
1827
1828int
1829reg_or_mem_operand (op, mode)
592696dd
SS
1830 rtx op;
1831 enum machine_mode mode;
9878760c 1832{
b6c9286a
MM
1833 return (gpc_reg_operand (op, mode)
1834 || memory_operand (op, mode)
1835 || volatile_mem_operand (op, mode));
9878760c
RK
1836}
1837
a7a813f7 1838/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1839 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1840 instruction. */
1841
1842int
1843lwa_operand (op, mode)
592696dd
SS
1844 rtx op;
1845 enum machine_mode mode;
a7a813f7
RK
1846{
1847 rtx inner = op;
1848
1849 if (reload_completed && GET_CODE (inner) == SUBREG)
1850 inner = SUBREG_REG (inner);
1851
1852 return gpc_reg_operand (inner, mode)
1853 || (memory_operand (inner, mode)
1854 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1855 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1856 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1857 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1858 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1859}
1860
cc4d5fec
JH
1861/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1862
1863int
1864symbol_ref_operand (op, mode)
1865 rtx op;
1866 enum machine_mode mode;
1867{
1868 if (mode != VOIDmode && GET_MODE (op) != mode)
1869 return 0;
1870
1871 return (GET_CODE (op) == SYMBOL_REF);
1872}
1873
9878760c 1874/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1875 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1876
1877int
1878call_operand (op, mode)
592696dd 1879 rtx op;
9878760c
RK
1880 enum machine_mode mode;
1881{
1882 if (mode != VOIDmode && GET_MODE (op) != mode)
1883 return 0;
1884
1885 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1886 || (GET_CODE (op) == REG
1887 && (REGNO (op) == LINK_REGISTER_REGNUM
1888 || REGNO (op) == COUNT_REGISTER_REGNUM
1889 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1890}
1891
2af3d377 1892/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1893 this file and the function is not weakly defined. */
2af3d377
RK
1894
1895int
1896current_file_function_operand (op, mode)
592696dd 1897 rtx op;
296b8152 1898 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1899{
1900 return (GET_CODE (op) == SYMBOL_REF
1901 && (SYMBOL_REF_FLAG (op)
8f1b829e 1902 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1903 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1904}
1905
9878760c
RK
1906/* Return 1 if this operand is a valid input for a move insn. */
1907
1908int
1909input_operand (op, mode)
592696dd 1910 rtx op;
9878760c
RK
1911 enum machine_mode mode;
1912{
eb4e8003 1913 /* Memory is always valid. */
9878760c
RK
1914 if (memory_operand (op, mode))
1915 return 1;
1916
34792e82 1917 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1918 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1919 return 1;
1920
eb4e8003
RK
1921 /* For floating-point, easy constants are valid. */
1922 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1923 && CONSTANT_P (op)
1924 && easy_fp_constant (op, mode))
1925 return 1;
1926
4e74d8ec
MM
1927 /* Allow any integer constant. */
1928 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1929 && (GET_CODE (op) == CONST_INT
e675f625 1930 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1931 return 1;
1932
eb4e8003
RK
1933 /* For floating-point or multi-word mode, the only remaining valid type
1934 is a register. */
9878760c
RK
1935 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1936 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1937 return register_operand (op, mode);
9878760c 1938
88fe15a1
RK
1939 /* The only cases left are integral modes one word or smaller (we
1940 do not get called for MODE_CC values). These can be in any
1941 register. */
1942 if (register_operand (op, mode))
a8b3aeda 1943 return 1;
88fe15a1 1944
84cf9dda 1945 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 1946 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
1947 return 1;
1948
9ebbca7d
GK
1949 /* A constant pool expression (relative to the TOC) is valid */
1950 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
1951 return 1;
1952
88228c4b
MM
1953 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1954 to be valid. */
f607bc57 1955 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
1956 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1957 && small_data_operand (op, Pmode))
1958 return 1;
1959
042259f2 1960 return 0;
9878760c 1961}
7509c759 1962
a4f6c312 1963/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
1964
1965int
1966small_data_operand (op, mode)
296b8152
KG
1967 rtx op ATTRIBUTE_UNUSED;
1968 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 1969{
38c1f2d7 1970#if TARGET_ELF
5f59ecb7 1971 rtx sym_ref;
7509c759 1972
d9407988 1973 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 1974 return 0;
a54d04b7 1975
f607bc57 1976 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
1977 return 0;
1978
88228c4b
MM
1979 if (GET_CODE (op) == SYMBOL_REF)
1980 sym_ref = op;
1981
1982 else if (GET_CODE (op) != CONST
1983 || GET_CODE (XEXP (op, 0)) != PLUS
1984 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
1985 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
1986 return 0;
1987
88228c4b 1988 else
dbf55e53
MM
1989 {
1990 rtx sum = XEXP (op, 0);
1991 HOST_WIDE_INT summand;
1992
1993 /* We have to be careful here, because it is the referenced address
1994 that must be 32k from _SDA_BASE_, not just the symbol. */
1995 summand = INTVAL (XEXP (sum, 1));
1996 if (summand < 0 || summand > g_switch_value)
1997 return 0;
1998
1999 sym_ref = XEXP (sum, 0);
2000 }
88228c4b
MM
2001
2002 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
2003 return 0;
2004
2005 return 1;
d9407988
MM
2006
2007#else
2008 return 0;
2009#endif
7509c759 2010}
9ebbca7d
GK
2011\f
2012static int
2013constant_pool_expr_1 (op, have_sym, have_toc)
2014 rtx op;
2015 int *have_sym;
2016 int *have_toc;
2017{
2018 switch (GET_CODE(op))
2019 {
2020 case SYMBOL_REF:
a4f6c312
SS
2021 if (CONSTANT_POOL_ADDRESS_P (op))
2022 {
2023 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2024 {
2025 *have_sym = 1;
2026 return 1;
2027 }
2028 else
2029 return 0;
2030 }
2031 else if (! strcmp (XSTR (op, 0), toc_label_name))
2032 {
2033 *have_toc = 1;
2034 return 1;
2035 }
2036 else
2037 return 0;
9ebbca7d
GK
2038 case PLUS:
2039 case MINUS:
c1f11548
DE
2040 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2041 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2042 case CONST:
a4f6c312 2043 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2044 case CONST_INT:
a4f6c312 2045 return 1;
9ebbca7d 2046 default:
a4f6c312 2047 return 0;
9ebbca7d
GK
2048 }
2049}
2050
2051int
2052constant_pool_expr_p (op)
2053 rtx op;
2054{
2055 int have_sym = 0;
2056 int have_toc = 0;
2057 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2058}
2059
2060int
2061toc_relative_expr_p (op)
2062 rtx op;
2063{
2064 int have_sym = 0;
2065 int have_toc = 0;
2066 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2067}
2068
2069/* Try machine-dependent ways of modifying an illegitimate address
2070 to be legitimate. If we find one, return the new, valid address.
2071 This is used from only one place: `memory_address' in explow.c.
2072
a4f6c312
SS
2073 OLDX is the address as it was before break_out_memory_refs was
2074 called. In some cases it is useful to look at this to decide what
2075 needs to be done.
9ebbca7d 2076
a4f6c312 2077 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2078
a4f6c312
SS
2079 It is always safe for this function to do nothing. It exists to
2080 recognize opportunities to optimize the output.
9ebbca7d
GK
2081
2082 On RS/6000, first check for the sum of a register with a constant
2083 integer that is out of range. If so, generate code to add the
2084 constant with the low-order 16 bits masked to the register and force
2085 this result into another register (this can be done with `cau').
2086 Then generate an address of REG+(CONST&0xffff), allowing for the
2087 possibility of bit 16 being a one.
2088
2089 Then check for the sum of a register and something not constant, try to
2090 load the other things into a register and return the sum. */
2091rtx
2092rs6000_legitimize_address (x, oldx, mode)
2093 rtx x;
2094 rtx oldx ATTRIBUTE_UNUSED;
2095 enum machine_mode mode;
0ac081f6 2096{
9ebbca7d
GK
2097 if (GET_CODE (x) == PLUS
2098 && GET_CODE (XEXP (x, 0)) == REG
2099 && GET_CODE (XEXP (x, 1)) == CONST_INT
2100 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2101 {
2102 HOST_WIDE_INT high_int, low_int;
2103 rtx sum;
a65c591c
DE
2104 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2105 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2106 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2107 GEN_INT (high_int)), 0);
2108 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2109 }
2110 else if (GET_CODE (x) == PLUS
2111 && GET_CODE (XEXP (x, 0)) == REG
2112 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2113 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2114 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2115 || TARGET_POWERPC64
fcce224d 2116 || (mode != DFmode && mode != TFmode))
9ebbca7d
GK
2117 && (TARGET_POWERPC64 || mode != DImode)
2118 && mode != TImode)
2119 {
2120 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2121 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2122 }
0ac081f6
AH
2123 else if (ALTIVEC_VECTOR_MODE (mode))
2124 {
2125 rtx reg;
2126
2127 /* Make sure both operands are registers. */
2128 if (GET_CODE (x) == PLUS)
9f85ed45 2129 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2130 force_reg (Pmode, XEXP (x, 1)));
2131
2132 reg = force_reg (Pmode, x);
2133 return reg;
2134 }
a3170dc6
AH
2135 else if (SPE_VECTOR_MODE (mode))
2136 {
2137 /* We accept [reg + reg] and [reg + OFFSET]. */
2138
2139 if (GET_CODE (x) == PLUS)
2140 {
2141 rtx op1 = XEXP (x, 0);
2142 rtx op2 = XEXP (x, 1);
2143
2144 op1 = force_reg (Pmode, op1);
2145
2146 if (GET_CODE (op2) != REG
2147 && (GET_CODE (op2) != CONST_INT
2148 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2149 op2 = force_reg (Pmode, op2);
2150
2151 return gen_rtx_PLUS (Pmode, op1, op2);
2152 }
2153
2154 return force_reg (Pmode, x);
2155 }
9ebbca7d
GK
2156 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2157 && GET_CODE (x) != CONST_INT
2158 && GET_CODE (x) != CONST_DOUBLE
2159 && CONSTANT_P (x)
6ac7bf2c
GK
2160 && GET_MODE_NUNITS (mode) == 1
2161 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2162 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2163 {
2164 rtx reg = gen_reg_rtx (Pmode);
2165 emit_insn (gen_elf_high (reg, (x)));
2166 return gen_rtx_LO_SUM (Pmode, reg, (x));
2167 }
ee890fe2
SS
2168 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2169 && ! flag_pic
2170 && GET_CODE (x) != CONST_INT
2171 && GET_CODE (x) != CONST_DOUBLE
2172 && CONSTANT_P (x)
a3170dc6 2173 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2174 && mode != DImode
2175 && mode != TImode)
2176 {
2177 rtx reg = gen_reg_rtx (Pmode);
2178 emit_insn (gen_macho_high (reg, (x)));
2179 return gen_rtx_LO_SUM (Pmode, reg, (x));
2180 }
9ebbca7d
GK
2181 else if (TARGET_TOC
2182 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2183 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2184 {
2185 return create_TOC_reference (x);
2186 }
2187 else
2188 return NULL_RTX;
2189}
258bfae2 2190
24ea750e
DJ
2191/* The convention appears to be to define this wherever it is used.
2192 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2193 is now used here. */
2194#ifndef REG_MODE_OK_FOR_BASE_P
2195#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2196#endif
2197
2198/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2199 replace the input X, or the original X if no replacement is called for.
2200 The output parameter *WIN is 1 if the calling macro should goto WIN,
2201 0 if it should not.
2202
2203 For RS/6000, we wish to handle large displacements off a base
2204 register by splitting the addend across an addiu/addis and the mem insn.
2205 This cuts number of extra insns needed from 3 to 1.
2206
2207 On Darwin, we use this to generate code for floating point constants.
2208 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2209 The Darwin code is inside #if TARGET_MACHO because only then is
2210 machopic_function_base_name() defined. */
2211rtx
2212rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2213 rtx x;
2214 enum machine_mode mode;
2215 int opnum;
2216 int type;
2217 int ind_levels ATTRIBUTE_UNUSED;
2218 int *win;
2219{
2220 /* We must recognize output that we have already generated ourselves. */
2221 if (GET_CODE (x) == PLUS
2222 && GET_CODE (XEXP (x, 0)) == PLUS
2223 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2224 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2225 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2226 {
2227 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2228 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2229 opnum, (enum reload_type)type);
2230 *win = 1;
2231 return x;
2232 }
3deb2758 2233
24ea750e
DJ
2234#if TARGET_MACHO
2235 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2236 && GET_CODE (x) == LO_SUM
2237 && GET_CODE (XEXP (x, 0)) == PLUS
2238 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2239 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2240 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2241 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2242 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2243 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2244 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2245 {
2246 /* Result of previous invocation of this function on Darwin
6f317ef3 2247 floating point constant. */
24ea750e
DJ
2248 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2249 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2250 opnum, (enum reload_type)type);
2251 *win = 1;
2252 return x;
2253 }
2254#endif
2255 if (GET_CODE (x) == PLUS
2256 && GET_CODE (XEXP (x, 0)) == REG
2257 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2258 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2259 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 2260 && !SPE_VECTOR_MODE (mode)
78c875e8 2261 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2262 {
2263 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2264 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2265 HOST_WIDE_INT high
2266 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2267
2268 /* Check for 32-bit overflow. */
2269 if (high + low != val)
2270 {
2271 *win = 0;
2272 return x;
2273 }
2274
2275 /* Reload the high part into a base reg; leave the low part
2276 in the mem directly. */
2277
2278 x = gen_rtx_PLUS (GET_MODE (x),
2279 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2280 GEN_INT (high)),
2281 GEN_INT (low));
2282
2283 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2284 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2285 opnum, (enum reload_type)type);
2286 *win = 1;
2287 return x;
2288 }
2289#if TARGET_MACHO
2290 if (GET_CODE (x) == SYMBOL_REF
2291 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2292 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2293 && flag_pic)
2294 {
2295 /* Darwin load of floating point constant. */
2296 rtx offset = gen_rtx (CONST, Pmode,
2297 gen_rtx (MINUS, Pmode, x,
2298 gen_rtx (SYMBOL_REF, Pmode,
2299 machopic_function_base_name ())));
2300 x = gen_rtx (LO_SUM, GET_MODE (x),
2301 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2302 gen_rtx (HIGH, Pmode, offset)), offset);
2303 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2304 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2305 opnum, (enum reload_type)type);
2306 *win = 1;
2307 return x;
2308 }
2309#endif
2310 if (TARGET_TOC
c1f11548
DE
2311 && CONSTANT_POOL_EXPR_P (x)
2312 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2313 {
2314 (x) = create_TOC_reference (x);
2315 *win = 1;
2316 return x;
2317 }
2318 *win = 0;
2319 return x;
2320}
2321
258bfae2
FS
2322/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2323 that is a valid memory address for an instruction.
2324 The MODE argument is the machine mode for the MEM expression
2325 that wants to use this address.
2326
2327 On the RS/6000, there are four valid address: a SYMBOL_REF that
2328 refers to a constant pool entry of an address (or the sum of it
2329 plus a constant), a short (16-bit signed) constant plus a register,
2330 the sum of two registers, or a register indirect, possibly with an
2331 auto-increment. For DFmode and DImode with an constant plus register,
2332 we must ensure that both words are addressable or PowerPC64 with offset
2333 word aligned.
2334
2335 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2336 32-bit DImode, TImode), indexed addressing cannot be used because
2337 adjacent memory cells are accessed by adding word-sized offsets
2338 during assembly output. */
2339int
2340rs6000_legitimate_address (mode, x, reg_ok_strict)
2341 enum machine_mode mode;
2342 rtx x;
2343 int reg_ok_strict;
2344{
2345 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2346 return 1;
2347 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2348 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2349 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2350 && TARGET_UPDATE
2351 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2352 return 1;
2353 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2354 return 1;
2355 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2356 return 1;
2357 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2358 if (! reg_ok_strict
2359 && GET_CODE (x) == PLUS
2360 && GET_CODE (XEXP (x, 0)) == REG
2361 && XEXP (x, 0) == virtual_stack_vars_rtx
2362 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2363 return 1;
2364 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2365 return 1;
2366 if (mode != TImode
a3170dc6
AH
2367 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2368 || TARGET_POWERPC64
fcce224d 2369 || (mode != DFmode && mode != TFmode))
258bfae2
FS
2370 && (TARGET_POWERPC64 || mode != DImode)
2371 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2372 return 1;
2373 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2374 return 1;
2375 return 0;
2376}
fb4d4348 2377\f
a4f6c312
SS
2378/* Try to output insns to set TARGET equal to the constant C if it can
2379 be done in less than N insns. Do all computations in MODE.
2380 Returns the place where the output has been placed if it can be
2381 done and the insns have been emitted. If it would take more than N
2382 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2383
2384rtx
2385rs6000_emit_set_const (dest, mode, source, n)
2386 rtx dest, source;
2387 enum machine_mode mode;
2388 int n ATTRIBUTE_UNUSED;
2389{
af8cb5c5 2390 rtx result, insn, set;
2bfcf297
DB
2391 HOST_WIDE_INT c0, c1;
2392
af8cb5c5 2393 if (mode == QImode || mode == HImode)
2bfcf297
DB
2394 {
2395 if (dest == NULL)
2396 dest = gen_reg_rtx (mode);
2397 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2398 return dest;
2399 }
af8cb5c5 2400 else if (mode == SImode)
2bfcf297 2401 {
af8cb5c5
DE
2402 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2403
2404 emit_insn (gen_rtx_SET (VOIDmode, result,
2405 GEN_INT (INTVAL (source)
2406 & (~ (HOST_WIDE_INT) 0xffff))));
2407 emit_insn (gen_rtx_SET (VOIDmode, dest,
2408 gen_rtx_IOR (SImode, result,
2409 GEN_INT (INTVAL (source) & 0xffff))));
2410 result = dest;
2bfcf297 2411 }
af8cb5c5 2412 else if (mode == DImode)
2bfcf297 2413 {
af8cb5c5
DE
2414 if (GET_CODE (source) == CONST_INT)
2415 {
2416 c0 = INTVAL (source);
2417 c1 = -(c0 < 0);
2418 }
2419 else if (GET_CODE (source) == CONST_DOUBLE)
2420 {
2bfcf297 2421#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
2422 c0 = CONST_DOUBLE_LOW (source);
2423 c1 = -(c0 < 0);
2bfcf297 2424#else
af8cb5c5
DE
2425 c0 = CONST_DOUBLE_LOW (source);
2426 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 2427#endif
af8cb5c5
DE
2428 }
2429 else
2430 abort ();
2431
2432 result = rs6000_emit_set_long_const (dest, c0, c1);
2bfcf297
DB
2433 }
2434 else
a4f6c312 2435 abort ();
2bfcf297 2436
af8cb5c5
DE
2437 insn = get_last_insn ();
2438 set = single_set (insn);
2439 if (! CONSTANT_P (SET_SRC (set)))
2440 set_unique_reg_note (insn, REG_EQUAL, source);
2441
2442 return result;
2bfcf297
DB
2443}
2444
2445/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2446 fall back to a straight forward decomposition. We do this to avoid
2447 exponential run times encountered when looking for longer sequences
2448 with rs6000_emit_set_const. */
2449static rtx
2450rs6000_emit_set_long_const (dest, c1, c2)
2451 rtx dest;
2452 HOST_WIDE_INT c1, c2;
2453{
2454 if (!TARGET_POWERPC64)
2455 {
2456 rtx operand1, operand2;
2457
2458 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2459 DImode);
2460 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2461 DImode);
2462 emit_move_insn (operand1, GEN_INT (c1));
2463 emit_move_insn (operand2, GEN_INT (c2));
2464 }
2465 else
2466 {
bc06712d 2467 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2468
bc06712d
TR
2469 ud1 = c1 & 0xffff;
2470 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2471#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2472 c2 = c1 >> 32;
2bfcf297 2473#endif
bc06712d
TR
2474 ud3 = c2 & 0xffff;
2475 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2476
bc06712d
TR
2477 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2478 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2479 {
bc06712d
TR
2480 if (ud1 & 0x8000)
2481 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2482 else
2483 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2484 }
2bfcf297 2485
bc06712d
TR
2486 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2487 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2488 {
bc06712d
TR
2489 if (ud2 & 0x8000)
2490 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2491 - 0x80000000));
252b88f7 2492 else
bc06712d
TR
2493 emit_move_insn (dest, GEN_INT (ud2 << 16));
2494 if (ud1 != 0)
2495 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2496 }
bc06712d
TR
2497 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2498 || (ud4 == 0 && ! (ud3 & 0x8000)))
2499 {
2500 if (ud3 & 0x8000)
2501 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2502 - 0x80000000));
2503 else
2504 emit_move_insn (dest, GEN_INT (ud3 << 16));
2505
2506 if (ud2 != 0)
2507 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2508 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2509 if (ud1 != 0)
2510 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2511 }
2512 else
2513 {
2514 if (ud4 & 0x8000)
2515 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2516 - 0x80000000));
2517 else
2518 emit_move_insn (dest, GEN_INT (ud4 << 16));
2519
2520 if (ud3 != 0)
2521 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2522
bc06712d
TR
2523 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2524 if (ud2 != 0)
2525 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2526 GEN_INT (ud2 << 16)));
2527 if (ud1 != 0)
2528 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2529 }
2530 }
2bfcf297
DB
2531 return dest;
2532}
2533
fb4d4348
GK
2534/* Emit a move from SOURCE to DEST in mode MODE. */
2535void
2536rs6000_emit_move (dest, source, mode)
2537 rtx dest;
2538 rtx source;
2539 enum machine_mode mode;
2540{
2541 rtx operands[2];
2542 operands[0] = dest;
2543 operands[1] = source;
2544
2545 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2546 if (GET_CODE (operands[1]) == CONST_DOUBLE
2547 && ! FLOAT_MODE_P (mode)
2548 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2549 {
2550 /* FIXME. This should never happen. */
2551 /* Since it seems that it does, do the safe thing and convert
2552 to a CONST_INT. */
2496c7bd 2553 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2554 }
2555 if (GET_CODE (operands[1]) == CONST_DOUBLE
2556 && ! FLOAT_MODE_P (mode)
2557 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2558 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2559 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2560 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2561 abort ();
c9e8cb32
DD
2562
2563 /* Check if GCC is setting up a block move that will end up using FP
2564 registers as temporaries. We must make sure this is acceptable. */
2565 if (GET_CODE (operands[0]) == MEM
2566 && GET_CODE (operands[1]) == MEM
2567 && mode == DImode
41543739
GK
2568 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2569 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2570 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2571 ? 32 : MEM_ALIGN (operands[0])))
2572 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2573 ? 32
2574 : MEM_ALIGN (operands[1]))))
2575 && ! MEM_VOLATILE_P (operands [0])
2576 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2577 {
41543739
GK
2578 emit_move_insn (adjust_address (operands[0], SImode, 0),
2579 adjust_address (operands[1], SImode, 0));
2580 emit_move_insn (adjust_address (operands[0], SImode, 4),
2581 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2582 return;
2583 }
fb4d4348 2584
67cef334
DE
2585 if (!no_new_pseudos)
2586 {
2587 if (GET_CODE (operands[1]) == MEM && optimize > 0
2588 && (mode == QImode || mode == HImode || mode == SImode)
2589 && GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
2590 {
2591 rtx reg = gen_reg_rtx (word_mode);
2592
2593 emit_insn (gen_rtx_SET (word_mode, reg,
2594 gen_rtx_ZERO_EXTEND (word_mode,
2595 operands[1])));
2596 operands[1] = gen_lowpart (mode, reg);
2597 }
2598 if (GET_CODE (operands[0]) != REG)
2599 operands[1] = force_reg (mode, operands[1]);
2600 }
a9098fd0 2601
a3170dc6
AH
2602 if (mode == SFmode && ! TARGET_POWERPC
2603 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2604 && GET_CODE (operands[0]) == MEM)
fb4d4348 2605 {
ffc14f31
GK
2606 int regnum;
2607
2608 if (reload_in_progress || reload_completed)
2609 regnum = true_regnum (operands[1]);
2610 else if (GET_CODE (operands[1]) == REG)
2611 regnum = REGNO (operands[1]);
2612 else
2613 regnum = -1;
fb4d4348
GK
2614
2615 /* If operands[1] is a register, on POWER it may have
2616 double-precision data in it, so truncate it to single
2617 precision. */
2618 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2619 {
2620 rtx newreg;
2621 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2622 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2623 operands[1] = newreg;
2624 }
2625 }
2626
a9098fd0
GK
2627 /* Handle the case where reload calls us with an invalid address;
2628 and the case of CONSTANT_P_RTX. */
16861f33 2629 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2630 && (! general_operand (operands[1], mode)
2631 || ! nonimmediate_operand (operands[0], mode)
2632 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2633 {
2634 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2635 return;
2636 }
a9098fd0 2637
fb4d4348
GK
2638 /* FIXME: In the long term, this switch statement should go away
2639 and be replaced by a sequence of tests based on things like
2640 mode == Pmode. */
2641 switch (mode)
2642 {
2643 case HImode:
2644 case QImode:
2645 if (CONSTANT_P (operands[1])
2646 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2647 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2648 break;
2649
06f4e019 2650 case TFmode:
fb4d4348
GK
2651 case DFmode:
2652 case SFmode:
2653 if (CONSTANT_P (operands[1])
2654 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2655 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2656 break;
2657
0ac081f6
AH
2658 case V16QImode:
2659 case V8HImode:
2660 case V4SFmode:
2661 case V4SImode:
a3170dc6
AH
2662 case V4HImode:
2663 case V2SFmode:
2664 case V2SImode:
00a892b8 2665 case V1DImode:
69ef87e2
AH
2666 if (CONSTANT_P (operands[1])
2667 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2668 operands[1] = force_const_mem (mode, operands[1]);
2669 break;
2670
fb4d4348 2671 case SImode:
a9098fd0 2672 case DImode:
fb4d4348
GK
2673 /* Use default pattern for address of ELF small data */
2674 if (TARGET_ELF
a9098fd0 2675 && mode == Pmode
f607bc57 2676 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2677 && (GET_CODE (operands[1]) == SYMBOL_REF
2678 || GET_CODE (operands[1]) == CONST)
2679 && small_data_operand (operands[1], mode))
fb4d4348
GK
2680 {
2681 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2682 return;
2683 }
2684
f607bc57 2685 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2686 && mode == Pmode && mode == SImode
2687 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2688 {
2689 emit_insn (gen_movsi_got (operands[0], operands[1]));
2690 return;
2691 }
2692
ee890fe2
SS
2693 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2694 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2695 && mode == Pmode
fb4d4348
GK
2696 && CONSTANT_P (operands[1])
2697 && GET_CODE (operands[1]) != HIGH
2698 && GET_CODE (operands[1]) != CONST_INT)
2699 {
a9098fd0 2700 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2701
2702 /* If this is a function address on -mcall-aixdesc,
2703 convert it to the address of the descriptor. */
2704 if (DEFAULT_ABI == ABI_AIX
2705 && GET_CODE (operands[1]) == SYMBOL_REF
2706 && XSTR (operands[1], 0)[0] == '.')
2707 {
2708 const char *name = XSTR (operands[1], 0);
2709 rtx new_ref;
2710 while (*name == '.')
2711 name++;
2712 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2713 CONSTANT_POOL_ADDRESS_P (new_ref)
2714 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2715 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2716 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2717 operands[1] = new_ref;
2718 }
7509c759 2719
ee890fe2
SS
2720 if (DEFAULT_ABI == ABI_DARWIN)
2721 {
2722 emit_insn (gen_macho_high (target, operands[1]));
2723 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2724 return;
2725 }
2726
fb4d4348
GK
2727 emit_insn (gen_elf_high (target, operands[1]));
2728 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2729 return;
2730 }
2731
a9098fd0
GK
2732 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2733 and we have put it in the TOC, we just need to make a TOC-relative
2734 reference to it. */
2735 if (TARGET_TOC
2736 && GET_CODE (operands[1]) == SYMBOL_REF
2737 && CONSTANT_POOL_EXPR_P (operands[1])
2738 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2739 get_pool_mode (operands[1])))
fb4d4348 2740 {
a9098fd0 2741 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2742 }
a9098fd0
GK
2743 else if (mode == Pmode
2744 && CONSTANT_P (operands[1])
38886f37
AO
2745 && ((GET_CODE (operands[1]) != CONST_INT
2746 && ! easy_fp_constant (operands[1], mode))
2747 || (GET_CODE (operands[1]) == CONST_INT
2748 && num_insns_constant (operands[1], mode) > 2)
2749 || (GET_CODE (operands[0]) == REG
2750 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2751 && GET_CODE (operands[1]) != HIGH
2752 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2753 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2754 {
2755 /* Emit a USE operation so that the constant isn't deleted if
2756 expensive optimizations are turned on because nobody
2757 references it. This should only be done for operands that
2758 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2759 This should not be done for operands that contain LABEL_REFs.
2760 For now, we just handle the obvious case. */
2761 if (GET_CODE (operands[1]) != LABEL_REF)
2762 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2763
c859cda6 2764#if TARGET_MACHO
ee890fe2
SS
2765 /* Darwin uses a special PIC legitimizer. */
2766 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2767 {
ee890fe2
SS
2768 operands[1] =
2769 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2770 operands[0]);
2771 if (operands[0] != operands[1])
2772 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2773 return;
2774 }
c859cda6 2775#endif
ee890fe2 2776
fb4d4348
GK
2777 /* If we are to limit the number of things we put in the TOC and
2778 this is a symbol plus a constant we can add in one insn,
2779 just put the symbol in the TOC and add the constant. Don't do
2780 this if reload is in progress. */
2781 if (GET_CODE (operands[1]) == CONST
2782 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2783 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2784 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2785 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2786 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2787 && ! side_effects_p (operands[0]))
2788 {
a4f6c312
SS
2789 rtx sym =
2790 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2791 rtx other = XEXP (XEXP (operands[1], 0), 1);
2792
a9098fd0
GK
2793 sym = force_reg (mode, sym);
2794 if (mode == SImode)
2795 emit_insn (gen_addsi3 (operands[0], sym, other));
2796 else
2797 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2798 return;
2799 }
2800
a9098fd0 2801 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2802
2803 if (TARGET_TOC
d34c5b80
DE
2804 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2805 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2806 get_pool_constant (XEXP (operands[1], 0)),
2807 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2808 {
ba4828e0
RK
2809 operands[1]
2810 = gen_rtx_MEM (mode,
2811 create_TOC_reference (XEXP (operands[1], 0)));
2812 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2813 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2814 }
fb4d4348
GK
2815 }
2816 break;
a9098fd0 2817
fb4d4348
GK
2818 case TImode:
2819 if (GET_CODE (operands[0]) == MEM
2820 && GET_CODE (XEXP (operands[0], 0)) != REG
2821 && ! reload_in_progress)
792760b9
RK
2822 operands[0]
2823 = replace_equiv_address (operands[0],
2824 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2825
2826 if (GET_CODE (operands[1]) == MEM
2827 && GET_CODE (XEXP (operands[1], 0)) != REG
2828 && ! reload_in_progress)
792760b9
RK
2829 operands[1]
2830 = replace_equiv_address (operands[1],
2831 copy_addr_to_reg (XEXP (operands[1], 0)));
fb4d4348
GK
2832 break;
2833
2834 default:
2835 abort ();
2836 }
2837
a9098fd0
GK
2838 /* Above, we may have called force_const_mem which may have returned
2839 an invalid address. If we can, fix this up; otherwise, reload will
2840 have to deal with it. */
2841 if (GET_CODE (operands[1]) == MEM
2842 && ! memory_address_p (mode, XEXP (operands[1], 0))
2843 && ! reload_in_progress)
f4ef873c 2844 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2845
fb4d4348 2846 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2847 return;
fb4d4348 2848}
4697a36c
MM
2849\f
2850/* Initialize a variable CUM of type CUMULATIVE_ARGS
2851 for a call to a function whose data type is FNTYPE.
2852 For a library call, FNTYPE is 0.
2853
2854 For incoming args we set the number of arguments in the prototype large
1c20ae99 2855 so we never return a PARALLEL. */
4697a36c
MM
2856
2857void
2858init_cumulative_args (cum, fntype, libname, incoming)
2859 CUMULATIVE_ARGS *cum;
2860 tree fntype;
296b8152 2861 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2862 int incoming;
2863{
2864 static CUMULATIVE_ARGS zero_cumulative;
2865
2866 *cum = zero_cumulative;
2867 cum->words = 0;
2868 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2869 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2870 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2871 cum->call_cookie = CALL_NORMAL;
4cc833b7 2872 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2873
2874 if (incoming)
bd227acc 2875 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2876
2877 else if (cum->prototype)
2878 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2879 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2880 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2881
2882 else
2883 cum->nargs_prototype = 0;
2884
2885 cum->orig_nargs = cum->nargs_prototype;
7509c759 2886
a5c76ee6
ZW
2887 /* Check for a longcall attribute. */
2888 if (fntype
2889 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2890 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2891 cum->call_cookie = CALL_LONG;
2892
4697a36c
MM
2893 if (TARGET_DEBUG_ARG)
2894 {
2895 fprintf (stderr, "\ninit_cumulative_args:");
2896 if (fntype)
2897 {
2898 tree ret_type = TREE_TYPE (fntype);
2899 fprintf (stderr, " ret code = %s,",
2900 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2901 }
2902
6a4cee5f
MM
2903 if (cum->call_cookie & CALL_LONG)
2904 fprintf (stderr, " longcall,");
2905
4697a36c
MM
2906 fprintf (stderr, " proto = %d, nargs = %d\n",
2907 cum->prototype, cum->nargs_prototype);
2908 }
2909}
2910\f
c229cba9
DE
2911/* If defined, a C expression which determines whether, and in which
2912 direction, to pad out an argument with extra space. The value
2913 should be of type `enum direction': either `upward' to pad above
2914 the argument, `downward' to pad below, or `none' to inhibit
2915 padding.
2916
2917 For the AIX ABI structs are always stored left shifted in their
2918 argument slot. */
2919
9ebbca7d 2920enum direction
c229cba9
DE
2921function_arg_padding (mode, type)
2922 enum machine_mode mode;
2923 tree type;
2924{
c85f7c16 2925 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 2926 return upward;
c229cba9
DE
2927
2928 /* This is the default definition. */
2929 return (! BYTES_BIG_ENDIAN
9ebbca7d 2930 ? upward
c229cba9
DE
2931 : ((mode == BLKmode
2932 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2933 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2934 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 2935 ? downward : upward));
c229cba9
DE
2936}
2937
b6c9286a
MM
2938/* If defined, a C expression that gives the alignment boundary, in bits,
2939 of an argument with the specified mode and type. If it is not defined,
2940 PARM_BOUNDARY is used for all arguments.
2941
2310f99a 2942 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
2943
2944int
2945function_arg_boundary (mode, type)
2946 enum machine_mode mode;
9ebbca7d 2947 tree type ATTRIBUTE_UNUSED;
b6c9286a 2948{
f607bc57 2949 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 2950 return 64;
a3170dc6
AH
2951 else if (SPE_VECTOR_MODE (mode))
2952 return 64;
0ac081f6
AH
2953 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2954 return 128;
9ebbca7d 2955 else
b6c9286a 2956 return PARM_BOUNDARY;
b6c9286a
MM
2957}
2958\f
4697a36c
MM
2959/* Update the data in CUM to advance over an argument
2960 of mode MODE and data type TYPE.
2961 (TYPE is null for libcalls where that information may not be available.) */
2962
2963void
2964function_arg_advance (cum, mode, type, named)
2965 CUMULATIVE_ARGS *cum;
2966 enum machine_mode mode;
2967 tree type;
2968 int named;
2969{
2970 cum->nargs_prototype--;
2971
0ac081f6
AH
2972 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2973 {
2974 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2975 cum->vregno++;
2976 else
2977 cum->words += RS6000_ARG_SIZE (mode, type);
2978 }
a4b0320c
AH
2979 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
2980 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
2981 cum->sysv_gregno++;
f607bc57 2982 else if (DEFAULT_ABI == ABI_V4)
4697a36c 2983 {
a3170dc6 2984 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 2985 && (mode == SFmode || mode == DFmode))
4697a36c 2986 {
4cc833b7
RH
2987 if (cum->fregno <= FP_ARG_V4_MAX_REG)
2988 cum->fregno++;
2989 else
2990 {
2991 if (mode == DFmode)
2992 cum->words += cum->words & 1;
d34c5b80 2993 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 2994 }
4697a36c 2995 }
4cc833b7
RH
2996 else
2997 {
2998 int n_words;
2999 int gregno = cum->sysv_gregno;
3000
3001 /* Aggregates and IEEE quad get passed by reference. */
3002 if ((type && AGGREGATE_TYPE_P (type))
3003 || mode == TFmode)
3004 n_words = 1;
3005 else
d34c5b80 3006 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3007
a4b0320c 3008 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3009 if (n_words == 2 && (gregno & 1) == 0)
3010 gregno += 1;
3011
a4b0320c
AH
3012 /* Long long and SPE vectors are not split between registers
3013 and stack. */
4cc833b7
RH
3014 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
3015 {
3016 /* Long long is aligned on the stack. */
3017 if (n_words == 2)
3018 cum->words += cum->words & 1;
3019 cum->words += n_words;
3020 }
4697a36c 3021
4cc833b7
RH
3022 /* Note: continuing to accumulate gregno past when we've started
3023 spilling to the stack indicates the fact that we've started
3024 spilling to the stack to expand_builtin_saveregs. */
3025 cum->sysv_gregno = gregno + n_words;
3026 }
4697a36c 3027
4cc833b7
RH
3028 if (TARGET_DEBUG_ARG)
3029 {
3030 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3031 cum->words, cum->fregno);
3032 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3033 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3034 fprintf (stderr, "mode = %4s, named = %d\n",
3035 GET_MODE_NAME (mode), named);
3036 }
4697a36c
MM
3037 }
3038 else
4cc833b7
RH
3039 {
3040 int align = (TARGET_32BIT && (cum->words & 1) != 0
3041 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 3042
d34c5b80 3043 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 3044
a3170dc6
AH
3045 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3046 && TARGET_HARD_FLOAT && TARGET_FPRS)
fcce224d 3047 cum->fregno += (mode == TFmode ? 2 : 1);
4cc833b7
RH
3048
3049 if (TARGET_DEBUG_ARG)
3050 {
3051 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3052 cum->words, cum->fregno);
3053 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3054 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3055 fprintf (stderr, "named = %d, align = %d\n", named, align);
3056 }
3057 }
4697a36c
MM
3058}
3059\f
3060/* Determine where to put an argument to a function.
3061 Value is zero to push the argument on the stack,
3062 or a hard register in which to store the argument.
3063
3064 MODE is the argument's machine mode.
3065 TYPE is the data type of the argument (as a tree).
3066 This is null for libcalls where that information may
3067 not be available.
3068 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3069 the preceding args and about the function being called.
3070 NAMED is nonzero if this argument is a named parameter
3071 (otherwise it is an extra parameter matching an ellipsis).
3072
3073 On RS/6000 the first eight words of non-FP are normally in registers
3074 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3075 Under V.4, the first 8 FP args are in registers.
3076
3077 If this is floating-point and no prototype is specified, we use
3078 both an FP and integer register (or possibly FP reg and stack). Library
3079 functions (when TYPE is zero) always have the proper types for args,
3080 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3081 doesn't support PARALLEL anyway. */
4697a36c
MM
3082
3083struct rtx_def *
3084function_arg (cum, mode, type, named)
3085 CUMULATIVE_ARGS *cum;
3086 enum machine_mode mode;
3087 tree type;
20c29ebe 3088 int named;
4697a36c 3089{
4cc833b7 3090 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3091
a4f6c312
SS
3092 /* Return a marker to indicate whether CR1 needs to set or clear the
3093 bit that V.4 uses to say fp args were passed in registers.
3094 Assume that we don't need the marker for software floating point,
3095 or compiler generated library calls. */
4697a36c
MM
3096 if (mode == VOIDmode)
3097 {
f607bc57 3098 if (abi == ABI_V4
7509c759 3099 && cum->nargs_prototype < 0
4697a36c 3100 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3101 {
a3170dc6
AH
3102 /* For the SPE, we need to crxor CR6 always. */
3103 if (TARGET_SPE_ABI)
3104 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3105 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3106 return GEN_INT (cum->call_cookie
3107 | ((cum->fregno == FP_ARG_MIN_REG)
3108 ? CALL_V4_SET_FP_ARGS
3109 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3110 }
4697a36c 3111
7509c759 3112 return GEN_INT (cum->call_cookie);
4697a36c
MM
3113 }
3114
0ac081f6
AH
3115 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3116 {
20c29ebe 3117 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3118 return gen_rtx_REG (mode, cum->vregno);
3119 else
3120 return NULL;
3121 }
a4b0320c 3122 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3123 {
a4b0320c 3124 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3125 return gen_rtx_REG (mode, cum->sysv_gregno);
3126 else
3127 return NULL;
3128 }
f607bc57 3129 else if (abi == ABI_V4)
4697a36c 3130 {
a3170dc6 3131 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3132 && (mode == SFmode || mode == DFmode))
3133 {
3134 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3135 return gen_rtx_REG (mode, cum->fregno);
3136 else
3137 return NULL;
3138 }
3139 else
3140 {
3141 int n_words;
3142 int gregno = cum->sysv_gregno;
3143
3144 /* Aggregates and IEEE quad get passed by reference. */
3145 if ((type && AGGREGATE_TYPE_P (type))
3146 || mode == TFmode)
3147 n_words = 1;
3148 else
d34c5b80 3149 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3150
a4b0320c 3151 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3152 if (n_words == 2 && (gregno & 1) == 0)
3153 gregno += 1;
3154
a4b0320c
AH
3155 /* Long long and SPE vectors are not split between registers
3156 and stack. */
4cc833b7 3157 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3158 {
3159 /* SPE vectors in ... get split into 2 registers. */
3160 if (TARGET_SPE && TARGET_SPE_ABI
3161 && SPE_VECTOR_MODE (mode) && !named)
3162 {
3163 rtx r1, r2;
3164 enum machine_mode m = GET_MODE_INNER (mode);
3165
f9dd72da
AH
3166 if (mode == V1DImode)
3167 m = SImode;
3168
a4b0320c
AH
3169 r1 = gen_rtx_REG (m, gregno);
3170 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3171 r2 = gen_rtx_REG (m, gregno + 1);
3172 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3173 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3174 }
3175 return gen_rtx_REG (mode, gregno);
3176 }
4cc833b7
RH
3177 else
3178 return NULL;
3179 }
4697a36c 3180 }
4cc833b7
RH
3181 else
3182 {
3183 int align = (TARGET_32BIT && (cum->words & 1) != 0
3184 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3185 int align_words = cum->words + align;
4697a36c 3186
4cc833b7
RH
3187 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3188 return NULL_RTX;
3189
3190 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3191 {
3192 if (! type
3193 || ((cum->nargs_prototype > 0)
3194 /* IBM AIX extended its linkage convention definition always
3195 to require FP args after register save area hole on the
3196 stack. */
3197 && (DEFAULT_ABI != ABI_AIX
3198 || ! TARGET_XL_CALL
3199 || (align_words < GP_ARG_NUM_REG))))
3200 return gen_rtx_REG (mode, cum->fregno);
3201
3202 return gen_rtx_PARALLEL (mode,
3203 gen_rtvec (2,
39403d82 3204 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3205 ((align_words >= GP_ARG_NUM_REG)
3206 ? NULL_RTX
3207 : (align_words
d34c5b80 3208 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3209 > GP_ARG_NUM_REG
3210 /* If this is partially on the stack, then
3211 we only include the portion actually
3212 in registers here. */
39403d82 3213 ? gen_rtx_REG (SImode,
1c20ae99 3214 GP_ARG_MIN_REG + align_words)
39403d82 3215 : gen_rtx_REG (mode,
1c20ae99
JW
3216 GP_ARG_MIN_REG + align_words))),
3217 const0_rtx),
39403d82
DE
3218 gen_rtx_EXPR_LIST (VOIDmode,
3219 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3220 const0_rtx)));
4cc833b7
RH
3221 }
3222 else if (align_words < GP_ARG_NUM_REG)
3223 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3224 else
3225 return NULL_RTX;
4697a36c 3226 }
4697a36c
MM
3227}
3228\f
3229/* For an arg passed partly in registers and partly in memory,
3230 this is the number of registers used.
3231 For args passed entirely in registers or entirely in memory, zero. */
3232
3233int
3234function_arg_partial_nregs (cum, mode, type, named)
3235 CUMULATIVE_ARGS *cum;
3236 enum machine_mode mode;
3237 tree type;
d34c5b80 3238 int named ATTRIBUTE_UNUSED;
4697a36c 3239{
f607bc57 3240 if (DEFAULT_ABI == ABI_V4)
4697a36c 3241 return 0;
4697a36c 3242
0ac081f6
AH
3243 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3244 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3245 {
3246 if (cum->nargs_prototype >= 0)
3247 return 0;
3248 }
3249
3250 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3251 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3252 {
3253 int ret = GP_ARG_NUM_REG - cum->words;
3254 if (ret && TARGET_DEBUG_ARG)
3255 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3256
3257 return ret;
3258 }
3259
3260 return 0;
3261}
3262\f
3263/* A C expression that indicates when an argument must be passed by
3264 reference. If nonzero for an argument, a copy of that argument is
3265 made in memory and a pointer to the argument is passed instead of
3266 the argument itself. The pointer is passed in whatever way is
3267 appropriate for passing a pointer to that type.
3268
3269 Under V.4, structures and unions are passed by reference. */
3270
3271int
3272function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3273 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3274 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3275 tree type;
296b8152 3276 int named ATTRIBUTE_UNUSED;
4697a36c 3277{
f607bc57 3278 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3279 && ((type && AGGREGATE_TYPE_P (type))
3280 || mode == TFmode))
4697a36c
MM
3281 {
3282 if (TARGET_DEBUG_ARG)
3283 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3284
3285 return 1;
3286 }
4697a36c
MM
3287
3288 return 0;
3289}
4697a36c
MM
3290\f
3291/* Perform any needed actions needed for a function that is receiving a
3292 variable number of arguments.
3293
3294 CUM is as above.
3295
3296 MODE and TYPE are the mode and type of the current parameter.
3297
3298 PRETEND_SIZE is a variable that should be set to the amount of stack
3299 that must be pushed by the prolog to pretend that our caller pushed
3300 it.
3301
3302 Normally, this macro will push all remaining incoming registers on the
3303 stack and set PRETEND_SIZE to the length of the registers pushed. */
3304
3305void
3306setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3307 CUMULATIVE_ARGS *cum;
3308 enum machine_mode mode;
3309 tree type;
3310 int *pretend_size;
3311 int no_rtl;
3312
3313{
4cc833b7
RH
3314 CUMULATIVE_ARGS next_cum;
3315 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3316 rtx save_area = NULL_RTX, mem;
dfafc897 3317 int first_reg_offset, set;
d34c5b80
DE
3318 tree fntype;
3319 int stdarg_p;
4697a36c 3320
d34c5b80
DE
3321 fntype = TREE_TYPE (current_function_decl);
3322 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3323 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3324 != void_type_node));
4cc833b7 3325
d34c5b80
DE
3326 /* For varargs, we do not want to skip the dummy va_dcl argument.
3327 For stdargs, we do want to skip the last named argument. */
3328 next_cum = *cum;
3329 if (stdarg_p)
3330 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3331
f607bc57 3332 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3333 {
4cc833b7 3334 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3335 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3336 if (! no_rtl)
2c4974b7 3337 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3338 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3339
3340 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3341 }
60e2d0ca 3342 else
4697a36c 3343 {
d34c5b80 3344 first_reg_offset = next_cum.words;
4cc833b7 3345 save_area = virtual_incoming_args_rtx;
00dba523 3346 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3347
3348 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3349 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3350 }
4697a36c 3351
dfafc897 3352 set = get_varargs_alias_set ();
c81fc13e 3353 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3354 {
dfafc897
FS
3355 mem = gen_rtx_MEM (BLKmode,
3356 plus_constant (save_area,
3357 first_reg_offset * reg_size)),
ba4828e0 3358 set_mem_alias_set (mem, set);
8ac61af7 3359 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3360
4cc833b7 3361 move_block_from_reg
dfafc897 3362 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3363 GP_ARG_NUM_REG - first_reg_offset,
3364 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
3365
3366 /* ??? Does ABI_V4 need this at all? */
4697a36c
MM
3367 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
3368 }
3369
4697a36c 3370 /* Save FP registers if needed. */
f607bc57 3371 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3372 && TARGET_HARD_FLOAT && TARGET_FPRS
3373 && ! no_rtl
4cc833b7 3374 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3375 {
4cc833b7 3376 int fregno = next_cum.fregno;
9ebbca7d 3377 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3378 rtx lab = gen_label_rtx ();
3379 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3380
4cc833b7 3381 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3382 pc_rtx,
39403d82 3383 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3384 gen_rtx_NE (VOIDmode, cr1,
3385 const0_rtx),
39403d82 3386 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3387 pc_rtx)));
3388
4cc833b7
RH
3389 while (fregno <= FP_ARG_V4_MAX_REG)
3390 {
dfafc897 3391 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3392 set_mem_alias_set (mem, set);
dfafc897 3393 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3394 fregno++;
3395 off += 8;
4697a36c 3396 }
4cc833b7
RH
3397
3398 emit_label (lab);
4697a36c 3399 }
4697a36c 3400}
4697a36c 3401
dfafc897 3402/* Create the va_list data type. */
2c4974b7 3403
dfafc897
FS
3404tree
3405rs6000_build_va_list ()
3406{
bab45a51 3407 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3408
9ebbca7d
GK
3409 /* For AIX, prefer 'char *' because that's what the system
3410 header files like. */
f607bc57 3411 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3412 return build_pointer_type (char_type_node);
dfafc897 3413
f1e639b1 3414 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3415 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3416
9ebbca7d
GK
3417 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3418 unsigned_char_type_node);
3419 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3420 unsigned_char_type_node);
dfafc897
FS
3421 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3422 ptr_type_node);
3423 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3424 ptr_type_node);
3425
3426 DECL_FIELD_CONTEXT (f_gpr) = record;
3427 DECL_FIELD_CONTEXT (f_fpr) = record;
3428 DECL_FIELD_CONTEXT (f_ovf) = record;
3429 DECL_FIELD_CONTEXT (f_sav) = record;
3430
bab45a51
FS
3431 TREE_CHAIN (record) = type_decl;
3432 TYPE_NAME (record) = type_decl;
dfafc897
FS
3433 TYPE_FIELDS (record) = f_gpr;
3434 TREE_CHAIN (f_gpr) = f_fpr;
3435 TREE_CHAIN (f_fpr) = f_ovf;
3436 TREE_CHAIN (f_ovf) = f_sav;
3437
3438 layout_type (record);
3439
3440 /* The correct type is an array type of one element. */
3441 return build_array_type (record, build_index_type (size_zero_node));
3442}
3443
3444/* Implement va_start. */
3445
3446void
e5faf155 3447rs6000_va_start (valist, nextarg)
dfafc897
FS
3448 tree valist;
3449 rtx nextarg;
4697a36c 3450{
dfafc897
FS
3451 HOST_WIDE_INT words, n_gpr, n_fpr;
3452 tree f_gpr, f_fpr, f_ovf, f_sav;
3453 tree gpr, fpr, ovf, sav, t;
2c4974b7 3454
dfafc897 3455 /* Only SVR4 needs something special. */
f607bc57 3456 if (DEFAULT_ABI != ABI_V4)
dfafc897 3457 {
e5faf155 3458 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3459 return;
3460 }
3461
973a648b 3462 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3463 f_fpr = TREE_CHAIN (f_gpr);
3464 f_ovf = TREE_CHAIN (f_fpr);
3465 f_sav = TREE_CHAIN (f_ovf);
3466
8ebecc3b 3467 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3468 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3469 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3470 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3471 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3472
3473 /* Count number of gp and fp argument registers used. */
4cc833b7 3474 words = current_function_args_info.words;
dfafc897
FS
3475 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3476 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3477
3478 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3479 {
3480 fputs ("va_start: words = ", stderr);
3481 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3482 fputs (", n_gpr = ", stderr);
3483 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3484 fputs (", n_fpr = ", stderr);
3485 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3486 putc ('\n', stderr);
3487 }
dfafc897
FS
3488
3489 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3490 TREE_SIDE_EFFECTS (t) = 1;
3491 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3492
3493 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3494 TREE_SIDE_EFFECTS (t) = 1;
3495 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3496
3497 /* Find the overflow area. */
3498 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3499 if (words != 0)
3500 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3501 build_int_2 (words * UNITS_PER_WORD, 0));
3502 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3503 TREE_SIDE_EFFECTS (t) = 1;
3504 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3505
3506 /* Find the register save area. */
3507 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3508 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3509 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3510 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3511 TREE_SIDE_EFFECTS (t) = 1;
3512 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3513}
3514
3515/* Implement va_arg. */
3516
3517rtx
3518rs6000_va_arg (valist, type)
3519 tree valist, type;
3520{
3521 tree f_gpr, f_fpr, f_ovf, f_sav;
3522 tree gpr, fpr, ovf, sav, reg, t, u;
3523 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3524 rtx lab_false, lab_over, addr_rtx, r;
3525
f607bc57 3526 if (DEFAULT_ABI != ABI_V4)
2a55fd42 3527 return std_expand_builtin_va_arg (valist, type);
dfafc897 3528
973a648b 3529 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3530 f_fpr = TREE_CHAIN (f_gpr);
3531 f_ovf = TREE_CHAIN (f_fpr);
3532 f_sav = TREE_CHAIN (f_ovf);
3533
8ebecc3b 3534 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3535 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3536 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3537 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3538 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3539
3540 size = int_size_in_bytes (type);
3541 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3542
dfafc897 3543 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3544 {
dfafc897
FS
3545 /* Aggregates and long doubles are passed by reference. */
3546 indirect_p = 1;
3547 reg = gpr;
3548 n_reg = 1;
3549 sav_ofs = 0;
3550 sav_scale = 4;
d3294cd9
FS
3551 size = UNITS_PER_WORD;
3552 rsize = 1;
dfafc897 3553 }
a3170dc6 3554 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3555 {
3556 /* FP args go in FP registers, if present. */
3557 indirect_p = 0;
3558 reg = fpr;
3559 n_reg = 1;
3560 sav_ofs = 8*4;
3561 sav_scale = 8;
4cc833b7 3562 }
dfafc897
FS
3563 else
3564 {
3565 /* Otherwise into GP registers. */
3566 indirect_p = 0;
3567 reg = gpr;
3568 n_reg = rsize;
3569 sav_ofs = 0;
3570 sav_scale = 4;
3571 }
3572
a4f6c312 3573 /* Pull the value out of the saved registers ... */
dfafc897
FS
3574
3575 lab_false = gen_label_rtx ();
3576 lab_over = gen_label_rtx ();
3577 addr_rtx = gen_reg_rtx (Pmode);
3578
16861f33
AH
3579 /* AltiVec vectors never go in registers. */
3580 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3581 {
41daaf0e
AH
3582 TREE_THIS_VOLATILE (reg) = 1;
3583 emit_cmp_and_jump_insns
3584 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3585 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3586 lab_false);
dfafc897 3587
41daaf0e
AH
3588 /* Long long is aligned in the registers. */
3589 if (n_reg > 1)
3590 {
3591 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3592 build_int_2 (n_reg - 1, 0));
3593 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3594 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3595 TREE_SIDE_EFFECTS (u) = 1;
3596 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3597 }
2c4974b7 3598
41daaf0e
AH
3599 if (sav_ofs)
3600 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3601 else
3602 t = sav;
2c4974b7 3603
41daaf0e
AH
3604 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3605 build_int_2 (n_reg, 0));
3606 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3607
41daaf0e
AH
3608 u = build1 (CONVERT_EXPR, integer_type_node, u);
3609 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3610
41daaf0e
AH
3611 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3612 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3613
41daaf0e
AH
3614 t = build (PLUS_EXPR, ptr_type_node, t, u);
3615 TREE_SIDE_EFFECTS (t) = 1;
3616
3617 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3618 if (r != addr_rtx)
3619 emit_move_insn (addr_rtx, r);
3620
3621 emit_jump_insn (gen_jump (lab_over));
3622 emit_barrier ();
3623 }
dfafc897 3624
dfafc897
FS
3625 emit_label (lab_false);
3626
a4f6c312 3627 /* ... otherwise out of the overflow area. */
dfafc897 3628
41daaf0e
AH
3629 /* Make sure we don't find reg 7 for the next int arg.
3630
3631 All AltiVec vectors go in the overflow area. So in the AltiVec
3632 case we need to get the vectors from the overflow area, but
3633 remember where the GPRs and FPRs are. */
16861f33
AH
3634 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3635 || !TARGET_ALTIVEC))
dfafc897
FS
3636 {
3637 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3638 TREE_SIDE_EFFECTS (t) = 1;
3639 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3640 }
3641
3642 /* Care for on-stack alignment if needed. */
3643 if (rsize <= 1)
3644 t = ovf;
3645 else
3646 {
41daaf0e
AH
3647 int align;
3648
16861f33
AH
3649 /* AltiVec vectors are 16 byte aligned. */
3650 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3651 align = 15;
3652 else
3653 align = 7;
3654
3655 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3656 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3657 }
3658 t = save_expr (t);
3659
3660 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3661 if (r != addr_rtx)
3662 emit_move_insn (addr_rtx, r);
3663
3664 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3665 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3666 TREE_SIDE_EFFECTS (t) = 1;
3667 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3668
3669 emit_label (lab_over);
3670
3671 if (indirect_p)
3672 {
3673 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3674 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3675 emit_move_insn (addr_rtx, r);
3676 }
3677
3678 return addr_rtx;
4697a36c 3679}
0ac081f6
AH
3680
3681/* Builtins. */
3682
6a2dd09a
RS
3683#define def_builtin(MASK, NAME, TYPE, CODE) \
3684do { \
3685 if ((MASK) & target_flags) \
3686 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3687 NULL, NULL_TREE); \
0ac081f6
AH
3688} while (0)
3689
24408032
AH
3690/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3691
2212663f 3692static const struct builtin_description bdesc_3arg[] =
24408032
AH
3693{
3694 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3695 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3696 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3697 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3698 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3699 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3700 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3701 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3702 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3703 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3704 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3705 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3706 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3707 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3708 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3709 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3710 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3711 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3712 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3713 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3714 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3715 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3716 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3717};
2212663f 3718
95385cbb
AH
3719/* DST operations: void foo (void *, const int, const char). */
3720
3721static const struct builtin_description bdesc_dst[] =
3722{
3723 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3724 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3725 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3726 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3727};
3728
2212663f 3729/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3730
a3170dc6 3731static struct builtin_description bdesc_2arg[] =
0ac081f6 3732{
f18c054f
DB
3733 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3734 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3735 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3736 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3737 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3738 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3739 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3740 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3741 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3742 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3743 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3744 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3745 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3746 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3747 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3748 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3749 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3750 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3751 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3752 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3753 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3754 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3755 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3756 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3757 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3758 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3759 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3760 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3761 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3762 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3763 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3764 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3765 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3766 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3767 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3768 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3769 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3770 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
3771 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3772 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3773 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3774 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3775 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3776 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3777 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3778 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3779 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3780 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3781 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3782 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3783 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3784 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3785 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3786 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3787 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3788 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3789 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3790 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3791 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3792 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3793 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3794 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3795 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3796 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3797 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3798 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3799 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3800 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3801 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3802 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3803 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3804 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3805 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3806 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3807 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3808 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3809 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3810 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3811 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3812 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3813 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3814 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3815 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3816 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3817 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3818 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3819 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3820 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3821 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3822 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3823 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3824 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3825 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3826 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3827 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3828 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3829 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3830 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3831 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3832 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3833 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3834 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3835 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3836 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3837 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3838 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3839 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3840 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3841 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3842 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3843 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3844 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3845 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
3846
3847 /* Place holder, leave as first spe builtin. */
3848 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3849 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3850 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3851 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3852 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3853 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3854 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3855 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3856 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3857 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3858 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3859 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3860 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3861 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3862 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3863 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3864 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3865 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3866 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3867 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3868 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3869 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3870 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3871 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3872 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3873 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3874 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3875 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3876 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3877 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3878 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3879 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3880 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3881 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3882 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3883 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3884 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3885 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3886 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
3887 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
3888 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
3889 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
3890 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
3891 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
3892 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
3893 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
3894 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
3895 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
3896 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
3897 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
3898 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
3899 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
3900 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
3901 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
3902 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
3903 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
3904 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
3905 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
3906 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
3907 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
3908 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
3909 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
3910 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
3911 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
3912 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
3913 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
3914 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
3915 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
3916 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
3917 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
3918 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
3919 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
3920 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
3921 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
3922 { 0, CODE_FOR_spe_evmwlsmf, "__builtin_spe_evmwlsmf", SPE_BUILTIN_EVMWLSMF },
3923 { 0, CODE_FOR_spe_evmwlsmfa, "__builtin_spe_evmwlsmfa", SPE_BUILTIN_EVMWLSMFA },
3924 { 0, CODE_FOR_spe_evmwlsmfaaw, "__builtin_spe_evmwlsmfaaw", SPE_BUILTIN_EVMWLSMFAAW },
3925 { 0, CODE_FOR_spe_evmwlsmfanw, "__builtin_spe_evmwlsmfanw", SPE_BUILTIN_EVMWLSMFANW },
3926 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
3927 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
3928 { 0, CODE_FOR_spe_evmwlssf, "__builtin_spe_evmwlssf", SPE_BUILTIN_EVMWLSSF },
3929 { 0, CODE_FOR_spe_evmwlssfa, "__builtin_spe_evmwlssfa", SPE_BUILTIN_EVMWLSSFA },
3930 { 0, CODE_FOR_spe_evmwlssfaaw, "__builtin_spe_evmwlssfaaw", SPE_BUILTIN_EVMWLSSFAAW },
3931 { 0, CODE_FOR_spe_evmwlssfanw, "__builtin_spe_evmwlssfanw", SPE_BUILTIN_EVMWLSSFANW },
3932 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
3933 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
3934 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
3935 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
3936 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
3937 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
3938 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
3939 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
3940 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
3941 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
3942 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
3943 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
3944 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
3945 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
3946 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
3947 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
3948 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
3949 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
3950 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
3951 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
3952 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
3953 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
3954 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
3955 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
3956 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
3957 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
3958 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
3959 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
3960 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
3961 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
3962 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
3963 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
3964 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
3965
3966 /* SPE binary operations expecting a 5-bit unsigned literal. */
3967 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
3968
3969 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
3970 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
3971 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
3972 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
3973 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
3974 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
3975 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
3976 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
3977 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
3978 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
3979 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
3980 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
3981 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
3982 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
3983 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
3984 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
3985 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
3986 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
3987 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
3988 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
3989 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
3990 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
3991 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
3992 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
3993 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
3994 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
3995
3996 /* Place-holder. Leave as last binary SPE builtin. */
3997 { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
3998};
3999
4000/* AltiVec predicates. */
4001
4002struct builtin_description_predicates
4003{
4004 const unsigned int mask;
4005 const enum insn_code icode;
4006 const char *opcode;
4007 const char *const name;
4008 const enum rs6000_builtins code;
4009};
4010
4011static const struct builtin_description_predicates bdesc_altivec_preds[] =
4012{
4013 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
4014 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
4015 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
4016 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
4017 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
4018 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
4019 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
4020 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
4021 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
4022 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
4023 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
4024 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
4025 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 4026};
24408032 4027
a3170dc6
AH
4028/* SPE predicates. */
4029static struct builtin_description bdesc_spe_predicates[] =
4030{
4031 /* Place-holder. Leave as first. */
4032 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
4033 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
4034 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
4035 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4036 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4037 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4038 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4039 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4040 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4041 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4042 /* Place-holder. Leave as last. */
4043 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4044};
4045
4046/* SPE evsel predicates. */
4047static struct builtin_description bdesc_spe_evsel[] =
4048{
4049 /* Place-holder. Leave as first. */
4050 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4051 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4052 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4053 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4054 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4055 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4056 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4057 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4058 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4059 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4060 /* Place-holder. Leave as last. */
4061 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4062};
4063
100c4561
AH
4064/* ABS* opreations. */
4065
4066static const struct builtin_description bdesc_abs[] =
4067{
4068 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4069 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4070 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4071 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4072 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4073 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4074 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4075};
4076
617e0e1d
DB
4077/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4078 foo (VECa). */
24408032 4079
a3170dc6 4080static struct builtin_description bdesc_1arg[] =
2212663f 4081{
617e0e1d
DB
4082 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4083 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4084 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4085 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4086 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4087 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4088 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4089 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4090 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4091 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4092 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4093 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4094 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4095 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4096 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4097 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4098 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4099
4100 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4101 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4102 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4103 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4104 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4105 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4106 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4107 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4108 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4109 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4110 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4111 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4112 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4113 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4114 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4115 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4116 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4117 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4118 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4119 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4120 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4121 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4122 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4123 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4124 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4125 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4126 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4127 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4128 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4129 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4130 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4131 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4132
4133 /* Place-holder. Leave as last unary SPE builtin. */
4134 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4135};
4136
4137static rtx
92898235 4138rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4139 enum insn_code icode;
4140 tree arglist;
4141 rtx target;
4142{
4143 rtx pat;
4144 tree arg0 = TREE_VALUE (arglist);
4145 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4146 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4147 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4148
0559cc77
DE
4149 if (icode == CODE_FOR_nothing)
4150 /* Builtin not supported on this processor. */
4151 return 0;
4152
20e26713
AH
4153 /* If we got invalid arguments bail out before generating bad rtl. */
4154 if (arg0 == error_mark_node)
9a171fcd 4155 return const0_rtx;
20e26713 4156
0559cc77
DE
4157 if (icode == CODE_FOR_altivec_vspltisb
4158 || icode == CODE_FOR_altivec_vspltish
4159 || icode == CODE_FOR_altivec_vspltisw
4160 || icode == CODE_FOR_spe_evsplatfi
4161 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4162 {
4163 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4164 if (GET_CODE (op0) != CONST_INT
4165 || INTVAL (op0) > 0x1f
4166 || INTVAL (op0) < -0x1f)
4167 {
4168 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4169 return const0_rtx;
b44140e7 4170 }
b44140e7
AH
4171 }
4172
c62f2db5 4173 if (target == 0
2212663f
DB
4174 || GET_MODE (target) != tmode
4175 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4176 target = gen_reg_rtx (tmode);
4177
4178 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4179 op0 = copy_to_mode_reg (mode0, op0);
4180
4181 pat = GEN_FCN (icode) (target, op0);
4182 if (! pat)
4183 return 0;
4184 emit_insn (pat);
0ac081f6 4185
2212663f
DB
4186 return target;
4187}
ae4b4a02 4188
100c4561
AH
4189static rtx
4190altivec_expand_abs_builtin (icode, arglist, target)
4191 enum insn_code icode;
4192 tree arglist;
4193 rtx target;
4194{
4195 rtx pat, scratch1, scratch2;
4196 tree arg0 = TREE_VALUE (arglist);
4197 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4198 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4199 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4200
4201 /* If we have invalid arguments, bail out before generating bad rtl. */
4202 if (arg0 == error_mark_node)
9a171fcd 4203 return const0_rtx;
100c4561
AH
4204
4205 if (target == 0
4206 || GET_MODE (target) != tmode
4207 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4208 target = gen_reg_rtx (tmode);
4209
4210 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4211 op0 = copy_to_mode_reg (mode0, op0);
4212
4213 scratch1 = gen_reg_rtx (mode0);
4214 scratch2 = gen_reg_rtx (mode0);
4215
4216 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4217 if (! pat)
4218 return 0;
4219 emit_insn (pat);
4220
4221 return target;
4222}
4223
0ac081f6 4224static rtx
92898235 4225rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4226 enum insn_code icode;
4227 tree arglist;
4228 rtx target;
4229{
4230 rtx pat;
4231 tree arg0 = TREE_VALUE (arglist);
4232 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4233 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4234 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4235 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4236 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4237 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4238
0559cc77
DE
4239 if (icode == CODE_FOR_nothing)
4240 /* Builtin not supported on this processor. */
4241 return 0;
4242
20e26713
AH
4243 /* If we got invalid arguments bail out before generating bad rtl. */
4244 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4245 return const0_rtx;
20e26713 4246
0559cc77
DE
4247 if (icode == CODE_FOR_altivec_vcfux
4248 || icode == CODE_FOR_altivec_vcfsx
4249 || icode == CODE_FOR_altivec_vctsxs
4250 || icode == CODE_FOR_altivec_vctuxs
4251 || icode == CODE_FOR_altivec_vspltb
4252 || icode == CODE_FOR_altivec_vsplth
4253 || icode == CODE_FOR_altivec_vspltw
4254 || icode == CODE_FOR_spe_evaddiw
4255 || icode == CODE_FOR_spe_evldd
4256 || icode == CODE_FOR_spe_evldh
4257 || icode == CODE_FOR_spe_evldw
4258 || icode == CODE_FOR_spe_evlhhesplat
4259 || icode == CODE_FOR_spe_evlhhossplat
4260 || icode == CODE_FOR_spe_evlhhousplat
4261 || icode == CODE_FOR_spe_evlwhe
4262 || icode == CODE_FOR_spe_evlwhos
4263 || icode == CODE_FOR_spe_evlwhou
4264 || icode == CODE_FOR_spe_evlwhsplat
4265 || icode == CODE_FOR_spe_evlwwsplat
4266 || icode == CODE_FOR_spe_evrlwi
4267 || icode == CODE_FOR_spe_evslwi
4268 || icode == CODE_FOR_spe_evsrwis
4269 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4270 {
4271 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4272 if (TREE_CODE (arg1) != INTEGER_CST
4273 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4274 {
4275 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4276 return const0_rtx;
b44140e7 4277 }
b44140e7
AH
4278 }
4279
c62f2db5 4280 if (target == 0
0ac081f6
AH
4281 || GET_MODE (target) != tmode
4282 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4283 target = gen_reg_rtx (tmode);
4284
4285 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4286 op0 = copy_to_mode_reg (mode0, op0);
4287 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4288 op1 = copy_to_mode_reg (mode1, op1);
4289
4290 pat = GEN_FCN (icode) (target, op0, op1);
4291 if (! pat)
4292 return 0;
4293 emit_insn (pat);
4294
4295 return target;
4296}
6525c0e7 4297
ae4b4a02
AH
4298static rtx
4299altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4300 enum insn_code icode;
4301 const char *opcode;
4302 tree arglist;
4303 rtx target;
4304{
4305 rtx pat, scratch;
4306 tree cr6_form = TREE_VALUE (arglist);
4307 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4308 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4309 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4310 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4311 enum machine_mode tmode = SImode;
4312 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4313 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4314 int cr6_form_int;
4315
4316 if (TREE_CODE (cr6_form) != INTEGER_CST)
4317 {
4318 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4319 return const0_rtx;
ae4b4a02
AH
4320 }
4321 else
4322 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4323
4324 if (mode0 != mode1)
4325 abort ();
4326
4327 /* If we have invalid arguments, bail out before generating bad rtl. */
4328 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4329 return const0_rtx;
ae4b4a02
AH
4330
4331 if (target == 0
4332 || GET_MODE (target) != tmode
4333 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4334 target = gen_reg_rtx (tmode);
4335
4336 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4337 op0 = copy_to_mode_reg (mode0, op0);
4338 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4339 op1 = copy_to_mode_reg (mode1, op1);
4340
4341 scratch = gen_reg_rtx (mode0);
4342
4343 pat = GEN_FCN (icode) (scratch, op0, op1,
4344 gen_rtx (SYMBOL_REF, Pmode, opcode));
4345 if (! pat)
4346 return 0;
4347 emit_insn (pat);
4348
4349 /* The vec_any* and vec_all* predicates use the same opcodes for two
4350 different operations, but the bits in CR6 will be different
4351 depending on what information we want. So we have to play tricks
4352 with CR6 to get the right bits out.
4353
4354 If you think this is disgusting, look at the specs for the
4355 AltiVec predicates. */
4356
4357 switch (cr6_form_int)
4358 {
4359 case 0:
4360 emit_insn (gen_cr6_test_for_zero (target));
4361 break;
4362 case 1:
4363 emit_insn (gen_cr6_test_for_zero_reverse (target));
4364 break;
4365 case 2:
4366 emit_insn (gen_cr6_test_for_lt (target));
4367 break;
4368 case 3:
4369 emit_insn (gen_cr6_test_for_lt_reverse (target));
4370 break;
4371 default:
4372 error ("argument 1 of __builtin_altivec_predicate is out of range");
4373 break;
4374 }
4375
4376 return target;
4377}
4378
6525c0e7
AH
4379static rtx
4380altivec_expand_stv_builtin (icode, arglist)
4381 enum insn_code icode;
4382 tree arglist;
4383{
4384 tree arg0 = TREE_VALUE (arglist);
4385 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4386 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4387 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4388 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4389 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4390 rtx pat;
4391 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4392 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4393 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4394
4395 /* Invalid arguments. Bail before doing anything stoopid! */
4396 if (arg0 == error_mark_node
4397 || arg1 == error_mark_node
4398 || arg2 == error_mark_node)
9a171fcd 4399 return const0_rtx;
6525c0e7
AH
4400
4401 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4402 op0 = copy_to_mode_reg (mode2, op0);
4403 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4404 op1 = copy_to_mode_reg (mode0, op1);
4405 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4406 op2 = copy_to_mode_reg (mode1, op2);
4407
4408 pat = GEN_FCN (icode) (op1, op2, op0);
4409 if (pat)
4410 emit_insn (pat);
4411 return NULL_RTX;
4412}
4413
2212663f 4414static rtx
92898235 4415rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4416 enum insn_code icode;
4417 tree arglist;
4418 rtx target;
4419{
4420 rtx pat;
4421 tree arg0 = TREE_VALUE (arglist);
4422 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4423 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4424 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4425 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4426 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4427 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4428 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4429 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4430 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4431
774b5662
DE
4432 if (icode == CODE_FOR_nothing)
4433 /* Builtin not supported on this processor. */
4434 return 0;
4435
20e26713
AH
4436 /* If we got invalid arguments bail out before generating bad rtl. */
4437 if (arg0 == error_mark_node
4438 || arg1 == error_mark_node
4439 || arg2 == error_mark_node)
9a171fcd 4440 return const0_rtx;
20e26713 4441
774b5662
DE
4442 if (icode == CODE_FOR_altivec_vsldoi_4sf
4443 || icode == CODE_FOR_altivec_vsldoi_4si
4444 || icode == CODE_FOR_altivec_vsldoi_8hi
4445 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4446 {
4447 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4448 if (TREE_CODE (arg2) != INTEGER_CST
4449 || TREE_INT_CST_LOW (arg2) & ~0xf)
4450 {
4451 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4452 return const0_rtx;
b44140e7 4453 }
b44140e7
AH
4454 }
4455
c62f2db5 4456 if (target == 0
2212663f
DB
4457 || GET_MODE (target) != tmode
4458 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4459 target = gen_reg_rtx (tmode);
4460
4461 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4462 op0 = copy_to_mode_reg (mode0, op0);
4463 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4464 op1 = copy_to_mode_reg (mode1, op1);
4465 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4466 op2 = copy_to_mode_reg (mode2, op2);
4467
4468 pat = GEN_FCN (icode) (target, op0, op1, op2);
4469 if (! pat)
4470 return 0;
4471 emit_insn (pat);
4472
4473 return target;
4474}
92898235 4475
3a9b8c7e 4476/* Expand the lvx builtins. */
0ac081f6 4477static rtx
3a9b8c7e 4478altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4479 tree exp;
4480 rtx target;
92898235 4481 bool *expandedp;
0ac081f6 4482{
0ac081f6
AH
4483 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4484 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4485 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4486 tree arg0;
4487 enum machine_mode tmode, mode0;
7c3abc73 4488 rtx pat, op0;
3a9b8c7e 4489 enum insn_code icode;
92898235 4490
0ac081f6
AH
4491 switch (fcode)
4492 {
f18c054f
DB
4493 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4494 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4495 break;
f18c054f
DB
4496 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4497 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4498 break;
4499 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4500 icode = CODE_FOR_altivec_lvx_4si;
4501 break;
4502 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4503 icode = CODE_FOR_altivec_lvx_4sf;
4504 break;
4505 default:
4506 *expandedp = false;
4507 return NULL_RTX;
4508 }
0ac081f6 4509
3a9b8c7e 4510 *expandedp = true;
f18c054f 4511
3a9b8c7e
AH
4512 arg0 = TREE_VALUE (arglist);
4513 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4514 tmode = insn_data[icode].operand[0].mode;
4515 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4516
3a9b8c7e
AH
4517 if (target == 0
4518 || GET_MODE (target) != tmode
4519 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4520 target = gen_reg_rtx (tmode);
24408032 4521
3a9b8c7e
AH
4522 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4523 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4524
3a9b8c7e
AH
4525 pat = GEN_FCN (icode) (target, op0);
4526 if (! pat)
4527 return 0;
4528 emit_insn (pat);
4529 return target;
4530}
f18c054f 4531
3a9b8c7e
AH
4532/* Expand the stvx builtins. */
4533static rtx
4534altivec_expand_st_builtin (exp, target, expandedp)
4535 tree exp;
7c3abc73 4536 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4537 bool *expandedp;
4538{
4539 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4540 tree arglist = TREE_OPERAND (exp, 1);
4541 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4542 tree arg0, arg1;
4543 enum machine_mode mode0, mode1;
7c3abc73 4544 rtx pat, op0, op1;
3a9b8c7e 4545 enum insn_code icode;
f18c054f 4546
3a9b8c7e
AH
4547 switch (fcode)
4548 {
4549 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4550 icode = CODE_FOR_altivec_stvx_16qi;
4551 break;
4552 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4553 icode = CODE_FOR_altivec_stvx_8hi;
4554 break;
4555 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4556 icode = CODE_FOR_altivec_stvx_4si;
4557 break;
4558 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4559 icode = CODE_FOR_altivec_stvx_4sf;
4560 break;
4561 default:
4562 *expandedp = false;
4563 return NULL_RTX;
4564 }
24408032 4565
3a9b8c7e
AH
4566 arg0 = TREE_VALUE (arglist);
4567 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4568 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4569 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4570 mode0 = insn_data[icode].operand[0].mode;
4571 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4572
3a9b8c7e
AH
4573 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4574 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4575 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4576 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4577
3a9b8c7e
AH
4578 pat = GEN_FCN (icode) (op0, op1);
4579 if (pat)
4580 emit_insn (pat);
f18c054f 4581
3a9b8c7e
AH
4582 *expandedp = true;
4583 return NULL_RTX;
4584}
f18c054f 4585
3a9b8c7e
AH
4586/* Expand the dst builtins. */
4587static rtx
4588altivec_expand_dst_builtin (exp, target, expandedp)
4589 tree exp;
7c3abc73 4590 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4591 bool *expandedp;
4592{
4593 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4594 tree arglist = TREE_OPERAND (exp, 1);
4595 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4596 tree arg0, arg1, arg2;
4597 enum machine_mode mode0, mode1, mode2;
7c3abc73 4598 rtx pat, op0, op1, op2;
3a9b8c7e 4599 struct builtin_description *d;
a3170dc6 4600 size_t i;
f18c054f 4601
3a9b8c7e 4602 *expandedp = false;
f18c054f 4603
3a9b8c7e
AH
4604 /* Handle DST variants. */
4605 d = (struct builtin_description *) bdesc_dst;
4606 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4607 if (d->code == fcode)
4608 {
4609 arg0 = TREE_VALUE (arglist);
4610 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4611 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4612 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4613 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4614 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4615 mode0 = insn_data[d->icode].operand[0].mode;
4616 mode1 = insn_data[d->icode].operand[1].mode;
4617 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4618
3a9b8c7e
AH
4619 /* Invalid arguments, bail out before generating bad rtl. */
4620 if (arg0 == error_mark_node
4621 || arg1 == error_mark_node
4622 || arg2 == error_mark_node)
4623 return const0_rtx;
f18c054f 4624
3a9b8c7e
AH
4625 if (TREE_CODE (arg2) != INTEGER_CST
4626 || TREE_INT_CST_LOW (arg2) & ~0x3)
4627 {
4628 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4629 return const0_rtx;
4630 }
f18c054f 4631
3a9b8c7e
AH
4632 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4633 op0 = copy_to_mode_reg (mode0, op0);
4634 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4635 op1 = copy_to_mode_reg (mode1, op1);
24408032 4636
3a9b8c7e
AH
4637 pat = GEN_FCN (d->icode) (op0, op1, op2);
4638 if (pat != 0)
4639 emit_insn (pat);
f18c054f 4640
3a9b8c7e
AH
4641 *expandedp = true;
4642 return NULL_RTX;
4643 }
f18c054f 4644
3a9b8c7e
AH
4645 return NULL_RTX;
4646}
24408032 4647
3a9b8c7e
AH
4648/* Expand the builtin in EXP and store the result in TARGET. Store
4649 true in *EXPANDEDP if we found a builtin to expand. */
4650static rtx
4651altivec_expand_builtin (exp, target, expandedp)
4652 tree exp;
4653 rtx target;
4654 bool *expandedp;
4655{
4656 struct builtin_description *d;
4657 struct builtin_description_predicates *dp;
4658 size_t i;
4659 enum insn_code icode;
4660 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4661 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4662 tree arg0;
4663 rtx op0, pat;
4664 enum machine_mode tmode, mode0;
3a9b8c7e 4665 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4666
3a9b8c7e
AH
4667 target = altivec_expand_ld_builtin (exp, target, expandedp);
4668 if (*expandedp)
4669 return target;
0ac081f6 4670
3a9b8c7e
AH
4671 target = altivec_expand_st_builtin (exp, target, expandedp);
4672 if (*expandedp)
4673 return target;
4674
4675 target = altivec_expand_dst_builtin (exp, target, expandedp);
4676 if (*expandedp)
4677 return target;
4678
4679 *expandedp = true;
95385cbb 4680
3a9b8c7e
AH
4681 switch (fcode)
4682 {
6525c0e7
AH
4683 case ALTIVEC_BUILTIN_STVX:
4684 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4685 case ALTIVEC_BUILTIN_STVEBX:
4686 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4687 case ALTIVEC_BUILTIN_STVEHX:
4688 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4689 case ALTIVEC_BUILTIN_STVEWX:
4690 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4691 case ALTIVEC_BUILTIN_STVXL:
4692 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4693
95385cbb
AH
4694 case ALTIVEC_BUILTIN_MFVSCR:
4695 icode = CODE_FOR_altivec_mfvscr;
4696 tmode = insn_data[icode].operand[0].mode;
4697
4698 if (target == 0
4699 || GET_MODE (target) != tmode
4700 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4701 target = gen_reg_rtx (tmode);
4702
4703 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4704 if (! pat)
4705 return 0;
4706 emit_insn (pat);
95385cbb
AH
4707 return target;
4708
4709 case ALTIVEC_BUILTIN_MTVSCR:
4710 icode = CODE_FOR_altivec_mtvscr;
4711 arg0 = TREE_VALUE (arglist);
4712 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4713 mode0 = insn_data[icode].operand[0].mode;
4714
4715 /* If we got invalid arguments bail out before generating bad rtl. */
4716 if (arg0 == error_mark_node)
9a171fcd 4717 return const0_rtx;
95385cbb
AH
4718
4719 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4720 op0 = copy_to_mode_reg (mode0, op0);
4721
4722 pat = GEN_FCN (icode) (op0);
4723 if (pat)
4724 emit_insn (pat);
4725 return NULL_RTX;
3a9b8c7e 4726
95385cbb
AH
4727 case ALTIVEC_BUILTIN_DSSALL:
4728 emit_insn (gen_altivec_dssall ());
4729 return NULL_RTX;
4730
4731 case ALTIVEC_BUILTIN_DSS:
4732 icode = CODE_FOR_altivec_dss;
4733 arg0 = TREE_VALUE (arglist);
4734 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4735 mode0 = insn_data[icode].operand[0].mode;
4736
4737 /* If we got invalid arguments bail out before generating bad rtl. */
4738 if (arg0 == error_mark_node)
9a171fcd 4739 return const0_rtx;
95385cbb 4740
b44140e7
AH
4741 if (TREE_CODE (arg0) != INTEGER_CST
4742 || TREE_INT_CST_LOW (arg0) & ~0x3)
4743 {
4744 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4745 return const0_rtx;
b44140e7
AH
4746 }
4747
95385cbb
AH
4748 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4749 op0 = copy_to_mode_reg (mode0, op0);
4750
4751 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4752 return NULL_RTX;
4753 }
24408032 4754
100c4561
AH
4755 /* Expand abs* operations. */
4756 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4757 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4758 if (d->code == fcode)
4759 return altivec_expand_abs_builtin (d->icode, arglist, target);
4760
ae4b4a02
AH
4761 /* Expand the AltiVec predicates. */
4762 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4763 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4764 if (dp->code == fcode)
4765 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4766
6525c0e7
AH
4767 /* LV* are funky. We initialized them differently. */
4768 switch (fcode)
4769 {
4770 case ALTIVEC_BUILTIN_LVSL:
92898235 4771 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
4772 arglist, target);
4773 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
4774 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4775 arglist, target);
6525c0e7 4776 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
4777 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4778 arglist, target);
6525c0e7 4779 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
4780 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4781 arglist, target);
6525c0e7 4782 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
4783 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4784 arglist, target);
6525c0e7 4785 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
4786 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4787 arglist, target);
6525c0e7 4788 case ALTIVEC_BUILTIN_LVX:
92898235
AH
4789 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4790 arglist, target);
6525c0e7
AH
4791 default:
4792 break;
4793 /* Fall through. */
4794 }
95385cbb 4795
92898235 4796 *expandedp = false;
0ac081f6
AH
4797 return NULL_RTX;
4798}
4799
a3170dc6
AH
4800/* Binops that need to be initialized manually, but can be expanded
4801 automagically by rs6000_expand_binop_builtin. */
4802static struct builtin_description bdesc_2arg_spe[] =
4803{
4804 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4805 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4806 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4807 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4808 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4809 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4810 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4811 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4812 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4813 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4814 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4815 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4816 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4817 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4818 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4819 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4820 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4821 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4822 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4823 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4824 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4825 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4826};
4827
4828/* Expand the builtin in EXP and store the result in TARGET. Store
4829 true in *EXPANDEDP if we found a builtin to expand.
4830
4831 This expands the SPE builtins that are not simple unary and binary
4832 operations. */
4833static rtx
4834spe_expand_builtin (exp, target, expandedp)
4835 tree exp;
4836 rtx target;
4837 bool *expandedp;
4838{
4839 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4840 tree arglist = TREE_OPERAND (exp, 1);
4841 tree arg1, arg0;
4842 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4843 enum insn_code icode;
4844 enum machine_mode tmode, mode0;
4845 rtx pat, op0;
4846 struct builtin_description *d;
4847 size_t i;
4848
4849 *expandedp = true;
4850
4851 /* Syntax check for a 5-bit unsigned immediate. */
4852 switch (fcode)
4853 {
4854 case SPE_BUILTIN_EVSTDD:
4855 case SPE_BUILTIN_EVSTDH:
4856 case SPE_BUILTIN_EVSTDW:
4857 case SPE_BUILTIN_EVSTWHE:
4858 case SPE_BUILTIN_EVSTWHO:
4859 case SPE_BUILTIN_EVSTWWE:
4860 case SPE_BUILTIN_EVSTWWO:
4861 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4862 if (TREE_CODE (arg1) != INTEGER_CST
4863 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4864 {
4865 error ("argument 2 must be a 5-bit unsigned literal");
4866 return const0_rtx;
4867 }
4868 break;
4869 default:
4870 break;
4871 }
4872
4873 d = (struct builtin_description *) bdesc_2arg_spe;
4874 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4875 if (d->code == fcode)
4876 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4877
4878 d = (struct builtin_description *) bdesc_spe_predicates;
4879 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4880 if (d->code == fcode)
4881 return spe_expand_predicate_builtin (d->icode, arglist, target);
4882
4883 d = (struct builtin_description *) bdesc_spe_evsel;
4884 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4885 if (d->code == fcode)
4886 return spe_expand_evsel_builtin (d->icode, arglist, target);
4887
4888 switch (fcode)
4889 {
4890 case SPE_BUILTIN_EVSTDDX:
4891 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4892 case SPE_BUILTIN_EVSTDHX:
4893 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4894 case SPE_BUILTIN_EVSTDWX:
4895 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
4896 case SPE_BUILTIN_EVSTWHEX:
4897 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
4898 case SPE_BUILTIN_EVSTWHOX:
4899 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
4900 case SPE_BUILTIN_EVSTWWEX:
4901 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
4902 case SPE_BUILTIN_EVSTWWOX:
4903 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
4904 case SPE_BUILTIN_EVSTDD:
4905 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
4906 case SPE_BUILTIN_EVSTDH:
4907 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
4908 case SPE_BUILTIN_EVSTDW:
4909 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
4910 case SPE_BUILTIN_EVSTWHE:
4911 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
4912 case SPE_BUILTIN_EVSTWHO:
4913 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
4914 case SPE_BUILTIN_EVSTWWE:
4915 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
4916 case SPE_BUILTIN_EVSTWWO:
4917 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
4918 case SPE_BUILTIN_MFSPEFSCR:
4919 icode = CODE_FOR_spe_mfspefscr;
4920 tmode = insn_data[icode].operand[0].mode;
4921
4922 if (target == 0
4923 || GET_MODE (target) != tmode
4924 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4925 target = gen_reg_rtx (tmode);
4926
4927 pat = GEN_FCN (icode) (target);
4928 if (! pat)
4929 return 0;
4930 emit_insn (pat);
4931 return target;
4932 case SPE_BUILTIN_MTSPEFSCR:
4933 icode = CODE_FOR_spe_mtspefscr;
4934 arg0 = TREE_VALUE (arglist);
4935 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4936 mode0 = insn_data[icode].operand[0].mode;
4937
4938 if (arg0 == error_mark_node)
4939 return const0_rtx;
4940
4941 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4942 op0 = copy_to_mode_reg (mode0, op0);
4943
4944 pat = GEN_FCN (icode) (op0);
4945 if (pat)
4946 emit_insn (pat);
4947 return NULL_RTX;
4948 default:
4949 break;
4950 }
4951
4952 *expandedp = false;
4953 return NULL_RTX;
4954}
4955
4956static rtx
4957spe_expand_predicate_builtin (icode, arglist, target)
4958 enum insn_code icode;
4959 tree arglist;
4960 rtx target;
4961{
4962 rtx pat, scratch, tmp;
4963 tree form = TREE_VALUE (arglist);
4964 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4965 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4966 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4967 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4968 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4969 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4970 int form_int;
4971 enum rtx_code code;
4972
4973 if (TREE_CODE (form) != INTEGER_CST)
4974 {
4975 error ("argument 1 of __builtin_spe_predicate must be a constant");
4976 return const0_rtx;
4977 }
4978 else
4979 form_int = TREE_INT_CST_LOW (form);
4980
4981 if (mode0 != mode1)
4982 abort ();
4983
4984 if (arg0 == error_mark_node || arg1 == error_mark_node)
4985 return const0_rtx;
4986
4987 if (target == 0
4988 || GET_MODE (target) != SImode
4989 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
4990 target = gen_reg_rtx (SImode);
4991
4992 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4993 op0 = copy_to_mode_reg (mode0, op0);
4994 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4995 op1 = copy_to_mode_reg (mode1, op1);
4996
4997 scratch = gen_reg_rtx (CCmode);
4998
4999 pat = GEN_FCN (icode) (scratch, op0, op1);
5000 if (! pat)
5001 return const0_rtx;
5002 emit_insn (pat);
5003
5004 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
5005 _lower_. We use one compare, but look in different bits of the
5006 CR for each variant.
5007
5008 There are 2 elements in each SPE simd type (upper/lower). The CR
5009 bits are set as follows:
5010
5011 BIT0 | BIT 1 | BIT 2 | BIT 3
5012 U | L | (U | L) | (U & L)
5013
5014 So, for an "all" relationship, BIT 3 would be set.
5015 For an "any" relationship, BIT 2 would be set. Etc.
5016
5017 Following traditional nomenclature, these bits map to:
5018
5019 BIT0 | BIT 1 | BIT 2 | BIT 3
5020 LT | GT | EQ | OV
5021
5022 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
5023 */
5024
5025 switch (form_int)
5026 {
5027 /* All variant. OV bit. */
5028 case 0:
5029 /* We need to get to the OV bit, which is the ORDERED bit. We
5030 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
5031 that's ugly and will trigger a validate_condition_mode abort.
5032 So let's just use another pattern. */
5033 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
5034 return target;
5035 /* Any variant. EQ bit. */
5036 case 1:
5037 code = EQ;
5038 break;
5039 /* Upper variant. LT bit. */
5040 case 2:
5041 code = LT;
5042 break;
5043 /* Lower variant. GT bit. */
5044 case 3:
5045 code = GT;
5046 break;
5047 default:
5048 error ("argument 1 of __builtin_spe_predicate is out of range");
5049 return const0_rtx;
5050 }
5051
5052 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5053 emit_move_insn (target, tmp);
5054
5055 return target;
5056}
5057
5058/* The evsel builtins look like this:
5059
5060 e = __builtin_spe_evsel_OP (a, b, c, d);
5061
5062 and work like this:
5063
5064 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5065 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5066*/
5067
5068static rtx
5069spe_expand_evsel_builtin (icode, arglist, target)
5070 enum insn_code icode;
5071 tree arglist;
5072 rtx target;
5073{
5074 rtx pat, scratch;
5075 tree arg0 = TREE_VALUE (arglist);
5076 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5077 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5078 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5079 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5080 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5081 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5082 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5083 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5084 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5085
5086 if (mode0 != mode1)
5087 abort ();
5088
5089 if (arg0 == error_mark_node || arg1 == error_mark_node
5090 || arg2 == error_mark_node || arg3 == error_mark_node)
5091 return const0_rtx;
5092
5093 if (target == 0
5094 || GET_MODE (target) != mode0
5095 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5096 target = gen_reg_rtx (mode0);
5097
5098 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5099 op0 = copy_to_mode_reg (mode0, op0);
5100 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5101 op1 = copy_to_mode_reg (mode0, op1);
5102 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5103 op2 = copy_to_mode_reg (mode0, op2);
5104 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5105 op3 = copy_to_mode_reg (mode0, op3);
5106
5107 /* Generate the compare. */
5108 scratch = gen_reg_rtx (CCmode);
5109 pat = GEN_FCN (icode) (scratch, op0, op1);
5110 if (! pat)
5111 return const0_rtx;
5112 emit_insn (pat);
5113
5114 if (mode0 == V2SImode)
5115 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5116 else
5117 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5118
5119 return target;
5120}
5121
0ac081f6
AH
5122/* Expand an expression EXP that calls a built-in function,
5123 with result going to TARGET if that's convenient
5124 (and in mode MODE if that's convenient).
5125 SUBTARGET may be used as the target for computing one of EXP's operands.
5126 IGNORE is nonzero if the value is to be ignored. */
5127
5128static rtx
5129rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5130 tree exp;
5131 rtx target;
00b960c7
AH
5132 rtx subtarget ATTRIBUTE_UNUSED;
5133 enum machine_mode mode ATTRIBUTE_UNUSED;
5134 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5135{
92898235
AH
5136 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5137 tree arglist = TREE_OPERAND (exp, 1);
5138 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5139 struct builtin_description *d;
5140 size_t i;
5141 rtx ret;
5142 bool success;
5143
0ac081f6 5144 if (TARGET_ALTIVEC)
92898235
AH
5145 {
5146 ret = altivec_expand_builtin (exp, target, &success);
5147
a3170dc6
AH
5148 if (success)
5149 return ret;
5150 }
5151 if (TARGET_SPE)
5152 {
5153 ret = spe_expand_builtin (exp, target, &success);
5154
92898235
AH
5155 if (success)
5156 return ret;
5157 }
5158
0559cc77
DE
5159 if (TARGET_ALTIVEC || TARGET_SPE)
5160 {
5161 /* Handle simple unary operations. */
5162 d = (struct builtin_description *) bdesc_1arg;
5163 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5164 if (d->code == fcode)
5165 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5166
5167 /* Handle simple binary operations. */
5168 d = (struct builtin_description *) bdesc_2arg;
5169 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5170 if (d->code == fcode)
5171 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5172
5173 /* Handle simple ternary operations. */
5174 d = (struct builtin_description *) bdesc_3arg;
5175 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5176 if (d->code == fcode)
5177 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5178 }
0ac081f6
AH
5179
5180 abort ();
92898235 5181 return NULL_RTX;
0ac081f6
AH
5182}
5183
5184static void
6fa3f289 5185rs6000_init_builtins ()
0ac081f6 5186{
a3170dc6
AH
5187 if (TARGET_SPE)
5188 spe_init_builtins ();
0ac081f6
AH
5189 if (TARGET_ALTIVEC)
5190 altivec_init_builtins ();
0559cc77
DE
5191 if (TARGET_ALTIVEC || TARGET_SPE)
5192 rs6000_common_init_builtins ();
0ac081f6
AH
5193}
5194
a3170dc6
AH
5195/* Search through a set of builtins and enable the mask bits.
5196 DESC is an array of builtins.
5197 SIZE is the totaly number of builtins.
5198 START is the builtin enum at which to start.
5199 END is the builtin enum at which to end. */
0ac081f6 5200static void
a3170dc6
AH
5201enable_mask_for_builtins (desc, size, start, end)
5202 struct builtin_description *desc;
5203 int size;
5204 enum rs6000_builtins start, end;
5205{
5206 int i;
5207
5208 for (i = 0; i < size; ++i)
5209 if (desc[i].code == start)
5210 break;
5211
5212 if (i == size)
5213 return;
5214
5215 for (; i < size; ++i)
5216 {
5217 /* Flip all the bits on. */
5218 desc[i].mask = target_flags;
5219 if (desc[i].code == end)
5220 break;
5221 }
5222}
5223
5224static void
b24c9d35 5225spe_init_builtins ()
0ac081f6 5226{
a3170dc6
AH
5227 tree endlink = void_list_node;
5228 tree puint_type_node = build_pointer_type (unsigned_type_node);
5229 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5230 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5231 struct builtin_description *d;
0ac081f6
AH
5232 size_t i;
5233
a3170dc6
AH
5234 tree v2si_ftype_4_v2si
5235 = build_function_type
5236 (V2SI_type_node,
5237 tree_cons (NULL_TREE, V2SI_type_node,
5238 tree_cons (NULL_TREE, V2SI_type_node,
5239 tree_cons (NULL_TREE, V2SI_type_node,
5240 tree_cons (NULL_TREE, V2SI_type_node,
5241 endlink)))));
5242
5243 tree v2sf_ftype_4_v2sf
5244 = build_function_type
5245 (V2SF_type_node,
5246 tree_cons (NULL_TREE, V2SF_type_node,
5247 tree_cons (NULL_TREE, V2SF_type_node,
5248 tree_cons (NULL_TREE, V2SF_type_node,
5249 tree_cons (NULL_TREE, V2SF_type_node,
5250 endlink)))));
5251
5252 tree int_ftype_int_v2si_v2si
5253 = build_function_type
5254 (integer_type_node,
5255 tree_cons (NULL_TREE, integer_type_node,
5256 tree_cons (NULL_TREE, V2SI_type_node,
5257 tree_cons (NULL_TREE, V2SI_type_node,
5258 endlink))));
5259
5260 tree int_ftype_int_v2sf_v2sf
5261 = build_function_type
5262 (integer_type_node,
5263 tree_cons (NULL_TREE, integer_type_node,
5264 tree_cons (NULL_TREE, V2SF_type_node,
5265 tree_cons (NULL_TREE, V2SF_type_node,
5266 endlink))));
5267
5268 tree void_ftype_v2si_puint_int
5269 = build_function_type (void_type_node,
5270 tree_cons (NULL_TREE, V2SI_type_node,
5271 tree_cons (NULL_TREE, puint_type_node,
5272 tree_cons (NULL_TREE,
5273 integer_type_node,
5274 endlink))));
5275
5276 tree void_ftype_v2si_puint_char
5277 = build_function_type (void_type_node,
5278 tree_cons (NULL_TREE, V2SI_type_node,
5279 tree_cons (NULL_TREE, puint_type_node,
5280 tree_cons (NULL_TREE,
5281 char_type_node,
5282 endlink))));
5283
5284 tree void_ftype_v2si_pv2si_int
5285 = build_function_type (void_type_node,
5286 tree_cons (NULL_TREE, V2SI_type_node,
5287 tree_cons (NULL_TREE, pv2si_type_node,
5288 tree_cons (NULL_TREE,
5289 integer_type_node,
5290 endlink))));
5291
5292 tree void_ftype_v2si_pv2si_char
5293 = build_function_type (void_type_node,
5294 tree_cons (NULL_TREE, V2SI_type_node,
5295 tree_cons (NULL_TREE, pv2si_type_node,
5296 tree_cons (NULL_TREE,
5297 char_type_node,
5298 endlink))));
5299
5300 tree void_ftype_int
5301 = build_function_type (void_type_node,
5302 tree_cons (NULL_TREE, integer_type_node, endlink));
5303
5304 tree int_ftype_void
5305 = build_function_type (integer_type_node,
5306 tree_cons (NULL_TREE, void_type_node, endlink));
5307
5308 tree v2si_ftype_pv2si_int
5309 = build_function_type (V2SI_type_node,
5310 tree_cons (NULL_TREE, pv2si_type_node,
5311 tree_cons (NULL_TREE, integer_type_node,
5312 endlink)));
5313
5314 tree v2si_ftype_puint_int
5315 = build_function_type (V2SI_type_node,
5316 tree_cons (NULL_TREE, puint_type_node,
5317 tree_cons (NULL_TREE, integer_type_node,
5318 endlink)));
5319
5320 tree v2si_ftype_pushort_int
5321 = build_function_type (V2SI_type_node,
5322 tree_cons (NULL_TREE, pushort_type_node,
5323 tree_cons (NULL_TREE, integer_type_node,
5324 endlink)));
5325
5326 /* The initialization of the simple binary and unary builtins is
5327 done in rs6000_common_init_builtins, but we have to enable the
5328 mask bits here manually because we have run out of `target_flags'
5329 bits. We really need to redesign this mask business. */
5330
5331 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5332 ARRAY_SIZE (bdesc_2arg),
5333 SPE_BUILTIN_EVADDW,
5334 SPE_BUILTIN_EVXOR);
5335 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5336 ARRAY_SIZE (bdesc_1arg),
5337 SPE_BUILTIN_EVABS,
5338 SPE_BUILTIN_EVSUBFUSIAAW);
5339 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5340 ARRAY_SIZE (bdesc_spe_predicates),
5341 SPE_BUILTIN_EVCMPEQ,
5342 SPE_BUILTIN_EVFSTSTLT);
5343 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5344 ARRAY_SIZE (bdesc_spe_evsel),
5345 SPE_BUILTIN_EVSEL_CMPGTS,
5346 SPE_BUILTIN_EVSEL_FSTSTEQ);
5347
5348 /* Initialize irregular SPE builtins. */
5349
5350 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5351 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5352 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5353 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5354 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5355 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5356 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5357 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5358 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5359 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5360 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5361 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5362 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5363 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5364 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5365 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5366
5367 /* Loads. */
5368 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5369 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5370 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5371 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5372 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5373 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5374 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5375 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5376 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5377 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5378 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5379 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5380 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5381 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5382 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5383 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5384 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5385 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5386 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5387 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5388 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5389 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5390
5391 /* Predicates. */
5392 d = (struct builtin_description *) bdesc_spe_predicates;
5393 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5394 {
5395 tree type;
5396
5397 switch (insn_data[d->icode].operand[1].mode)
5398 {
5399 case V2SImode:
5400 type = int_ftype_int_v2si_v2si;
5401 break;
5402 case V2SFmode:
5403 type = int_ftype_int_v2sf_v2sf;
5404 break;
5405 default:
5406 abort ();
5407 }
5408
5409 def_builtin (d->mask, d->name, type, d->code);
5410 }
5411
5412 /* Evsel predicates. */
5413 d = (struct builtin_description *) bdesc_spe_evsel;
5414 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5415 {
5416 tree type;
5417
5418 switch (insn_data[d->icode].operand[1].mode)
5419 {
5420 case V2SImode:
5421 type = v2si_ftype_4_v2si;
5422 break;
5423 case V2SFmode:
5424 type = v2sf_ftype_4_v2sf;
5425 break;
5426 default:
5427 abort ();
5428 }
5429
5430 def_builtin (d->mask, d->name, type, d->code);
5431 }
5432}
5433
5434static void
b24c9d35 5435altivec_init_builtins ()
a3170dc6
AH
5436{
5437 struct builtin_description *d;
5438 struct builtin_description_predicates *dp;
5439 size_t i;
5440 tree pfloat_type_node = build_pointer_type (float_type_node);
5441 tree pint_type_node = build_pointer_type (integer_type_node);
5442 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5443 tree pchar_type_node = build_pointer_type (char_type_node);
5444
5445 tree pvoid_type_node = build_pointer_type (void_type_node);
5446
5447 tree int_ftype_int_v4si_v4si
5448 = build_function_type_list (integer_type_node,
5449 integer_type_node, V4SI_type_node,
5450 V4SI_type_node, NULL_TREE);
f18c054f 5451 tree v4sf_ftype_pfloat
b4de2f7d 5452 = build_function_type_list (V4SF_type_node, pfloat_type_node, NULL_TREE);
a3170dc6 5453 tree void_ftype_pfloat_v4sf
b4de2f7d 5454 = build_function_type_list (void_type_node,
a3170dc6
AH
5455 pfloat_type_node, V4SF_type_node, NULL_TREE);
5456 tree v4si_ftype_pint
5457 = build_function_type_list (V4SI_type_node, pint_type_node, NULL_TREE); tree void_ftype_pint_v4si
b4de2f7d
AH
5458 = build_function_type_list (void_type_node,
5459 pint_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5460 tree v8hi_ftype_pshort
5461 = build_function_type_list (V8HI_type_node, pshort_type_node, NULL_TREE);
f18c054f 5462 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5463 = build_function_type_list (void_type_node,
5464 pshort_type_node, V8HI_type_node, NULL_TREE);
a3170dc6
AH
5465 tree v16qi_ftype_pchar
5466 = build_function_type_list (V16QI_type_node, pchar_type_node, NULL_TREE);
f18c054f 5467 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5468 = build_function_type_list (void_type_node,
5469 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5470 tree void_ftype_v4si
b4de2f7d 5471 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5472 tree v8hi_ftype_void
5473 = build_function_type (V8HI_type_node, void_list_node);
5474 tree void_ftype_void
5475 = build_function_type (void_type_node, void_list_node);
5476 tree void_ftype_qi
5477 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
5478 tree v16qi_ftype_int_pvoid
5479 = build_function_type_list (V16QI_type_node,
5480 integer_type_node, pvoid_type_node, NULL_TREE);
5481 tree v8hi_ftype_int_pvoid
5482 = build_function_type_list (V8HI_type_node,
5483 integer_type_node, pvoid_type_node, NULL_TREE);
5484 tree v4si_ftype_int_pvoid
5485 = build_function_type_list (V4SI_type_node,
5486 integer_type_node, pvoid_type_node, NULL_TREE);
14b32f4e 5487 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5488 = build_function_type_list (void_type_node,
5489 V4SI_type_node, integer_type_node,
5490 pvoid_type_node, NULL_TREE);
6525c0e7 5491 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5492 = build_function_type_list (void_type_node,
5493 V16QI_type_node, integer_type_node,
5494 pvoid_type_node, NULL_TREE);
6525c0e7 5495 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5496 = build_function_type_list (void_type_node,
5497 V8HI_type_node, integer_type_node,
5498 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5499 tree int_ftype_int_v8hi_v8hi
5500 = build_function_type_list (integer_type_node,
5501 integer_type_node, V8HI_type_node,
5502 V8HI_type_node, NULL_TREE);
5503 tree int_ftype_int_v16qi_v16qi
5504 = build_function_type_list (integer_type_node,
5505 integer_type_node, V16QI_type_node,
5506 V16QI_type_node, NULL_TREE);
5507 tree int_ftype_int_v4sf_v4sf
5508 = build_function_type_list (integer_type_node,
5509 integer_type_node, V4SF_type_node,
5510 V4SF_type_node, NULL_TREE);
5511 tree v4si_ftype_v4si
5512 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5513 tree v8hi_ftype_v8hi
5514 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5515 tree v16qi_ftype_v16qi
5516 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5517 tree v4sf_ftype_v4sf
5518 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5519 tree void_ftype_pvoid_int_char
5520 = build_function_type_list (void_type_node,
5521 pvoid_type_node, integer_type_node,
5522 char_type_node, NULL_TREE);
5523
5524 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pfloat, ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5525 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf, ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5526 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5527 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5528 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pshort, ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5529 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi, ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5530 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pchar, ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5531 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi, ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
5532 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5533 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5534 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5535 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
5536 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
5537 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
5538 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEBX);
5539 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEHX);
5540 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEWX);
5541 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVXL);
5542 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVX);
5543 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5544 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5545 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5546 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5547 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5548
5549 /* Add the DST variants. */
5550 d = (struct builtin_description *) bdesc_dst;
5551 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
5552 def_builtin (d->mask, d->name, void_ftype_pvoid_int_char, d->code);
5553
5554 /* Initialize the predicates. */
5555 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5556 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5557 {
5558 enum machine_mode mode1;
5559 tree type;
5560
5561 mode1 = insn_data[dp->icode].operand[1].mode;
5562
5563 switch (mode1)
5564 {
5565 case V4SImode:
5566 type = int_ftype_int_v4si_v4si;
5567 break;
5568 case V8HImode:
5569 type = int_ftype_int_v8hi_v8hi;
5570 break;
5571 case V16QImode:
5572 type = int_ftype_int_v16qi_v16qi;
5573 break;
5574 case V4SFmode:
5575 type = int_ftype_int_v4sf_v4sf;
5576 break;
5577 default:
5578 abort ();
5579 }
5580
5581 def_builtin (dp->mask, dp->name, type, dp->code);
5582 }
5583
5584 /* Initialize the abs* operators. */
5585 d = (struct builtin_description *) bdesc_abs;
5586 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5587 {
5588 enum machine_mode mode0;
5589 tree type;
5590
5591 mode0 = insn_data[d->icode].operand[0].mode;
5592
5593 switch (mode0)
5594 {
5595 case V4SImode:
5596 type = v4si_ftype_v4si;
5597 break;
5598 case V8HImode:
5599 type = v8hi_ftype_v8hi;
5600 break;
5601 case V16QImode:
5602 type = v16qi_ftype_v16qi;
5603 break;
5604 case V4SFmode:
5605 type = v4sf_ftype_v4sf;
5606 break;
5607 default:
5608 abort ();
5609 }
5610
5611 def_builtin (d->mask, d->name, type, d->code);
5612 }
5613}
5614
5615static void
b24c9d35 5616rs6000_common_init_builtins ()
a3170dc6
AH
5617{
5618 struct builtin_description *d;
5619 size_t i;
5620
5621 tree v4sf_ftype_v4sf_v4sf_v16qi
5622 = build_function_type_list (V4SF_type_node,
5623 V4SF_type_node, V4SF_type_node,
5624 V16QI_type_node, NULL_TREE);
5625 tree v4si_ftype_v4si_v4si_v16qi
5626 = build_function_type_list (V4SI_type_node,
5627 V4SI_type_node, V4SI_type_node,
5628 V16QI_type_node, NULL_TREE);
5629 tree v8hi_ftype_v8hi_v8hi_v16qi
5630 = build_function_type_list (V8HI_type_node,
5631 V8HI_type_node, V8HI_type_node,
5632 V16QI_type_node, NULL_TREE);
5633 tree v16qi_ftype_v16qi_v16qi_v16qi
5634 = build_function_type_list (V16QI_type_node,
5635 V16QI_type_node, V16QI_type_node,
5636 V16QI_type_node, NULL_TREE);
5637 tree v4si_ftype_char
5638 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5639 tree v8hi_ftype_char
5640 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5641 tree v16qi_ftype_char
5642 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5643 tree v8hi_ftype_v16qi
5644 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5645 tree v4sf_ftype_v4sf
5646 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5647
5648 tree v2si_ftype_v2si_v2si
5649 = build_function_type_list (V2SI_type_node,
5650 V2SI_type_node, V2SI_type_node, NULL_TREE);
5651
5652 tree v2sf_ftype_v2sf_v2sf
5653 = build_function_type_list (V2SF_type_node,
5654 V2SF_type_node, V2SF_type_node, NULL_TREE);
5655
5656 tree v2si_ftype_int_int
5657 = build_function_type_list (V2SI_type_node,
5658 integer_type_node, integer_type_node,
5659 NULL_TREE);
5660
5661 tree v2si_ftype_v2si
5662 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5663
5664 tree v2sf_ftype_v2sf
5665 = build_function_type_list (V2SF_type_node,
5666 V2SF_type_node, NULL_TREE);
5667
5668 tree v2sf_ftype_v2si
5669 = build_function_type_list (V2SF_type_node,
5670 V2SI_type_node, NULL_TREE);
5671
5672 tree v2si_ftype_v2sf
5673 = build_function_type_list (V2SI_type_node,
5674 V2SF_type_node, NULL_TREE);
5675
5676 tree v2si_ftype_v2si_char
5677 = build_function_type_list (V2SI_type_node,
5678 V2SI_type_node, char_type_node, NULL_TREE);
5679
5680 tree v2si_ftype_int_char
5681 = build_function_type_list (V2SI_type_node,
5682 integer_type_node, char_type_node, NULL_TREE);
5683
5684 tree v2si_ftype_char
5685 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5686
5687 tree int_ftype_int_int
5688 = build_function_type_list (integer_type_node,
5689 integer_type_node, integer_type_node,
5690 NULL_TREE);
95385cbb 5691
0ac081f6 5692 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5693 = build_function_type_list (V4SI_type_node,
5694 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5695 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5696 = build_function_type_list (V4SF_type_node,
5697 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5698 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5699 = build_function_type_list (V4SI_type_node,
5700 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5701 tree v4si_ftype_v4si_char
b4de2f7d
AH
5702 = build_function_type_list (V4SI_type_node,
5703 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5704 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5705 = build_function_type_list (V8HI_type_node,
5706 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5707 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5708 = build_function_type_list (V16QI_type_node,
5709 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5710 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5711 = build_function_type_list (V16QI_type_node,
5712 V16QI_type_node, V16QI_type_node,
5713 char_type_node, NULL_TREE);
24408032 5714 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5715 = build_function_type_list (V8HI_type_node,
5716 V8HI_type_node, V8HI_type_node,
5717 char_type_node, NULL_TREE);
24408032 5718 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5719 = build_function_type_list (V4SI_type_node,
5720 V4SI_type_node, V4SI_type_node,
5721 char_type_node, NULL_TREE);
24408032 5722 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5723 = build_function_type_list (V4SF_type_node,
5724 V4SF_type_node, V4SF_type_node,
5725 char_type_node, NULL_TREE);
0ac081f6 5726 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5727 = build_function_type_list (V4SF_type_node,
5728 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5729 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5730 = build_function_type_list (V4SF_type_node,
5731 V4SF_type_node, V4SF_type_node,
5732 V4SI_type_node, NULL_TREE);
2212663f 5733 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5734 = build_function_type_list (V4SF_type_node,
5735 V4SF_type_node, V4SF_type_node,
5736 V4SF_type_node, NULL_TREE);
617e0e1d 5737 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
5738 = build_function_type_list (V4SI_type_node,
5739 V4SI_type_node, V4SI_type_node,
5740 V4SI_type_node, NULL_TREE);
0ac081f6 5741 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
5742 = build_function_type_list (V8HI_type_node,
5743 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 5744 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
5745 = build_function_type_list (V8HI_type_node,
5746 V8HI_type_node, V8HI_type_node,
5747 V8HI_type_node, NULL_TREE);
2212663f 5748 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
5749 = build_function_type_list (V4SI_type_node,
5750 V8HI_type_node, V8HI_type_node,
5751 V4SI_type_node, NULL_TREE);
2212663f 5752 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
5753 = build_function_type_list (V4SI_type_node,
5754 V16QI_type_node, V16QI_type_node,
5755 V4SI_type_node, NULL_TREE);
0ac081f6 5756 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
5757 = build_function_type_list (V16QI_type_node,
5758 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5759 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
5760 = build_function_type_list (V4SI_type_node,
5761 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 5762 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
5763 = build_function_type_list (V8HI_type_node,
5764 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5765 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
5766 = build_function_type_list (V4SI_type_node,
5767 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5768 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
5769 = build_function_type_list (V8HI_type_node,
5770 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 5771 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
5772 = build_function_type_list (V16QI_type_node,
5773 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5774 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
5775 = build_function_type_list (V4SI_type_node,
5776 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 5777 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
5778 = build_function_type_list (V4SI_type_node,
5779 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5780 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
5781 = build_function_type_list (V4SI_type_node,
5782 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5783 tree v4si_ftype_v8hi
5784 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5785 tree int_ftype_v4si_v4si
5786 = build_function_type_list (integer_type_node,
5787 V4SI_type_node, V4SI_type_node, NULL_TREE);
5788 tree int_ftype_v4sf_v4sf
5789 = build_function_type_list (integer_type_node,
5790 V4SF_type_node, V4SF_type_node, NULL_TREE);
5791 tree int_ftype_v16qi_v16qi
5792 = build_function_type_list (integer_type_node,
5793 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5794 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
5795 = build_function_type_list (integer_type_node,
5796 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5797
6f317ef3 5798 /* Add the simple ternary operators. */
2212663f 5799 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 5800 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
5801 {
5802
5803 enum machine_mode mode0, mode1, mode2, mode3;
5804 tree type;
5805
0559cc77 5806 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5807 continue;
5808
5809 mode0 = insn_data[d->icode].operand[0].mode;
5810 mode1 = insn_data[d->icode].operand[1].mode;
5811 mode2 = insn_data[d->icode].operand[2].mode;
5812 mode3 = insn_data[d->icode].operand[3].mode;
5813
5814 /* When all four are of the same mode. */
5815 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5816 {
5817 switch (mode0)
5818 {
617e0e1d
DB
5819 case V4SImode:
5820 type = v4si_ftype_v4si_v4si_v4si;
5821 break;
2212663f
DB
5822 case V4SFmode:
5823 type = v4sf_ftype_v4sf_v4sf_v4sf;
5824 break;
5825 case V8HImode:
5826 type = v8hi_ftype_v8hi_v8hi_v8hi;
5827 break;
5828 case V16QImode:
5829 type = v16qi_ftype_v16qi_v16qi_v16qi;
5830 break;
5831 default:
5832 abort();
5833 }
5834 }
5835 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5836 {
5837 switch (mode0)
5838 {
5839 case V4SImode:
5840 type = v4si_ftype_v4si_v4si_v16qi;
5841 break;
5842 case V4SFmode:
5843 type = v4sf_ftype_v4sf_v4sf_v16qi;
5844 break;
5845 case V8HImode:
5846 type = v8hi_ftype_v8hi_v8hi_v16qi;
5847 break;
5848 case V16QImode:
5849 type = v16qi_ftype_v16qi_v16qi_v16qi;
5850 break;
5851 default:
5852 abort();
5853 }
5854 }
5855 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5856 && mode3 == V4SImode)
24408032 5857 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
5858 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5859 && mode3 == V4SImode)
24408032 5860 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
5861 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5862 && mode3 == V4SImode)
24408032
AH
5863 type = v4sf_ftype_v4sf_v4sf_v4si;
5864
5865 /* vchar, vchar, vchar, 4 bit literal. */
5866 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5867 && mode3 == QImode)
5868 type = v16qi_ftype_v16qi_v16qi_char;
5869
5870 /* vshort, vshort, vshort, 4 bit literal. */
5871 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5872 && mode3 == QImode)
5873 type = v8hi_ftype_v8hi_v8hi_char;
5874
5875 /* vint, vint, vint, 4 bit literal. */
5876 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
5877 && mode3 == QImode)
5878 type = v4si_ftype_v4si_v4si_char;
5879
5880 /* vfloat, vfloat, vfloat, 4 bit literal. */
5881 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
5882 && mode3 == QImode)
5883 type = v4sf_ftype_v4sf_v4sf_char;
5884
2212663f
DB
5885 else
5886 abort ();
5887
5888 def_builtin (d->mask, d->name, type, d->code);
5889 }
5890
0ac081f6 5891 /* Add the simple binary operators. */
00b960c7 5892 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 5893 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
5894 {
5895 enum machine_mode mode0, mode1, mode2;
5896 tree type;
5897
0559cc77 5898 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
5899 continue;
5900
5901 mode0 = insn_data[d->icode].operand[0].mode;
5902 mode1 = insn_data[d->icode].operand[1].mode;
5903 mode2 = insn_data[d->icode].operand[2].mode;
5904
5905 /* When all three operands are of the same mode. */
5906 if (mode0 == mode1 && mode1 == mode2)
5907 {
5908 switch (mode0)
5909 {
5910 case V4SFmode:
5911 type = v4sf_ftype_v4sf_v4sf;
5912 break;
5913 case V4SImode:
5914 type = v4si_ftype_v4si_v4si;
5915 break;
5916 case V16QImode:
5917 type = v16qi_ftype_v16qi_v16qi;
5918 break;
5919 case V8HImode:
5920 type = v8hi_ftype_v8hi_v8hi;
5921 break;
a3170dc6
AH
5922 case V2SImode:
5923 type = v2si_ftype_v2si_v2si;
5924 break;
5925 case V2SFmode:
5926 type = v2sf_ftype_v2sf_v2sf;
5927 break;
5928 case SImode:
5929 type = int_ftype_int_int;
5930 break;
0ac081f6
AH
5931 default:
5932 abort ();
5933 }
5934 }
5935
5936 /* A few other combos we really don't want to do manually. */
5937
5938 /* vint, vfloat, vfloat. */
5939 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
5940 type = v4si_ftype_v4sf_v4sf;
5941
5942 /* vshort, vchar, vchar. */
5943 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
5944 type = v8hi_ftype_v16qi_v16qi;
5945
5946 /* vint, vshort, vshort. */
5947 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
5948 type = v4si_ftype_v8hi_v8hi;
5949
5950 /* vshort, vint, vint. */
5951 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
5952 type = v8hi_ftype_v4si_v4si;
5953
5954 /* vchar, vshort, vshort. */
5955 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
5956 type = v16qi_ftype_v8hi_v8hi;
5957
5958 /* vint, vchar, vint. */
5959 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
5960 type = v4si_ftype_v16qi_v4si;
5961
fa066a23
AH
5962 /* vint, vchar, vchar. */
5963 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
5964 type = v4si_ftype_v16qi_v16qi;
5965
0ac081f6
AH
5966 /* vint, vshort, vint. */
5967 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
5968 type = v4si_ftype_v8hi_v4si;
2212663f
DB
5969
5970 /* vint, vint, 5 bit literal. */
5971 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
5972 type = v4si_ftype_v4si_char;
5973
5974 /* vshort, vshort, 5 bit literal. */
5975 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
5976 type = v8hi_ftype_v8hi_char;
5977
5978 /* vchar, vchar, 5 bit literal. */
5979 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
5980 type = v16qi_ftype_v16qi_char;
0ac081f6 5981
617e0e1d
DB
5982 /* vfloat, vint, 5 bit literal. */
5983 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
5984 type = v4sf_ftype_v4si_char;
5985
5986 /* vint, vfloat, 5 bit literal. */
5987 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
5988 type = v4si_ftype_v4sf_char;
5989
a3170dc6
AH
5990 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
5991 type = v2si_ftype_int_int;
5992
5993 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
5994 type = v2si_ftype_v2si_char;
5995
5996 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
5997 type = v2si_ftype_int_char;
5998
0ac081f6
AH
5999 /* int, x, x. */
6000 else if (mode0 == SImode)
6001 {
6002 switch (mode1)
6003 {
6004 case V4SImode:
6005 type = int_ftype_v4si_v4si;
6006 break;
6007 case V4SFmode:
6008 type = int_ftype_v4sf_v4sf;
6009 break;
6010 case V16QImode:
6011 type = int_ftype_v16qi_v16qi;
6012 break;
6013 case V8HImode:
6014 type = int_ftype_v8hi_v8hi;
6015 break;
6016 default:
6017 abort ();
6018 }
6019 }
6020
6021 else
6022 abort ();
6023
2212663f
DB
6024 def_builtin (d->mask, d->name, type, d->code);
6025 }
24408032 6026
2212663f
DB
6027 /* Add the simple unary operators. */
6028 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 6029 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
6030 {
6031 enum machine_mode mode0, mode1;
6032 tree type;
6033
0559cc77 6034 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
6035 continue;
6036
6037 mode0 = insn_data[d->icode].operand[0].mode;
6038 mode1 = insn_data[d->icode].operand[1].mode;
6039
6040 if (mode0 == V4SImode && mode1 == QImode)
6041 type = v4si_ftype_char;
6042 else if (mode0 == V8HImode && mode1 == QImode)
6043 type = v8hi_ftype_char;
6044 else if (mode0 == V16QImode && mode1 == QImode)
6045 type = v16qi_ftype_char;
617e0e1d
DB
6046 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6047 type = v4sf_ftype_v4sf;
20e26713
AH
6048 else if (mode0 == V8HImode && mode1 == V16QImode)
6049 type = v8hi_ftype_v16qi;
6050 else if (mode0 == V4SImode && mode1 == V8HImode)
6051 type = v4si_ftype_v8hi;
a3170dc6
AH
6052 else if (mode0 == V2SImode && mode1 == V2SImode)
6053 type = v2si_ftype_v2si;
6054 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6055 type = v2sf_ftype_v2sf;
6056 else if (mode0 == V2SFmode && mode1 == V2SImode)
6057 type = v2sf_ftype_v2si;
6058 else if (mode0 == V2SImode && mode1 == V2SFmode)
6059 type = v2si_ftype_v2sf;
6060 else if (mode0 == V2SImode && mode1 == QImode)
6061 type = v2si_ftype_char;
2212663f
DB
6062 else
6063 abort ();
6064
0ac081f6
AH
6065 def_builtin (d->mask, d->name, type, d->code);
6066 }
6067}
6068
35aff10b 6069\f
7e69e155
MM
6070/* Expand a block move operation, and return 1 if successful. Return 0
6071 if we should let the compiler generate normal code.
6072
6073 operands[0] is the destination
6074 operands[1] is the source
6075 operands[2] is the length
6076 operands[3] is the alignment */
6077
3933e0e1
MM
6078#define MAX_MOVE_REG 4
6079
7e69e155
MM
6080int
6081expand_block_move (operands)
6082 rtx operands[];
6083{
b6c9286a
MM
6084 rtx orig_dest = operands[0];
6085 rtx orig_src = operands[1];
7e69e155 6086 rtx bytes_rtx = operands[2];
7e69e155 6087 rtx align_rtx = operands[3];
3933e0e1 6088 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6089 int align;
3933e0e1
MM
6090 int bytes;
6091 int offset;
7e69e155
MM
6092 int move_bytes;
6093
3933e0e1 6094 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6095 if (! constp)
3933e0e1
MM
6096 return 0;
6097
5ee95df6
FS
6098 /* If this is not a fixed size alignment, abort */
6099 if (GET_CODE (align_rtx) != CONST_INT)
6100 abort ();
6101 align = INTVAL (align_rtx);
6102
7e69e155 6103 /* Anything to move? */
3933e0e1
MM
6104 bytes = INTVAL (bytes_rtx);
6105 if (bytes <= 0)
7e69e155
MM
6106 return 1;
6107
ea9982a8 6108 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6109 reg_parm_stack_space. */
ea9982a8 6110 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6111 return 0;
6112
3933e0e1 6113 if (TARGET_STRING) /* string instructions are available */
7e69e155 6114 {
35aff10b 6115 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6116 {
35aff10b
AM
6117 union {
6118 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
6119 rtx (*mov) PARAMS ((rtx, rtx));
6120 } gen_func;
6121 enum machine_mode mode = BLKmode;
6122 rtx src, dest;
6123
3933e0e1 6124 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6125 && ! fixed_regs[5]
6126 && ! fixed_regs[6]
6127 && ! fixed_regs[7]
6128 && ! fixed_regs[8]
6129 && ! fixed_regs[9]
6130 && ! fixed_regs[10]
6131 && ! fixed_regs[11]
6132 && ! fixed_regs[12])
3933e0e1
MM
6133 {
6134 move_bytes = (bytes > 32) ? 32 : bytes;
35aff10b 6135 gen_func.movstrsi = gen_movstrsi_8reg;
3933e0e1
MM
6136 }
6137 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6138 && ! fixed_regs[5]
6139 && ! fixed_regs[6]
cc0d9ba8
DE
6140 && ! fixed_regs[7]
6141 && ! fixed_regs[8]
6142 && ! fixed_regs[9]
f9562f27 6143 && ! fixed_regs[10])
3933e0e1
MM
6144 {
6145 move_bytes = (bytes > 24) ? 24 : bytes;
35aff10b 6146 gen_func.movstrsi = gen_movstrsi_6reg;
3933e0e1
MM
6147 }
6148 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6149 && ! fixed_regs[5]
6150 && ! fixed_regs[6]
6151 && ! fixed_regs[7]
6152 && ! fixed_regs[8])
3933e0e1
MM
6153 {
6154 move_bytes = (bytes > 16) ? 16 : bytes;
35aff10b 6155 gen_func.movstrsi = gen_movstrsi_4reg;
3933e0e1 6156 }
acad7ed3 6157 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6158 /* 64-bit loads and stores require word-aligned
82e41834 6159 displacements. */
a4f6c312 6160 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6161 {
6162 move_bytes = 8;
35aff10b
AM
6163 mode = DImode;
6164 gen_func.mov = gen_movdi;
acad7ed3 6165 }
09a625f7 6166 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6167 { /* move up to 8 bytes at a time */
6168 move_bytes = (bytes > 8) ? 8 : bytes;
35aff10b 6169 gen_func.movstrsi = gen_movstrsi_2reg;
3933e0e1 6170 }
cc0d9ba8 6171 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6172 { /* move 4 bytes */
6173 move_bytes = 4;
35aff10b
AM
6174 mode = SImode;
6175 gen_func.mov = gen_movsi;
3933e0e1 6176 }
cc0d9ba8 6177 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6178 { /* move 2 bytes */
6179 move_bytes = 2;
35aff10b
AM
6180 mode = HImode;
6181 gen_func.mov = gen_movhi;
3933e0e1
MM
6182 }
6183 else if (bytes == 1) /* move 1 byte */
6184 {
6185 move_bytes = 1;
35aff10b
AM
6186 mode = QImode;
6187 gen_func.mov = gen_movqi;
3933e0e1
MM
6188 }
6189 else
6190 { /* move up to 4 bytes at a time */
6191 move_bytes = (bytes > 4) ? 4 : bytes;
35aff10b 6192 gen_func.movstrsi = gen_movstrsi_1reg;
3933e0e1 6193 }
4c64a852 6194
35aff10b
AM
6195 src = adjust_address (orig_src, mode, offset);
6196 dest = adjust_address (orig_dest, mode, offset);
6197
6198 if (mode == BLKmode)
015892ee 6199 {
35aff10b
AM
6200 /* Move the address into scratch registers. The movstrsi
6201 patterns require zero offset. */
6202 if (!REG_P (XEXP (src, 0)))
cc0d9ba8 6203 {
35aff10b
AM
6204 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
6205 src = replace_equiv_address (src, src_reg);
cc0d9ba8 6206 }
35aff10b
AM
6207 set_mem_size (src, GEN_INT (move_bytes));
6208
6209 if (!REG_P (XEXP (dest, 0)))
cc0d9ba8 6210 {
35aff10b
AM
6211 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
6212 dest = replace_equiv_address (dest, dest_reg);
cc0d9ba8 6213 }
35aff10b
AM
6214 set_mem_size (dest, GEN_INT (move_bytes));
6215
6216 emit_insn ((*gen_func.movstrsi) (dest, src,
6217 GEN_INT (move_bytes & 31),
6218 align_rtx));
6219 }
6220 else
6221 {
6222 rtx tmp_reg = gen_reg_rtx (mode);
6223
6224 emit_insn ((*gen_func.mov) (tmp_reg, src));
6225 emit_insn ((*gen_func.mov) (dest, tmp_reg));
015892ee 6226 }
4c64a852 6227 }
3933e0e1
MM
6228 }
6229
6230 else /* string instructions not available */
6231 {
35aff10b
AM
6232 rtx stores[MAX_MOVE_REG];
6233 int num_reg = 0;
6234 int i;
6235
6236 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6237 {
35aff10b
AM
6238 rtx (*gen_mov_func) PARAMS ((rtx, rtx));
6239 enum machine_mode mode;
6240 rtx src, dest, tmp_reg;
3933e0e1 6241
cc0d9ba8
DE
6242 /* Generate the appropriate load and store, saving the stores
6243 for later. */
6244 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6245 /* 64-bit loads and stores require word-aligned
6246 displacements. */
cc0d9ba8 6247 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6248 {
6249 move_bytes = 8;
35aff10b
AM
6250 mode = DImode;
6251 gen_mov_func = gen_movdi;
b6c9286a 6252 }
cc0d9ba8 6253 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6254 {
6255 move_bytes = 4;
35aff10b
AM
6256 mode = SImode;
6257 gen_mov_func = gen_movsi;
3933e0e1 6258 }
cc0d9ba8 6259 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6260 {
6261 move_bytes = 2;
35aff10b
AM
6262 mode = HImode;
6263 gen_mov_func = gen_movhi;
3933e0e1
MM
6264 }
6265 else
6266 {
6267 move_bytes = 1;
35aff10b
AM
6268 mode = QImode;
6269 gen_mov_func = gen_movqi;
3933e0e1
MM
6270 }
6271
35aff10b
AM
6272 src = adjust_address (orig_src, mode, offset);
6273 dest = adjust_address (orig_dest, mode, offset);
6274 tmp_reg = gen_reg_rtx (mode);
6275
6276 emit_insn ((*gen_mov_func) (tmp_reg, src));
6277 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
6278
3933e0e1
MM
6279 if (num_reg >= MAX_MOVE_REG)
6280 {
6281 for (i = 0; i < num_reg; i++)
6282 emit_insn (stores[i]);
6283 num_reg = 0;
7e69e155
MM
6284 }
6285 }
3933e0e1 6286
b6c9286a
MM
6287 for (i = 0; i < num_reg; i++)
6288 emit_insn (stores[i]);
7e69e155
MM
6289 }
6290
6291 return 1;
6292}
6293
9878760c
RK
6294\f
6295/* Return 1 if OP is a load multiple operation. It is known to be a
6296 PARALLEL and the first section will be tested. */
6297
6298int
6299load_multiple_operation (op, mode)
6300 rtx op;
296b8152 6301 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6302{
6303 int count = XVECLEN (op, 0);
e2c953b6 6304 unsigned int dest_regno;
9878760c
RK
6305 rtx src_addr;
6306 int i;
6307
6308 /* Perform a quick check so we don't blow up below. */
6309 if (count <= 1
6310 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6311 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6312 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6313 return 0;
6314
6315 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6316 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6317
6318 for (i = 1; i < count; i++)
6319 {
6320 rtx elt = XVECEXP (op, 0, i);
6321
6322 if (GET_CODE (elt) != SET
6323 || GET_CODE (SET_DEST (elt)) != REG
6324 || GET_MODE (SET_DEST (elt)) != SImode
6325 || REGNO (SET_DEST (elt)) != dest_regno + i
6326 || GET_CODE (SET_SRC (elt)) != MEM
6327 || GET_MODE (SET_SRC (elt)) != SImode
6328 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6329 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6330 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6331 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6332 return 0;
6333 }
6334
6335 return 1;
6336}
6337
6338/* Similar, but tests for store multiple. Here, the second vector element
6339 is a CLOBBER. It will be tested later. */
6340
6341int
6342store_multiple_operation (op, mode)
6343 rtx op;
296b8152 6344 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6345{
6346 int count = XVECLEN (op, 0) - 1;
e2c953b6 6347 unsigned int src_regno;
9878760c
RK
6348 rtx dest_addr;
6349 int i;
6350
6351 /* Perform a quick check so we don't blow up below. */
6352 if (count <= 1
6353 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6354 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6355 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6356 return 0;
6357
6358 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6359 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6360
6361 for (i = 1; i < count; i++)
6362 {
6363 rtx elt = XVECEXP (op, 0, i + 1);
6364
6365 if (GET_CODE (elt) != SET
6366 || GET_CODE (SET_SRC (elt)) != REG
6367 || GET_MODE (SET_SRC (elt)) != SImode
6368 || REGNO (SET_SRC (elt)) != src_regno + i
6369 || GET_CODE (SET_DEST (elt)) != MEM
6370 || GET_MODE (SET_DEST (elt)) != SImode
6371 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6372 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6373 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6374 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6375 return 0;
6376 }
6377
6378 return 1;
6379}
9ebbca7d 6380
00b960c7
AH
6381/* Return 1 for a parallel vrsave operation. */
6382
6383int
6384vrsave_operation (op, mode)
6385 rtx op;
6386 enum machine_mode mode ATTRIBUTE_UNUSED;
6387{
6388 int count = XVECLEN (op, 0);
6389 unsigned int dest_regno, src_regno;
6390 int i;
6391
6392 if (count <= 1
6393 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6394 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6395 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6396 return 0;
6397
6398 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6399 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6400
6401 if (dest_regno != VRSAVE_REGNO
6402 && src_regno != VRSAVE_REGNO)
6403 return 0;
6404
6405 for (i = 1; i < count; i++)
6406 {
6407 rtx elt = XVECEXP (op, 0, i);
6408
9aa86737
AH
6409 if (GET_CODE (elt) != CLOBBER
6410 && GET_CODE (elt) != SET)
00b960c7
AH
6411 return 0;
6412 }
6413
6414 return 1;
6415}
6416
a4f6c312 6417/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6418
6419int
6420mtcrf_operation (op, mode)
6421 rtx op;
6422 enum machine_mode mode ATTRIBUTE_UNUSED;
6423{
6424 int count = XVECLEN (op, 0);
6425 int i;
9ebbca7d
GK
6426 rtx src_reg;
6427
6428 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6429 if (count < 1
6430 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6431 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6432 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6433 return 0;
e35b9579 6434 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6435
6436 if (GET_CODE (src_reg) != REG
6437 || GET_MODE (src_reg) != SImode
6438 || ! INT_REGNO_P (REGNO (src_reg)))
6439 return 0;
6440
e35b9579 6441 for (i = 0; i < count; i++)
9ebbca7d
GK
6442 {
6443 rtx exp = XVECEXP (op, 0, i);
6444 rtx unspec;
6445 int maskval;
6446
6447 if (GET_CODE (exp) != SET
6448 || GET_CODE (SET_DEST (exp)) != REG
6449 || GET_MODE (SET_DEST (exp)) != CCmode
6450 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6451 return 0;
6452 unspec = SET_SRC (exp);
6453 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6454
6455 if (GET_CODE (unspec) != UNSPEC
6456 || XINT (unspec, 1) != 20
6457 || XVECLEN (unspec, 0) != 2
6458 || XVECEXP (unspec, 0, 0) != src_reg
6459 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6460 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6461 return 0;
6462 }
e35b9579 6463 return 1;
9ebbca7d
GK
6464}
6465
a4f6c312 6466/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6467
6468int
6469lmw_operation (op, mode)
6470 rtx op;
6471 enum machine_mode mode ATTRIBUTE_UNUSED;
6472{
6473 int count = XVECLEN (op, 0);
e2c953b6 6474 unsigned int dest_regno;
9ebbca7d 6475 rtx src_addr;
e2c953b6 6476 unsigned int base_regno;
9ebbca7d
GK
6477 HOST_WIDE_INT offset;
6478 int i;
6479
6480 /* Perform a quick check so we don't blow up below. */
6481 if (count <= 1
6482 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6483 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6484 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6485 return 0;
6486
6487 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6488 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6489
6490 if (dest_regno > 31
e2c953b6 6491 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6492 return 0;
6493
258bfae2 6494 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6495 {
6496 offset = 0;
6497 base_regno = REGNO (src_addr);
6498 if (base_regno == 0)
6499 return 0;
6500 }
258bfae2 6501 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6502 {
6503 offset = INTVAL (XEXP (src_addr, 1));
6504 base_regno = REGNO (XEXP (src_addr, 0));
6505 }
6506 else
6507 return 0;
6508
6509 for (i = 0; i < count; i++)
6510 {
6511 rtx elt = XVECEXP (op, 0, i);
6512 rtx newaddr;
6513 rtx addr_reg;
6514 HOST_WIDE_INT newoffset;
6515
6516 if (GET_CODE (elt) != SET
6517 || GET_CODE (SET_DEST (elt)) != REG
6518 || GET_MODE (SET_DEST (elt)) != SImode
6519 || REGNO (SET_DEST (elt)) != dest_regno + i
6520 || GET_CODE (SET_SRC (elt)) != MEM
6521 || GET_MODE (SET_SRC (elt)) != SImode)
6522 return 0;
6523 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6524 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6525 {
6526 newoffset = 0;
6527 addr_reg = newaddr;
6528 }
258bfae2 6529 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6530 {
6531 addr_reg = XEXP (newaddr, 0);
6532 newoffset = INTVAL (XEXP (newaddr, 1));
6533 }
6534 else
6535 return 0;
6536 if (REGNO (addr_reg) != base_regno
6537 || newoffset != offset + 4 * i)
6538 return 0;
6539 }
6540
6541 return 1;
6542}
6543
a4f6c312 6544/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6545
6546int
6547stmw_operation (op, mode)
6548 rtx op;
6549 enum machine_mode mode ATTRIBUTE_UNUSED;
6550{
6551 int count = XVECLEN (op, 0);
e2c953b6 6552 unsigned int src_regno;
9ebbca7d 6553 rtx dest_addr;
e2c953b6 6554 unsigned int base_regno;
9ebbca7d
GK
6555 HOST_WIDE_INT offset;
6556 int i;
6557
6558 /* Perform a quick check so we don't blow up below. */
6559 if (count <= 1
6560 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6561 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6562 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6563 return 0;
6564
6565 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6566 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6567
6568 if (src_regno > 31
e2c953b6 6569 || count != 32 - (int) src_regno)
9ebbca7d
GK
6570 return 0;
6571
258bfae2 6572 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6573 {
6574 offset = 0;
6575 base_regno = REGNO (dest_addr);
6576 if (base_regno == 0)
6577 return 0;
6578 }
258bfae2 6579 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6580 {
6581 offset = INTVAL (XEXP (dest_addr, 1));
6582 base_regno = REGNO (XEXP (dest_addr, 0));
6583 }
6584 else
6585 return 0;
6586
6587 for (i = 0; i < count; i++)
6588 {
6589 rtx elt = XVECEXP (op, 0, i);
6590 rtx newaddr;
6591 rtx addr_reg;
6592 HOST_WIDE_INT newoffset;
6593
6594 if (GET_CODE (elt) != SET
6595 || GET_CODE (SET_SRC (elt)) != REG
6596 || GET_MODE (SET_SRC (elt)) != SImode
6597 || REGNO (SET_SRC (elt)) != src_regno + i
6598 || GET_CODE (SET_DEST (elt)) != MEM
6599 || GET_MODE (SET_DEST (elt)) != SImode)
6600 return 0;
6601 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6602 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6603 {
6604 newoffset = 0;
6605 addr_reg = newaddr;
6606 }
258bfae2 6607 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6608 {
6609 addr_reg = XEXP (newaddr, 0);
6610 newoffset = INTVAL (XEXP (newaddr, 1));
6611 }
6612 else
6613 return 0;
6614 if (REGNO (addr_reg) != base_regno
6615 || newoffset != offset + 4 * i)
6616 return 0;
6617 }
6618
6619 return 1;
6620}
9878760c 6621\f
a4f6c312
SS
6622/* A validation routine: say whether CODE, a condition code, and MODE
6623 match. The other alternatives either don't make sense or should
6624 never be generated. */
39a10a29 6625
39a10a29
GK
6626static void
6627validate_condition_mode (code, mode)
6628 enum rtx_code code;
6629 enum machine_mode mode;
6630{
6631 if (GET_RTX_CLASS (code) != '<'
6632 || GET_MODE_CLASS (mode) != MODE_CC)
6633 abort ();
6634
6635 /* These don't make sense. */
6636 if ((code == GT || code == LT || code == GE || code == LE)
6637 && mode == CCUNSmode)
6638 abort ();
6639
6640 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6641 && mode != CCUNSmode)
6642 abort ();
6643
6644 if (mode != CCFPmode
6645 && (code == ORDERED || code == UNORDERED
6646 || code == UNEQ || code == LTGT
6647 || code == UNGT || code == UNLT
6648 || code == UNGE || code == UNLE))
a4f6c312 6649 abort ();
39a10a29 6650
de6c5979 6651 /* These should never be generated except for
ad72b533 6652 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6653 if (mode == CCFPmode
de6c5979 6654 && ! flag_unsafe_math_optimizations
ad72b533 6655 && ! flag_finite_math_only
39a10a29
GK
6656 && (code == LE || code == GE
6657 || code == UNEQ || code == LTGT
6658 || code == UNGT || code == UNLT))
6659 abort ();
6660
6661 /* These are invalid; the information is not there. */
6662 if (mode == CCEQmode
6663 && code != EQ && code != NE)
6664 abort ();
6665}
6666
9878760c
RK
6667/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6668 We only check the opcode against the mode of the CC value here. */
6669
6670int
6671branch_comparison_operator (op, mode)
592696dd 6672 rtx op;
296b8152 6673 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6674{
6675 enum rtx_code code = GET_CODE (op);
6676 enum machine_mode cc_mode;
6677
6678 if (GET_RTX_CLASS (code) != '<')
6679 return 0;
6680
6681 cc_mode = GET_MODE (XEXP (op, 0));
6682 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6683 return 0;
6684
39a10a29 6685 validate_condition_mode (code, cc_mode);
9878760c 6686
39a10a29
GK
6687 return 1;
6688}
6689
6690/* Return 1 if OP is a comparison operation that is valid for a branch
6691 insn and which is true if the corresponding bit in the CC register
6692 is set. */
6693
6694int
6695branch_positive_comparison_operator (op, mode)
592696dd 6696 rtx op;
39a10a29
GK
6697 enum machine_mode mode;
6698{
6699 enum rtx_code code;
6700
6701 if (! branch_comparison_operator (op, mode))
9878760c
RK
6702 return 0;
6703
39a10a29
GK
6704 code = GET_CODE (op);
6705 return (code == EQ || code == LT || code == GT
a3170dc6 6706 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
6707 || code == LTU || code == GTU
6708 || code == UNORDERED);
9878760c
RK
6709}
6710
6711/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6712 We check the opcode against the mode of the CC value and disallow EQ or
6713 NE comparisons for integers. */
6714
6715int
6716scc_comparison_operator (op, mode)
592696dd 6717 rtx op;
9878760c
RK
6718 enum machine_mode mode;
6719{
6720 enum rtx_code code = GET_CODE (op);
6721 enum machine_mode cc_mode;
6722
6723 if (GET_MODE (op) != mode && mode != VOIDmode)
6724 return 0;
6725
6726 if (GET_RTX_CLASS (code) != '<')
6727 return 0;
6728
6729 cc_mode = GET_MODE (XEXP (op, 0));
6730 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6731 return 0;
6732
39a10a29 6733 validate_condition_mode (code, cc_mode);
9878760c 6734
39a10a29 6735 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
6736 return 0;
6737
9878760c
RK
6738 return 1;
6739}
e0cd0770
JC
6740
6741int
6742trap_comparison_operator (op, mode)
6743 rtx op;
6744 enum machine_mode mode;
6745{
6746 if (mode != VOIDmode && mode != GET_MODE (op))
6747 return 0;
39a10a29 6748 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 6749}
dfbdccdb
GK
6750
6751int
6752boolean_operator (op, mode)
6753 rtx op;
6754 enum machine_mode mode ATTRIBUTE_UNUSED;
6755{
6756 enum rtx_code code = GET_CODE (op);
6757 return (code == AND || code == IOR || code == XOR);
6758}
1d328b19
GK
6759
6760int
6761boolean_or_operator (op, mode)
6762 rtx op;
6763 enum machine_mode mode ATTRIBUTE_UNUSED;
6764{
6765 enum rtx_code code = GET_CODE (op);
6766 return (code == IOR || code == XOR);
6767}
50a0b056
GK
6768
6769int
6770min_max_operator (op, mode)
6771 rtx op;
6772 enum machine_mode mode ATTRIBUTE_UNUSED;
6773{
6774 enum rtx_code code = GET_CODE (op);
6775 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6776}
9878760c
RK
6777\f
6778/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6779 mask required to convert the result of a rotate insn into a shift
b1765bde 6780 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
6781
6782int
6783includes_lshift_p (shiftop, andop)
592696dd
SS
6784 rtx shiftop;
6785 rtx andop;
9878760c 6786{
e2c953b6
DE
6787 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6788
6789 shift_mask <<= INTVAL (shiftop);
9878760c 6790
b1765bde 6791 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
6792}
6793
6794/* Similar, but for right shift. */
6795
6796int
6797includes_rshift_p (shiftop, andop)
592696dd
SS
6798 rtx shiftop;
6799 rtx andop;
9878760c 6800{
a7653a2c 6801 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
6802
6803 shift_mask >>= INTVAL (shiftop);
6804
b1765bde 6805 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
6806}
6807
c5059423
AM
6808/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6809 to perform a left shift. It must have exactly SHIFTOP least
6810 signifigant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
6811
6812int
c5059423 6813includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
6814 rtx shiftop;
6815 rtx andop;
e2c953b6 6816{
c5059423
AM
6817 if (GET_CODE (andop) == CONST_INT)
6818 {
02071907 6819 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 6820
c5059423 6821 c = INTVAL (andop);
02071907 6822 if (c == 0 || c == ~0)
c5059423 6823 return 0;
e2c953b6 6824
02071907 6825 shift_mask = ~0;
c5059423
AM
6826 shift_mask <<= INTVAL (shiftop);
6827
6828 /* Find the least signifigant one bit. */
6829 lsb = c & -c;
6830
6831 /* It must coincide with the LSB of the shift mask. */
6832 if (-lsb != shift_mask)
6833 return 0;
e2c953b6 6834
c5059423
AM
6835 /* Invert to look for the next transition (if any). */
6836 c = ~c;
6837
6838 /* Remove the low group of ones (originally low group of zeros). */
6839 c &= -lsb;
6840
6841 /* Again find the lsb, and check we have all 1's above. */
6842 lsb = c & -c;
6843 return c == -lsb;
6844 }
6845 else if (GET_CODE (andop) == CONST_DOUBLE
6846 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6847 {
02071907
AM
6848 HOST_WIDE_INT low, high, lsb;
6849 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
6850
6851 low = CONST_DOUBLE_LOW (andop);
6852 if (HOST_BITS_PER_WIDE_INT < 64)
6853 high = CONST_DOUBLE_HIGH (andop);
6854
6855 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 6856 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
6857 return 0;
6858
6859 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6860 {
02071907 6861 shift_mask_high = ~0;
c5059423
AM
6862 if (INTVAL (shiftop) > 32)
6863 shift_mask_high <<= INTVAL (shiftop) - 32;
6864
6865 lsb = high & -high;
6866
6867 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
6868 return 0;
6869
6870 high = ~high;
6871 high &= -lsb;
6872
6873 lsb = high & -high;
6874 return high == -lsb;
6875 }
6876
02071907 6877 shift_mask_low = ~0;
c5059423
AM
6878 shift_mask_low <<= INTVAL (shiftop);
6879
6880 lsb = low & -low;
6881
6882 if (-lsb != shift_mask_low)
6883 return 0;
6884
6885 if (HOST_BITS_PER_WIDE_INT < 64)
6886 high = ~high;
6887 low = ~low;
6888 low &= -lsb;
6889
6890 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6891 {
6892 lsb = high & -high;
6893 return high == -lsb;
6894 }
6895
6896 lsb = low & -low;
6897 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
6898 }
6899 else
6900 return 0;
6901}
e2c953b6 6902
c5059423
AM
6903/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
6904 to perform a left shift. It must have SHIFTOP or more least
6905 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 6906
c5059423
AM
6907int
6908includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
6909 rtx shiftop;
6910 rtx andop;
c5059423 6911{
e2c953b6 6912 if (GET_CODE (andop) == CONST_INT)
c5059423 6913 {
02071907 6914 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 6915
02071907 6916 shift_mask = ~0;
c5059423
AM
6917 shift_mask <<= INTVAL (shiftop);
6918 c = INTVAL (andop);
6919
6920 /* Find the least signifigant one bit. */
6921 lsb = c & -c;
6922
6923 /* It must be covered by the shift mask.
a4f6c312 6924 This test also rejects c == 0. */
c5059423
AM
6925 if ((lsb & shift_mask) == 0)
6926 return 0;
6927
6928 /* Check we have all 1's above the transition, and reject all 1's. */
6929 return c == -lsb && lsb != 1;
6930 }
6931 else if (GET_CODE (andop) == CONST_DOUBLE
6932 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6933 {
02071907 6934 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
6935
6936 low = CONST_DOUBLE_LOW (andop);
6937
6938 if (HOST_BITS_PER_WIDE_INT < 64)
6939 {
02071907 6940 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
6941
6942 high = CONST_DOUBLE_HIGH (andop);
6943
6944 if (low == 0)
6945 {
02071907 6946 shift_mask_high = ~0;
c5059423
AM
6947 if (INTVAL (shiftop) > 32)
6948 shift_mask_high <<= INTVAL (shiftop) - 32;
6949
6950 lsb = high & -high;
6951
6952 if ((lsb & shift_mask_high) == 0)
6953 return 0;
6954
6955 return high == -lsb;
6956 }
6957 if (high != ~0)
6958 return 0;
6959 }
6960
02071907 6961 shift_mask_low = ~0;
c5059423
AM
6962 shift_mask_low <<= INTVAL (shiftop);
6963
6964 lsb = low & -low;
6965
6966 if ((lsb & shift_mask_low) == 0)
6967 return 0;
6968
6969 return low == -lsb && lsb != 1;
6970 }
e2c953b6 6971 else
c5059423 6972 return 0;
9878760c 6973}
35068b43
RK
6974
6975/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
6976 for lfq and stfq insns.
6977
6978 Note reg1 and reg2 *must* be hard registers. To be sure we will
6979 abort if we are passed pseudo registers. */
6980
6981int
6982registers_ok_for_quad_peep (reg1, reg2)
6983 rtx reg1, reg2;
6984{
6985 /* We might have been passed a SUBREG. */
6986 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
6987 return 0;
6988
6989 return (REGNO (reg1) == REGNO (reg2) - 1);
6990}
6991
a4f6c312
SS
6992/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
6993 addr1 and addr2 must be in consecutive memory locations
6994 (addr2 == addr1 + 8). */
35068b43
RK
6995
6996int
6997addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
6998 rtx addr1;
6999 rtx addr2;
35068b43 7000{
e2c953b6 7001 unsigned int reg1;
35068b43
RK
7002 int offset1;
7003
7004 /* Extract an offset (if used) from the first addr. */
7005 if (GET_CODE (addr1) == PLUS)
7006 {
7007 /* If not a REG, return zero. */
7008 if (GET_CODE (XEXP (addr1, 0)) != REG)
7009 return 0;
7010 else
7011 {
7012 reg1 = REGNO (XEXP (addr1, 0));
7013 /* The offset must be constant! */
7014 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7015 return 0;
7016 offset1 = INTVAL (XEXP (addr1, 1));
7017 }
7018 }
7019 else if (GET_CODE (addr1) != REG)
7020 return 0;
7021 else
7022 {
7023 reg1 = REGNO (addr1);
7024 /* This was a simple (mem (reg)) expression. Offset is 0. */
7025 offset1 = 0;
7026 }
7027
acad7ed3 7028 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
7029 if (GET_CODE (addr2) != PLUS)
7030 return 0;
7031
7032 if (GET_CODE (XEXP (addr2, 0)) != REG
7033 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7034 return 0;
7035
7036 if (reg1 != REGNO (XEXP (addr2, 0)))
7037 return 0;
7038
7039 /* The offset for the second addr must be 8 more than the first addr. */
7040 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7041 return 0;
7042
7043 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7044 instructions. */
7045 return 1;
7046}
9878760c
RK
7047\f
7048/* Return the register class of a scratch register needed to copy IN into
7049 or out of a register in CLASS in MODE. If it can be done directly,
7050 NO_REGS is returned. */
7051
7052enum reg_class
7053secondary_reload_class (class, mode, in)
7054 enum reg_class class;
296b8152 7055 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7056 rtx in;
7057{
5accd822 7058 int regno;
9878760c 7059
46fad5b7
DJ
7060 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
7061 {
7062 /* We cannot copy a symbolic operand directly into anything
7063 other than BASE_REGS for TARGET_ELF. So indicate that a
7064 register from BASE_REGS is needed as an intermediate
7065 register.
7066
7067 On Darwin, pic addresses require a load from memory, which
7068 needs a base register. */
7069 if (class != BASE_REGS
7070 && (GET_CODE (in) == SYMBOL_REF
7071 || GET_CODE (in) == HIGH
7072 || GET_CODE (in) == LABEL_REF
7073 || GET_CODE (in) == CONST))
7074 return BASE_REGS;
7075 }
e7b7998a 7076
5accd822
DE
7077 if (GET_CODE (in) == REG)
7078 {
7079 regno = REGNO (in);
7080 if (regno >= FIRST_PSEUDO_REGISTER)
7081 {
7082 regno = true_regnum (in);
7083 if (regno >= FIRST_PSEUDO_REGISTER)
7084 regno = -1;
7085 }
7086 }
7087 else if (GET_CODE (in) == SUBREG)
7088 {
7089 regno = true_regnum (in);
7090 if (regno >= FIRST_PSEUDO_REGISTER)
7091 regno = -1;
7092 }
7093 else
7094 regno = -1;
7095
9878760c
RK
7096 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7097 into anything. */
7098 if (class == GENERAL_REGS || class == BASE_REGS
7099 || (regno >= 0 && INT_REGNO_P (regno)))
7100 return NO_REGS;
7101
7102 /* Constants, memory, and FP registers can go into FP registers. */
7103 if ((regno == -1 || FP_REGNO_P (regno))
7104 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7105 return NO_REGS;
7106
0ac081f6
AH
7107 /* Memory, and AltiVec registers can go into AltiVec registers. */
7108 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7109 && class == ALTIVEC_REGS)
7110 return NO_REGS;
7111
9878760c
RK
7112 /* We can copy among the CR registers. */
7113 if ((class == CR_REGS || class == CR0_REGS)
7114 && regno >= 0 && CR_REGNO_P (regno))
7115 return NO_REGS;
7116
7117 /* Otherwise, we need GENERAL_REGS. */
7118 return GENERAL_REGS;
7119}
7120\f
7121/* Given a comparison operation, return the bit number in CCR to test. We
7122 know this is a valid comparison.
7123
7124 SCC_P is 1 if this is for an scc. That means that %D will have been
7125 used instead of %C, so the bits will be in different places.
7126
b4ac57ab 7127 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7128
7129int
7130ccr_bit (op, scc_p)
592696dd 7131 rtx op;
9878760c
RK
7132 int scc_p;
7133{
7134 enum rtx_code code = GET_CODE (op);
7135 enum machine_mode cc_mode;
7136 int cc_regnum;
7137 int base_bit;
9ebbca7d 7138 rtx reg;
9878760c
RK
7139
7140 if (GET_RTX_CLASS (code) != '<')
7141 return -1;
7142
9ebbca7d
GK
7143 reg = XEXP (op, 0);
7144
7145 if (GET_CODE (reg) != REG
7146 || ! CR_REGNO_P (REGNO (reg)))
7147 abort ();
7148
7149 cc_mode = GET_MODE (reg);
7150 cc_regnum = REGNO (reg);
7151 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7152
39a10a29 7153 validate_condition_mode (code, cc_mode);
c5defebb 7154
9878760c
RK
7155 switch (code)
7156 {
7157 case NE:
a3170dc6
AH
7158 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7159 return base_bit + 1;
9878760c
RK
7160 return scc_p ? base_bit + 3 : base_bit + 2;
7161 case EQ:
a3170dc6
AH
7162 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7163 return base_bit + 1;
9878760c 7164 return base_bit + 2;
1c882ea4 7165 case GT: case GTU: case UNLE:
9878760c 7166 return base_bit + 1;
1c882ea4 7167 case LT: case LTU: case UNGE:
9878760c 7168 return base_bit;
1c882ea4
GK
7169 case ORDERED: case UNORDERED:
7170 return base_bit + 3;
9878760c
RK
7171
7172 case GE: case GEU:
39a10a29 7173 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7174 unordered position. So test that bit. For integer, this is ! LT
7175 unless this is an scc insn. */
39a10a29 7176 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7177
7178 case LE: case LEU:
39a10a29 7179 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7180
9878760c
RK
7181 default:
7182 abort ();
7183 }
7184}
1ff7789b 7185\f
8d30c4ee 7186/* Return the GOT register. */
1ff7789b
MM
7187
7188struct rtx_def *
7189rs6000_got_register (value)
5f59ecb7 7190 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7191{
a4f6c312
SS
7192 /* The second flow pass currently (June 1999) can't update
7193 regs_ever_live without disturbing other parts of the compiler, so
7194 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7195 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7196 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7197
8d30c4ee 7198 current_function_uses_pic_offset_table = 1;
3cb999d8 7199
1ff7789b
MM
7200 return pic_offset_table_rtx;
7201}
a7df97e6 7202\f
e2500fed
GK
7203/* Function to init struct machine_function.
7204 This will be called, via a pointer variable,
7205 from push_function_context. */
a7df97e6 7206
e2500fed
GK
7207static struct machine_function *
7208rs6000_init_machine_status ()
a7df97e6 7209{
e2500fed 7210 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7211}
9878760c 7212\f
0ba1b2ff
AM
7213/* These macros test for integers and extract the low-order bits. */
7214#define INT_P(X) \
7215((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7216 && GET_MODE (X) == VOIDmode)
7217
7218#define INT_LOWPART(X) \
7219 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7220
7221int
7222extract_MB (op)
7223 rtx op;
7224{
7225 int i;
7226 unsigned long val = INT_LOWPART (op);
7227
7228 /* If the high bit is zero, the value is the first 1 bit we find
7229 from the left. */
7230 if ((val & 0x80000000) == 0)
7231 {
7232 if ((val & 0xffffffff) == 0)
7233 abort ();
7234
7235 i = 1;
7236 while (((val <<= 1) & 0x80000000) == 0)
7237 ++i;
7238 return i;
7239 }
7240
7241 /* If the high bit is set and the low bit is not, or the mask is all
7242 1's, the value is zero. */
7243 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7244 return 0;
7245
7246 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7247 from the right. */
7248 i = 31;
7249 while (((val >>= 1) & 1) != 0)
7250 --i;
7251
7252 return i;
7253}
7254
7255int
7256extract_ME (op)
7257 rtx op;
7258{
7259 int i;
7260 unsigned long val = INT_LOWPART (op);
7261
7262 /* If the low bit is zero, the value is the first 1 bit we find from
7263 the right. */
7264 if ((val & 1) == 0)
7265 {
7266 if ((val & 0xffffffff) == 0)
7267 abort ();
7268
7269 i = 30;
7270 while (((val >>= 1) & 1) == 0)
7271 --i;
7272
7273 return i;
7274 }
7275
7276 /* If the low bit is set and the high bit is not, or the mask is all
7277 1's, the value is 31. */
7278 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7279 return 31;
7280
7281 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7282 from the left. */
7283 i = 0;
7284 while (((val <<= 1) & 0x80000000) != 0)
7285 ++i;
7286
7287 return i;
7288}
7289
9878760c
RK
7290/* Print an operand. Recognize special options, documented below. */
7291
38c1f2d7 7292#if TARGET_ELF
d9407988 7293#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7294#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7295#else
7296#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7297#define SMALL_DATA_REG 0
ba5e43aa
MM
7298#endif
7299
9878760c
RK
7300void
7301print_operand (file, x, code)
7302 FILE *file;
7303 rtx x;
9ebbca7d 7304 int code;
9878760c
RK
7305{
7306 int i;
a260abc9 7307 HOST_WIDE_INT val;
0ba1b2ff 7308 unsigned HOST_WIDE_INT uval;
9878760c
RK
7309
7310 switch (code)
7311 {
a8b3aeda 7312 case '.':
a85d226b
RK
7313 /* Write out an instruction after the call which may be replaced
7314 with glue code by the loader. This depends on the AIX version. */
7315 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7316 return;
7317
81eace42
GK
7318 /* %a is output_address. */
7319
9854d9ed
RK
7320 case 'A':
7321 /* If X is a constant integer whose low-order 5 bits are zero,
7322 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7323 in the AIX assembler where "sri" with a zero shift count
20e26713 7324 writes a trash instruction. */
9854d9ed 7325 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7326 putc ('l', file);
9854d9ed 7327 else
76229ac8 7328 putc ('r', file);
9854d9ed
RK
7329 return;
7330
7331 case 'b':
e2c953b6
DE
7332 /* If constant, low-order 16 bits of constant, unsigned.
7333 Otherwise, write normally. */
7334 if (INT_P (x))
7335 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7336 else
7337 print_operand (file, x, 0);
cad12a8d
RK
7338 return;
7339
a260abc9
DE
7340 case 'B':
7341 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7342 for 64-bit mask direction. */
296b8152 7343 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7344 return;
a260abc9 7345
81eace42
GK
7346 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7347 output_operand. */
7348
9854d9ed 7349 case 'D':
39a10a29
GK
7350 /* There used to be a comment for 'C' reading "This is an
7351 optional cror needed for certain floating-point
7352 comparisons. Otherwise write nothing." */
7353
9854d9ed
RK
7354 /* Similar, except that this is for an scc, so we must be able to
7355 encode the test in a single bit that is one. We do the above
7356 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7357 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7358 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7359 {
9ebbca7d 7360 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7361
7362 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7363 base_bit + 2,
7364 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7365 }
7366
7367 else if (GET_CODE (x) == NE)
7368 {
9ebbca7d 7369 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7370
7371 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7372 base_bit + 2, base_bit + 2);
7373 }
a3170dc6
AH
7374 else if (TARGET_SPE && TARGET_HARD_FLOAT
7375 && GET_CODE (x) == EQ
7376 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7377 {
7378 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7379
7380 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7381 base_bit + 1, base_bit + 1);
7382 }
9854d9ed
RK
7383 return;
7384
7385 case 'E':
39a10a29 7386 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7387 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7388 output_operand_lossage ("invalid %%E value");
78fbdbf7 7389 else
39a10a29 7390 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7391 return;
9854d9ed
RK
7392
7393 case 'f':
7394 /* X is a CR register. Print the shift count needed to move it
7395 to the high-order four bits. */
7396 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7397 output_operand_lossage ("invalid %%f value");
7398 else
9ebbca7d 7399 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7400 return;
7401
7402 case 'F':
7403 /* Similar, but print the count for the rotate in the opposite
7404 direction. */
7405 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7406 output_operand_lossage ("invalid %%F value");
7407 else
9ebbca7d 7408 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7409 return;
7410
7411 case 'G':
7412 /* X is a constant integer. If it is negative, print "m",
43aa4e05 7413 otherwise print "z". This is to make an aze or ame insn. */
9854d9ed
RK
7414 if (GET_CODE (x) != CONST_INT)
7415 output_operand_lossage ("invalid %%G value");
7416 else if (INTVAL (x) >= 0)
76229ac8 7417 putc ('z', file);
9854d9ed 7418 else
76229ac8 7419 putc ('m', file);
9854d9ed 7420 return;
e2c953b6 7421
9878760c 7422 case 'h':
a4f6c312
SS
7423 /* If constant, output low-order five bits. Otherwise, write
7424 normally. */
9878760c 7425 if (INT_P (x))
5f59ecb7 7426 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7427 else
7428 print_operand (file, x, 0);
7429 return;
7430
64305719 7431 case 'H':
a4f6c312
SS
7432 /* If constant, output low-order six bits. Otherwise, write
7433 normally. */
64305719 7434 if (INT_P (x))
5f59ecb7 7435 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7436 else
7437 print_operand (file, x, 0);
7438 return;
7439
9854d9ed
RK
7440 case 'I':
7441 /* Print `i' if this is a constant, else nothing. */
9878760c 7442 if (INT_P (x))
76229ac8 7443 putc ('i', file);
9878760c
RK
7444 return;
7445
9854d9ed
RK
7446 case 'j':
7447 /* Write the bit number in CCR for jump. */
7448 i = ccr_bit (x, 0);
7449 if (i == -1)
7450 output_operand_lossage ("invalid %%j code");
9878760c 7451 else
9854d9ed 7452 fprintf (file, "%d", i);
9878760c
RK
7453 return;
7454
9854d9ed
RK
7455 case 'J':
7456 /* Similar, but add one for shift count in rlinm for scc and pass
7457 scc flag to `ccr_bit'. */
7458 i = ccr_bit (x, 1);
7459 if (i == -1)
7460 output_operand_lossage ("invalid %%J code");
7461 else
a0466a68
RK
7462 /* If we want bit 31, write a shift count of zero, not 32. */
7463 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7464 return;
7465
9854d9ed
RK
7466 case 'k':
7467 /* X must be a constant. Write the 1's complement of the
7468 constant. */
9878760c 7469 if (! INT_P (x))
9854d9ed 7470 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7471 else
7472 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7473 return;
7474
81eace42 7475 case 'K':
9ebbca7d
GK
7476 /* X must be a symbolic constant on ELF. Write an
7477 expression suitable for an 'addi' that adds in the low 16
7478 bits of the MEM. */
7479 if (GET_CODE (x) != CONST)
7480 {
7481 print_operand_address (file, x);
7482 fputs ("@l", file);
7483 }
7484 else
7485 {
7486 if (GET_CODE (XEXP (x, 0)) != PLUS
7487 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7488 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7489 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7490 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7491 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7492 fputs ("@l", file);
ed8d2920
MM
7493 /* For GNU as, there must be a non-alphanumeric character
7494 between 'l' and the number. The '-' is added by
7495 print_operand() already. */
7496 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7497 fputs ("+", file);
9ebbca7d
GK
7498 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7499 }
81eace42
GK
7500 return;
7501
7502 /* %l is output_asm_label. */
9ebbca7d 7503
9854d9ed
RK
7504 case 'L':
7505 /* Write second word of DImode or DFmode reference. Works on register
7506 or non-indexed memory only. */
7507 if (GET_CODE (x) == REG)
5ebfb2ba 7508 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7509 else if (GET_CODE (x) == MEM)
7510 {
7511 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7512 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7513 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7514 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7515 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7516 UNITS_PER_WORD));
9854d9ed 7517 else
d7624dc0
RK
7518 output_address (XEXP (adjust_address_nv (x, SImode,
7519 UNITS_PER_WORD),
7520 0));
ed8908e7 7521
ba5e43aa 7522 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7523 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7524 reg_names[SMALL_DATA_REG]);
9854d9ed 7525 }
9878760c 7526 return;
9854d9ed 7527
9878760c
RK
7528 case 'm':
7529 /* MB value for a mask operand. */
b1765bde 7530 if (! mask_operand (x, SImode))
9878760c
RK
7531 output_operand_lossage ("invalid %%m value");
7532
0ba1b2ff 7533 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7534 return;
7535
7536 case 'M':
7537 /* ME value for a mask operand. */
b1765bde 7538 if (! mask_operand (x, SImode))
a260abc9 7539 output_operand_lossage ("invalid %%M value");
9878760c 7540
0ba1b2ff 7541 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7542 return;
7543
81eace42
GK
7544 /* %n outputs the negative of its operand. */
7545
9878760c
RK
7546 case 'N':
7547 /* Write the number of elements in the vector times 4. */
7548 if (GET_CODE (x) != PARALLEL)
7549 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7550 else
7551 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7552 return;
7553
7554 case 'O':
7555 /* Similar, but subtract 1 first. */
7556 if (GET_CODE (x) != PARALLEL)
1427100a 7557 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7558 else
7559 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7560 return;
7561
9854d9ed
RK
7562 case 'p':
7563 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7564 if (! INT_P (x)
2bfcf297 7565 || INT_LOWPART (x) < 0
9854d9ed
RK
7566 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7567 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7568 else
7569 fprintf (file, "%d", i);
9854d9ed
RK
7570 return;
7571
9878760c
RK
7572 case 'P':
7573 /* The operand must be an indirect memory reference. The result
a4f6c312 7574 is the register number. */
9878760c
RK
7575 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7576 || REGNO (XEXP (x, 0)) >= 32)
7577 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7578 else
7579 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7580 return;
7581
dfbdccdb
GK
7582 case 'q':
7583 /* This outputs the logical code corresponding to a boolean
7584 expression. The expression may have one or both operands
39a10a29
GK
7585 negated (if one, only the first one). For condition register
7586 logical operations, it will also treat the negated
7587 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7588 {
63bc1d05 7589 const char *const *t = 0;
dfbdccdb
GK
7590 const char *s;
7591 enum rtx_code code = GET_CODE (x);
7592 static const char * const tbl[3][3] = {
7593 { "and", "andc", "nor" },
7594 { "or", "orc", "nand" },
7595 { "xor", "eqv", "xor" } };
7596
7597 if (code == AND)
7598 t = tbl[0];
7599 else if (code == IOR)
7600 t = tbl[1];
7601 else if (code == XOR)
7602 t = tbl[2];
7603 else
7604 output_operand_lossage ("invalid %%q value");
7605
7606 if (GET_CODE (XEXP (x, 0)) != NOT)
7607 s = t[0];
7608 else
7609 {
7610 if (GET_CODE (XEXP (x, 1)) == NOT)
7611 s = t[2];
7612 else
7613 s = t[1];
7614 }
7615
7616 fputs (s, file);
7617 }
7618 return;
7619
9854d9ed
RK
7620 case 'R':
7621 /* X is a CR register. Print the mask for `mtcrf'. */
7622 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7623 output_operand_lossage ("invalid %%R value");
7624 else
9ebbca7d 7625 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7626 return;
9854d9ed
RK
7627
7628 case 's':
7629 /* Low 5 bits of 32 - value */
7630 if (! INT_P (x))
7631 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7632 else
7633 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7634 return;
9854d9ed 7635
a260abc9 7636 case 'S':
0ba1b2ff 7637 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7638 CONST_INT 32-bit mask is considered sign-extended so any
7639 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7640 if (! mask64_operand (x, DImode))
a260abc9
DE
7641 output_operand_lossage ("invalid %%S value");
7642
0ba1b2ff 7643 uval = INT_LOWPART (x);
a260abc9 7644
0ba1b2ff 7645 if (uval & 1) /* Clear Left */
a260abc9 7646 {
0ba1b2ff
AM
7647 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7648 i = 64;
a260abc9 7649 }
0ba1b2ff 7650 else /* Clear Right */
a260abc9 7651 {
0ba1b2ff
AM
7652 uval = ~uval;
7653 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7654 i = 63;
a260abc9 7655 }
0ba1b2ff
AM
7656 while (uval != 0)
7657 --i, uval >>= 1;
7658 if (i < 0)
7659 abort ();
7660 fprintf (file, "%d", i);
7661 return;
a260abc9 7662
a3170dc6
AH
7663 case 't':
7664 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7665 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7666 abort ();
7667
7668 /* Bit 3 is OV bit. */
7669 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7670
7671 /* If we want bit 31, write a shift count of zero, not 32. */
7672 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7673 return;
7674
cccf3bdc
DE
7675 case 'T':
7676 /* Print the symbolic name of a branch target register. */
7677 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7678 && REGNO (x) != COUNT_REGISTER_REGNUM))
7679 output_operand_lossage ("invalid %%T value");
e2c953b6 7680 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
7681 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7682 else
7683 fputs ("ctr", file);
7684 return;
7685
9854d9ed 7686 case 'u':
802a0058 7687 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
7688 if (! INT_P (x))
7689 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
7690 else
7691 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7692 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
7693 return;
7694
802a0058
MM
7695 case 'v':
7696 /* High-order 16 bits of constant for use in signed operand. */
7697 if (! INT_P (x))
7698 output_operand_lossage ("invalid %%v value");
e2c953b6 7699 else
134c32f6
DE
7700 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7701 (INT_LOWPART (x) >> 16) & 0xffff);
7702 return;
802a0058 7703
9854d9ed
RK
7704 case 'U':
7705 /* Print `u' if this has an auto-increment or auto-decrement. */
7706 if (GET_CODE (x) == MEM
7707 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7708 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 7709 putc ('u', file);
9854d9ed 7710 return;
9878760c 7711
e0cd0770
JC
7712 case 'V':
7713 /* Print the trap code for this operand. */
7714 switch (GET_CODE (x))
7715 {
7716 case EQ:
7717 fputs ("eq", file); /* 4 */
7718 break;
7719 case NE:
7720 fputs ("ne", file); /* 24 */
7721 break;
7722 case LT:
7723 fputs ("lt", file); /* 16 */
7724 break;
7725 case LE:
7726 fputs ("le", file); /* 20 */
7727 break;
7728 case GT:
7729 fputs ("gt", file); /* 8 */
7730 break;
7731 case GE:
7732 fputs ("ge", file); /* 12 */
7733 break;
7734 case LTU:
7735 fputs ("llt", file); /* 2 */
7736 break;
7737 case LEU:
7738 fputs ("lle", file); /* 6 */
7739 break;
7740 case GTU:
7741 fputs ("lgt", file); /* 1 */
7742 break;
7743 case GEU:
7744 fputs ("lge", file); /* 5 */
7745 break;
7746 default:
7747 abort ();
7748 }
7749 break;
7750
9854d9ed
RK
7751 case 'w':
7752 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7753 normally. */
7754 if (INT_P (x))
5f59ecb7
DE
7755 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7756 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
7757 else
7758 print_operand (file, x, 0);
9878760c
RK
7759 return;
7760
9854d9ed 7761 case 'W':
e2c953b6 7762 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
7763 val = (GET_CODE (x) == CONST_INT
7764 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7765
7766 if (val < 0)
7767 i = -1;
9854d9ed 7768 else
e2c953b6
DE
7769 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7770 if ((val <<= 1) < 0)
7771 break;
7772
7773#if HOST_BITS_PER_WIDE_INT == 32
7774 if (GET_CODE (x) == CONST_INT && i >= 0)
7775 i += 32; /* zero-extend high-part was all 0's */
7776 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7777 {
7778 val = CONST_DOUBLE_LOW (x);
7779
7780 if (val == 0)
a4f6c312 7781 abort ();
e2c953b6
DE
7782 else if (val < 0)
7783 --i;
7784 else
7785 for ( ; i < 64; i++)
7786 if ((val <<= 1) < 0)
7787 break;
7788 }
7789#endif
7790
7791 fprintf (file, "%d", i + 1);
9854d9ed 7792 return;
9878760c 7793
9854d9ed
RK
7794 case 'X':
7795 if (GET_CODE (x) == MEM
258bfae2 7796 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 7797 putc ('x', file);
9854d9ed 7798 return;
9878760c 7799
9854d9ed
RK
7800 case 'Y':
7801 /* Like 'L', for third word of TImode */
7802 if (GET_CODE (x) == REG)
5ebfb2ba 7803 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 7804 else if (GET_CODE (x) == MEM)
9878760c 7805 {
9854d9ed
RK
7806 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7807 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7808 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 7809 else
d7624dc0 7810 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 7811 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7812 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7813 reg_names[SMALL_DATA_REG]);
9878760c
RK
7814 }
7815 return;
9854d9ed 7816
9878760c 7817 case 'z':
b4ac57ab
RS
7818 /* X is a SYMBOL_REF. Write out the name preceded by a
7819 period and without any trailing data in brackets. Used for function
4d30c363
MM
7820 names. If we are configured for System V (or the embedded ABI) on
7821 the PowerPC, do not emit the period, since those systems do not use
7822 TOCs and the like. */
9878760c
RK
7823 if (GET_CODE (x) != SYMBOL_REF)
7824 abort ();
7825
b6c9286a
MM
7826 if (XSTR (x, 0)[0] != '.')
7827 {
7828 switch (DEFAULT_ABI)
7829 {
7830 default:
7831 abort ();
7832
7833 case ABI_AIX:
7834 putc ('.', file);
7835 break;
7836
7837 case ABI_V4:
7838 case ABI_AIX_NODESC:
ee890fe2 7839 case ABI_DARWIN:
b6c9286a 7840 break;
b6c9286a
MM
7841 }
7842 }
54ee9799
DE
7843#if TARGET_AIX
7844 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
7845#else
9ebbca7d 7846 assemble_name (file, XSTR (x, 0));
54ee9799 7847#endif
9878760c
RK
7848 return;
7849
9854d9ed
RK
7850 case 'Z':
7851 /* Like 'L', for last word of TImode. */
7852 if (GET_CODE (x) == REG)
5ebfb2ba 7853 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
7854 else if (GET_CODE (x) == MEM)
7855 {
7856 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7857 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7858 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 7859 else
d7624dc0 7860 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 7861 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7862 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7863 reg_names[SMALL_DATA_REG]);
9854d9ed 7864 }
5c23c401 7865 return;
0ac081f6 7866
a3170dc6 7867 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
7868 case 'y':
7869 {
7870 rtx tmp;
7871
7872 if (GET_CODE (x) != MEM)
7873 abort ();
7874
7875 tmp = XEXP (x, 0);
7876
a3170dc6
AH
7877 if (TARGET_SPE)
7878 {
7879 /* Handle [reg]. */
7880 if (GET_CODE (tmp) == REG)
7881 {
7882 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
7883 break;
7884 }
7885 /* Handle [reg+UIMM]. */
7886 else if (GET_CODE (tmp) == PLUS &&
7887 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
7888 {
7889 int x;
7890
7891 if (GET_CODE (XEXP (tmp, 0)) != REG)
7892 abort ();
7893
7894 x = INTVAL (XEXP (tmp, 1));
7895 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
7896 break;
7897 }
7898
7899 /* Fall through. Must be [reg+reg]. */
7900 }
0ac081f6 7901 if (GET_CODE (tmp) == REG)
c62f2db5 7902 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
7903 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
7904 {
7905 if (REGNO (XEXP (tmp, 0)) == 0)
7906 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
7907 reg_names[ REGNO (XEXP (tmp, 0)) ]);
7908 else
7909 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
7910 reg_names[ REGNO (XEXP (tmp, 1)) ]);
7911 }
7912 else
7913 abort ();
7914 break;
7915 }
9854d9ed 7916
9878760c
RK
7917 case 0:
7918 if (GET_CODE (x) == REG)
7919 fprintf (file, "%s", reg_names[REGNO (x)]);
7920 else if (GET_CODE (x) == MEM)
7921 {
7922 /* We need to handle PRE_INC and PRE_DEC here, since we need to
7923 know the width from the mode. */
7924 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
7925 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
7926 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7927 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
7928 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
7929 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7930 else
a54d04b7 7931 output_address (XEXP (x, 0));
9878760c
RK
7932 }
7933 else
a54d04b7 7934 output_addr_const (file, x);
a85d226b 7935 return;
9878760c
RK
7936
7937 default:
7938 output_operand_lossage ("invalid %%xn code");
7939 }
7940}
7941\f
7942/* Print the address of an operand. */
7943
7944void
7945print_operand_address (file, x)
7946 FILE *file;
592696dd 7947 rtx x;
9878760c
RK
7948{
7949 if (GET_CODE (x) == REG)
4697a36c 7950 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
7951 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
7952 || GET_CODE (x) == LABEL_REF)
9878760c
RK
7953 {
7954 output_addr_const (file, x);
ba5e43aa 7955 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7956 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7957 reg_names[SMALL_DATA_REG]);
9ebbca7d 7958 else if (TARGET_TOC)
a4f6c312 7959 abort ();
9878760c
RK
7960 }
7961 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
7962 {
7963 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
7964 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
7965 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 7966 else
4697a36c
MM
7967 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
7968 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
7969 }
7970 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
7971 {
7972 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
7973 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7974 }
3cb999d8
DE
7975#if TARGET_ELF
7976 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
7977 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
7978 {
7979 output_addr_const (file, XEXP (x, 1));
7980 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7981 }
c859cda6
DJ
7982#endif
7983#if TARGET_MACHO
7984 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
7985 && CONSTANT_P (XEXP (x, 1)))
7986 {
7987 fprintf (file, "lo16(");
7988 output_addr_const (file, XEXP (x, 1));
7989 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7990 }
3cb999d8 7991#endif
9ebbca7d
GK
7992 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
7993 {
2bfcf297 7994 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 7995 {
2bfcf297
DB
7996 rtx contains_minus = XEXP (x, 1);
7997 rtx minus, symref;
7998 const char *name;
9ebbca7d
GK
7999
8000 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 8001 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
8002 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8003 contains_minus = XEXP (contains_minus, 0);
8004
2bfcf297
DB
8005 minus = XEXP (contains_minus, 0);
8006 symref = XEXP (minus, 0);
8007 XEXP (contains_minus, 0) = symref;
8008 if (TARGET_ELF)
8009 {
8010 char *newname;
8011
8012 name = XSTR (symref, 0);
8013 newname = alloca (strlen (name) + sizeof ("@toc"));
8014 strcpy (newname, name);
8015 strcat (newname, "@toc");
8016 XSTR (symref, 0) = newname;
8017 }
8018 output_addr_const (file, XEXP (x, 1));
8019 if (TARGET_ELF)
8020 XSTR (symref, 0) = name;
9ebbca7d
GK
8021 XEXP (contains_minus, 0) = minus;
8022 }
8023 else
8024 output_addr_const (file, XEXP (x, 1));
8025
8026 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8027 }
9878760c
RK
8028 else
8029 abort ();
8030}
8031\f
88cad84b 8032/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
8033 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8034 is defined. It also needs to handle DI-mode objects on 64-bit
8035 targets. */
8036
8037static bool
8038rs6000_assemble_integer (x, size, aligned_p)
8039 rtx x;
8040 unsigned int size;
8041 int aligned_p;
8042{
8043#ifdef RELOCATABLE_NEEDS_FIXUP
8044 /* Special handling for SI values. */
8045 if (size == 4 && aligned_p)
8046 {
8047 extern int in_toc_section PARAMS ((void));
8048 static int recurse = 0;
8049
8050 /* For -mrelocatable, we mark all addresses that need to be fixed up
8051 in the .fixup section. */
8052 if (TARGET_RELOCATABLE
8053 && !in_toc_section ()
8054 && !in_text_section ()
8055 && !recurse
8056 && GET_CODE (x) != CONST_INT
8057 && GET_CODE (x) != CONST_DOUBLE
8058 && CONSTANT_P (x))
8059 {
8060 char buf[256];
8061
8062 recurse = 1;
8063 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8064 fixuplabelno++;
8065 ASM_OUTPUT_LABEL (asm_out_file, buf);
8066 fprintf (asm_out_file, "\t.long\t(");
8067 output_addr_const (asm_out_file, x);
8068 fprintf (asm_out_file, ")@fixup\n");
8069 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8070 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8071 fprintf (asm_out_file, "\t.long\t");
8072 assemble_name (asm_out_file, buf);
8073 fprintf (asm_out_file, "\n\t.previous\n");
8074 recurse = 0;
8075 return true;
8076 }
8077 /* Remove initial .'s to turn a -mcall-aixdesc function
8078 address into the address of the descriptor, not the function
8079 itself. */
8080 else if (GET_CODE (x) == SYMBOL_REF
8081 && XSTR (x, 0)[0] == '.'
8082 && DEFAULT_ABI == ABI_AIX)
8083 {
8084 const char *name = XSTR (x, 0);
8085 while (*name == '.')
8086 name++;
8087
8088 fprintf (asm_out_file, "\t.long\t%s\n", name);
8089 return true;
8090 }
8091 }
8092#endif /* RELOCATABLE_NEEDS_FIXUP */
8093 return default_assemble_integer (x, size, aligned_p);
8094}
93638d7a
AM
8095
8096#ifdef HAVE_GAS_HIDDEN
8097/* Emit an assembler directive to set symbol visibility for DECL to
8098 VISIBILITY_TYPE. */
8099
5add3202 8100static void
93638d7a
AM
8101rs6000_assemble_visibility (decl, visibility_type)
8102 tree decl;
8103 const char *visibility_type;
8104{
bd79540a 8105 default_assemble_visibility (decl, visibility_type);
93638d7a
AM
8106
8107 /* Functions need to have their entry point symbol visibility set as
8108 well as their descriptor symbol visibility. */
8109 if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
8110 {
8111 const char *name;
8112
8113 name = ((* targetm.strip_name_encoding)
8114 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
8115
8116 fprintf (asm_out_file, "\t.%s\t.%s\n", visibility_type, name);
8117 }
8118}
8119#endif
301d03af 8120\f
39a10a29
GK
8121enum rtx_code
8122rs6000_reverse_condition (mode, code)
8123 enum machine_mode mode;
8124 enum rtx_code code;
8125{
8126 /* Reversal of FP compares takes care -- an ordered compare
8127 becomes an unordered compare and vice versa. */
8128 if (mode == CCFPmode)
bab6226b 8129 return reverse_condition_maybe_unordered (code);
39a10a29 8130 else
bab6226b 8131 return reverse_condition (code);
39a10a29
GK
8132}
8133
39a10a29
GK
8134/* Generate a compare for CODE. Return a brand-new rtx that
8135 represents the result of the compare. */
a4f6c312 8136
39a10a29
GK
8137static rtx
8138rs6000_generate_compare (code)
8139 enum rtx_code code;
8140{
8141 enum machine_mode comp_mode;
8142 rtx compare_result;
8143
8144 if (rs6000_compare_fp_p)
8145 comp_mode = CCFPmode;
8146 else if (code == GTU || code == LTU
8147 || code == GEU || code == LEU)
8148 comp_mode = CCUNSmode;
8149 else
8150 comp_mode = CCmode;
8151
8152 /* First, the compare. */
8153 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
8154
8155 /* SPE FP compare instructions on the GPRs. Yuck! */
8156 if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
8157 {
8158 rtx cmp, or1, or2, or_result, compare_result2;
8159
8160 switch (code)
8161 {
8162 case EQ:
8163 case UNEQ:
8164 case NE:
8165 case LTGT:
8166 cmp = flag_unsafe_math_optimizations
8167 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8168 rs6000_compare_op1)
8169 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8170 rs6000_compare_op1);
8171 break;
8172 case GT:
8173 case GTU:
8174 case UNGT:
8175 case UNGE:
8176 case GE:
8177 case GEU:
8178 cmp = flag_unsafe_math_optimizations
8179 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8180 rs6000_compare_op1)
8181 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8182 rs6000_compare_op1);
8183 break;
8184 case LT:
8185 case LTU:
8186 case UNLT:
8187 case UNLE:
8188 case LE:
8189 case LEU:
8190 cmp = flag_unsafe_math_optimizations
8191 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8192 rs6000_compare_op1)
8193 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8194 rs6000_compare_op1);
8195 break;
8196 default:
8197 abort ();
8198 }
8199
8200 /* Synthesize LE and GE from LT/GT || EQ. */
8201 if (code == LE || code == GE || code == LEU || code == GEU)
8202 {
8203 /* Synthesize GE/LE frome GT/LT || EQ. */
8204
8205 emit_insn (cmp);
8206
8207 switch (code)
8208 {
8209 case LE: code = LT; break;
8210 case GE: code = GT; break;
8211 case LEU: code = LT; break;
8212 case GEU: code = GT; break;
8213 default: abort ();
8214 }
8215
8216 or1 = gen_reg_rtx (SImode);
8217 or2 = gen_reg_rtx (SImode);
8218 or_result = gen_reg_rtx (CCEQmode);
8219 compare_result2 = gen_reg_rtx (CCFPmode);
8220
8221 /* Do the EQ. */
8222 cmp = flag_unsafe_math_optimizations
8223 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8224 rs6000_compare_op1)
8225 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8226 rs6000_compare_op1);
8227 emit_insn (cmp);
8228
8229 /* The MC8540 FP compare instructions set the CR bits
8230 differently than other PPC compare instructions. For
8231 that matter, there is no generic test instruction, but a
8232 testgt, testlt, and testeq. For a true condition, bit 2
8233 is set (x1xx) in the CR. Following the traditional CR
8234 values:
8235
8236 LT GT EQ OV
8237 bit3 bit2 bit1 bit0
8238
8239 ... bit 2 would be a GT CR alias, so later on we
8240 look in the GT bits for the branch instructins.
8241 However, we must be careful to emit correct RTL in
8242 the meantime, so optimizations don't get confused. */
8243
8244 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8245 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8246
8247 /* OR them together. */
8248 cmp = gen_rtx_SET (VOIDmode, or_result,
8249 gen_rtx_COMPARE (CCEQmode,
8250 gen_rtx_IOR (SImode, or1, or2),
8251 const_true_rtx));
8252 compare_result = or_result;
8253 code = EQ;
8254 }
8255 else
8256 {
8257 /* We only care about 1 bit (x1xx), so map everything to NE to
8258 maintain rtl sanity. We'll get to the right bit (x1xx) at
8259 code output time. */
8260 if (code == NE || code == LTGT)
8261 /* Do the inverse here because we have no cmpne
8262 instruction. We use the cmpeq instruction and expect
8263 to get a 0 instead. */
8264 code = EQ;
8265 else
8266 code = NE;
8267 }
8268
8269 emit_insn (cmp);
8270 }
8271 else
8272 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8273 gen_rtx_COMPARE (comp_mode,
8274 rs6000_compare_op0,
8275 rs6000_compare_op1)));
39a10a29 8276
ca5adc63 8277 /* Some kinds of FP comparisons need an OR operation;
de6c5979 8278 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 8279 if (rs6000_compare_fp_p
de6c5979 8280 && ! flag_unsafe_math_optimizations
a3170dc6 8281 && ! (TARGET_HARD_FLOAT && TARGET_SPE)
39a10a29
GK
8282 && (code == LE || code == GE
8283 || code == UNEQ || code == LTGT
8284 || code == UNGT || code == UNLT))
8285 {
8286 enum rtx_code or1, or2;
8287 rtx or1_rtx, or2_rtx, compare2_rtx;
8288 rtx or_result = gen_reg_rtx (CCEQmode);
8289
8290 switch (code)
8291 {
8292 case LE: or1 = LT; or2 = EQ; break;
8293 case GE: or1 = GT; or2 = EQ; break;
8294 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8295 case LTGT: or1 = LT; or2 = GT; break;
8296 case UNGT: or1 = UNORDERED; or2 = GT; break;
8297 case UNLT: or1 = UNORDERED; or2 = LT; break;
8298 default: abort ();
8299 }
8300 validate_condition_mode (or1, comp_mode);
8301 validate_condition_mode (or2, comp_mode);
8302 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8303 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8304 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8305 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8306 const_true_rtx);
8307 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8308
8309 compare_result = or_result;
8310 code = EQ;
8311 }
8312
8313 validate_condition_mode (code, GET_MODE (compare_result));
8314
8315 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8316}
8317
8318
8319/* Emit the RTL for an sCOND pattern. */
8320
8321void
8322rs6000_emit_sCOND (code, result)
8323 enum rtx_code code;
8324 rtx result;
8325{
8326 rtx condition_rtx;
8327 enum machine_mode op_mode;
8328
8329 condition_rtx = rs6000_generate_compare (code);
8330
8331 op_mode = GET_MODE (rs6000_compare_op0);
8332 if (op_mode == VOIDmode)
8333 op_mode = GET_MODE (rs6000_compare_op1);
8334
8335 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8336 {
8337 PUT_MODE (condition_rtx, DImode);
8338 convert_move (result, condition_rtx, 0);
8339 }
8340 else
8341 {
8342 PUT_MODE (condition_rtx, SImode);
8343 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8344 }
8345}
8346
39a10a29
GK
8347/* Emit a branch of kind CODE to location LOC. */
8348
8349void
8350rs6000_emit_cbranch (code, loc)
8351 enum rtx_code code;
8352 rtx loc;
8353{
8354 rtx condition_rtx, loc_ref;
8355
8356 condition_rtx = rs6000_generate_compare (code);
8357 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8358 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8359 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8360 loc_ref, pc_rtx)));
8361}
8362
12a4e8c5
GK
8363/* Return the string to output a conditional branch to LABEL, which is
8364 the operand number of the label, or -1 if the branch is really a
8365 conditional return.
8366
8367 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8368 condition code register and its mode specifies what kind of
8369 comparison we made.
8370
a0ab749a 8371 REVERSED is nonzero if we should reverse the sense of the comparison.
12a4e8c5
GK
8372
8373 INSN is the insn. */
8374
8375char *
8376output_cbranch (op, label, reversed, insn)
8377 rtx op;
8378 const char * label;
8379 int reversed;
8380 rtx insn;
8381{
8382 static char string[64];
8383 enum rtx_code code = GET_CODE (op);
8384 rtx cc_reg = XEXP (op, 0);
8385 enum machine_mode mode = GET_MODE (cc_reg);
8386 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 8387 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
8388 int really_reversed = reversed ^ need_longbranch;
8389 char *s = string;
8390 const char *ccode;
8391 const char *pred;
8392 rtx note;
8393
39a10a29
GK
8394 validate_condition_mode (code, mode);
8395
8396 /* Work out which way this really branches. We could use
8397 reverse_condition_maybe_unordered here always but this
8398 makes the resulting assembler clearer. */
12a4e8c5 8399 if (really_reversed)
39a10a29 8400 code = rs6000_reverse_condition (mode, code);
12a4e8c5 8401
a3170dc6
AH
8402 if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
8403 {
8404 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8405 to the GT bit. */
8406 if (code == EQ)
8407 /* Opposite of GT. */
8408 code = UNLE;
8409 else if (code == NE)
8410 code = GT;
8411 else
8412 abort ();
8413 }
8414
39a10a29 8415 switch (code)
12a4e8c5
GK
8416 {
8417 /* Not all of these are actually distinct opcodes, but
8418 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
8419 case NE: case LTGT:
8420 ccode = "ne"; break;
8421 case EQ: case UNEQ:
8422 ccode = "eq"; break;
8423 case GE: case GEU:
8424 ccode = "ge"; break;
8425 case GT: case GTU: case UNGT:
8426 ccode = "gt"; break;
8427 case LE: case LEU:
8428 ccode = "le"; break;
8429 case LT: case LTU: case UNLT:
8430 ccode = "lt"; break;
12a4e8c5
GK
8431 case UNORDERED: ccode = "un"; break;
8432 case ORDERED: ccode = "nu"; break;
8433 case UNGE: ccode = "nl"; break;
8434 case UNLE: ccode = "ng"; break;
8435 default:
a4f6c312 8436 abort ();
12a4e8c5
GK
8437 }
8438
94a54f47
GK
8439 /* Maybe we have a guess as to how likely the branch is.
8440 The old mnemonics don't have a way to specify this information. */
f4857b9b 8441 pred = "";
12a4e8c5
GK
8442 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8443 if (note != NULL_RTX)
8444 {
8445 /* PROB is the difference from 50%. */
8446 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
8447 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8448
8449 /* Only hint for highly probable/improbable branches on newer
8450 cpus as static prediction overrides processor dynamic
8451 prediction. For older cpus we may as well always hint, but
8452 assume not taken for branches that are very close to 50% as a
8453 mispredicted taken branch is more expensive than a
8454 mispredicted not-taken branch. */
8455 if (always_hint
8456 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8457 {
8458 if (abs (prob) > REG_BR_PROB_BASE / 20
8459 && ((prob > 0) ^ need_longbranch))
8460 pred = "+";
8461 else
8462 pred = "-";
8463 }
12a4e8c5 8464 }
12a4e8c5
GK
8465
8466 if (label == NULL)
94a54f47 8467 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 8468 else
94a54f47 8469 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 8470
37c67319
GK
8471 /* We need to escape any '%' characters in the reg_names string.
8472 Assume they'd only be the first character... */
8473 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8474 *s++ = '%';
94a54f47 8475 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
8476
8477 if (label != NULL)
8478 {
8479 /* If the branch distance was too far, we may have to use an
8480 unconditional branch to go the distance. */
8481 if (need_longbranch)
44518ddd 8482 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
8483 else
8484 s += sprintf (s, ",%s", label);
8485 }
8486
8487 return string;
8488}
50a0b056
GK
8489
8490/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8491 operands of the last comparison is nonzero/true, FALSE_COND if it
8492 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 8493
50a0b056
GK
8494int
8495rs6000_emit_cmove (dest, op, true_cond, false_cond)
8496 rtx dest;
8497 rtx op;
8498 rtx true_cond;
8499 rtx false_cond;
8500{
8501 enum rtx_code code = GET_CODE (op);
8502 rtx op0 = rs6000_compare_op0;
8503 rtx op1 = rs6000_compare_op1;
8504 REAL_VALUE_TYPE c1;
3148ad6d
DJ
8505 enum machine_mode compare_mode = GET_MODE (op0);
8506 enum machine_mode result_mode = GET_MODE (dest);
50a0b056
GK
8507 rtx temp;
8508
3148ad6d 8509 /* These modes should always match. */
a3170dc6
AH
8510 if (GET_MODE (op1) != compare_mode
8511 /* In the isel case however, we can use a compare immediate, so
8512 op1 may be a small constant. */
8513 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 8514 return 0;
178c3eff 8515 if (GET_MODE (true_cond) != result_mode)
3148ad6d 8516 return 0;
178c3eff 8517 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
8518 return 0;
8519
50a0b056
GK
8520 /* First, work out if the hardware can do this at all, or
8521 if it's too slow... */
50a0b056 8522 if (! rs6000_compare_fp_p)
a3170dc6
AH
8523 {
8524 if (TARGET_ISEL)
8525 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8526 return 0;
8527 }
50a0b056
GK
8528
8529 /* Eliminate half of the comparisons by switching operands, this
8530 makes the remaining code simpler. */
8531 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8532 || code == LTGT || code == LT)
8533 {
8534 code = reverse_condition_maybe_unordered (code);
8535 temp = true_cond;
8536 true_cond = false_cond;
8537 false_cond = temp;
8538 }
8539
8540 /* UNEQ and LTGT take four instructions for a comparison with zero,
8541 it'll probably be faster to use a branch here too. */
8542 if (code == UNEQ)
8543 return 0;
8544
8545 if (GET_CODE (op1) == CONST_DOUBLE)
8546 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8547
8548 /* We're going to try to implement comparions by performing
8549 a subtract, then comparing against zero. Unfortunately,
8550 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 8551 know that the operand is finite and the comparison
50a0b056
GK
8552 would treat EQ different to UNORDERED, we can't do it. */
8553 if (! flag_unsafe_math_optimizations
8554 && code != GT && code != UNGE
045572c7 8555 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
8556 /* Constructs of the form (a OP b ? a : b) are safe. */
8557 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8558 || (! rtx_equal_p (op0, true_cond)
8559 && ! rtx_equal_p (op1, true_cond))))
8560 return 0;
8561 /* At this point we know we can use fsel. */
8562
8563 /* Reduce the comparison to a comparison against zero. */
3148ad6d 8564 temp = gen_reg_rtx (compare_mode);
50a0b056 8565 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8566 gen_rtx_MINUS (compare_mode, op0, op1)));
50a0b056 8567 op0 = temp;
3148ad6d 8568 op1 = CONST0_RTX (compare_mode);
50a0b056
GK
8569
8570 /* If we don't care about NaNs we can reduce some of the comparisons
8571 down to faster ones. */
8572 if (flag_unsafe_math_optimizations)
8573 switch (code)
8574 {
8575 case GT:
8576 code = LE;
8577 temp = true_cond;
8578 true_cond = false_cond;
8579 false_cond = temp;
8580 break;
8581 case UNGE:
8582 code = GE;
8583 break;
8584 case UNEQ:
8585 code = EQ;
8586 break;
8587 default:
8588 break;
8589 }
8590
8591 /* Now, reduce everything down to a GE. */
8592 switch (code)
8593 {
8594 case GE:
8595 break;
8596
8597 case LE:
3148ad6d
DJ
8598 temp = gen_reg_rtx (compare_mode);
8599 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8600 op0 = temp;
8601 break;
8602
8603 case ORDERED:
3148ad6d
DJ
8604 temp = gen_reg_rtx (compare_mode);
8605 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
8606 op0 = temp;
8607 break;
8608
8609 case EQ:
3148ad6d 8610 temp = gen_reg_rtx (compare_mode);
50a0b056 8611 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
8612 gen_rtx_NEG (compare_mode,
8613 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
8614 op0 = temp;
8615 break;
8616
8617 case UNGE:
3148ad6d 8618 temp = gen_reg_rtx (result_mode);
50a0b056 8619 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8620 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8621 gen_rtx_GE (VOIDmode,
8622 op0, op1),
8623 true_cond, false_cond)));
8624 false_cond = temp;
8625 true_cond = false_cond;
8626
3148ad6d
DJ
8627 temp = gen_reg_rtx (compare_mode);
8628 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8629 op0 = temp;
8630 break;
8631
8632 case GT:
3148ad6d 8633 temp = gen_reg_rtx (result_mode);
50a0b056 8634 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8635 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8636 gen_rtx_GE (VOIDmode,
8637 op0, op1),
8638 true_cond, false_cond)));
8639 true_cond = temp;
8640 false_cond = true_cond;
8641
3148ad6d
DJ
8642 temp = gen_reg_rtx (compare_mode);
8643 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8644 op0 = temp;
8645 break;
8646
8647 default:
8648 abort ();
8649 }
8650
8651 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 8652 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8653 gen_rtx_GE (VOIDmode,
8654 op0, op1),
8655 true_cond, false_cond)));
8656 return 1;
8657}
8658
a3170dc6
AH
8659/* Same as above, but for ints (isel). */
8660
8661static int
8662rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
8663 rtx dest;
8664 rtx op;
8665 rtx true_cond;
8666 rtx false_cond;
8667{
8668 rtx condition_rtx, cr;
8669
8670 /* All isel implementations thus far are 32-bits. */
8671 if (GET_MODE (rs6000_compare_op0) != SImode)
8672 return 0;
8673
8674 /* We still have to do the compare, because isel doesn't do a
8675 compare, it just looks at the CRx bits set by a previous compare
8676 instruction. */
8677 condition_rtx = rs6000_generate_compare (GET_CODE (op));
8678 cr = XEXP (condition_rtx, 0);
8679
8680 if (GET_MODE (cr) == CCmode)
8681 emit_insn (gen_isel_signed (dest, condition_rtx,
8682 true_cond, false_cond, cr));
8683 else
8684 emit_insn (gen_isel_unsigned (dest, condition_rtx,
8685 true_cond, false_cond, cr));
8686
8687 return 1;
8688}
8689
8690const char *
8691output_isel (operands)
8692 rtx *operands;
8693{
8694 enum rtx_code code;
8695
8696 code = GET_CODE (operands[1]);
8697 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
8698 {
8699 PUT_CODE (operands[1], reverse_condition (code));
8700 return "isel %0,%3,%2,%j1";
8701 }
8702 else
8703 return "isel %0,%2,%3,%j1";
8704}
8705
50a0b056
GK
8706void
8707rs6000_emit_minmax (dest, code, op0, op1)
8708 rtx dest;
8709 enum rtx_code code;
8710 rtx op0;
8711 rtx op1;
8712{
8713 enum machine_mode mode = GET_MODE (op0);
5dc8d536 8714 enum rtx_code c;
50a0b056 8715 rtx target;
5dc8d536
AH
8716
8717 if (code == SMAX || code == SMIN)
8718 c = GE;
8719 else
8720 c = GEU;
8721
50a0b056 8722 if (code == SMAX || code == UMAX)
5dc8d536 8723 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8724 op0, op1, mode, 0);
8725 else
5dc8d536 8726 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8727 op1, op0, mode, 0);
8728 if (target == NULL_RTX)
8729 abort ();
8730 if (target != dest)
8731 emit_move_insn (dest, target);
8732}
12a4e8c5 8733\f
a4f6c312
SS
8734/* This page contains routines that are used to determine what the
8735 function prologue and epilogue code will do and write them out. */
9878760c 8736
a4f6c312
SS
8737/* Return the first fixed-point register that is required to be
8738 saved. 32 if none. */
9878760c
RK
8739
8740int
8741first_reg_to_save ()
8742{
8743 int first_reg;
8744
8745 /* Find lowest numbered live register. */
8746 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
8747 if (regs_ever_live[first_reg]
8748 && (! call_used_regs[first_reg]
1db02437 8749 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
8750 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
8751 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
8752 break;
8753
ee890fe2 8754#if TARGET_MACHO
93638d7a
AM
8755 if (flag_pic
8756 && current_function_uses_pic_offset_table
8757 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 8758 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
8759#endif
8760
9878760c
RK
8761 return first_reg;
8762}
8763
8764/* Similar, for FP regs. */
8765
8766int
8767first_fp_reg_to_save ()
8768{
8769 int first_reg;
8770
8771 /* Find lowest numbered live register. */
8772 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8773 if (regs_ever_live[first_reg])
8774 break;
8775
8776 return first_reg;
8777}
00b960c7
AH
8778
8779/* Similar, for AltiVec regs. */
8780
8781static int
8782first_altivec_reg_to_save ()
8783{
8784 int i;
8785
8786 /* Stack frame remains as is unless we are in AltiVec ABI. */
8787 if (! TARGET_ALTIVEC_ABI)
8788 return LAST_ALTIVEC_REGNO + 1;
8789
8790 /* Find lowest numbered live register. */
8791 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8792 if (regs_ever_live[i])
8793 break;
8794
8795 return i;
8796}
8797
8798/* Return a 32-bit mask of the AltiVec registers we need to set in
8799 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
8800 the 32-bit word is 0. */
8801
8802static unsigned int
8803compute_vrsave_mask ()
8804{
8805 unsigned int i, mask = 0;
8806
8807 /* First, find out if we use _any_ altivec registers. */
8808 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8809 if (regs_ever_live[i])
8810 mask |= ALTIVEC_REG_BIT (i);
8811
8812 if (mask == 0)
8813 return mask;
8814
8815 /* Next, add all registers that are call-clobbered. We do this
8816 because post-reload register optimizers such as regrename_optimize
8817 may choose to use them. They never change the register class
8818 chosen by reload, so cannot create new uses of altivec registers
8819 if there were none before, so the early exit above is safe. */
8820 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
8821 altivec registers not saved in the mask, which might well make the
8822 adjustments below more effective in eliding the save/restore of
8823 VRSAVE in small functions. */
8824 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8825 if (call_used_regs[i])
8826 mask |= ALTIVEC_REG_BIT (i);
8827
8828 /* Next, remove the argument registers from the set. These must
8829 be in the VRSAVE mask set by the caller, so we don't need to add
8830 them in again. More importantly, the mask we compute here is
8831 used to generate CLOBBERs in the set_vrsave insn, and we do not
8832 wish the argument registers to die. */
8833 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
8834 mask &= ~ALTIVEC_REG_BIT (i);
8835
8836 /* Similarly, remove the return value from the set. */
8837 {
8838 bool yes = false;
8839 diddle_return_value (is_altivec_return_reg, &yes);
8840 if (yes)
8841 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
8842 }
8843
8844 return mask;
8845}
8846
8847static void
8848is_altivec_return_reg (reg, xyes)
8849 rtx reg;
8850 void *xyes;
8851{
8852 bool *yes = (bool *) xyes;
8853 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
8854 *yes = true;
8855}
8856
4697a36c
MM
8857\f
8858/* Calculate the stack information for the current function. This is
8859 complicated by having two separate calling sequences, the AIX calling
8860 sequence and the V.4 calling sequence.
8861
592696dd 8862 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 8863 32-bit 64-bit
4697a36c 8864 SP----> +---------------------------------------+
a260abc9 8865 | back chain to caller | 0 0
4697a36c 8866 +---------------------------------------+
a260abc9 8867 | saved CR | 4 8 (8-11)
4697a36c 8868 +---------------------------------------+
a260abc9 8869 | saved LR | 8 16
4697a36c 8870 +---------------------------------------+
a260abc9 8871 | reserved for compilers | 12 24
4697a36c 8872 +---------------------------------------+
a260abc9 8873 | reserved for binders | 16 32
4697a36c 8874 +---------------------------------------+
a260abc9 8875 | saved TOC pointer | 20 40
4697a36c 8876 +---------------------------------------+
a260abc9 8877 | Parameter save area (P) | 24 48
4697a36c 8878 +---------------------------------------+
a260abc9 8879 | Alloca space (A) | 24+P etc.
802a0058 8880 +---------------------------------------+
a7df97e6 8881 | Local variable space (L) | 24+P+A
4697a36c 8882 +---------------------------------------+
a7df97e6 8883 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 8884 +---------------------------------------+
00b960c7
AH
8885 | Save area for AltiVec registers (W) | 24+P+A+L+X
8886 +---------------------------------------+
8887 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
8888 +---------------------------------------+
8889 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 8890 +---------------------------------------+
00b960c7
AH
8891 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
8892 +---------------------------------------+
8893 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
8894 +---------------------------------------+
8895 old SP->| back chain to caller's caller |
8896 +---------------------------------------+
8897
5376a30c
KR
8898 The required alignment for AIX configurations is two words (i.e., 8
8899 or 16 bytes).
8900
8901
4697a36c
MM
8902 V.4 stack frames look like:
8903
8904 SP----> +---------------------------------------+
8905 | back chain to caller | 0
8906 +---------------------------------------+
5eb387b8 8907 | caller's saved LR | 4
4697a36c
MM
8908 +---------------------------------------+
8909 | Parameter save area (P) | 8
8910 +---------------------------------------+
a7df97e6
MM
8911 | Alloca space (A) | 8+P
8912 +---------------------------------------+
8913 | Varargs save area (V) | 8+P+A
8914 +---------------------------------------+
8915 | Local variable space (L) | 8+P+A+V
8916 +---------------------------------------+
8917 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 8918 +---------------------------------------+
00b960c7
AH
8919 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
8920 +---------------------------------------+
8921 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
8922 +---------------------------------------+
8923 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
8924 +---------------------------------------+
a3170dc6
AH
8925 | SPE: area for 64-bit GP registers |
8926 +---------------------------------------+
8927 | SPE alignment padding |
8928 +---------------------------------------+
00b960c7 8929 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 8930 +---------------------------------------+
00b960c7 8931 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 8932 +---------------------------------------+
00b960c7 8933 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
8934 +---------------------------------------+
8935 old SP->| back chain to caller's caller |
8936 +---------------------------------------+
b6c9286a 8937
5376a30c
KR
8938 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
8939 given. (But note below and in sysv4.h that we require only 8 and
8940 may round up the size of our stack frame anyways. The historical
8941 reason is early versions of powerpc-linux which didn't properly
8942 align the stack at program startup. A happy side-effect is that
8943 -mno-eabi libraries can be used with -meabi programs.)
8944
5376a30c
KR
8945 The EABI configuration defaults to the V.4 layout, unless
8946 -mcall-aix is used, in which case the AIX layout is used. However,
8947 the stack alignment requirements may differ. If -mno-eabi is not
8948 given, the required stack alignment is 8 bytes; if -mno-eabi is
8949 given, the required alignment is 16 bytes. (But see V.4 comment
8950 above.) */
4697a36c 8951
61b2fbe7
MM
8952#ifndef ABI_STACK_BOUNDARY
8953#define ABI_STACK_BOUNDARY STACK_BOUNDARY
8954#endif
8955
4697a36c
MM
8956rs6000_stack_t *
8957rs6000_stack_info ()
8958{
8959 static rs6000_stack_t info, zero_info;
8960 rs6000_stack_t *info_ptr = &info;
9ebbca7d 8961 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 8962 enum rs6000_abi abi;
83720594 8963 int ehrd_size;
b6c9286a 8964 int total_raw_size;
4697a36c 8965
a4f6c312 8966 /* Zero all fields portably. */
4697a36c
MM
8967 info = zero_info;
8968
a4f6c312 8969 /* Select which calling sequence. */
b6c9286a 8970 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 8971
a4f6c312 8972 /* Calculate which registers need to be saved & save area size. */
4697a36c 8973 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 8974 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 8975 even if it currently looks like we won't. */
2bfcf297 8976 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
8977 || (flag_pic == 1 && abi == ABI_V4)
8978 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
8979 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
8980 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
8981 else
8982 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 8983
a3170dc6
AH
8984 /* For the SPE, we have an additional upper 32-bits on each GPR.
8985 Ideally we should save the entire 64-bits only when the upper
8986 half is used in SIMD instructions. Since we only record
8987 registers live (not the size they are used in), this proves
8988 difficult because we'd have to traverse the instruction chain at
8989 the right time, taking reload into account. This is a real pain,
8990 so we opt to save the GPRs in 64-bits always. Anyone overly
8991 concerned with frame size can fix this. ;-).
8992
8993 So... since we save all GPRs (except the SP) in 64-bits, the
8994 traditional GP save area will be empty. */
8995 if (TARGET_SPE_ABI)
8996 info_ptr->gp_size = 0;
8997
4697a36c
MM
8998 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
8999 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
9000
00b960c7
AH
9001 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9002 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9003 - info_ptr->first_altivec_reg_save);
9004
592696dd 9005 /* Does this function call anything? */
71f123ca
FS
9006 info_ptr->calls_p = (! current_function_is_leaf
9007 || cfun->machine->ra_needs_full_frame);
b6c9286a 9008
a4f6c312 9009 /* Determine if we need to save the link register. */
71f123ca 9010 if (rs6000_ra_ever_killed ()
70f4f91c 9011 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
9012#ifdef TARGET_RELOCATABLE
9013 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9014#endif
9015 || (info_ptr->first_fp_reg_save != 64
9016 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 9017 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 9018 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
9019 || (DEFAULT_ABI == ABI_DARWIN
9020 && flag_pic
9021 && current_function_uses_pic_offset_table)
4697a36c
MM
9022 || info_ptr->calls_p)
9023 {
9024 info_ptr->lr_save_p = 1;
9ebbca7d 9025 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9026 }
9027
9ebbca7d
GK
9028 /* Determine if we need to save the condition code registers. */
9029 if (regs_ever_live[CR2_REGNO]
9030 || regs_ever_live[CR3_REGNO]
9031 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9032 {
9033 info_ptr->cr_save_p = 1;
f607bc57 9034 if (abi == ABI_V4)
4697a36c
MM
9035 info_ptr->cr_size = reg_size;
9036 }
9037
83720594
RH
9038 /* If the current function calls __builtin_eh_return, then we need
9039 to allocate stack space for registers that will hold data for
9040 the exception handler. */
9041 if (current_function_calls_eh_return)
9042 {
9043 unsigned int i;
9044 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9045 continue;
a3170dc6
AH
9046
9047 /* SPE saves EH registers in 64-bits. */
9048 ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9049 }
9050 else
9051 ehrd_size = 0;
9052
592696dd 9053 /* Determine various sizes. */
4697a36c
MM
9054 info_ptr->reg_size = reg_size;
9055 info_ptr->fixed_size = RS6000_SAVE_AREA;
9056 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9057 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9058 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9059 8);
00b960c7 9060
a3170dc6
AH
9061 if (TARGET_SPE_ABI)
9062 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9063 else
9064 info_ptr->spe_gp_size = 0;
9065
08b57fb3 9066 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9067 {
9068 info_ptr->vrsave_mask = compute_vrsave_mask ();
9069 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9070 }
9071 else
9072 {
9073 info_ptr->vrsave_mask = 0;
9074 info_ptr->vrsave_size = 0;
9075 }
b6c9286a 9076
592696dd 9077 /* Calculate the offsets. */
24d304eb 9078 switch (abi)
4697a36c 9079 {
b6c9286a 9080 case ABI_NONE:
24d304eb 9081 default:
b6c9286a
MM
9082 abort ();
9083
9084 case ABI_AIX:
9085 case ABI_AIX_NODESC:
ee890fe2 9086 case ABI_DARWIN:
b6c9286a
MM
9087 info_ptr->fp_save_offset = - info_ptr->fp_size;
9088 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9089
9090 if (TARGET_ALTIVEC_ABI)
9091 {
9092 info_ptr->vrsave_save_offset
9093 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9094
9095 /* Align stack so vector save area is on a quadword boundary. */
9096 if (info_ptr->altivec_size != 0)
9097 info_ptr->altivec_padding_size
9098 = 16 - (-info_ptr->vrsave_save_offset % 16);
9099 else
9100 info_ptr->altivec_padding_size = 0;
9101
9102 info_ptr->altivec_save_offset
9103 = info_ptr->vrsave_save_offset
9104 - info_ptr->altivec_padding_size
9105 - info_ptr->altivec_size;
9106
9107 /* Adjust for AltiVec case. */
9108 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9109 }
9110 else
9111 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9112 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9113 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9114 break;
9115
9116 case ABI_V4:
b6c9286a
MM
9117 info_ptr->fp_save_offset = - info_ptr->fp_size;
9118 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9119 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9120
a3170dc6
AH
9121 if (TARGET_SPE_ABI)
9122 {
9123 /* Align stack so SPE GPR save area is aligned on a
9124 double-word boundary. */
9125 if (info_ptr->spe_gp_size != 0)
9126 info_ptr->spe_padding_size
9127 = 8 - (-info_ptr->cr_save_offset % 8);
9128 else
9129 info_ptr->spe_padding_size = 0;
9130
9131 info_ptr->spe_gp_save_offset
9132 = info_ptr->cr_save_offset
9133 - info_ptr->spe_padding_size
9134 - info_ptr->spe_gp_size;
9135
9136 /* Adjust for SPE case. */
9137 info_ptr->toc_save_offset
9138 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9139 }
9140 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9141 {
9142 info_ptr->vrsave_save_offset
9143 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9144
9145 /* Align stack so vector save area is on a quadword boundary. */
9146 if (info_ptr->altivec_size != 0)
9147 info_ptr->altivec_padding_size
9148 = 16 - (-info_ptr->vrsave_save_offset % 16);
9149 else
9150 info_ptr->altivec_padding_size = 0;
9151
9152 info_ptr->altivec_save_offset
9153 = info_ptr->vrsave_save_offset
9154 - info_ptr->altivec_padding_size
9155 - info_ptr->altivec_size;
9156
9157 /* Adjust for AltiVec case. */
9158 info_ptr->toc_save_offset
9159 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9160 }
9161 else
9162 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9163 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9164 info_ptr->lr_save_offset = reg_size;
9165 break;
4697a36c
MM
9166 }
9167
00b960c7
AH
9168 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9169 + info_ptr->gp_size
9170 + info_ptr->altivec_size
9171 + info_ptr->altivec_padding_size
9172 + info_ptr->vrsave_size
a3170dc6
AH
9173 + info_ptr->spe_gp_size
9174 + info_ptr->spe_padding_size
00b960c7
AH
9175 + ehrd_size
9176 + info_ptr->cr_size
9177 + info_ptr->lr_size
9178 + info_ptr->vrsave_size
9179 + info_ptr->toc_size,
9180 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9181 ? 16 : 8);
9182
ff381587
MM
9183 total_raw_size = (info_ptr->vars_size
9184 + info_ptr->parm_size
ff381587
MM
9185 + info_ptr->save_size
9186 + info_ptr->varargs_size
9187 + info_ptr->fixed_size);
9188
a4f6c312
SS
9189 info_ptr->total_size =
9190 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9191
9192 /* Determine if we need to allocate any stack frame:
9193
a4f6c312
SS
9194 For AIX we need to push the stack if a frame pointer is needed
9195 (because the stack might be dynamically adjusted), if we are
9196 debugging, if we make calls, or if the sum of fp_save, gp_save,
9197 and local variables are more than the space needed to save all
9198 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9199 + 18*8 = 288 (GPR13 reserved).
ff381587 9200
a4f6c312
SS
9201 For V.4 we don't have the stack cushion that AIX uses, but assume
9202 that the debugger can handle stackless frames. */
ff381587
MM
9203
9204 if (info_ptr->calls_p)
9205 info_ptr->push_p = 1;
9206
f607bc57 9207 else if (abi == ABI_V4)
e72247f4 9208 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
9209
9210 else
9211 info_ptr->push_p = (frame_pointer_needed
ee890fe2 9212 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 9213 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 9214 > (TARGET_32BIT ? 220 : 288)));
ff381587 9215
a4f6c312 9216 /* Zero offsets if we're not saving those registers. */
8dda1a21 9217 if (info_ptr->fp_size == 0)
4697a36c
MM
9218 info_ptr->fp_save_offset = 0;
9219
8dda1a21 9220 if (info_ptr->gp_size == 0)
4697a36c
MM
9221 info_ptr->gp_save_offset = 0;
9222
00b960c7
AH
9223 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9224 info_ptr->altivec_save_offset = 0;
9225
9226 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9227 info_ptr->vrsave_save_offset = 0;
9228
a3170dc6
AH
9229 if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
9230 info_ptr->spe_gp_save_offset = 0;
9231
c81fc13e 9232 if (! info_ptr->lr_save_p)
4697a36c
MM
9233 info_ptr->lr_save_offset = 0;
9234
c81fc13e 9235 if (! info_ptr->cr_save_p)
4697a36c
MM
9236 info_ptr->cr_save_offset = 0;
9237
c81fc13e 9238 if (! info_ptr->toc_save_p)
b6c9286a
MM
9239 info_ptr->toc_save_offset = 0;
9240
4697a36c
MM
9241 return info_ptr;
9242}
9243
9244void
9245debug_stack_info (info)
9246 rs6000_stack_t *info;
9878760c 9247{
d330fd93 9248 const char *abi_string;
24d304eb 9249
c81fc13e 9250 if (! info)
4697a36c
MM
9251 info = rs6000_stack_info ();
9252
9253 fprintf (stderr, "\nStack information for function %s:\n",
9254 ((current_function_decl && DECL_NAME (current_function_decl))
9255 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9256 : "<unknown>"));
9257
24d304eb
RK
9258 switch (info->abi)
9259 {
b6c9286a
MM
9260 default: abi_string = "Unknown"; break;
9261 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9262 case ABI_AIX:
b6c9286a 9263 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9264 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9265 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9266 }
9267
9268 fprintf (stderr, "\tABI = %5s\n", abi_string);
9269
00b960c7
AH
9270 if (TARGET_ALTIVEC_ABI)
9271 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9272
a3170dc6
AH
9273 if (TARGET_SPE_ABI)
9274 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9275
4697a36c
MM
9276 if (info->first_gp_reg_save != 32)
9277 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9278
9279 if (info->first_fp_reg_save != 64)
9280 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9281
00b960c7
AH
9282 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9283 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9284 info->first_altivec_reg_save);
9285
4697a36c
MM
9286 if (info->lr_save_p)
9287 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9288
4697a36c
MM
9289 if (info->cr_save_p)
9290 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9291
b6c9286a
MM
9292 if (info->toc_save_p)
9293 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9294
00b960c7
AH
9295 if (info->vrsave_mask)
9296 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9297
4697a36c
MM
9298 if (info->push_p)
9299 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9300
9301 if (info->calls_p)
9302 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9303
4697a36c
MM
9304 if (info->gp_save_offset)
9305 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9306
9307 if (info->fp_save_offset)
9308 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9309
00b960c7
AH
9310 if (info->altivec_save_offset)
9311 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9312 info->altivec_save_offset);
9313
a3170dc6
AH
9314 if (info->spe_gp_save_offset)
9315 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9316 info->spe_gp_save_offset);
9317
00b960c7
AH
9318 if (info->vrsave_save_offset)
9319 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9320 info->vrsave_save_offset);
9321
4697a36c
MM
9322 if (info->lr_save_offset)
9323 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9324
9325 if (info->cr_save_offset)
9326 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9327
b6c9286a
MM
9328 if (info->toc_save_offset)
9329 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9330
4697a36c
MM
9331 if (info->varargs_save_offset)
9332 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9333
9334 if (info->total_size)
9335 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9336
9337 if (info->varargs_size)
9338 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9339
9340 if (info->vars_size)
9341 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9342
9343 if (info->parm_size)
9344 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9345
9346 if (info->fixed_size)
9347 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9348
9349 if (info->gp_size)
9350 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9351
a3170dc6
AH
9352 if (info->spe_gp_size)
9353 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9354
4697a36c
MM
9355 if (info->fp_size)
9356 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9357
00b960c7
AH
9358 if (info->altivec_size)
9359 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9360
9361 if (info->vrsave_size)
9362 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9363
9364 if (info->altivec_padding_size)
9365 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9366 info->altivec_padding_size);
9367
a3170dc6
AH
9368 if (info->spe_padding_size)
9369 fprintf (stderr, "\tspe_padding_size = %5d\n",
9370 info->spe_padding_size);
9371
a4f6c312 9372 if (info->lr_size)
ed947a96 9373 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9374
4697a36c
MM
9375 if (info->cr_size)
9376 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9377
a4f6c312 9378 if (info->toc_size)
b6c9286a
MM
9379 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9380
4697a36c
MM
9381 if (info->save_size)
9382 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9383
9384 if (info->reg_size != 4)
9385 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9386
9387 fprintf (stderr, "\n");
9878760c 9388}
71f123ca
FS
9389
9390rtx
9391rs6000_return_addr (count, frame)
9392 int count;
9393 rtx frame;
9394{
a4f6c312
SS
9395 /* Currently we don't optimize very well between prolog and body
9396 code and for PIC code the code can be actually quite bad, so
9397 don't try to be too clever here. */
f585a356 9398 if (count != 0 || flag_pic != 0)
71f123ca
FS
9399 {
9400 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9401
9402 return
9403 gen_rtx_MEM
9404 (Pmode,
9405 memory_address
9406 (Pmode,
9407 plus_constant (copy_to_reg
9408 (gen_rtx_MEM (Pmode,
9409 memory_address (Pmode, frame))),
9410 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9411 }
9412
9e2f7ec7 9413 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9414}
9415
5e1bf043
DJ
9416/* Say whether a function is a candidate for sibcall handling or not.
9417 We do not allow indirect calls to be optimized into sibling calls.
9418 Also, we can't do it if there are any vector parameters; there's
9419 nowhere to put the VRsave code so it works; note that functions with
9420 vector parameters are required to have a prototype, so the argument
9421 type info must be available here. (The tail recursion case can work
9422 with vector parameters, but there's no way to distinguish here.) */
9423int
9424function_ok_for_sibcall (fndecl)
9425 tree fndecl;
9426{
9427 tree type;
9428 if (fndecl)
9429 {
9430 if (TARGET_ALTIVEC_VRSAVE)
9431 {
9432 for (type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
9433 type; type = TREE_CHAIN (type))
9434 {
c15b529f 9435 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
5e1bf043
DJ
9436 return 0;
9437 }
9438 }
9439 if (DEFAULT_ABI == ABI_DARWIN
2bcc50d0
AM
9440 || (*targetm.binds_local_p) (fndecl))
9441 {
9442 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
9443
9444 if (!lookup_attribute ("longcall", attr_list)
9445 || lookup_attribute ("shortcall", attr_list))
9446 return 1;
9447 }
5e1bf043
DJ
9448 }
9449 return 0;
9450}
9451
71f123ca
FS
9452static int
9453rs6000_ra_ever_killed ()
9454{
9455 rtx top;
5e1bf043
DJ
9456 rtx reg;
9457 rtx insn;
71f123ca
FS
9458
9459#ifdef ASM_OUTPUT_MI_THUNK
9460 if (current_function_is_thunk)
9461 return 0;
9462#endif
36f7e964
AH
9463 /* regs_ever_live has LR marked as used if any sibcalls are present,
9464 but this should not force saving and restoring in the
9465 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
9466 clobbers LR, so that is inappropriate. */
9467
5e1bf043
DJ
9468 /* Also, the prologue can generate a store into LR that
9469 doesn't really count, like this:
36f7e964 9470
5e1bf043
DJ
9471 move LR->R0
9472 bcl to set PIC register
9473 move LR->R31
9474 move R0->LR
36f7e964
AH
9475
9476 When we're called from the epilogue, we need to avoid counting
9477 this as a store. */
5e1bf043 9478
71f123ca
FS
9479 push_topmost_sequence ();
9480 top = get_insns ();
9481 pop_topmost_sequence ();
5e1bf043 9482 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9483
5e1bf043
DJ
9484 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9485 {
9486 if (INSN_P (insn))
9487 {
9488 if (FIND_REG_INC_NOTE (insn, reg))
9489 return 1;
9490 else if (GET_CODE (insn) == CALL_INSN
c15b529f 9491 && !SIBLING_CALL_P (insn))
5e1bf043 9492 return 1;
36f7e964
AH
9493 else if (set_of (reg, insn) != NULL_RTX
9494 && !prologue_epilogue_contains (insn))
5e1bf043
DJ
9495 return 1;
9496 }
9497 }
9498 return 0;
71f123ca 9499}
4697a36c 9500\f
8cd8f856
GK
9501/* Add a REG_MAYBE_DEAD note to the insn. */
9502static void
9503rs6000_maybe_dead (insn)
9504 rtx insn;
9505{
9506 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9507 const0_rtx,
9508 REG_NOTES (insn));
9509}
9510
9ebbca7d 9511/* Emit instructions needed to load the TOC register.
c7ca610e 9512 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9513 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9514
9515void
9ebbca7d
GK
9516rs6000_emit_load_toc_table (fromprolog)
9517 int fromprolog;
c7ca610e 9518{
9ebbca7d 9519 rtx dest;
1db02437 9520 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9521
20b71b17
AM
9522 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9523 {
9524 rtx temp = (fromprolog
9525 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9526 : gen_reg_rtx (Pmode));
9527 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
9528 rs6000_maybe_dead (emit_move_insn (dest, temp));
9529 }
9530 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
9531 {
9532 char buf[30];
9533 rtx tempLR = (fromprolog
9534 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9535 : gen_reg_rtx (Pmode));
9536 rtx temp0 = (fromprolog
9537 ? gen_rtx_REG (Pmode, 0)
9538 : gen_reg_rtx (Pmode));
9539 rtx symF;
9540
9541 /* possibly create the toc section */
9542 if (! toc_initialized)
38c1f2d7 9543 {
20b71b17
AM
9544 toc_section ();
9545 function_section (current_function_decl);
38c1f2d7 9546 }
9ebbca7d 9547
20b71b17
AM
9548 if (fromprolog)
9549 {
9550 rtx symL;
38c1f2d7 9551
20b71b17
AM
9552 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
9553 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9554
20b71b17
AM
9555 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
9556 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9557
9558 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9559 symF)));
9560 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9561 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9562 symL,
9563 symF)));
9ebbca7d
GK
9564 }
9565 else
20b71b17
AM
9566 {
9567 rtx tocsym;
9568 static int reload_toc_labelno = 0;
9569
9570 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
9571
9572 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
9573 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9574
9575 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9576 symF,
9577 tocsym)));
9578 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9579 rs6000_maybe_dead (emit_move_insn (temp0,
9580 gen_rtx_MEM (Pmode, dest)));
9581 }
9582 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d 9583 }
20b71b17
AM
9584 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
9585 {
9586 /* This is for AIX code running in non-PIC ELF32. */
9587 char buf[30];
9588 rtx realsym;
9589 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9590 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9591
9592 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9593 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9594 }
9595 else if (DEFAULT_ABI == ABI_AIX)
9ebbca7d
GK
9596 {
9597 if (TARGET_32BIT)
20b71b17 9598 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 9599 else
20b71b17 9600 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d 9601 }
20b71b17
AM
9602 else
9603 abort ();
9ebbca7d
GK
9604}
9605
9606int
9607get_TOC_alias_set ()
9608{
9609 static int set = -1;
9610 if (set == -1)
9611 set = new_alias_set ();
9612 return set;
9613}
9614
9615/* This retuns nonzero if the current function uses the TOC. This is
9616 determined by the presence of (unspec ... 7), which is generated by
9617 the various load_toc_* patterns. */
a4f6c312 9618
9ebbca7d
GK
9619int
9620uses_TOC ()
9621{
9622 rtx insn;
38c1f2d7 9623
9ebbca7d 9624 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 9625 if (INSN_P (insn))
9ebbca7d
GK
9626 {
9627 rtx pat = PATTERN (insn);
9628 int i;
9629
8cd8f856 9630 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
9631 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9632 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9633 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9634 return 1;
38c1f2d7 9635 }
9ebbca7d
GK
9636 return 0;
9637}
38c1f2d7 9638
9ebbca7d 9639rtx
a4f6c312 9640create_TOC_reference (symbol)
9ebbca7d
GK
9641 rtx symbol;
9642{
a8a05998
ZW
9643 return gen_rtx_PLUS (Pmode,
9644 gen_rtx_REG (Pmode, TOC_REGISTER),
9645 gen_rtx_CONST (Pmode,
9646 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 9647 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 9648}
38c1f2d7 9649
9ebbca7d
GK
9650#if TARGET_AIX
9651/* __throw will restore its own return address to be the same as the
9652 return address of the function that the throw is being made to.
9653 This is unfortunate, because we want to check the original
9654 return address to see if we need to restore the TOC.
9655 So we have to squirrel it away here.
9656 This is used only in compiling __throw and __rethrow.
c7ca610e 9657
9ebbca7d
GK
9658 Most of this code should be removed by CSE. */
9659static rtx insn_after_throw;
c7ca610e 9660
a4f6c312 9661/* This does the saving... */
9ebbca7d
GK
9662void
9663rs6000_aix_emit_builtin_unwind_init ()
9664{
9665 rtx mem;
9666 rtx stack_top = gen_reg_rtx (Pmode);
9667 rtx opcode_addr = gen_reg_rtx (Pmode);
9668
9669 insn_after_throw = gen_reg_rtx (SImode);
9670
9671 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9672 emit_move_insn (stack_top, mem);
9673
9674 mem = gen_rtx_MEM (Pmode,
9675 gen_rtx_PLUS (Pmode, stack_top,
9676 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9677 emit_move_insn (opcode_addr, mem);
9678 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
9679}
9680
a4f6c312
SS
9681/* Emit insns to _restore_ the TOC register, at runtime (specifically
9682 in _eh.o). Only used on AIX.
9ebbca7d
GK
9683
9684 The idea is that on AIX, function calls look like this:
9685 bl somefunction-trampoline
9686 lwz r2,20(sp)
9687
a4f6c312 9688 and later,
9ebbca7d
GK
9689 somefunction-trampoline:
9690 stw r2,20(sp)
9691 ... load function address in the count register ...
9692 bctr
9693 or like this, if the linker determines that this is not a cross-module call
9694 and so the TOC need not be restored:
9695 bl somefunction
9696 nop
9697 or like this, if the compiler could determine that this is not a
9698 cross-module call:
9699 bl somefunction
9700 now, the tricky bit here is that register 2 is saved and restored
9701 by the _linker_, so we can't readily generate debugging information
9702 for it. So we need to go back up the call chain looking at the
9703 insns at return addresses to see which calls saved the TOC register
9704 and so see where it gets restored from.
9705
9706 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9707 just before the actual epilogue.
9708
9709 On the bright side, this incurs no space or time overhead unless an
9710 exception is thrown, except for the extra code in libgcc.a.
9711
9712 The parameter STACKSIZE is a register containing (at runtime)
9713 the amount to be popped off the stack in addition to the stack frame
9714 of this routine (which will be __throw or __rethrow, and so is
9715 guaranteed to have a stack frame). */
a4f6c312 9716
9ebbca7d
GK
9717void
9718rs6000_emit_eh_toc_restore (stacksize)
9719 rtx stacksize;
9720{
9721 rtx top_of_stack;
9722 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9723 rtx tocompare = gen_reg_rtx (SImode);
9724 rtx opcode = gen_reg_rtx (SImode);
9725 rtx opcode_addr = gen_reg_rtx (Pmode);
9726 rtx mem;
9727 rtx loop_start = gen_label_rtx ();
9728 rtx no_toc_restore_needed = gen_label_rtx ();
9729 rtx loop_exit = gen_label_rtx ();
9730
9731 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 9732 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9733 emit_move_insn (bottom_of_stack, mem);
9734
9735 top_of_stack = expand_binop (Pmode, add_optab,
9736 bottom_of_stack, stacksize,
9737 NULL_RTX, 1, OPTAB_WIDEN);
9738
2496c7bd
LB
9739 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9740 : 0xE8410028, SImode));
9ebbca7d
GK
9741
9742 if (insn_after_throw == NULL_RTX)
a4f6c312 9743 abort ();
9ebbca7d
GK
9744 emit_move_insn (opcode, insn_after_throw);
9745
6496a589 9746 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
9747 emit_label (loop_start);
9748
9749 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 9750 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9751 no_toc_restore_needed);
9752
9753 mem = gen_rtx_MEM (Pmode,
9754 gen_rtx_PLUS (Pmode, bottom_of_stack,
9755 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
9756 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
9757
9758 emit_label (no_toc_restore_needed);
9759 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 9760 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9761 loop_exit);
9762
9763 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 9764 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9765 emit_move_insn (bottom_of_stack, mem);
9766
9767 mem = gen_rtx_MEM (Pmode,
9768 gen_rtx_PLUS (Pmode, bottom_of_stack,
9769 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9770 emit_move_insn (opcode_addr, mem);
9771 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
9772
6496a589 9773 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 9774 emit_jump (loop_start);
6496a589 9775 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
9776 emit_label (loop_exit);
9777}
9778#endif /* TARGET_AIX */
38c1f2d7 9779\f
ba4828e0
RK
9780/* This ties together stack memory (MEM with an alias set of
9781 rs6000_sr_alias_set) and the change to the stack pointer. */
9782
9ebbca7d
GK
9783static void
9784rs6000_emit_stack_tie ()
9785{
ba4828e0
RK
9786 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
9787
9788 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9789 emit_insn (gen_stack_tie (mem));
9790}
38c1f2d7 9791
9ebbca7d
GK
9792/* Emit the correct code for allocating stack space, as insns.
9793 If COPY_R12, make sure a copy of the old frame is left in r12.
9794 The generated code may use hard register 0 as a temporary. */
9795
9796static void
9797rs6000_emit_allocate_stack (size, copy_r12)
9798 HOST_WIDE_INT size;
38c1f2d7
MM
9799 int copy_r12;
9800{
9ebbca7d
GK
9801 rtx insn;
9802 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9803 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
9804 rtx todec = GEN_INT (-size);
a157febd
GK
9805
9806 if (current_function_limit_stack)
9807 {
9808 if (REG_P (stack_limit_rtx)
9809 && REGNO (stack_limit_rtx) > 1
9810 && REGNO (stack_limit_rtx) <= 31)
9811 {
9ebbca7d
GK
9812 emit_insn (Pmode == SImode
9813 ? gen_addsi3 (tmp_reg,
9814 stack_limit_rtx,
9815 GEN_INT (size))
9816 : gen_adddi3 (tmp_reg,
9817 stack_limit_rtx,
9818 GEN_INT (size)));
9819
9820 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9821 const0_rtx));
a157febd
GK
9822 }
9823 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 9824 && TARGET_32BIT
f607bc57 9825 && DEFAULT_ABI == ABI_V4)
a157febd 9826 {
9ebbca7d
GK
9827 rtx toload = gen_rtx_CONST (VOIDmode,
9828 gen_rtx_PLUS (Pmode,
9829 stack_limit_rtx,
9830 GEN_INT (size)));
9831
9832 emit_insn (gen_elf_high (tmp_reg, toload));
9833 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
9834 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9835 const0_rtx));
a157febd
GK
9836 }
9837 else
9838 warning ("stack limit expression is not supported");
9839 }
9840
9ebbca7d
GK
9841 if (copy_r12 || ! TARGET_UPDATE)
9842 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
9843
38c1f2d7
MM
9844 if (TARGET_UPDATE)
9845 {
9ebbca7d 9846 if (size > 32767)
38c1f2d7 9847 {
9ebbca7d
GK
9848 /* Need a note here so that try_split doesn't get confused. */
9849 if (get_last_insn() == NULL_RTX)
9850 emit_note (0, NOTE_INSN_DELETED);
9851 insn = emit_move_insn (tmp_reg, todec);
9852 try_split (PATTERN (insn), insn, 0);
9853 todec = tmp_reg;
38c1f2d7 9854 }
9ebbca7d
GK
9855
9856 if (Pmode == SImode)
9857 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
9858 todec, stack_reg));
9859 else
9860 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
9861 todec, stack_reg));
38c1f2d7
MM
9862 }
9863 else
9864 {
9ebbca7d
GK
9865 if (Pmode == SImode)
9866 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
38c1f2d7 9867 else
9ebbca7d
GK
9868 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
9869 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
9870 gen_rtx_REG (Pmode, 12));
9871 }
9872
9873 RTX_FRAME_RELATED_P (insn) = 1;
9874 REG_NOTES (insn) =
9875 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9876 gen_rtx_SET (VOIDmode, stack_reg,
9877 gen_rtx_PLUS (Pmode, stack_reg,
9878 GEN_INT (-size))),
9879 REG_NOTES (insn));
9880}
9881
9aa86737
AH
9882/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
9883 knows that:
9884
9885 (mem (plus (blah) (regXX)))
9886
9887 is really:
9888
9889 (mem (plus (blah) (const VALUE_OF_REGXX))). */
9890
9891static void
9892altivec_frame_fixup (insn, reg, val)
9893 rtx insn, reg;
9894 HOST_WIDE_INT val;
9895{
9896 rtx real;
9897
9898 real = copy_rtx (PATTERN (insn));
9899
9900 real = replace_rtx (real, reg, GEN_INT (val));
9901
9902 RTX_FRAME_RELATED_P (insn) = 1;
9903 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9904 real,
9905 REG_NOTES (insn));
9906}
9907
a4f6c312
SS
9908/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
9909 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
9910 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
9911 deduce these equivalences by itself so it wasn't necessary to hold
9912 its hand so much. */
9ebbca7d
GK
9913
9914static void
9915rs6000_frame_related (insn, reg, val, reg2, rreg)
9916 rtx insn;
9917 rtx reg;
9918 HOST_WIDE_INT val;
9919 rtx reg2;
9920 rtx rreg;
9921{
9922 rtx real, temp;
9923
e56c4463
JL
9924 /* copy_rtx will not make unique copies of registers, so we need to
9925 ensure we don't have unwanted sharing here. */
9926 if (reg == reg2)
9927 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9928
9929 if (reg == rreg)
9930 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9931
9ebbca7d
GK
9932 real = copy_rtx (PATTERN (insn));
9933
89e7058f
AH
9934 if (reg2 != NULL_RTX)
9935 real = replace_rtx (real, reg2, rreg);
9936
9ebbca7d
GK
9937 real = replace_rtx (real, reg,
9938 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
9939 STACK_POINTER_REGNUM),
9940 GEN_INT (val)));
9941
9942 /* We expect that 'real' is either a SET or a PARALLEL containing
9943 SETs (and possibly other stuff). In a PARALLEL, all the SETs
9944 are important so they all have to be marked RTX_FRAME_RELATED_P. */
9945
9946 if (GET_CODE (real) == SET)
9947 {
9948 rtx set = real;
9949
9950 temp = simplify_rtx (SET_SRC (set));
9951 if (temp)
9952 SET_SRC (set) = temp;
9953 temp = simplify_rtx (SET_DEST (set));
9954 if (temp)
9955 SET_DEST (set) = temp;
9956 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 9957 {
9ebbca7d
GK
9958 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9959 if (temp)
9960 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 9961 }
38c1f2d7 9962 }
9ebbca7d
GK
9963 else if (GET_CODE (real) == PARALLEL)
9964 {
9965 int i;
9966 for (i = 0; i < XVECLEN (real, 0); i++)
9967 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
9968 {
9969 rtx set = XVECEXP (real, 0, i);
9970
9971 temp = simplify_rtx (SET_SRC (set));
9972 if (temp)
9973 SET_SRC (set) = temp;
9974 temp = simplify_rtx (SET_DEST (set));
9975 if (temp)
9976 SET_DEST (set) = temp;
9977 if (GET_CODE (SET_DEST (set)) == MEM)
9978 {
9979 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9980 if (temp)
9981 XEXP (SET_DEST (set), 0) = temp;
9982 }
9983 RTX_FRAME_RELATED_P (set) = 1;
9984 }
9985 }
9986 else
a4f6c312 9987 abort ();
9ebbca7d 9988
9ebbca7d
GK
9989 RTX_FRAME_RELATED_P (insn) = 1;
9990 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9991 real,
9992 REG_NOTES (insn));
38c1f2d7
MM
9993}
9994
00b960c7
AH
9995/* Returns an insn that has a vrsave set operation with the
9996 appropriate CLOBBERs. */
9997
9998static rtx
9aa86737 9999generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
10000 rtx reg;
10001 rs6000_stack_t *info;
9aa86737 10002 int epiloguep;
00b960c7
AH
10003{
10004 int nclobs, i;
10005 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 10006 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 10007
a004eb82
AH
10008 clobs[0]
10009 = gen_rtx_SET (VOIDmode,
10010 vrsave,
10011 gen_rtx_UNSPEC_VOLATILE (SImode,
10012 gen_rtvec (2, reg, vrsave),
10013 30));
00b960c7
AH
10014
10015 nclobs = 1;
10016
9aa86737
AH
10017 /* We need to clobber the registers in the mask so the scheduler
10018 does not move sets to VRSAVE before sets of AltiVec registers.
10019
10020 However, if the function receives nonlocal gotos, reload will set
10021 all call saved registers live. We will end up with:
10022
10023 (set (reg 999) (mem))
10024 (parallel [ (set (reg vrsave) (unspec blah))
10025 (clobber (reg 999))])
10026
10027 The clobber will cause the store into reg 999 to be dead, and
10028 flow will attempt to delete an epilogue insn. In this case, we
10029 need an unspec use/set of the register. */
00b960c7
AH
10030
10031 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10032 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10033 {
10034 if (!epiloguep || call_used_regs [i])
10035 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10036 gen_rtx_REG (V4SImode, i));
10037 else
10038 {
10039 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10040
10041 clobs[nclobs++]
a004eb82
AH
10042 = gen_rtx_SET (VOIDmode,
10043 reg,
10044 gen_rtx_UNSPEC (V4SImode,
10045 gen_rtvec (1, reg), 27));
9aa86737
AH
10046 }
10047 }
00b960c7
AH
10048
10049 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10050
10051 for (i = 0; i < nclobs; ++i)
10052 XVECEXP (insn, 0, i) = clobs[i];
10053
10054 return insn;
10055}
10056
89e7058f
AH
10057/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10058 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10059
10060static void
10061emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10062 rtx frame_reg;
10063 rtx frame_ptr;
10064 enum machine_mode mode;
10065 unsigned int regno;
10066 int offset;
10067 int total_size;
10068{
10069 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10070 rtx replacea, replaceb;
10071
10072 int_rtx = GEN_INT (offset);
10073
10074 /* Some cases that need register indexed addressing. */
10075 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10076 || (TARGET_SPE_ABI
10077 && SPE_VECTOR_MODE (mode)
10078 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10079 {
10080 /* Whomever calls us must make sure r11 is available in the
10081 flow path of instructions in the prologue. */
10082 offset_rtx = gen_rtx_REG (Pmode, 11);
10083 emit_move_insn (offset_rtx, int_rtx);
10084
10085 replacea = offset_rtx;
10086 replaceb = int_rtx;
10087 }
10088 else
10089 {
10090 offset_rtx = int_rtx;
10091 replacea = NULL_RTX;
10092 replaceb = NULL_RTX;
10093 }
10094
10095 reg = gen_rtx_REG (mode, regno);
10096 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10097 mem = gen_rtx_MEM (mode, addr);
10098 set_mem_alias_set (mem, rs6000_sr_alias_set);
10099
10100 insn = emit_move_insn (mem, reg);
10101
10102 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10103}
10104
a3170dc6
AH
10105/* Emit an offset memory reference suitable for a frame store, while
10106 converting to a valid addressing mode. */
10107
10108static rtx
10109gen_frame_mem_offset (mode, reg, offset)
10110 enum machine_mode mode;
10111 rtx reg;
10112 int offset;
10113{
10114 rtx int_rtx, offset_rtx;
10115
10116 int_rtx = GEN_INT (offset);
10117
10118 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10119 {
10120 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10121 emit_move_insn (offset_rtx, int_rtx);
10122 }
10123 else
10124 offset_rtx = int_rtx;
10125
10126 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10127}
10128
9ebbca7d
GK
10129/* Emit function prologue as insns. */
10130
9878760c 10131void
83720594 10132rs6000_emit_prologue ()
9878760c 10133{
4697a36c 10134 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10135 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10136 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10137 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10138 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10139 rtx frame_reg_rtx = sp_reg_rtx;
10140 rtx cr_save_rtx = NULL;
10141 rtx insn;
10142 int saving_FPRs_inline;
10143 int using_store_multiple;
10144 HOST_WIDE_INT sp_offset = 0;
10145
a3170dc6
AH
10146 if (TARGET_SPE_ABI)
10147 {
10148 reg_mode = V2SImode;
10149 reg_size = 8;
10150 }
10151
9ebbca7d 10152 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10153 && !TARGET_SPE_ABI
9ebbca7d
GK
10154 && info->first_gp_reg_save < 31);
10155 saving_FPRs_inline = (info->first_fp_reg_save == 64
10156 || FP_SAVE_INLINE (info->first_fp_reg_save));
10157
10158 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10159 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10160 {
10161 if (info->total_size < 32767)
10162 sp_offset = info->total_size;
10163 else
10164 frame_reg_rtx = frame_ptr_rtx;
10165 rs6000_emit_allocate_stack (info->total_size,
10166 (frame_reg_rtx != sp_reg_rtx
10167 && (info->cr_save_p
10168 || info->lr_save_p
10169 || info->first_fp_reg_save < 64
10170 || info->first_gp_reg_save < 32
10171 )));
10172 if (frame_reg_rtx != sp_reg_rtx)
10173 rs6000_emit_stack_tie ();
10174 }
10175
9aa86737
AH
10176 /* Save AltiVec registers if needed. */
10177 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10178 {
10179 int i;
10180
10181 /* There should be a non inline version of this, for when we
10182 are saving lots of vector registers. */
10183 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10184 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10185 {
10186 rtx areg, savereg, mem;
10187 int offset;
10188
10189 offset = info->altivec_save_offset + sp_offset
10190 + 16 * (i - info->first_altivec_reg_save);
10191
10192 savereg = gen_rtx_REG (V4SImode, i);
10193
10194 areg = gen_rtx_REG (Pmode, 0);
10195 emit_move_insn (areg, GEN_INT (offset));
10196
10197 /* AltiVec addressing mode is [reg+reg]. */
10198 mem = gen_rtx_MEM (V4SImode,
10199 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10200
10201 set_mem_alias_set (mem, rs6000_sr_alias_set);
10202
10203 insn = emit_move_insn (mem, savereg);
10204
10205 altivec_frame_fixup (insn, areg, offset);
10206 }
10207 }
10208
10209 /* VRSAVE is a bit vector representing which AltiVec registers
10210 are used. The OS uses this to determine which vector
10211 registers to save on a context switch. We need to save
10212 VRSAVE on the stack frame, add whatever AltiVec registers we
10213 used in this function, and do the corresponding magic in the
10214 epilogue. */
10215
10216 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10217 {
a004eb82 10218 rtx reg, mem, vrsave;
9aa86737
AH
10219 int offset;
10220
10221 /* Get VRSAVE onto a GPR. */
10222 reg = gen_rtx_REG (SImode, 12);
a004eb82 10223 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10224 if (TARGET_MACHO)
10225 emit_insn (gen_get_vrsave_internal (reg));
10226 else
10227 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10228
10229 /* Save VRSAVE. */
10230 offset = info->vrsave_save_offset + sp_offset;
10231 mem
10232 = gen_rtx_MEM (SImode,
10233 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10234 set_mem_alias_set (mem, rs6000_sr_alias_set);
10235 insn = emit_move_insn (mem, reg);
10236
10237 /* Include the registers in the mask. */
10238 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10239
10240 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10241 }
10242
9ebbca7d
GK
10243 /* If we use the link register, get it into r0. */
10244 if (info->lr_save_p)
71f123ca 10245 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10246 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10247
10248 /* If we need to save CR, put it into r12. */
10249 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10250 {
10251 cr_save_rtx = gen_rtx_REG (SImode, 12);
10252 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10253 }
10254
a4f6c312
SS
10255 /* Do any required saving of fpr's. If only one or two to save, do
10256 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10257 if (saving_FPRs_inline)
10258 {
10259 int i;
10260 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10261 if ((regs_ever_live[info->first_fp_reg_save+i]
10262 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10263 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10264 info->first_fp_reg_save + i,
10265 info->fp_save_offset + sp_offset + 8 * i,
10266 info->total_size);
9ebbca7d
GK
10267 }
10268 else if (info->first_fp_reg_save != 64)
10269 {
10270 int i;
10271 char rname[30];
520a57c8 10272 const char *alloc_rname;
9ebbca7d
GK
10273 rtvec p;
10274 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10275
10276 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10277 gen_rtx_REG (Pmode,
10278 LINK_REGISTER_REGNUM));
10279 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10280 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10281 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10282 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10283 gen_rtx_SYMBOL_REF (Pmode,
10284 alloc_rname));
10285 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10286 {
10287 rtx addr, reg, mem;
10288 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10289 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10290 GEN_INT (info->fp_save_offset
10291 + sp_offset + 8*i));
10292 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10293 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10294
10295 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10296 }
10297 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10298 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10299 NULL_RTX, NULL_RTX);
10300 }
b6c9286a 10301
9ebbca7d
GK
10302 /* Save GPRs. This is done as a PARALLEL if we are using
10303 the store-multiple instructions. */
10304 if (using_store_multiple)
b6c9286a 10305 {
308c142a 10306 rtvec p;
9ebbca7d
GK
10307 int i;
10308 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10309 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10310 {
10311 rtx addr, reg, mem;
10312 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10313 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10314 GEN_INT (info->gp_save_offset
10315 + sp_offset
10316 + reg_size * i));
10317 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10318 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10319
10320 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10321 }
10322 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10323 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10324 NULL_RTX, NULL_RTX);
b6c9286a
MM
10325 }
10326 else
10327 {
9ebbca7d
GK
10328 int i;
10329 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10330 if ((regs_ever_live[info->first_gp_reg_save+i]
10331 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10332 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10333 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10334 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10335 {
10336 rtx addr, reg, mem;
10337 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10338
10339 if (TARGET_SPE_ABI)
10340 {
10341 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10342 rtx b;
10343
10344 if (!SPE_CONST_OFFSET_OK (offset))
10345 {
10346 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10347 emit_move_insn (b, GEN_INT (offset));
10348 }
10349 else
10350 b = GEN_INT (offset);
10351
10352 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10353 mem = gen_rtx_MEM (V2SImode, addr);
10354 set_mem_alias_set (mem, rs6000_sr_alias_set);
10355 insn = emit_move_insn (mem, reg);
10356
10357 if (GET_CODE (b) == CONST_INT)
10358 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10359 NULL_RTX, NULL_RTX);
10360 else
10361 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10362 b, GEN_INT (offset));
10363 }
10364 else
10365 {
10366 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10367 GEN_INT (info->gp_save_offset
10368 + sp_offset
10369 + reg_size * i));
10370 mem = gen_rtx_MEM (reg_mode, addr);
10371 set_mem_alias_set (mem, rs6000_sr_alias_set);
10372
10373 insn = emit_move_insn (mem, reg);
10374 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10375 NULL_RTX, NULL_RTX);
10376 }
10377 }
9ebbca7d
GK
10378 }
10379
83720594
RH
10380 /* ??? There's no need to emit actual instructions here, but it's the
10381 easiest way to get the frame unwind information emitted. */
10382 if (current_function_calls_eh_return)
10383 {
78e1b90d
DE
10384 unsigned int i, regno;
10385
83720594
RH
10386 for (i = 0; ; ++i)
10387 {
83720594
RH
10388 regno = EH_RETURN_DATA_REGNO (i);
10389 if (regno == INVALID_REGNUM)
10390 break;
10391
89e7058f
AH
10392 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10393 info->ehrd_offset + sp_offset
10394 + reg_size * (int) i,
10395 info->total_size);
83720594
RH
10396 }
10397 }
10398
9ebbca7d
GK
10399 /* Save lr if we used it. */
10400 if (info->lr_save_p)
10401 {
10402 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10403 GEN_INT (info->lr_save_offset + sp_offset));
10404 rtx reg = gen_rtx_REG (Pmode, 0);
10405 rtx mem = gen_rtx_MEM (Pmode, addr);
10406 /* This should not be of rs6000_sr_alias_set, because of
10407 __builtin_return_address. */
10408
10409 insn = emit_move_insn (mem, reg);
10410 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10411 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10412 }
10413
10414 /* Save CR if we use any that must be preserved. */
10415 if (info->cr_save_p)
10416 {
10417 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10418 GEN_INT (info->cr_save_offset + sp_offset));
10419 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10420
10421 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10422
10423 /* If r12 was used to hold the original sp, copy cr into r0 now
10424 that it's free. */
10425 if (REGNO (frame_reg_rtx) == 12)
10426 {
10427 cr_save_rtx = gen_rtx_REG (SImode, 0);
10428 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10429 }
10430 insn = emit_move_insn (mem, cr_save_rtx);
10431
10432 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10433 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10434 OK. All we have to do is specify that _one_ condition code
10435 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10436 will then restore all the call-saved registers.
10437 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10438 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10439 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10440 }
10441
10442 /* Update stack and set back pointer unless this is V.4,
10443 for which it was done previously. */
f607bc57 10444 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10445 rs6000_emit_allocate_stack (info->total_size, FALSE);
10446
10447 /* Set frame pointer, if needed. */
10448 if (frame_pointer_needed)
10449 {
a3170dc6 10450 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10451 sp_reg_rtx);
10452 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10453 }
9878760c 10454
1db02437 10455 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10456 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10457 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10458 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10459 {
10460 /* If emit_load_toc_table will use the link register, we need to save
10461 it. We use R11 for this purpose because emit_load_toc_table
10462 can use register 0. This allows us to use a plain 'blr' to return
10463 from the procedure more often. */
d5fa86ba
GK
10464 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10465 && ! info->lr_save_p
10466 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10467 if (save_LR_around_toc_setup)
10468 emit_move_insn (gen_rtx_REG (Pmode, 11),
10469 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10470
10471 rs6000_emit_load_toc_table (TRUE);
10472
10473 if (save_LR_around_toc_setup)
10474 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10475 gen_rtx_REG (Pmode, 11));
10476 }
ee890fe2 10477
fcce224d 10478#if TARGET_MACHO
ee890fe2
SS
10479 if (DEFAULT_ABI == ABI_DARWIN
10480 && flag_pic && current_function_uses_pic_offset_table)
10481 {
10482 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
f51eee6a
GK
10483 char *picbase = machopic_function_base_name ();
10484 rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
ee890fe2 10485
f51eee6a 10486 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
ee890fe2
SS
10487
10488 rs6000_maybe_dead (
1db02437 10489 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10490 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10491 }
fcce224d 10492#endif
9ebbca7d
GK
10493}
10494
9ebbca7d 10495/* Write function prologue. */
a4f6c312 10496
08c148a8
NB
10497static void
10498rs6000_output_function_prologue (file, size)
9ebbca7d 10499 FILE *file;
08c148a8 10500 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10501{
10502 rs6000_stack_t *info = rs6000_stack_info ();
10503
4697a36c
MM
10504 if (TARGET_DEBUG_STACK)
10505 debug_stack_info (info);
9878760c 10506
a4f6c312
SS
10507 /* Write .extern for any function we will call to save and restore
10508 fp values. */
10509 if (info->first_fp_reg_save < 64
10510 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10511 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10512 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10513 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10514 RESTORE_FP_SUFFIX);
9878760c 10515
c764f757
RK
10516 /* Write .extern for AIX common mode routines, if needed. */
10517 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10518 {
f6709c70
JW
10519 fputs ("\t.extern __mulh\n", file);
10520 fputs ("\t.extern __mull\n", file);
10521 fputs ("\t.extern __divss\n", file);
10522 fputs ("\t.extern __divus\n", file);
10523 fputs ("\t.extern __quoss\n", file);
10524 fputs ("\t.extern __quous\n", file);
c764f757
RK
10525 common_mode_defined = 1;
10526 }
9878760c 10527
9ebbca7d 10528 if (! HAVE_prologue)
979721f8 10529 {
9ebbca7d 10530 start_sequence ();
9dda4cc8 10531
a4f6c312
SS
10532 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10533 the "toplevel" insn chain. */
9ebbca7d
GK
10534 emit_note (0, NOTE_INSN_DELETED);
10535 rs6000_emit_prologue ();
10536 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10537
10538 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10539 {
10540 rtx insn;
10541 unsigned addr = 0;
10542 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10543 {
10544 INSN_ADDRESSES_NEW (insn, addr);
10545 addr += 4;
10546 }
10547 }
9dda4cc8 10548
9ebbca7d 10549 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10550 debug_rtx_list (get_insns (), 100);
10551 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10552 end_sequence ();
979721f8
MM
10553 }
10554
9ebbca7d
GK
10555 rs6000_pic_labelno++;
10556}
10557
10558/* Emit function epilogue as insns.
9878760c 10559
9ebbca7d
GK
10560 At present, dwarf2out_frame_debug_expr doesn't understand
10561 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10562 anywhere in the epilogue. Most of the insns below would in any case
10563 need special notes to explain where r11 is in relation to the stack. */
9878760c 10564
9ebbca7d 10565void
83720594 10566rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
10567 int sibcall;
10568{
10569 rs6000_stack_t *info;
10570 int restoring_FPRs_inline;
10571 int using_load_multiple;
10572 int using_mfcr_multiple;
10573 int use_backchain_to_restore_sp;
10574 int sp_offset = 0;
10575 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10576 rtx frame_reg_rtx = sp_reg_rtx;
10577 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10578 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10579 int i;
10580
a3170dc6
AH
10581 if (TARGET_SPE_ABI)
10582 {
10583 reg_mode = V2SImode;
10584 reg_size = 8;
10585 }
10586
9ebbca7d
GK
10587 info = rs6000_stack_info ();
10588 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10589 && !TARGET_SPE_ABI
9ebbca7d
GK
10590 && info->first_gp_reg_save < 31);
10591 restoring_FPRs_inline = (sibcall
83720594 10592 || current_function_calls_eh_return
9ebbca7d
GK
10593 || info->first_fp_reg_save == 64
10594 || FP_SAVE_INLINE (info->first_fp_reg_save));
10595 use_backchain_to_restore_sp = (frame_pointer_needed
10596 || current_function_calls_alloca
10597 || info->total_size > 32767);
10598 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10599 || rs6000_cpu == PROCESSOR_PPC603
10600 || rs6000_cpu == PROCESSOR_PPC750
10601 || optimize_size);
10602
10603 /* If we have a frame pointer, a call to alloca, or a large stack
10604 frame, restore the old stack pointer using the backchain. Otherwise,
10605 we know what size to update it with. */
10606 if (use_backchain_to_restore_sp)
bacbde18 10607 {
9ebbca7d
GK
10608 /* Under V.4, don't reset the stack pointer until after we're done
10609 loading the saved registers. */
f607bc57 10610 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 10611 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 10612
9ebbca7d
GK
10613 emit_move_insn (frame_reg_rtx,
10614 gen_rtx_MEM (Pmode, sp_reg_rtx));
10615
bacbde18 10616 }
9ebbca7d 10617 else if (info->push_p)
85638c0d 10618 {
f607bc57 10619 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10620 sp_offset = info->total_size;
10621 else
10622 {
10623 emit_insn (TARGET_32BIT
10624 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10625 GEN_INT (info->total_size))
10626 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10627 GEN_INT (info->total_size)));
10628 }
85638c0d 10629 }
9ebbca7d 10630
9aa86737
AH
10631 /* Restore AltiVec registers if needed. */
10632 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10633 {
10634 int i;
10635
10636 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10637 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10638 {
10639 rtx addr, areg, mem;
10640
10641 areg = gen_rtx_REG (Pmode, 0);
10642 emit_move_insn
10643 (areg, GEN_INT (info->altivec_save_offset
10644 + sp_offset
10645 + 16 * (i - info->first_altivec_reg_save)));
10646
10647 /* AltiVec addressing mode is [reg+reg]. */
10648 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10649 mem = gen_rtx_MEM (V4SImode, addr);
10650 set_mem_alias_set (mem, rs6000_sr_alias_set);
10651
10652 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10653 }
10654 }
10655
10656 /* Restore VRSAVE if needed. */
10657 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10658 {
10659 rtx addr, mem, reg;
10660
10661 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10662 GEN_INT (info->vrsave_save_offset + sp_offset));
10663 mem = gen_rtx_MEM (SImode, addr);
10664 set_mem_alias_set (mem, rs6000_sr_alias_set);
10665 reg = gen_rtx_REG (SImode, 12);
10666 emit_move_insn (reg, mem);
10667
10668 emit_insn (generate_set_vrsave (reg, info, 1));
10669 }
10670
9ebbca7d
GK
10671 /* Get the old lr if we saved it. */
10672 if (info->lr_save_p)
b6c9286a 10673 {
a3170dc6
AH
10674 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10675 info->lr_save_offset + sp_offset);
ba4828e0
RK
10676
10677 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10678
9ebbca7d 10679 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 10680 }
9ebbca7d
GK
10681
10682 /* Get the old cr if we saved it. */
10683 if (info->cr_save_p)
10684 {
10685 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10686 GEN_INT (info->cr_save_offset + sp_offset));
10687 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10688
10689 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10690
9ebbca7d
GK
10691 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10692 }
10693
10694 /* Set LR here to try to overlap restores below. */
4697a36c 10695 if (info->lr_save_p)
9ebbca7d
GK
10696 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10697 gen_rtx_REG (Pmode, 0));
10698
83720594
RH
10699 /* Load exception handler data registers, if needed. */
10700 if (current_function_calls_eh_return)
10701 {
78e1b90d
DE
10702 unsigned int i, regno;
10703
83720594
RH
10704 for (i = 0; ; ++i)
10705 {
a3170dc6 10706 rtx mem;
83720594
RH
10707
10708 regno = EH_RETURN_DATA_REGNO (i);
10709 if (regno == INVALID_REGNUM)
10710 break;
10711
a3170dc6
AH
10712 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
10713 info->ehrd_offset + sp_offset
10714 + reg_size * (int) i);
ba4828e0 10715 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
10716
10717 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
10718 }
10719 }
9ebbca7d
GK
10720
10721 /* Restore GPRs. This is done as a PARALLEL if we are using
10722 the load-multiple instructions. */
10723 if (using_load_multiple)
979721f8 10724 {
9ebbca7d
GK
10725 rtvec p;
10726 p = rtvec_alloc (32 - info->first_gp_reg_save);
10727 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 10728 {
9ebbca7d
GK
10729 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10730 GEN_INT (info->gp_save_offset
10731 + sp_offset
10732 + reg_size * i));
10733 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
10734
10735 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10736
10737 RTVEC_ELT (p, i) =
10738 gen_rtx_SET (VOIDmode,
10739 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
10740 mem);
979721f8 10741 }
9ebbca7d 10742 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 10743 }
9ebbca7d
GK
10744 else
10745 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10746 if ((regs_ever_live[info->first_gp_reg_save+i]
10747 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10748 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10749 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10750 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
10751 {
10752 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10753 GEN_INT (info->gp_save_offset
10754 + sp_offset
10755 + reg_size * i));
10756 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10757
a3170dc6
AH
10758 /* Restore 64-bit quantities for SPE. */
10759 if (TARGET_SPE_ABI)
10760 {
10761 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10762 rtx b;
10763
10764 if (!SPE_CONST_OFFSET_OK (offset))
10765 {
10766 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10767 emit_move_insn (b, GEN_INT (offset));
10768 }
10769 else
10770 b = GEN_INT (offset);
10771
10772 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10773 mem = gen_rtx_MEM (V2SImode, addr);
10774 }
10775
ba4828e0 10776 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10777
10778 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 10779 info->first_gp_reg_save + i), mem);
9ebbca7d 10780 }
9878760c 10781
9ebbca7d
GK
10782 /* Restore fpr's if we need to do it without calling a function. */
10783 if (restoring_FPRs_inline)
10784 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10785 if ((regs_ever_live[info->first_fp_reg_save+i]
10786 && ! call_used_regs[info->first_fp_reg_save+i]))
10787 {
10788 rtx addr, mem;
10789 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10790 GEN_INT (info->fp_save_offset
10791 + sp_offset
a4f6c312 10792 + 8 * i));
9ebbca7d 10793 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10794 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10795
10796 emit_move_insn (gen_rtx_REG (DFmode,
10797 info->first_fp_reg_save + i),
10798 mem);
10799 }
8d30c4ee 10800
9ebbca7d
GK
10801 /* If we saved cr, restore it here. Just those that were used. */
10802 if (info->cr_save_p)
979721f8 10803 {
9ebbca7d 10804 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 10805 int count = 0;
9ebbca7d
GK
10806
10807 if (using_mfcr_multiple)
979721f8 10808 {
9ebbca7d
GK
10809 for (i = 0; i < 8; i++)
10810 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 10811 count++;
9ebbca7d 10812 if (count == 0)
e35b9579
GK
10813 abort ();
10814 }
10815
10816 if (using_mfcr_multiple && count > 1)
10817 {
10818 rtvec p;
10819 int ndx;
9ebbca7d 10820
e35b9579 10821 p = rtvec_alloc (count);
9ebbca7d 10822
e35b9579 10823 ndx = 0;
9ebbca7d
GK
10824 for (i = 0; i < 8; i++)
10825 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
10826 {
10827 rtvec r = rtvec_alloc (2);
10828 RTVEC_ELT (r, 0) = r12_rtx;
10829 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 10830 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
10831 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
10832 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 10833 ndx++;
9ebbca7d
GK
10834 }
10835 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
10836 if (ndx != count)
10837 abort ();
979721f8
MM
10838 }
10839 else
9ebbca7d
GK
10840 for (i = 0; i < 8; i++)
10841 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 10842 {
9ebbca7d
GK
10843 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
10844 CR0_REGNO+i),
10845 r12_rtx));
979721f8 10846 }
979721f8
MM
10847 }
10848
9ebbca7d
GK
10849 /* If this is V.4, unwind the stack pointer after all of the loads
10850 have been done. We need to emit a block here so that sched
10851 doesn't decide to move the sp change before the register restores
10852 (which may not have any obvious dependency on the stack). This
10853 doesn't hurt performance, because there is no scheduling that can
10854 be done after this point. */
f607bc57 10855 if (DEFAULT_ABI == ABI_V4)
b6c9286a 10856 {
9ebbca7d
GK
10857 if (frame_reg_rtx != sp_reg_rtx)
10858 rs6000_emit_stack_tie ();
b6c9286a 10859
9ebbca7d 10860 if (use_backchain_to_restore_sp)
b6c9286a 10861 {
9ebbca7d 10862 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 10863 }
9ebbca7d 10864 else if (sp_offset != 0)
13f1623b 10865 {
9ebbca7d
GK
10866 emit_insn (Pmode == SImode
10867 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10868 GEN_INT (sp_offset))
10869 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10870 GEN_INT (sp_offset)));
13f1623b 10871 }
9ebbca7d 10872 }
b6c9286a 10873
83720594
RH
10874 if (current_function_calls_eh_return)
10875 {
10876 rtx sa = EH_RETURN_STACKADJ_RTX;
10877 emit_insn (Pmode == SImode
10878 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
10879 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
10880 }
10881
9ebbca7d
GK
10882 if (!sibcall)
10883 {
10884 rtvec p;
10885 if (! restoring_FPRs_inline)
10886 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
10887 else
10888 p = rtvec_alloc (2);
b6c9286a 10889
e35b9579
GK
10890 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
10891 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
10892 gen_rtx_REG (Pmode,
10893 LINK_REGISTER_REGNUM));
9ebbca7d
GK
10894
10895 /* If we have to restore more than two FP registers, branch to the
10896 restore function. It will return to our caller. */
10897 if (! restoring_FPRs_inline)
10898 {
10899 int i;
10900 char rname[30];
520a57c8 10901 const char *alloc_rname;
979721f8 10902
9ebbca7d
GK
10903 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
10904 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 10905 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10906 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
10907 gen_rtx_SYMBOL_REF (Pmode,
10908 alloc_rname));
b6c9286a 10909
9ebbca7d
GK
10910 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10911 {
10912 rtx addr, mem;
10913 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
10914 GEN_INT (info->fp_save_offset + 8*i));
10915 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10916 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10917
10918 RTVEC_ELT (p, i+3) =
10919 gen_rtx_SET (VOIDmode,
10920 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
10921 mem);
b6c9286a
MM
10922 }
10923 }
9ebbca7d
GK
10924
10925 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 10926 }
9878760c
RK
10927}
10928
10929/* Write function epilogue. */
10930
08c148a8
NB
10931static void
10932rs6000_output_function_epilogue (file, size)
9878760c 10933 FILE *file;
08c148a8 10934 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 10935{
4697a36c 10936 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 10937
9ebbca7d 10938 if (! HAVE_epilogue)
9878760c 10939 {
9ebbca7d
GK
10940 rtx insn = get_last_insn ();
10941 /* If the last insn was a BARRIER, we don't have to write anything except
10942 the trace table. */
10943 if (GET_CODE (insn) == NOTE)
10944 insn = prev_nonnote_insn (insn);
10945 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 10946 {
9ebbca7d
GK
10947 /* This is slightly ugly, but at least we don't have two
10948 copies of the epilogue-emitting code. */
10949 start_sequence ();
10950
10951 /* A NOTE_INSN_DELETED is supposed to be at the start
10952 and end of the "toplevel" insn chain. */
10953 emit_note (0, NOTE_INSN_DELETED);
10954 rs6000_emit_epilogue (FALSE);
10955 emit_note (0, NOTE_INSN_DELETED);
10956
178c3eff
DJ
10957 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10958 {
10959 rtx insn;
10960 unsigned addr = 0;
10961 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10962 {
10963 INSN_ADDRESSES_NEW (insn, addr);
10964 addr += 4;
10965 }
10966 }
10967
9ebbca7d 10968 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10969 debug_rtx_list (get_insns (), 100);
10970 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10971 end_sequence ();
4697a36c 10972 }
9878760c 10973 }
b4ac57ab 10974
9b30bae2 10975 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
10976 on its format.
10977
10978 We don't output a traceback table if -finhibit-size-directive was
10979 used. The documentation for -finhibit-size-directive reads
10980 ``don't output a @code{.size} assembler directive, or anything
10981 else that would cause trouble if the function is split in the
10982 middle, and the two halves are placed at locations far apart in
10983 memory.'' The traceback table has this property, since it
10984 includes the offset from the start of the function to the
4d30c363
MM
10985 traceback table itself.
10986
10987 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 10988 different traceback table. */
57ac7be9
AM
10989 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
10990 && rs6000_traceback != traceback_none)
9b30bae2 10991 {
69c75916 10992 const char *fname = NULL;
3ac88239 10993 const char *language_string = lang_hooks.name;
6041bf2f 10994 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 10995 int i;
57ac7be9
AM
10996 int optional_tbtab;
10997
10998 if (rs6000_traceback == traceback_full)
10999 optional_tbtab = 1;
11000 else if (rs6000_traceback == traceback_part)
11001 optional_tbtab = 0;
11002 else
11003 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 11004
69c75916
AM
11005 if (optional_tbtab)
11006 {
11007 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
11008 while (*fname == '.') /* V.4 encodes . in the name */
11009 fname++;
11010
11011 /* Need label immediately before tbtab, so we can compute
11012 its offset from the function start. */
11013 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11014 ASM_OUTPUT_LABEL (file, fname);
11015 }
314fc5a9
ILT
11016
11017 /* The .tbtab pseudo-op can only be used for the first eight
11018 expressions, since it can't handle the possibly variable
11019 length fields that follow. However, if you omit the optional
11020 fields, the assembler outputs zeros for all optional fields
11021 anyways, giving each variable length field is minimum length
11022 (as defined in sys/debug.h). Thus we can not use the .tbtab
11023 pseudo-op at all. */
11024
11025 /* An all-zero word flags the start of the tbtab, for debuggers
11026 that have to find it by searching forward from the entry
11027 point or from the current pc. */
19d2d16f 11028 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11029
11030 /* Tbtab format type. Use format type 0. */
19d2d16f 11031 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11032
11033 /* Language type. Unfortunately, there doesn't seem to be any
11034 official way to get this info, so we use language_string. C
11035 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11036 value for C for now. There is no official value for Java,
6f573ff9 11037 although IBM appears to be using 13. There is no official value
f710504c 11038 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11039 if (! strcmp (language_string, "GNU C")
e2c953b6 11040 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11041 i = 0;
11042 else if (! strcmp (language_string, "GNU F77"))
11043 i = 1;
11044 else if (! strcmp (language_string, "GNU Ada"))
11045 i = 3;
8b83775b 11046 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11047 i = 2;
11048 else if (! strcmp (language_string, "GNU C++"))
11049 i = 9;
9517ead8
AG
11050 else if (! strcmp (language_string, "GNU Java"))
11051 i = 13;
6f573ff9
JL
11052 else if (! strcmp (language_string, "GNU CHILL"))
11053 i = 44;
314fc5a9
ILT
11054 else
11055 abort ();
11056 fprintf (file, "%d,", i);
11057
11058 /* 8 single bit fields: global linkage (not set for C extern linkage,
11059 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11060 from start of procedure stored in tbtab, internal function, function
11061 has controlled storage, function has no toc, function uses fp,
11062 function logs/aborts fp operations. */
11063 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11064 fprintf (file, "%d,",
11065 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11066
11067 /* 6 bitfields: function is interrupt handler, name present in
11068 proc table, function calls alloca, on condition directives
11069 (controls stack walks, 3 bits), saves condition reg, saves
11070 link reg. */
11071 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11072 set up as a frame pointer, even when there is no alloca call. */
11073 fprintf (file, "%d,",
6041bf2f
DE
11074 ((optional_tbtab << 6)
11075 | ((optional_tbtab & frame_pointer_needed) << 5)
11076 | (info->cr_save_p << 1)
11077 | (info->lr_save_p)));
314fc5a9 11078
6041bf2f 11079 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11080 (6 bits). */
11081 fprintf (file, "%d,",
4697a36c 11082 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11083
11084 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11085 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11086
6041bf2f
DE
11087 if (optional_tbtab)
11088 {
11089 /* Compute the parameter info from the function decl argument
11090 list. */
11091 tree decl;
11092 int next_parm_info_bit = 31;
314fc5a9 11093
6041bf2f
DE
11094 for (decl = DECL_ARGUMENTS (current_function_decl);
11095 decl; decl = TREE_CHAIN (decl))
11096 {
11097 rtx parameter = DECL_INCOMING_RTL (decl);
11098 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11099
6041bf2f
DE
11100 if (GET_CODE (parameter) == REG)
11101 {
11102 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11103 {
11104 int bits;
11105
11106 float_parms++;
11107
11108 if (mode == SFmode)
11109 bits = 0x2;
fcce224d 11110 else if (mode == DFmode || mode == TFmode)
6041bf2f
DE
11111 bits = 0x3;
11112 else
11113 abort ();
11114
11115 /* If only one bit will fit, don't or in this entry. */
11116 if (next_parm_info_bit > 0)
11117 parm_info |= (bits << (next_parm_info_bit - 1));
11118 next_parm_info_bit -= 2;
11119 }
11120 else
11121 {
11122 fixed_parms += ((GET_MODE_SIZE (mode)
11123 + (UNITS_PER_WORD - 1))
11124 / UNITS_PER_WORD);
11125 next_parm_info_bit -= 1;
11126 }
11127 }
11128 }
11129 }
314fc5a9
ILT
11130
11131 /* Number of fixed point parameters. */
11132 /* This is actually the number of words of fixed point parameters; thus
11133 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11134 fprintf (file, "%d,", fixed_parms);
11135
11136 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11137 all on stack. */
11138 /* This is actually the number of fp registers that hold parameters;
11139 and thus the maximum value is 13. */
11140 /* Set parameters on stack bit if parameters are not in their original
11141 registers, regardless of whether they are on the stack? Xlc
11142 seems to set the bit when not optimizing. */
11143 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11144
6041bf2f
DE
11145 if (! optional_tbtab)
11146 return;
11147
314fc5a9
ILT
11148 /* Optional fields follow. Some are variable length. */
11149
11150 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11151 11 double float. */
11152 /* There is an entry for each parameter in a register, in the order that
11153 they occur in the parameter list. Any intervening arguments on the
11154 stack are ignored. If the list overflows a long (max possible length
11155 34 bits) then completely leave off all elements that don't fit. */
11156 /* Only emit this long if there was at least one parameter. */
11157 if (fixed_parms || float_parms)
11158 fprintf (file, "\t.long %d\n", parm_info);
11159
11160 /* Offset from start of code to tb table. */
19d2d16f 11161 fputs ("\t.long ", file);
314fc5a9 11162 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11163#if TARGET_AIX
11164 RS6000_OUTPUT_BASENAME (file, fname);
11165#else
9ebbca7d 11166 assemble_name (file, fname);
54ee9799 11167#endif
19d2d16f 11168 fputs ("-.", file);
54ee9799
DE
11169#if TARGET_AIX
11170 RS6000_OUTPUT_BASENAME (file, fname);
11171#else
9ebbca7d 11172 assemble_name (file, fname);
54ee9799 11173#endif
19d2d16f 11174 putc ('\n', file);
314fc5a9
ILT
11175
11176 /* Interrupt handler mask. */
11177 /* Omit this long, since we never set the interrupt handler bit
11178 above. */
11179
11180 /* Number of CTL (controlled storage) anchors. */
11181 /* Omit this long, since the has_ctl bit is never set above. */
11182
11183 /* Displacement into stack of each CTL anchor. */
11184 /* Omit this list of longs, because there are no CTL anchors. */
11185
11186 /* Length of function name. */
69c75916
AM
11187 if (*fname == '*')
11188 ++fname;
296b8152 11189 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11190
11191 /* Function name. */
11192 assemble_string (fname, strlen (fname));
11193
11194 /* Register for alloca automatic storage; this is always reg 31.
11195 Only emit this if the alloca bit was set above. */
11196 if (frame_pointer_needed)
19d2d16f 11197 fputs ("\t.byte 31\n", file);
b1765bde
DE
11198
11199 fputs ("\t.align 2\n", file);
9b30bae2 11200 }
9878760c 11201}
17167fd8 11202\f
a4f6c312
SS
11203/* A C compound statement that outputs the assembler code for a thunk
11204 function, used to implement C++ virtual function calls with
11205 multiple inheritance. The thunk acts as a wrapper around a virtual
11206 function, adjusting the implicit object parameter before handing
11207 control off to the real function.
11208
11209 First, emit code to add the integer DELTA to the location that
11210 contains the incoming first argument. Assume that this argument
11211 contains a pointer, and is the one used to pass the `this' pointer
11212 in C++. This is the incoming argument *before* the function
11213 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11214 values of all other incoming arguments.
17167fd8
MM
11215
11216 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11217 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11218 not touch the return address. Hence returning from FUNCTION will
11219 return to whoever called the current `thunk'.
17167fd8 11220
a4f6c312
SS
11221 The effect must be as if FUNCTION had been called directly with the
11222 adjusted first argument. This macro is responsible for emitting
11223 all of the code for a thunk function; output_function_prologue()
11224 and output_function_epilogue() are not invoked.
17167fd8 11225
a4f6c312
SS
11226 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11227 been extracted from it.) It might possibly be useful on some
11228 targets, but probably not.
17167fd8 11229
a4f6c312
SS
11230 If you do not define this macro, the target-independent code in the
11231 C++ frontend will generate a less efficient heavyweight thunk that
11232 calls FUNCTION instead of jumping to it. The generic approach does
11233 not support varargs. */
17167fd8
MM
11234
11235void
11236output_mi_thunk (file, thunk_fndecl, delta, function)
11237 FILE *file;
d330fd93 11238 tree thunk_fndecl ATTRIBUTE_UNUSED;
17167fd8
MM
11239 int delta;
11240 tree function;
11241{
a4f6c312
SS
11242 const char *this_reg =
11243 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
d330fd93 11244 const char *prefix;
3cce094d 11245 const char *fname;
d330fd93 11246 const char *r0 = reg_names[0];
d330fd93
KG
11247 const char *toc = reg_names[2];
11248 const char *schain = reg_names[11];
11249 const char *r12 = reg_names[12];
17167fd8
MM
11250 char buf[512];
11251 static int labelno = 0;
11252
a4f6c312 11253 /* Small constants that can be done by one add instruction. */
17167fd8
MM
11254 if (delta >= -32768 && delta <= 32767)
11255 {
22b4a3b0 11256 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11257 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta, this_reg);
11258 else
11259 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
11260 }
11261
56a7189a
AM
11262 /* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
11263 else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
11264 abort ();
11265
a4f6c312 11266 /* Large constants that can be done by one addis instruction. */
56a7189a 11267 else if ((delta & 0xffff) == 0)
17167fd8
MM
11268 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11269 delta >> 16);
11270
11271 /* 32-bit constants that can be done by an add and addis instruction. */
56a7189a 11272 else
17167fd8 11273 {
a4f6c312
SS
11274 /* Break into two pieces, propagating the sign bit from the low
11275 word to the upper word. */
56a7189a
AM
11276 int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
11277 int delta_high = (delta - delta_low) >> 16;
17167fd8
MM
11278
11279 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11280 delta_high);
11281
22b4a3b0 11282 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11283 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
11284 else
11285 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
11286 }
11287
17167fd8
MM
11288 /* Get the prefix in front of the names. */
11289 switch (DEFAULT_ABI)
11290 {
11291 default:
11292 abort ();
11293
11294 case ABI_AIX:
11295 prefix = ".";
11296 break;
11297
11298 case ABI_V4:
11299 case ABI_AIX_NODESC:
17167fd8
MM
11300 prefix = "";
11301 break;
17167fd8
MM
11302 }
11303
11304 /* If the function is compiled in this module, jump to it directly.
11305 Otherwise, load up its address and jump to it. */
11306
11307 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
42820a49 11308
9ebbca7d 11309 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
a5c76ee6
ZW
11310 && (! lookup_attribute ("longcall",
11311 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11312 || lookup_attribute ("shortcall",
11313 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
17167fd8
MM
11314 {
11315 fprintf (file, "\tb %s", prefix);
11316 assemble_name (file, fname);
22b4a3b0 11317 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
949ea356 11318 putc ('\n', file);
17167fd8
MM
11319 }
11320
11321 else
11322 {
11323 switch (DEFAULT_ABI)
11324 {
11325 default:
17167fd8
MM
11326 abort ();
11327
11328 case ABI_AIX:
11329 /* Set up a TOC entry for the function. */
11330 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
11331 toc_section ();
11332 ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
11333 labelno++;
11334
fa9b5c6b
DE
11335 if (TARGET_MINIMAL_TOC)
11336 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
11337 else
11338 {
11339 fputs ("\t.tc ", file);
11340 assemble_name (file, fname);
11341 fputs ("[TC],", file);
11342 }
11343 assemble_name (file, fname);
17167fd8 11344 putc ('\n', file);
b4d330e1
DE
11345 if (TARGET_ELF)
11346 function_section (current_function_decl);
11347 else
69c75916 11348 text_section ();
468e8dba
DE
11349 if (TARGET_MINIMAL_TOC)
11350 asm_fprintf (file, (TARGET_32BIT)
11351 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
11352 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
d2574c50 11353 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
17167fd8 11354 assemble_name (file, buf);
468e8dba
DE
11355 if (TARGET_ELF && TARGET_MINIMAL_TOC)
11356 fputs ("-(.LCTOC1)", file);
11357 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
17167fd8
MM
11358 asm_fprintf (file,
11359 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
11360 r0, r12);
11361
11362 asm_fprintf (file,
11363 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
11364 toc, r12);
11365
11366 asm_fprintf (file, "\tmtctr %s\n", r0);
11367 asm_fprintf (file,
11368 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
11369 schain, r12);
11370
11371 asm_fprintf (file, "\tbctr\n");
11372 break;
11373
9ebbca7d 11374 case ABI_AIX_NODESC:
17167fd8 11375 case ABI_V4:
22b4a3b0
FS
11376 fprintf (file, "\tb %s", prefix);
11377 assemble_name (file, fname);
11378 if (flag_pic) fputs ("@plt", file);
949ea356 11379 putc ('\n', file);
22b4a3b0 11380 break;
ee890fe2
SS
11381
11382#if TARGET_MACHO
11383 case ABI_DARWIN:
11384 fprintf (file, "\tb %s", prefix);
11385 if (flag_pic && !machopic_name_defined_p (fname))
11386 assemble_name (file, machopic_stub_name (fname));
11387 else
11388 assemble_name (file, fname);
11389 putc ('\n', file);
11390 break;
11391#endif
9ebbca7d
GK
11392 }
11393 }
11394}
42820a49 11395
9ebbca7d
GK
11396\f
11397/* A quick summary of the various types of 'constant-pool tables'
11398 under PowerPC:
11399
11400 Target Flags Name One table per
11401 AIX (none) AIX TOC object file
11402 AIX -mfull-toc AIX TOC object file
11403 AIX -mminimal-toc AIX minimal TOC translation unit
11404 SVR4/EABI (none) SVR4 SDATA object file
11405 SVR4/EABI -fpic SVR4 pic object file
11406 SVR4/EABI -fPIC SVR4 PIC translation unit
11407 SVR4/EABI -mrelocatable EABI TOC function
11408 SVR4/EABI -maix AIX TOC object file
11409 SVR4/EABI -maix -mminimal-toc
11410 AIX minimal TOC translation unit
11411
11412 Name Reg. Set by entries contains:
11413 made by addrs? fp? sum?
11414
11415 AIX TOC 2 crt0 as Y option option
11416 AIX minimal TOC 30 prolog gcc Y Y option
11417 SVR4 SDATA 13 crt0 gcc N Y N
11418 SVR4 pic 30 prolog ld Y not yet N
11419 SVR4 PIC 30 prolog gcc Y option option
11420 EABI TOC 30 prolog gcc Y option option
11421
11422*/
11423
11424/* Hash table stuff for keeping track of TOC entries. */
11425
11426struct toc_hash_struct
11427{
11428 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
11429 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
11430 rtx key;
a9098fd0 11431 enum machine_mode key_mode;
9ebbca7d
GK
11432 int labelno;
11433};
17167fd8 11434
9ebbca7d
GK
11435static htab_t toc_hash_table;
11436
11437/* Hash functions for the hash table. */
11438
11439static unsigned
11440rs6000_hash_constant (k)
11441 rtx k;
11442{
46b33600
RH
11443 enum rtx_code code = GET_CODE (k);
11444 enum machine_mode mode = GET_MODE (k);
11445 unsigned result = (code << 3) ^ mode;
11446 const char *format;
11447 int flen, fidx;
9ebbca7d 11448
46b33600
RH
11449 format = GET_RTX_FORMAT (code);
11450 flen = strlen (format);
11451 fidx = 0;
9ebbca7d 11452
46b33600
RH
11453 switch (code)
11454 {
11455 case LABEL_REF:
11456 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
11457
11458 case CONST_DOUBLE:
11459 if (mode != VOIDmode)
11460 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
11461 flen = 2;
11462 break;
11463
11464 case CODE_LABEL:
11465 fidx = 3;
11466 break;
11467
11468 default:
11469 break;
11470 }
9ebbca7d
GK
11471
11472 for (; fidx < flen; fidx++)
11473 switch (format[fidx])
11474 {
11475 case 's':
11476 {
11477 unsigned i, len;
11478 const char *str = XSTR (k, fidx);
11479 len = strlen (str);
11480 result = result * 613 + len;
11481 for (i = 0; i < len; i++)
11482 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11483 break;
11484 }
9ebbca7d
GK
11485 case 'u':
11486 case 'e':
11487 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11488 break;
11489 case 'i':
11490 case 'n':
11491 result = result * 613 + (unsigned) XINT (k, fidx);
11492 break;
11493 case 'w':
11494 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11495 result = result * 613 + (unsigned) XWINT (k, fidx);
11496 else
11497 {
11498 size_t i;
11499 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11500 result = result * 613 + (unsigned) (XWINT (k, fidx)
11501 >> CHAR_BIT * i);
11502 }
11503 break;
11504 default:
a4f6c312 11505 abort ();
9ebbca7d 11506 }
46b33600 11507
9ebbca7d
GK
11508 return result;
11509}
11510
11511static unsigned
11512toc_hash_function (hash_entry)
11513 const void * hash_entry;
11514{
a9098fd0
GK
11515 const struct toc_hash_struct *thc =
11516 (const struct toc_hash_struct *) hash_entry;
11517 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11518}
11519
11520/* Compare H1 and H2 for equivalence. */
11521
11522static int
11523toc_hash_eq (h1, h2)
11524 const void * h1;
11525 const void * h2;
11526{
11527 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11528 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11529
a9098fd0
GK
11530 if (((const struct toc_hash_struct *) h1)->key_mode
11531 != ((const struct toc_hash_struct *) h2)->key_mode)
11532 return 0;
11533
5692c7bc 11534 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11535}
11536
11537/* Mark the hash table-entry HASH_ENTRY. */
11538
11539static int
11540toc_hash_mark_entry (hash_slot, unused)
2eba1afa 11541 void ** hash_slot;
9ebbca7d
GK
11542 void * unused ATTRIBUTE_UNUSED;
11543{
11544 const struct toc_hash_struct * hash_entry =
11545 *(const struct toc_hash_struct **) hash_slot;
11546 rtx r = hash_entry->key;
11547 ggc_set_mark (hash_entry);
a4f6c312 11548 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
9ebbca7d
GK
11549 if (GET_CODE (r) == LABEL_REF)
11550 {
11551 ggc_set_mark (r);
11552 ggc_set_mark (XEXP (r, 0));
11553 }
11554 else
11555 ggc_mark_rtx (r);
11556 return 1;
11557}
11558
11559/* Mark all the elements of the TOC hash-table *HT. */
11560
11561static void
11562toc_hash_mark_table (vht)
11563 void *vht;
11564{
11565 htab_t *ht = vht;
11566
11567 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
17167fd8
MM
11568}
11569
28e510bd
MM
11570/* These are the names given by the C++ front-end to vtables, and
11571 vtable-like objects. Ideally, this logic should not be here;
11572 instead, there should be some programmatic way of inquiring as
11573 to whether or not an object is a vtable. */
11574
11575#define VTABLE_NAME_P(NAME) \
11576 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11577 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11578 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11579 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11580
11581void
11582rs6000_output_symbol_ref (file, x)
11583 FILE *file;
11584 rtx x;
11585{
11586 /* Currently C++ toc references to vtables can be emitted before it
11587 is decided whether the vtable is public or private. If this is
11588 the case, then the linker will eventually complain that there is
11589 a reference to an unknown section. Thus, for vtables only,
11590 we emit the TOC reference to reference the symbol and not the
11591 section. */
11592 const char *name = XSTR (x, 0);
54ee9799
DE
11593
11594 if (VTABLE_NAME_P (name))
11595 {
11596 RS6000_OUTPUT_BASENAME (file, name);
11597 }
11598 else
11599 assemble_name (file, name);
28e510bd
MM
11600}
11601
a4f6c312
SS
11602/* Output a TOC entry. We derive the entry name from what is being
11603 written. */
9878760c
RK
11604
11605void
a9098fd0 11606output_toc (file, x, labelno, mode)
9878760c
RK
11607 FILE *file;
11608 rtx x;
11609 int labelno;
a9098fd0 11610 enum machine_mode mode;
9878760c
RK
11611{
11612 char buf[256];
3cce094d 11613 const char *name = buf;
ec940faa 11614 const char *real_name;
9878760c
RK
11615 rtx base = x;
11616 int offset = 0;
11617
4697a36c
MM
11618 if (TARGET_NO_TOC)
11619 abort ();
11620
9ebbca7d
GK
11621 /* When the linker won't eliminate them, don't output duplicate
11622 TOC entries (this happens on AIX if there is any kind of TOC,
1f8f4a0b
MM
11623 and on SVR4 under -fPIC or -mrelocatable). */
11624 if (TARGET_TOC)
9ebbca7d
GK
11625 {
11626 struct toc_hash_struct *h;
11627 void * * found;
11628
11629 h = ggc_alloc (sizeof (*h));
11630 h->key = x;
a9098fd0 11631 h->key_mode = mode;
9ebbca7d
GK
11632 h->labelno = labelno;
11633
11634 found = htab_find_slot (toc_hash_table, h, 1);
11635 if (*found == NULL)
11636 *found = h;
11637 else /* This is indeed a duplicate.
11638 Set this label equal to that label. */
11639 {
11640 fputs ("\t.set ", file);
11641 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11642 fprintf (file, "%d,", labelno);
11643 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11644 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11645 found)->labelno));
11646 return;
11647 }
11648 }
11649
11650 /* If we're going to put a double constant in the TOC, make sure it's
11651 aligned properly when strict alignment is on. */
ff1720ed
RK
11652 if (GET_CODE (x) == CONST_DOUBLE
11653 && STRICT_ALIGNMENT
a9098fd0 11654 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
11655 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11656 ASM_OUTPUT_ALIGN (file, 3);
11657 }
11658
9ebbca7d 11659 ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
9878760c 11660
37c37a57
RK
11661 /* Handle FP constants specially. Note that if we have a minimal
11662 TOC, things we put here aren't actually in the TOC, so we can allow
11663 FP constants. */
fcce224d
DE
11664 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
11665 {
11666 REAL_VALUE_TYPE rv;
11667 long k[4];
11668
11669 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11670 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
11671
11672 if (TARGET_64BIT)
11673 {
11674 if (TARGET_MINIMAL_TOC)
11675 fputs (DOUBLE_INT_ASM_OP, file);
11676 else
11677 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11678 k[0] & 0xffffffff, k[1] & 0xffffffff,
11679 k[2] & 0xffffffff, k[3] & 0xffffffff);
11680 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
11681 k[0] & 0xffffffff, k[1] & 0xffffffff,
11682 k[2] & 0xffffffff, k[3] & 0xffffffff);
11683 return;
11684 }
11685 else
11686 {
11687 if (TARGET_MINIMAL_TOC)
11688 fputs ("\t.long ", file);
11689 else
11690 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11691 k[0] & 0xffffffff, k[1] & 0xffffffff,
11692 k[2] & 0xffffffff, k[3] & 0xffffffff);
11693 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
11694 k[0] & 0xffffffff, k[1] & 0xffffffff,
11695 k[2] & 0xffffffff, k[3] & 0xffffffff);
11696 return;
11697 }
11698 }
11699 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 11700 {
042259f2
DE
11701 REAL_VALUE_TYPE rv;
11702 long k[2];
0adc764e 11703
042259f2
DE
11704 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11705 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 11706
13ded975
DE
11707 if (TARGET_64BIT)
11708 {
11709 if (TARGET_MINIMAL_TOC)
2bfcf297 11710 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11711 else
2f0552b6
AM
11712 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11713 k[0] & 0xffffffff, k[1] & 0xffffffff);
11714 fprintf (file, "0x%lx%08lx\n",
11715 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11716 return;
11717 }
1875cc88 11718 else
13ded975
DE
11719 {
11720 if (TARGET_MINIMAL_TOC)
2bfcf297 11721 fputs ("\t.long ", file);
13ded975 11722 else
2f0552b6
AM
11723 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11724 k[0] & 0xffffffff, k[1] & 0xffffffff);
11725 fprintf (file, "0x%lx,0x%lx\n",
11726 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11727 return;
11728 }
9878760c 11729 }
a9098fd0 11730 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 11731 {
042259f2
DE
11732 REAL_VALUE_TYPE rv;
11733 long l;
9878760c 11734
042259f2
DE
11735 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11736 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11737
31bfaa0b
DE
11738 if (TARGET_64BIT)
11739 {
11740 if (TARGET_MINIMAL_TOC)
2bfcf297 11741 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 11742 else
2f0552b6
AM
11743 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11744 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
11745 return;
11746 }
042259f2 11747 else
31bfaa0b
DE
11748 {
11749 if (TARGET_MINIMAL_TOC)
2bfcf297 11750 fputs ("\t.long ", file);
31bfaa0b 11751 else
2f0552b6
AM
11752 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11753 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
11754 return;
11755 }
042259f2 11756 }
f176e826 11757 else if (GET_MODE (x) == VOIDmode
a9098fd0 11758 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 11759 {
e2c953b6 11760 unsigned HOST_WIDE_INT low;
042259f2
DE
11761 HOST_WIDE_INT high;
11762
11763 if (GET_CODE (x) == CONST_DOUBLE)
11764 {
11765 low = CONST_DOUBLE_LOW (x);
11766 high = CONST_DOUBLE_HIGH (x);
11767 }
11768 else
11769#if HOST_BITS_PER_WIDE_INT == 32
11770 {
11771 low = INTVAL (x);
0858c623 11772 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
11773 }
11774#else
11775 {
0858c623 11776 low = INTVAL (x) & 0xffffffff;
042259f2
DE
11777 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11778 }
11779#endif
9878760c 11780
a9098fd0
GK
11781 /* TOC entries are always Pmode-sized, but since this
11782 is a bigendian machine then if we're putting smaller
11783 integer constants in the TOC we have to pad them.
11784 (This is still a win over putting the constants in
11785 a separate constant pool, because then we'd have
02a4ec28
FS
11786 to have both a TOC entry _and_ the actual constant.)
11787
11788 For a 32-bit target, CONST_INT values are loaded and shifted
11789 entirely within `low' and can be stored in one TOC entry. */
11790
11791 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 11792 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
11793
11794 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
11795 {
11796#if HOST_BITS_PER_WIDE_INT == 32
11797 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11798 POINTER_SIZE, &low, &high, 0);
11799#else
11800 low |= high << 32;
11801 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11802 high = (HOST_WIDE_INT) low >> 32;
11803 low &= 0xffffffff;
11804#endif
11805 }
a9098fd0 11806
13ded975
DE
11807 if (TARGET_64BIT)
11808 {
11809 if (TARGET_MINIMAL_TOC)
2bfcf297 11810 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11811 else
2f0552b6
AM
11812 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
11813 (long) high & 0xffffffff, (long) low & 0xffffffff);
11814 fprintf (file, "0x%lx%08lx\n",
11815 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
11816 return;
11817 }
1875cc88 11818 else
13ded975 11819 {
02a4ec28
FS
11820 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
11821 {
11822 if (TARGET_MINIMAL_TOC)
2bfcf297 11823 fputs ("\t.long ", file);
02a4ec28 11824 else
2bfcf297 11825 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
11826 (long) high & 0xffffffff, (long) low & 0xffffffff);
11827 fprintf (file, "0x%lx,0x%lx\n",
11828 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 11829 }
13ded975 11830 else
02a4ec28
FS
11831 {
11832 if (TARGET_MINIMAL_TOC)
2bfcf297 11833 fputs ("\t.long ", file);
02a4ec28 11834 else
2f0552b6
AM
11835 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
11836 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 11837 }
13ded975
DE
11838 return;
11839 }
9878760c
RK
11840 }
11841
11842 if (GET_CODE (x) == CONST)
11843 {
2bfcf297
DB
11844 if (GET_CODE (XEXP (x, 0)) != PLUS)
11845 abort ();
11846
9878760c
RK
11847 base = XEXP (XEXP (x, 0), 0);
11848 offset = INTVAL (XEXP (XEXP (x, 0), 1));
11849 }
11850
11851 if (GET_CODE (base) == SYMBOL_REF)
11852 name = XSTR (base, 0);
11853 else if (GET_CODE (base) == LABEL_REF)
11854 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
11855 else if (GET_CODE (base) == CODE_LABEL)
11856 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
11857 else
11858 abort ();
11859
772c5265 11860 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 11861 if (TARGET_MINIMAL_TOC)
2bfcf297 11862 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
11863 else
11864 {
b6c9286a 11865 fprintf (file, "\t.tc %s", real_name);
9878760c 11866
1875cc88
JW
11867 if (offset < 0)
11868 fprintf (file, ".N%d", - offset);
11869 else if (offset)
11870 fprintf (file, ".P%d", offset);
9878760c 11871
19d2d16f 11872 fputs ("[TC],", file);
1875cc88 11873 }
581bc4de
MM
11874
11875 /* Currently C++ toc references to vtables can be emitted before it
11876 is decided whether the vtable is public or private. If this is
11877 the case, then the linker will eventually complain that there is
11878 a TOC reference to an unknown section. Thus, for vtables only,
11879 we emit the TOC reference to reference the symbol and not the
11880 section. */
28e510bd 11881 if (VTABLE_NAME_P (name))
581bc4de 11882 {
54ee9799 11883 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
11884 if (offset < 0)
11885 fprintf (file, "%d", offset);
11886 else if (offset > 0)
11887 fprintf (file, "+%d", offset);
11888 }
11889 else
11890 output_addr_const (file, x);
19d2d16f 11891 putc ('\n', file);
9878760c
RK
11892}
11893\f
11894/* Output an assembler pseudo-op to write an ASCII string of N characters
11895 starting at P to FILE.
11896
11897 On the RS/6000, we have to do this using the .byte operation and
11898 write out special characters outside the quoted string.
11899 Also, the assembler is broken; very long strings are truncated,
a4f6c312 11900 so we must artificially break them up early. */
9878760c
RK
11901
11902void
11903output_ascii (file, p, n)
11904 FILE *file;
d330fd93 11905 const char *p;
9878760c
RK
11906 int n;
11907{
11908 char c;
11909 int i, count_string;
d330fd93
KG
11910 const char *for_string = "\t.byte \"";
11911 const char *for_decimal = "\t.byte ";
11912 const char *to_close = NULL;
9878760c
RK
11913
11914 count_string = 0;
11915 for (i = 0; i < n; i++)
11916 {
11917 c = *p++;
11918 if (c >= ' ' && c < 0177)
11919 {
11920 if (for_string)
11921 fputs (for_string, file);
11922 putc (c, file);
11923
11924 /* Write two quotes to get one. */
11925 if (c == '"')
11926 {
11927 putc (c, file);
11928 ++count_string;
11929 }
11930
11931 for_string = NULL;
11932 for_decimal = "\"\n\t.byte ";
11933 to_close = "\"\n";
11934 ++count_string;
11935
11936 if (count_string >= 512)
11937 {
11938 fputs (to_close, file);
11939
11940 for_string = "\t.byte \"";
11941 for_decimal = "\t.byte ";
11942 to_close = NULL;
11943 count_string = 0;
11944 }
11945 }
11946 else
11947 {
11948 if (for_decimal)
11949 fputs (for_decimal, file);
11950 fprintf (file, "%d", c);
11951
11952 for_string = "\n\t.byte \"";
11953 for_decimal = ", ";
11954 to_close = "\n";
11955 count_string = 0;
11956 }
11957 }
11958
11959 /* Now close the string if we have written one. Then end the line. */
11960 if (to_close)
9ebbca7d 11961 fputs (to_close, file);
9878760c
RK
11962}
11963\f
11964/* Generate a unique section name for FILENAME for a section type
11965 represented by SECTION_DESC. Output goes into BUF.
11966
11967 SECTION_DESC can be any string, as long as it is different for each
11968 possible section type.
11969
11970 We name the section in the same manner as xlc. The name begins with an
11971 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
11972 names) with the last period replaced by the string SECTION_DESC. If
11973 FILENAME does not contain a period, SECTION_DESC is appended to the end of
11974 the name. */
9878760c
RK
11975
11976void
11977rs6000_gen_section_name (buf, filename, section_desc)
11978 char **buf;
9ebbca7d
GK
11979 const char *filename;
11980 const char *section_desc;
9878760c 11981{
9ebbca7d 11982 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
11983 char *p;
11984 int len;
9878760c
RK
11985
11986 after_last_slash = filename;
11987 for (q = filename; *q; q++)
11e5fe42
RK
11988 {
11989 if (*q == '/')
11990 after_last_slash = q + 1;
11991 else if (*q == '.')
11992 last_period = q;
11993 }
9878760c 11994
11e5fe42 11995 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 11996 *buf = (char *) xmalloc (len);
9878760c
RK
11997
11998 p = *buf;
11999 *p++ = '_';
12000
12001 for (q = after_last_slash; *q; q++)
12002 {
11e5fe42 12003 if (q == last_period)
9878760c
RK
12004 {
12005 strcpy (p, section_desc);
12006 p += strlen (section_desc);
9878760c
RK
12007 }
12008
e9a780ec 12009 else if (ISALNUM (*q))
9878760c
RK
12010 *p++ = *q;
12011 }
12012
11e5fe42 12013 if (last_period == 0)
9878760c
RK
12014 strcpy (p, section_desc);
12015 else
12016 *p = '\0';
12017}
e165f3f0 12018\f
a4f6c312 12019/* Emit profile function. */
411707f4 12020
411707f4
CC
12021void
12022output_profile_hook (labelno)
57ac7be9 12023 int labelno ATTRIBUTE_UNUSED;
411707f4 12024{
8480e480
CC
12025 if (DEFAULT_ABI == ABI_AIX)
12026 {
57ac7be9
AM
12027#ifdef NO_PROFILE_COUNTERS
12028 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
12029#else
8480e480 12030 char buf[30];
40501e5f 12031 const char *label_name;
8480e480 12032 rtx fun;
411707f4 12033
8480e480 12034 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 12035 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 12036 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 12037
8480e480
CC
12038 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
12039 fun, Pmode);
57ac7be9 12040#endif
8480e480 12041 }
ee890fe2
SS
12042 else if (DEFAULT_ABI == ABI_DARWIN)
12043 {
d5fa86ba 12044 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
12045 int caller_addr_regno = LINK_REGISTER_REGNUM;
12046
12047 /* Be conservative and always set this, at least for now. */
12048 current_function_uses_pic_offset_table = 1;
12049
12050#if TARGET_MACHO
12051 /* For PIC code, set up a stub and collect the caller's address
12052 from r0, which is where the prologue puts it. */
12053 if (flag_pic)
12054 {
12055 mcount_name = machopic_stub_name (mcount_name);
12056 if (current_function_uses_pic_offset_table)
12057 caller_addr_regno = 0;
12058 }
12059#endif
12060 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
12061 0, VOIDmode, 1,
12062 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12063 }
411707f4
CC
12064}
12065
a4f6c312 12066/* Write function profiler code. */
e165f3f0
RK
12067
12068void
12069output_function_profiler (file, labelno)
12070 FILE *file;
12071 int labelno;
12072{
3daf36a4 12073 char buf[100];
09eeeacb 12074 int save_lr = 8;
e165f3f0 12075
3daf36a4 12076 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 12077 switch (DEFAULT_ABI)
3daf36a4 12078 {
38c1f2d7
MM
12079 default:
12080 abort ();
12081
12082 case ABI_V4:
09eeeacb
AM
12083 save_lr = 4;
12084 /* Fall through. */
12085
38c1f2d7 12086 case ABI_AIX_NODESC:
09eeeacb
AM
12087 if (!TARGET_32BIT)
12088 {
12089 warning ("no profiling of 64-bit code for this ABI");
12090 return;
12091 }
38c1f2d7
MM
12092 fprintf (file, "\tmflr %s\n", reg_names[0]);
12093 if (flag_pic == 1)
12094 {
dfdfa60f 12095 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12096 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12097 reg_names[0], save_lr, reg_names[1]);
17167fd8 12098 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12099 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12100 assemble_name (file, buf);
17167fd8 12101 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12102 }
9ebbca7d 12103 else if (flag_pic > 1)
38c1f2d7 12104 {
09eeeacb
AM
12105 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12106 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12107 /* Now, we need to get the address of the label. */
12108 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12109 assemble_name (file, buf);
9ebbca7d
GK
12110 fputs ("-.\n1:", file);
12111 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12112 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12113 reg_names[0], reg_names[11]);
12114 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12115 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12116 }
38c1f2d7
MM
12117 else
12118 {
17167fd8 12119 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12120 assemble_name (file, buf);
dfdfa60f 12121 fputs ("@ha\n", file);
09eeeacb
AM
12122 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12123 reg_names[0], save_lr, reg_names[1]);
a260abc9 12124 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12125 assemble_name (file, buf);
17167fd8 12126 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12127 }
12128
09eeeacb
AM
12129 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12130 {
12131 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12132 reg_names[STATIC_CHAIN_REGNUM],
12133 12, reg_names[1]);
12134 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12135 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12136 reg_names[STATIC_CHAIN_REGNUM],
12137 12, reg_names[1]);
12138 }
12139 else
12140 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12141 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12142 break;
12143
12144 case ABI_AIX:
ee890fe2 12145 case ABI_DARWIN:
a4f6c312 12146 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7
MM
12147 break;
12148 }
e165f3f0 12149}
a251ffd0
TG
12150
12151/* Adjust the cost of a scheduling dependency. Return the new cost of
12152 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12153
c237e94a 12154static int
a06faf84 12155rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12156 rtx insn;
12157 rtx link;
296b8152 12158 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12159 int cost;
12160{
12161 if (! recog_memoized (insn))
12162 return 0;
12163
12164 if (REG_NOTE_KIND (link) != 0)
12165 return 0;
12166
12167 if (REG_NOTE_KIND (link) == 0)
12168 {
ed947a96
DJ
12169 /* Data dependency; DEP_INSN writes a register that INSN reads
12170 some cycles later. */
12171 switch (get_attr_type (insn))
12172 {
12173 case TYPE_JMPREG:
309323c2 12174 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12175 a mtctr and bctr (and mtlr and br/blr). The first
12176 scheduling pass will not know about this latency since
12177 the mtctr instruction, which has the latency associated
12178 to it, will be generated by reload. */
309323c2 12179 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12180 case TYPE_BRANCH:
12181 /* Leave some extra cycles between a compare and its
12182 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12183 if ((rs6000_cpu_attr == CPU_PPC603
12184 || rs6000_cpu_attr == CPU_PPC604
12185 || rs6000_cpu_attr == CPU_PPC604E
12186 || rs6000_cpu_attr == CPU_PPC620
12187 || rs6000_cpu_attr == CPU_PPC630
12188 || rs6000_cpu_attr == CPU_PPC750
12189 || rs6000_cpu_attr == CPU_PPC7400
12190 || rs6000_cpu_attr == CPU_PPC7450
12191 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12192 && recog_memoized (dep_insn)
12193 && (INSN_CODE (dep_insn) >= 0)
12194 && (get_attr_type (dep_insn) == TYPE_COMPARE
12195 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12196 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
12197 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
12198 return cost + 2;
12199 default:
12200 break;
12201 }
a251ffd0
TG
12202 /* Fall out to return default cost. */
12203 }
12204
12205 return cost;
12206}
b6c9286a 12207
a4f6c312
SS
12208/* A C statement (sans semicolon) to update the integer scheduling
12209 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12210 INSN earlier, increase the priority to execute INSN later. Do not
12211 define this macro if you do not need to adjust the scheduling
12212 priorities of insns. */
bef84347 12213
c237e94a 12214static int
bef84347 12215rs6000_adjust_priority (insn, priority)
d330fd93 12216 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12217 int priority;
12218{
a4f6c312
SS
12219 /* On machines (like the 750) which have asymmetric integer units,
12220 where one integer unit can do multiply and divides and the other
12221 can't, reduce the priority of multiply/divide so it is scheduled
12222 before other integer operations. */
bef84347
VM
12223
12224#if 0
2c3c49de 12225 if (! INSN_P (insn))
bef84347
VM
12226 return priority;
12227
12228 if (GET_CODE (PATTERN (insn)) == USE)
12229 return priority;
12230
12231 switch (rs6000_cpu_attr) {
12232 case CPU_PPC750:
12233 switch (get_attr_type (insn))
12234 {
12235 default:
12236 break;
12237
12238 case TYPE_IMUL:
12239 case TYPE_IDIV:
3cb999d8
DE
12240 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12241 priority, priority);
bef84347
VM
12242 if (priority >= 0 && priority < 0x01000000)
12243 priority >>= 3;
12244 break;
12245 }
12246 }
12247#endif
12248
12249 return priority;
12250}
12251
a4f6c312
SS
12252/* Return how many instructions the machine can issue per cycle. */
12253
c237e94a
ZW
12254static int
12255rs6000_issue_rate ()
b6c9286a
MM
12256{
12257 switch (rs6000_cpu_attr) {
3cb999d8
DE
12258 case CPU_RIOS1: /* ? */
12259 case CPU_RS64A:
12260 case CPU_PPC601: /* ? */
ed947a96 12261 case CPU_PPC7450:
3cb999d8 12262 return 3;
b6c9286a 12263 case CPU_PPC603:
bef84347 12264 case CPU_PPC750:
ed947a96 12265 case CPU_PPC7400:
bef84347 12266 return 2;
3cb999d8 12267 case CPU_RIOS2:
b6c9286a 12268 case CPU_PPC604:
19684119 12269 case CPU_PPC604E:
b6c9286a 12270 case CPU_PPC620:
3cb999d8 12271 case CPU_PPC630:
309323c2 12272 case CPU_POWER4:
b6c9286a
MM
12273 return 4;
12274 default:
12275 return 1;
12276 }
12277}
12278
b6c9286a 12279\f
b6c9286a
MM
12280/* Length in units of the trampoline for entering a nested function. */
12281
12282int
12283rs6000_trampoline_size ()
12284{
12285 int ret = 0;
12286
12287 switch (DEFAULT_ABI)
12288 {
12289 default:
12290 abort ();
12291
12292 case ABI_AIX:
8f802bfb 12293 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12294 break;
12295
4dabc42d 12296 case ABI_DARWIN:
b6c9286a
MM
12297 case ABI_V4:
12298 case ABI_AIX_NODESC:
03a7e1a5 12299 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12300 break;
b6c9286a
MM
12301 }
12302
12303 return ret;
12304}
12305
12306/* Emit RTL insns to initialize the variable parts of a trampoline.
12307 FNADDR is an RTX for the address of the function's pure code.
12308 CXT is an RTX for the static chain value for the function. */
12309
12310void
12311rs6000_initialize_trampoline (addr, fnaddr, cxt)
12312 rtx addr;
12313 rtx fnaddr;
12314 rtx cxt;
12315{
ac2a93a1 12316 enum machine_mode pmode = Pmode;
8bd04c56
MM
12317 int regsize = (TARGET_32BIT) ? 4 : 8;
12318 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12319
12320 switch (DEFAULT_ABI)
12321 {
12322 default:
12323 abort ();
12324
8bd04c56 12325/* Macros to shorten the code expansions below. */
39403d82 12326#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12327#define MEM_PLUS(addr,offset) \
12328 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12329
b6c9286a
MM
12330 /* Under AIX, just build the 3 word function descriptor */
12331 case ABI_AIX:
8bd04c56
MM
12332 {
12333 rtx fn_reg = gen_reg_rtx (pmode);
12334 rtx toc_reg = gen_reg_rtx (pmode);
12335 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12336 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12337 emit_move_insn (MEM_DEREF (addr), fn_reg);
12338 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12339 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12340 }
b6c9286a
MM
12341 break;
12342
4dabc42d
TC
12343 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12344 case ABI_DARWIN:
b6c9286a
MM
12345 case ABI_V4:
12346 case ABI_AIX_NODESC:
39403d82 12347 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12348 FALSE, VOIDmode, 4,
12349 addr, pmode,
12350 GEN_INT (rs6000_trampoline_size ()), SImode,
12351 fnaddr, pmode,
12352 ctx_reg, pmode);
b6c9286a 12353 break;
b6c9286a
MM
12354 }
12355
12356 return;
12357}
7509c759
MM
12358
12359\f
91d231cb 12360/* Table of valid machine attributes. */
a4f6c312 12361
91d231cb 12362const struct attribute_spec rs6000_attribute_table[] =
7509c759 12363{
91d231cb 12364 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12365 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12366 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12367 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12368};
7509c759 12369
a5c76ee6
ZW
12370/* Handle a "longcall" or "shortcall" attribute; arguments as in
12371 struct attribute_spec.handler. */
a4f6c312 12372
91d231cb
JM
12373static tree
12374rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12375 tree *node;
12376 tree name;
12377 tree args ATTRIBUTE_UNUSED;
12378 int flags ATTRIBUTE_UNUSED;
12379 bool *no_add_attrs;
12380{
12381 if (TREE_CODE (*node) != FUNCTION_TYPE
12382 && TREE_CODE (*node) != FIELD_DECL
12383 && TREE_CODE (*node) != TYPE_DECL)
12384 {
12385 warning ("`%s' attribute only applies to functions",
12386 IDENTIFIER_POINTER (name));
12387 *no_add_attrs = true;
12388 }
6a4cee5f 12389
91d231cb 12390 return NULL_TREE;
7509c759
MM
12391}
12392
a5c76ee6
ZW
12393/* Set longcall attributes on all functions declared when
12394 rs6000_default_long_calls is true. */
12395static void
12396rs6000_set_default_type_attributes (type)
12397 tree type;
12398{
12399 if (rs6000_default_long_calls
12400 && (TREE_CODE (type) == FUNCTION_TYPE
12401 || TREE_CODE (type) == METHOD_TYPE))
12402 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12403 NULL_TREE,
12404 TYPE_ATTRIBUTES (type));
12405}
12406
3cb999d8
DE
12407/* Return a reference suitable for calling a function with the
12408 longcall attribute. */
a4f6c312 12409
6a4cee5f
MM
12410struct rtx_def *
12411rs6000_longcall_ref (call_ref)
12412 rtx call_ref;
12413{
d330fd93 12414 const char *call_name;
6a4cee5f
MM
12415 tree node;
12416
12417 if (GET_CODE (call_ref) != SYMBOL_REF)
12418 return call_ref;
12419
12420 /* System V adds '.' to the internal name, so skip them. */
12421 call_name = XSTR (call_ref, 0);
12422 if (*call_name == '.')
12423 {
12424 while (*call_name == '.')
12425 call_name++;
12426
12427 node = get_identifier (call_name);
39403d82 12428 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12429 }
12430
12431 return force_reg (Pmode, call_ref);
12432}
12433
7509c759 12434\f
b64a1b53
RH
12435#ifdef USING_ELFOS_H
12436
7509c759
MM
12437/* A C statement or statements to switch to the appropriate section
12438 for output of RTX in mode MODE. You can assume that RTX is some
12439 kind of constant in RTL. The argument MODE is redundant except in
12440 the case of a `const_int' rtx. Select the section by calling
12441 `text_section' or one of the alternatives for other sections.
12442
12443 Do not define this macro if you put all constants in the read-only
12444 data section. */
12445
b64a1b53
RH
12446static void
12447rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12448 enum machine_mode mode;
7509c759 12449 rtx x;
b64a1b53 12450 unsigned HOST_WIDE_INT align;
7509c759 12451{
a9098fd0 12452 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12453 toc_section ();
7509c759 12454 else
b64a1b53 12455 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12456}
12457
12458/* A C statement or statements to switch to the appropriate
12459 section for output of DECL. DECL is either a `VAR_DECL' node
12460 or a constant of some sort. RELOC indicates whether forming
12461 the initial value of DECL requires link-time relocations. */
12462
ae46c4e0
RH
12463static void
12464rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12465 tree decl;
12466 int reloc;
0e5dbd9b 12467 unsigned HOST_WIDE_INT align;
7509c759 12468{
0e5dbd9b
DE
12469 default_elf_select_section_1 (decl, reloc, align,
12470 flag_pic || DEFAULT_ABI == ABI_AIX);
63019373
GK
12471}
12472
12473/* A C statement to build up a unique section name, expressed as a
12474 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12475 RELOC indicates whether the initial value of EXP requires
12476 link-time relocations. If you do not define this macro, GCC will use
12477 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12478 macro can now be called for uninitialized data items as well as
4912a07c 12479 initialized data and functions. */
63019373 12480
ae46c4e0
RH
12481static void
12482rs6000_elf_unique_section (decl, reloc)
63019373
GK
12483 tree decl;
12484 int reloc;
12485{
0e5dbd9b
DE
12486 default_unique_section_1 (decl, reloc,
12487 flag_pic || DEFAULT_ABI == ABI_AIX);
7509c759 12488}
d9407988
MM
12489
12490\f
d9407988
MM
12491/* If we are referencing a function that is static or is known to be
12492 in this file, make the SYMBOL_REF special. We can use this to indicate
12493 that we can branch to this function without emitting a no-op after the
9ebbca7d 12494 call. For real AIX calling sequences, we also replace the
d9407988
MM
12495 function name with the real name (1 or 2 leading .'s), rather than
12496 the function descriptor name. This saves a lot of overriding code
a260abc9 12497 to read the prefixes. */
d9407988 12498
fb49053f
RH
12499static void
12500rs6000_elf_encode_section_info (decl, first)
d9407988 12501 tree decl;
b2003250 12502 int first;
d9407988 12503{
b2003250
RH
12504 if (!first)
12505 return;
12506
d9407988
MM
12507 if (TREE_CODE (decl) == FUNCTION_DECL)
12508 {
12509 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
b629ba0c 12510 if ((*targetm.binds_local_p) (decl))
d9407988
MM
12511 SYMBOL_REF_FLAG (sym_ref) = 1;
12512
9ebbca7d 12513 if (DEFAULT_ABI == ABI_AIX)
d9407988 12514 {
ff669a6c
RH
12515 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12516 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12517 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12518 str[0] = '.';
12519 str[1] = '.';
12520 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12521
520a57c8 12522 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12523 }
12524 }
12525 else if (rs6000_sdata != SDATA_NONE
f607bc57 12526 && DEFAULT_ABI == ABI_V4
d9407988
MM
12527 && TREE_CODE (decl) == VAR_DECL)
12528 {
12529 int size = int_size_in_bytes (TREE_TYPE (decl));
12530 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12531 const char *name = (char *)0;
d9407988
MM
12532 int len = 0;
12533
12534 if (section_name)
12535 {
12536 if (TREE_CODE (section_name) == STRING_CST)
12537 {
12538 name = TREE_STRING_POINTER (section_name);
12539 len = TREE_STRING_LENGTH (section_name);
12540 }
12541 else
12542 abort ();
12543 }
12544
12545 if ((size > 0 && size <= g_switch_value)
12546 || (name
5f59ecb7 12547 && ((len == sizeof (".sdata") - 1
3cb999d8 12548 && strcmp (name, ".sdata") == 0)
5f59ecb7 12549 || (len == sizeof (".sdata2") - 1
3cb999d8 12550 && strcmp (name, ".sdata2") == 0)
5f59ecb7 12551 || (len == sizeof (".sbss") - 1
3cb999d8 12552 && strcmp (name, ".sbss") == 0)
5f59ecb7 12553 || (len == sizeof (".sbss2") - 1
3cb999d8 12554 && strcmp (name, ".sbss2") == 0)
5f59ecb7 12555 || (len == sizeof (".PPC.EMB.sdata0") - 1
3cb999d8 12556 && strcmp (name, ".PPC.EMB.sdata0") == 0)
5f59ecb7 12557 || (len == sizeof (".PPC.EMB.sbss0") - 1
3cb999d8 12558 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d9407988
MM
12559 {
12560 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
ff669a6c 12561 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 12562 char *str = alloca (len + 2);
ff669a6c 12563
ff669a6c
RH
12564 str[0] = '@';
12565 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 12566 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
12567 }
12568 }
12569}
12570
772c5265
RH
12571static const char *
12572rs6000_elf_strip_name_encoding (str)
12573 const char *str;
12574{
12575 while (*str == '*' || *str == '@')
12576 str++;
12577 return str;
12578}
12579
0e5dbd9b
DE
12580static bool
12581rs6000_elf_in_small_data_p (decl)
12582 tree decl;
12583{
12584 if (rs6000_sdata == SDATA_NONE)
12585 return false;
12586
12587 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
12588 {
12589 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
12590 if (strcmp (section, ".sdata") == 0
12591 || strcmp (section, ".sdata2") == 0
12592 || strcmp (section, ".sbss") == 0)
12593 return true;
12594 }
12595 else
12596 {
12597 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
12598
12599 if (size > 0
12600 && size <= g_switch_value
12601 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
12602 return true;
12603 }
12604
12605 return false;
12606}
12607
b91da81f 12608#endif /* USING_ELFOS_H */
000034eb 12609
a6c2a102 12610\f
000034eb 12611/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
12612 ADDR can be effectively incremented by incrementing REG.
12613
12614 r0 is special and we must not select it as an address
12615 register by this routine since our caller will try to
12616 increment the returned register via an "la" instruction. */
000034eb
DE
12617
12618struct rtx_def *
12619find_addr_reg (addr)
12620 rtx addr;
12621{
12622 while (GET_CODE (addr) == PLUS)
12623 {
02441cd6
JL
12624 if (GET_CODE (XEXP (addr, 0)) == REG
12625 && REGNO (XEXP (addr, 0)) != 0)
000034eb 12626 addr = XEXP (addr, 0);
02441cd6
JL
12627 else if (GET_CODE (XEXP (addr, 1)) == REG
12628 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
12629 addr = XEXP (addr, 1);
12630 else if (CONSTANT_P (XEXP (addr, 0)))
12631 addr = XEXP (addr, 1);
12632 else if (CONSTANT_P (XEXP (addr, 1)))
12633 addr = XEXP (addr, 0);
12634 else
12635 abort ();
12636 }
02441cd6 12637 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
12638 return addr;
12639 abort ();
12640}
12641
a6c2a102
DE
12642void
12643rs6000_fatal_bad_address (op)
12644 rtx op;
12645{
12646 fatal_insn ("bad address", op);
12647}
c8023011
MM
12648
12649/* Called to register all of our global variables with the garbage
12650 collector. */
12651
12652static void
12653rs6000_add_gc_roots ()
12654{
9ebbca7d
GK
12655 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
12656 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
12657 toc_hash_mark_table);
ee890fe2
SS
12658}
12659
12660#if TARGET_MACHO
12661
12662#if 0
12663/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12664 reference and a constant. */
12665
12666int
12667symbolic_operand (op)
592696dd 12668 rtx op;
ee890fe2
SS
12669{
12670 switch (GET_CODE (op))
12671 {
12672 case SYMBOL_REF:
12673 case LABEL_REF:
12674 return 1;
12675 case CONST:
12676 op = XEXP (op, 0);
12677 return (GET_CODE (op) == SYMBOL_REF ||
12678 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12679 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12680 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12681 default:
12682 return 0;
12683 }
c8023011 12684}
ee890fe2
SS
12685#endif
12686
12687#ifdef RS6000_LONG_BRANCH
12688
12689static tree stub_list = 0;
12690
12691/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12692 procedure calls to the linked list. */
12693
12694void
12695add_compiler_stub (label_name, function_name, line_number)
12696 tree label_name;
12697 tree function_name;
12698 int line_number;
12699{
12700 tree stub = build_tree_list (function_name, label_name);
12701 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12702 TREE_CHAIN (stub) = stub_list;
12703 stub_list = stub;
12704}
12705
12706#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12707#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12708#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12709
a4f6c312
SS
12710/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12711 handling procedure calls from the linked list and initializes the
12712 linked list. */
ee890fe2 12713
a4f6c312
SS
12714void
12715output_compiler_stub ()
ee890fe2
SS
12716{
12717 char tmp_buf[256];
12718 char label_buf[256];
308c142a 12719 tree stub;
ee890fe2
SS
12720
12721 if (!flag_pic)
12722 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12723 {
12724 fprintf (asm_out_file,
12725 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12726
12727#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12728 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12729 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12730#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12731
12732 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12733 strcpy (label_buf,
12734 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12735 else
12736 {
12737 label_buf[0] = '_';
12738 strcpy (label_buf+1,
12739 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12740 }
12741
12742 strcpy (tmp_buf, "lis r12,hi16(");
12743 strcat (tmp_buf, label_buf);
12744 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12745 strcat (tmp_buf, label_buf);
12746 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12747 output_asm_insn (tmp_buf, 0);
12748
12749#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12750 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12751 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12752#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12753 }
12754
12755 stub_list = 0;
12756}
12757
12758/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12759 already there or not. */
12760
a4f6c312
SS
12761int
12762no_previous_def (function_name)
ee890fe2
SS
12763 tree function_name;
12764{
12765 tree stub;
12766 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12767 if (function_name == STUB_FUNCTION_NAME (stub))
12768 return 0;
12769 return 1;
12770}
12771
12772/* GET_PREV_LABEL gets the label name from the previous definition of
12773 the function. */
12774
a4f6c312
SS
12775tree
12776get_prev_label (function_name)
ee890fe2
SS
12777 tree function_name;
12778{
12779 tree stub;
12780 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12781 if (function_name == STUB_FUNCTION_NAME (stub))
12782 return STUB_LABEL_NAME (stub);
12783 return 0;
12784}
12785
12786/* INSN is either a function call or a millicode call. It may have an
12787 unconditional jump in its delay slot.
12788
12789 CALL_DEST is the routine we are calling. */
12790
12791char *
12792output_call (insn, call_dest, operand_number)
12793 rtx insn;
12794 rtx call_dest;
12795 int operand_number;
12796{
12797 static char buf[256];
12798 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
12799 {
12800 tree labelname;
12801 tree funname = get_identifier (XSTR (call_dest, 0));
12802
12803 if (no_previous_def (funname))
12804 {
308c142a 12805 int line_number = 0;
ee890fe2
SS
12806 rtx label_rtx = gen_label_rtx ();
12807 char *label_buf, temp_buf[256];
12808 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
12809 CODE_LABEL_NUMBER (label_rtx));
12810 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
12811 labelname = get_identifier (label_buf);
12812 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
12813 if (insn)
12814 line_number = NOTE_LINE_NUMBER (insn);
12815 add_compiler_stub (labelname, funname, line_number);
12816 }
12817 else
12818 labelname = get_prev_label (funname);
12819
12820 sprintf (buf, "jbsr %%z%d,%.246s",
12821 operand_number, IDENTIFIER_POINTER (labelname));
12822 return buf;
12823 }
12824 else
12825 {
12826 sprintf (buf, "bl %%z%d", operand_number);
12827 return buf;
12828 }
12829}
12830
12831#endif /* RS6000_LONG_BRANCH */
12832
12833#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
12834 do { \
83182544 12835 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
12836 char *buffer_ = (BUF); \
12837 if (symbol_[0] == '"') \
12838 { \
12839 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
12840 } \
12841 else if (name_needs_quotes(symbol_)) \
12842 { \
12843 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
12844 } \
12845 else \
12846 { \
12847 sprintf(buffer_, "L%d$%s", (N), symbol_); \
12848 } \
12849 } while (0)
12850
12851
12852/* Generate PIC and indirect symbol stubs. */
12853
12854void
12855machopic_output_stub (file, symb, stub)
12856 FILE *file;
12857 const char *symb, *stub;
12858{
12859 unsigned int length;
a4f6c312
SS
12860 char *symbol_name, *lazy_ptr_name;
12861 char *local_label_0;
ee890fe2
SS
12862 static int label = 0;
12863
df56a27f 12864 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 12865 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 12866
ee890fe2
SS
12867 label += 1;
12868
ee890fe2
SS
12869 length = strlen (symb);
12870 symbol_name = alloca (length + 32);
12871 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
12872
12873 lazy_ptr_name = alloca (length + 32);
12874 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
12875
12876 local_label_0 = alloca (length + 32);
12877 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
12878
ee890fe2
SS
12879 if (flag_pic == 2)
12880 machopic_picsymbol_stub_section ();
12881 else
12882 machopic_symbol_stub_section ();
12883
12884 fprintf (file, "%s:\n", stub);
12885 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12886
12887 if (flag_pic == 2)
12888 {
12889 fprintf (file, "\tmflr r0\n");
12890 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
12891 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
12892 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
12893 lazy_ptr_name, local_label_0);
12894 fprintf (file, "\tmtlr r0\n");
12895 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
12896 lazy_ptr_name, local_label_0);
12897 fprintf (file, "\tmtctr r12\n");
12898 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
12899 lazy_ptr_name, local_label_0);
12900 fprintf (file, "\tbctr\n");
12901 }
12902 else
12903 fprintf (file, "non-pure not supported\n");
12904
12905 machopic_lazy_symbol_ptr_section ();
12906 fprintf (file, "%s:\n", lazy_ptr_name);
12907 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12908 fprintf (file, "\t.long dyld_stub_binding_helper\n");
12909}
12910
12911/* Legitimize PIC addresses. If the address is already
12912 position-independent, we return ORIG. Newly generated
12913 position-independent addresses go into a reg. This is REG if non
12914 zero, otherwise we allocate register(s) as necessary. */
12915
c859cda6 12916#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
12917
12918rtx
12919rs6000_machopic_legitimize_pic_address (orig, mode, reg)
12920 rtx orig;
12921 enum machine_mode mode;
12922 rtx reg;
12923{
12924 rtx base, offset;
12925
12926 if (reg == NULL && ! reload_in_progress && ! reload_completed)
12927 reg = gen_reg_rtx (Pmode);
12928
12929 if (GET_CODE (orig) == CONST)
12930 {
12931 if (GET_CODE (XEXP (orig, 0)) == PLUS
12932 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
12933 return orig;
12934
12935 if (GET_CODE (XEXP (orig, 0)) == PLUS)
12936 {
a4f6c312
SS
12937 base =
12938 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
12939 Pmode, reg);
12940 offset =
12941 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
12942 Pmode, reg);
ee890fe2
SS
12943 }
12944 else
12945 abort ();
12946
12947 if (GET_CODE (offset) == CONST_INT)
12948 {
12949 if (SMALL_INT (offset))
ed8908e7 12950 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
12951 else if (! reload_in_progress && ! reload_completed)
12952 offset = force_reg (Pmode, offset);
12953 else
c859cda6
DJ
12954 {
12955 rtx mem = force_const_mem (Pmode, orig);
12956 return machopic_legitimize_pic_address (mem, Pmode, reg);
12957 }
ee890fe2
SS
12958 }
12959 return gen_rtx (PLUS, Pmode, base, offset);
12960 }
12961
12962 /* Fall back on generic machopic code. */
12963 return machopic_legitimize_pic_address (orig, mode, reg);
12964}
12965
12966/* This is just a placeholder to make linking work without having to
12967 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
12968 ever needed for Darwin (not too likely!) this would have to get a
12969 real definition. */
12970
12971void
12972toc_section ()
12973{
12974}
12975
12976#endif /* TARGET_MACHO */
7c262518
RH
12977
12978#if TARGET_ELF
12979static unsigned int
12980rs6000_elf_section_type_flags (decl, name, reloc)
12981 tree decl;
12982 const char *name;
12983 int reloc;
12984{
5add3202
DE
12985 unsigned int flags
12986 = default_section_type_flags_1 (decl, name, reloc,
12987 flag_pic || DEFAULT_ABI == ABI_AIX);
7c262518 12988
270fc29b
RH
12989 if (TARGET_RELOCATABLE)
12990 flags |= SECTION_WRITE;
7c262518 12991
d0101753 12992 return flags;
7c262518 12993}
d9f6800d
RH
12994
12995/* Record an element in the table of global constructors. SYMBOL is
12996 a SYMBOL_REF of the function to be called; PRIORITY is a number
12997 between 0 and MAX_INIT_PRIORITY.
12998
12999 This differs from default_named_section_asm_out_constructor in
13000 that we have special handling for -mrelocatable. */
13001
13002static void
13003rs6000_elf_asm_out_constructor (symbol, priority)
13004 rtx symbol;
13005 int priority;
13006{
13007 const char *section = ".ctors";
13008 char buf[16];
13009
13010 if (priority != DEFAULT_INIT_PRIORITY)
13011 {
13012 sprintf (buf, ".ctors.%.5u",
13013 /* Invert the numbering so the linker puts us in the proper
13014 order; constructors are run from right to left, and the
13015 linker sorts in increasing order. */
13016 MAX_INIT_PRIORITY - priority);
13017 section = buf;
13018 }
13019
715bdd29
RH
13020 named_section_flags (section, SECTION_WRITE);
13021 assemble_align (POINTER_SIZE);
d9f6800d
RH
13022
13023 if (TARGET_RELOCATABLE)
13024 {
13025 fputs ("\t.long (", asm_out_file);
13026 output_addr_const (asm_out_file, symbol);
13027 fputs (")@fixup\n", asm_out_file);
13028 }
13029 else
c8af3574 13030 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
13031}
13032
13033static void
13034rs6000_elf_asm_out_destructor (symbol, priority)
13035 rtx symbol;
13036 int priority;
13037{
13038 const char *section = ".dtors";
13039 char buf[16];
13040
13041 if (priority != DEFAULT_INIT_PRIORITY)
13042 {
13043 sprintf (buf, ".dtors.%.5u",
13044 /* Invert the numbering so the linker puts us in the proper
13045 order; constructors are run from right to left, and the
13046 linker sorts in increasing order. */
13047 MAX_INIT_PRIORITY - priority);
13048 section = buf;
13049 }
13050
715bdd29
RH
13051 named_section_flags (section, SECTION_WRITE);
13052 assemble_align (POINTER_SIZE);
d9f6800d
RH
13053
13054 if (TARGET_RELOCATABLE)
13055 {
13056 fputs ("\t.long (", asm_out_file);
13057 output_addr_const (asm_out_file, symbol);
13058 fputs (")@fixup\n", asm_out_file);
13059 }
13060 else
c8af3574 13061 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 13062}
7c262518
RH
13063#endif
13064
cbaaba19 13065#if TARGET_XCOFF
7c262518 13066static void
b275d088
DE
13067rs6000_xcoff_asm_globalize_label (stream, name)
13068 FILE *stream;
13069 const char *name;
13070{
13071 fputs (GLOBAL_ASM_OP, stream);
13072 RS6000_OUTPUT_BASENAME (stream, name);
13073 putc ('\n', stream);
13074}
13075
13076static void
13077rs6000_xcoff_asm_named_section (name, flags)
7c262518 13078 const char *name;
0e5dbd9b 13079 unsigned int flags;
7c262518 13080{
0e5dbd9b
DE
13081 int smclass;
13082 static const char * const suffix[3] = { "PR", "RO", "RW" };
13083
13084 if (flags & SECTION_CODE)
13085 smclass = 0;
13086 else if (flags & SECTION_WRITE)
13087 smclass = 2;
13088 else
13089 smclass = 1;
13090
5b5198f7 13091 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 13092 (flags & SECTION_CODE) ? "." : "",
5b5198f7 13093 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 13094}
ae46c4e0
RH
13095
13096static void
0e5dbd9b
DE
13097rs6000_xcoff_select_section (decl, reloc, align)
13098 tree decl;
ae46c4e0
RH
13099 int reloc;
13100 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13101{
5add3202 13102 if (decl_readonly_section_1 (decl, reloc, 1))
ae46c4e0 13103 {
0e5dbd9b 13104 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13105 read_only_data_section ();
13106 else
13107 read_only_private_data_section ();
13108 }
13109 else
13110 {
0e5dbd9b 13111 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13112 data_section ();
13113 else
13114 private_data_section ();
13115 }
13116}
13117
13118static void
13119rs6000_xcoff_unique_section (decl, reloc)
13120 tree decl;
772c5265 13121 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13122{
13123 const char *name;
ae46c4e0 13124
5b5198f7
DE
13125 /* Use select_section for private and uninitialized data. */
13126 if (!TREE_PUBLIC (decl)
13127 || DECL_COMMON (decl)
0e5dbd9b
DE
13128 || DECL_INITIAL (decl) == NULL_TREE
13129 || DECL_INITIAL (decl) == error_mark_node
13130 || (flag_zero_initialized_in_bss
13131 && initializer_zerop (DECL_INITIAL (decl))))
13132 return;
13133
13134 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13135 name = (*targetm.strip_name_encoding) (name);
13136 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 13137}
b64a1b53 13138
fb49053f
RH
13139/* Select section for constant in constant pool.
13140
13141 On RS/6000, all constants are in the private read-only data area.
13142 However, if this is being placed in the TOC it must be output as a
13143 toc entry. */
13144
b64a1b53
RH
13145static void
13146rs6000_xcoff_select_rtx_section (mode, x, align)
13147 enum machine_mode mode;
13148 rtx x;
13149 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13150{
13151 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13152 toc_section ();
13153 else
13154 read_only_private_data_section ();
13155}
772c5265
RH
13156
13157/* Remove any trailing [DS] or the like from the symbol name. */
13158
13159static const char *
13160rs6000_xcoff_strip_name_encoding (name)
13161 const char *name;
13162{
13163 size_t len;
13164 if (*name == '*')
13165 name++;
13166 len = strlen (name);
13167 if (name[len - 1] == ']')
13168 return ggc_alloc_string (name, len - 4);
13169 else
13170 return name;
13171}
13172
5add3202
DE
13173/* Section attributes. AIX is always PIC. */
13174
13175static unsigned int
13176rs6000_xcoff_section_type_flags (decl, name, reloc)
13177 tree decl;
13178 const char *name;
13179 int reloc;
13180{
5b5198f7
DE
13181 unsigned int align;
13182 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
13183
13184 /* Align to at least UNIT size. */
13185 if (flags & SECTION_CODE)
13186 align = MIN_UNITS_PER_WORD;
13187 else
13188 /* Increase alignment of large objects if not already stricter. */
13189 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
13190 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
13191 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
13192
13193 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202
DE
13194}
13195
cbaaba19 13196#endif /* TARGET_XCOFF */
fb49053f 13197
0e5dbd9b 13198/* Note that this is also used for PPC64 Linux. */
fb49053f
RH
13199
13200static void
13201rs6000_xcoff_encode_section_info (decl, first)
13202 tree decl;
13203 int first ATTRIBUTE_UNUSED;
13204{
13205 if (TREE_CODE (decl) == FUNCTION_DECL
b629ba0c 13206 && (*targetm.binds_local_p) (decl))
fb49053f
RH
13207 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13208}
0e5dbd9b
DE
13209
13210/* Cross-module name binding. For AIX and PPC64 Linux, which always are
13211 PIC, use private copy of flag_pic. */
13212
2bcc50d0 13213static bool
0e5dbd9b
DE
13214rs6000_binds_local_p (decl)
13215 tree decl;
13216{
5add3202 13217 return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
0e5dbd9b 13218}