]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
c-common.c (flag_objc): New.
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
CommitLineData
9878760c 1/* Subroutines used for code generation on IBM RS/6000.
9ebbca7d 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
95385cbb 3 2000, 2001, 2002 Free Software Foundation, Inc.
fab3bcc3 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
9878760c
RK
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
c15c9075
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
9878760c 22
956d6950 23#include "config.h"
c4d38ccb 24#include "system.h"
9878760c
RK
25#include "rtl.h"
26#include "regs.h"
27#include "hard-reg-set.h"
28#include "real.h"
29#include "insn-config.h"
30#include "conditions.h"
9878760c
RK
31#include "insn-attr.h"
32#include "flags.h"
33#include "recog.h"
9878760c 34#include "obstack.h"
9b30bae2 35#include "tree.h"
dfafc897 36#include "expr.h"
2fc1c679 37#include "optabs.h"
2a430ec1 38#include "except.h"
a7df97e6 39#include "function.h"
296b8152 40#include "output.h"
d5fa86ba 41#include "basic-block.h"
d0101753 42#include "integrate.h"
296b8152 43#include "toplev.h"
c8023011 44#include "ggc.h"
9ebbca7d
GK
45#include "hashtab.h"
46#include "tm_p.h"
672a6f42
NB
47#include "target.h"
48#include "target-def.h"
3ac88239 49#include "langhooks.h"
24ea750e 50#include "reload.h"
9b30bae2 51
7509c759
MM
52#ifndef TARGET_NO_PROTOTYPE
53#define TARGET_NO_PROTOTYPE 0
54#endif
55
9878760c
RK
56#define min(A,B) ((A) < (B) ? (A) : (B))
57#define max(A,B) ((A) > (B) ? (A) : (B))
58
5248c961
RK
59/* Target cpu type */
60
61enum processor_type rs6000_cpu;
8e3f41e7
MM
62struct rs6000_cpu_select rs6000_select[3] =
63{
815cdc52
MM
64 /* switch name, tune arch */
65 { (const char *)0, "--with-cpu=", 1, 1 },
66 { (const char *)0, "-mcpu=", 1, 1 },
67 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 68};
5248c961 69
6fa3f289
ZW
70/* Size of long double */
71const char *rs6000_long_double_size_string;
72int rs6000_long_double_type_size;
73
74/* Whether -mabi=altivec has appeared */
75int rs6000_altivec_abi;
76
08b57fb3
AH
77/* Whether VRSAVE instructions should be generated. */
78int rs6000_altivec_vrsave;
79
80/* String from -mvrsave= option. */
81const char *rs6000_altivec_vrsave_string;
82
a3170dc6
AH
83/* Nonzero if we want SPE ABI extensions. */
84int rs6000_spe_abi;
85
86/* Whether isel instructions should be generated. */
87int rs6000_isel;
88
89/* Nonzero if we have FPRs. */
90int rs6000_fprs = 1;
91
92/* String from -misel=. */
93const char *rs6000_isel_string;
94
c764f757
RK
95/* Set to non-zero once AIX common-mode calls have been defined. */
96static int common_mode_defined;
c81bebd7 97
9878760c
RK
98/* Save information from a "cmpxx" operation until the branch or scc is
99 emitted. */
9878760c
RK
100rtx rs6000_compare_op0, rs6000_compare_op1;
101int rs6000_compare_fp_p;
874a0744 102
874a0744
MM
103/* Label number of label created for -mrelocatable, to call to so we can
104 get the address of the GOT section */
105int rs6000_pic_labelno;
c81bebd7 106
b91da81f 107#ifdef USING_ELFOS_H
c81bebd7 108/* Which abi to adhere to */
815cdc52 109const char *rs6000_abi_name = RS6000_ABI_NAME;
d9407988
MM
110
111/* Semantics of the small data area */
112enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
113
114/* Which small data model to use */
815cdc52 115const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
116
117/* Counter for labels which are to be placed in .fixup. */
118int fixuplabelno = 0;
874a0744 119#endif
4697a36c 120
b6c9286a
MM
121/* ABI enumeration available for subtarget to use. */
122enum rs6000_abi rs6000_current_abi;
123
0ac081f6
AH
124/* ABI string from -mabi= option. */
125const char *rs6000_abi_string;
126
38c1f2d7 127/* Debug flags */
815cdc52 128const char *rs6000_debug_name;
38c1f2d7
MM
129int rs6000_debug_stack; /* debug stack applications */
130int rs6000_debug_arg; /* debug argument handling */
131
57ac7be9
AM
132const char *rs6000_traceback_name;
133static enum {
134 traceback_default = 0,
135 traceback_none,
136 traceback_part,
137 traceback_full
138} rs6000_traceback;
139
38c1f2d7
MM
140/* Flag to say the TOC is initialized */
141int toc_initialized;
9ebbca7d 142char toc_label_name[10];
38c1f2d7 143
9ebbca7d
GK
144/* Alias set for saves and restores from the rs6000 stack. */
145static int rs6000_sr_alias_set;
c8023011 146
a5c76ee6
ZW
147/* Call distance, overridden by -mlongcall and #pragma longcall(1).
148 The only place that looks at this is rs6000_set_default_type_attributes;
149 everywhere else should rely on the presence or absence of a longcall
150 attribute on the function declaration. */
151int rs6000_default_long_calls;
152const char *rs6000_longcall_switch;
153
a3170dc6
AH
154struct builtin_description
155{
156 /* mask is not const because we're going to alter it below. This
157 nonsense will go away when we rewrite the -march infrastructure
158 to give us more target flag bits. */
159 unsigned int mask;
160 const enum insn_code icode;
161 const char *const name;
162 const enum rs6000_builtins code;
163};
164
9ebbca7d
GK
165static void rs6000_add_gc_roots PARAMS ((void));
166static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
167static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx));
39a10a29
GK
168static void validate_condition_mode
169 PARAMS ((enum rtx_code, enum machine_mode));
170static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
e50f5f3d 171static void rs6000_maybe_dead PARAMS ((rtx));
9ebbca7d
GK
172static void rs6000_emit_stack_tie PARAMS ((void));
173static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
89e7058f
AH
174static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
175 unsigned int, int, int));
a3170dc6 176static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
9ebbca7d
GK
177static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
178static unsigned rs6000_hash_constant PARAMS ((rtx));
179static unsigned toc_hash_function PARAMS ((const void *));
180static int toc_hash_eq PARAMS ((const void *, const void *));
2eba1afa 181static int toc_hash_mark_entry PARAMS ((void **, void *));
9ebbca7d
GK
182static void toc_hash_mark_table PARAMS ((void *));
183static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
e2500fed 184static struct machine_function * rs6000_init_machine_status PARAMS ((void));
301d03af 185static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
71f123ca 186static int rs6000_ra_ever_killed PARAMS ((void));
91d231cb
JM
187static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
188const struct attribute_spec rs6000_attribute_table[];
a5c76ee6 189static void rs6000_set_default_type_attributes PARAMS ((tree));
08c148a8
NB
190static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
191static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
2bfcf297
DB
192static rtx rs6000_emit_set_long_const PARAMS ((rtx,
193 HOST_WIDE_INT, HOST_WIDE_INT));
7c262518
RH
194#if TARGET_ELF
195static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
196 int));
d9f6800d
RH
197static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
198static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
ae46c4e0
RH
199static void rs6000_elf_select_section PARAMS ((tree, int,
200 unsigned HOST_WIDE_INT));
201static void rs6000_elf_unique_section PARAMS ((tree, int));
b64a1b53
RH
202static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
203 unsigned HOST_WIDE_INT));
fb49053f 204static void rs6000_elf_encode_section_info PARAMS ((tree, int));
772c5265 205static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
7c262518 206#endif
cbaaba19 207#if TARGET_XCOFF
715bdd29 208static void xcoff_asm_named_section PARAMS ((const char *, unsigned int));
ae46c4e0
RH
209static void rs6000_xcoff_select_section PARAMS ((tree, int,
210 unsigned HOST_WIDE_INT));
211static void rs6000_xcoff_unique_section PARAMS ((tree, int));
b64a1b53
RH
212static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
213 unsigned HOST_WIDE_INT));
772c5265 214static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
7c262518 215#endif
fb49053f
RH
216static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
217 ATTRIBUTE_UNUSED;
c237e94a
ZW
218static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
219static int rs6000_adjust_priority PARAMS ((rtx, int));
220static int rs6000_issue_rate PARAMS ((void));
221
6fa3f289 222static void rs6000_init_builtins PARAMS ((void));
92898235
AH
223static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
224static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
225static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 226static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
92898235 227static void altivec_init_builtins PARAMS ((void));
a3170dc6
AH
228static void rs6000_common_init_builtins PARAMS ((void));
229
230static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
231 int, enum rs6000_builtins,
232 enum rs6000_builtins));
233static void spe_init_builtins PARAMS ((void));
234static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
235static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
236static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
237static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
238
92898235 239static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
3a9b8c7e
AH
240static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
241static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
242static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
100c4561 243static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 244static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
6525c0e7 245static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 246static void rs6000_parse_abi_options PARAMS ((void));
08b57fb3 247static void rs6000_parse_vrsave_option PARAMS ((void));
a3170dc6 248static void rs6000_parse_isel_option PARAMS ((void));
00b960c7
AH
249static int first_altivec_reg_to_save PARAMS ((void));
250static unsigned int compute_vrsave_mask PARAMS ((void));
251static void is_altivec_return_reg PARAMS ((rtx, void *));
9aa86737
AH
252static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
253static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
69ef87e2 254static int easy_vector_constant PARAMS ((rtx));
c81bebd7
MM
255\f
256/* Default register names. */
257char rs6000_reg_names[][8] =
258{
802a0058
MM
259 "0", "1", "2", "3", "4", "5", "6", "7",
260 "8", "9", "10", "11", "12", "13", "14", "15",
261 "16", "17", "18", "19", "20", "21", "22", "23",
262 "24", "25", "26", "27", "28", "29", "30", "31",
263 "0", "1", "2", "3", "4", "5", "6", "7",
264 "8", "9", "10", "11", "12", "13", "14", "15",
265 "16", "17", "18", "19", "20", "21", "22", "23",
266 "24", "25", "26", "27", "28", "29", "30", "31",
267 "mq", "lr", "ctr","ap",
268 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
269 "xer",
270 /* AltiVec registers. */
0cd5e3a1
AH
271 "0", "1", "2", "3", "4", "5", "6", "7",
272 "8", "9", "10", "11", "12", "13", "14", "15",
273 "16", "17", "18", "19", "20", "21", "22", "23",
274 "24", "25", "26", "27", "28", "29", "30", "31",
0ac081f6 275 "vrsave"
c81bebd7
MM
276};
277
278#ifdef TARGET_REGNAMES
8b60264b 279static const char alt_reg_names[][8] =
c81bebd7 280{
802a0058
MM
281 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
282 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
283 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
284 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
285 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
286 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
287 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
288 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
289 "mq", "lr", "ctr", "ap",
290 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6
AH
291 "xer",
292 /* AltiVec registers. */
293 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
294 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
295 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
296 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
76a773f3 297 "vrsave"
c81bebd7
MM
298};
299#endif
9878760c 300\f
daf11973
MM
301#ifndef MASK_STRICT_ALIGN
302#define MASK_STRICT_ALIGN 0
303#endif
672a6f42
NB
304\f
305/* Initialize the GCC target structure. */
91d231cb
JM
306#undef TARGET_ATTRIBUTE_TABLE
307#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
308#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
309#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 310
301d03af
RS
311#undef TARGET_ASM_ALIGNED_DI_OP
312#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
313
314/* Default unaligned ops are only provided for ELF. Find the ops needed
315 for non-ELF systems. */
316#ifndef OBJECT_FORMAT_ELF
cbaaba19 317#if TARGET_XCOFF
ae6c1efd 318/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
319 64-bit targets. */
320#undef TARGET_ASM_UNALIGNED_HI_OP
321#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
322#undef TARGET_ASM_UNALIGNED_SI_OP
323#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
324#undef TARGET_ASM_UNALIGNED_DI_OP
325#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
326#else
327/* For Darwin. */
328#undef TARGET_ASM_UNALIGNED_HI_OP
329#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
330#undef TARGET_ASM_UNALIGNED_SI_OP
331#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
332#endif
333#endif
334
335/* This hook deals with fixups for relocatable code and DI-mode objects
336 in 64-bit code. */
337#undef TARGET_ASM_INTEGER
338#define TARGET_ASM_INTEGER rs6000_assemble_integer
339
08c148a8
NB
340#undef TARGET_ASM_FUNCTION_PROLOGUE
341#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
342#undef TARGET_ASM_FUNCTION_EPILOGUE
343#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
344
7c262518
RH
345#if TARGET_ELF
346#undef TARGET_SECTION_TYPE_FLAGS
347#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
348#endif
349
c237e94a
ZW
350#undef TARGET_SCHED_ISSUE_RATE
351#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
352#undef TARGET_SCHED_ADJUST_COST
353#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
354#undef TARGET_SCHED_ADJUST_PRIORITY
355#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
356
0ac081f6
AH
357#undef TARGET_INIT_BUILTINS
358#define TARGET_INIT_BUILTINS rs6000_init_builtins
359
360#undef TARGET_EXPAND_BUILTIN
361#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
362
00b960c7
AH
363/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
364#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
365
f6897b10 366struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 367\f
5248c961
RK
368/* Override command line options. Mostly we process the processor
369 type and sometimes adjust other TARGET_ options. */
370
371void
8e3f41e7 372rs6000_override_options (default_cpu)
d330fd93 373 const char *default_cpu;
5248c961 374{
c4d38ccb 375 size_t i, j;
8e3f41e7 376 struct rs6000_cpu_select *ptr;
5248c961 377
85638c0d
RK
378 /* Simplify the entries below by making a mask for any POWER
379 variant and any PowerPC variant. */
380
938937d8 381#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
382#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
383 | MASK_PPC_GFXOPT | MASK_POWERPC64)
384#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 385
5248c961
RK
386 static struct ptt
387 {
8b60264b
KG
388 const char *const name; /* Canonical processor name. */
389 const enum processor_type processor; /* Processor type enum value. */
390 const int target_enable; /* Target flags to enable. */
391 const int target_disable; /* Target flags to disable. */
392 } const processor_target_table[]
cf27b467
MM
393 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
394 POWER_MASKS | POWERPC_MASKS},
db7f1e43 395 {"power", PROCESSOR_POWER,
938937d8 396 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 397 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
398 {"power2", PROCESSOR_POWER,
399 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
400 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
401 {"power3", PROCESSOR_PPC630,
402 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
403 POWER_MASKS | MASK_PPC_GPOPT},
309323c2
DE
404 {"power4", PROCESSOR_POWER4,
405 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
406 POWER_MASKS | MASK_PPC_GPOPT},
db7f1e43
RK
407 {"powerpc", PROCESSOR_POWERPC,
408 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 409 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
410 {"powerpc64", PROCESSOR_POWERPC64,
411 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
412 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 413 {"rios", PROCESSOR_RIOS1,
938937d8 414 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
415 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
416 {"rios1", PROCESSOR_RIOS1,
938937d8 417 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
418 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
419 {"rsc", PROCESSOR_PPC601,
938937d8 420 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
421 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
422 {"rsc1", PROCESSOR_PPC601,
938937d8 423 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
424 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
425 {"rios2", PROCESSOR_RIOS2,
938937d8 426 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 427 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
428 {"rs64a", PROCESSOR_RS64A,
429 MASK_POWERPC | MASK_NEW_MNEMONICS,
430 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
431 {"401", PROCESSOR_PPC403,
432 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
433 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 434 {"403", PROCESSOR_PPC403,
daf11973 435 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 436 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
437 {"405", PROCESSOR_PPC405,
438 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
439 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
440 {"505", PROCESSOR_MPCCORE,
441 MASK_POWERPC | MASK_NEW_MNEMONICS,
442 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 443 {"601", PROCESSOR_PPC601,
938937d8 444 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 445 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 446 {"602", PROCESSOR_PPC603,
cf27b467
MM
447 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
448 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 449 {"603", PROCESSOR_PPC603,
68c49ffa
RK
450 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
451 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
452 {"603e", PROCESSOR_PPC603,
453 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
454 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 455 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
456 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
457 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 458 {"604", PROCESSOR_PPC604,
b6c9286a
MM
459 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
460 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 461 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
462 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
463 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 464 {"620", PROCESSOR_PPC620,
68c49ffa 465 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
a260abc9 466 POWER_MASKS | MASK_PPC_GPOPT},
3cb999d8
DE
467 {"630", PROCESSOR_PPC630,
468 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
469 POWER_MASKS | MASK_PPC_GPOPT},
bef84347
VM
470 {"740", PROCESSOR_PPC750,
471 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
472 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
473 {"750", PROCESSOR_PPC750,
474 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
475 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
476 {"7400", PROCESSOR_PPC7400,
477 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
478 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
479 {"7450", PROCESSOR_PPC7450,
480 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
481 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a3170dc6
AH
482 {"8540", PROCESSOR_PPC8540,
483 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
484 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
485 {"801", PROCESSOR_MPCCORE,
486 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
487 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
488 {"821", PROCESSOR_MPCCORE,
489 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
490 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
491 {"823", PROCESSOR_MPCCORE,
492 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
493 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
494 {"860", PROCESSOR_MPCCORE,
495 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
496 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 497
ca7558fc 498 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 499
a4f6c312
SS
500 /* Save current -mmultiple/-mno-multiple status. */
501 int multiple = TARGET_MULTIPLE;
502 /* Save current -mstring/-mno-string status. */
503 int string = TARGET_STRING;
8a61d227 504
a4f6c312 505 /* Identify the processor type. */
8e3f41e7 506 rs6000_select[0].string = default_cpu;
3cb999d8 507 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 508
b6a1cbae 509 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 510 {
8e3f41e7
MM
511 ptr = &rs6000_select[i];
512 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 513 {
8e3f41e7
MM
514 for (j = 0; j < ptt_size; j++)
515 if (! strcmp (ptr->string, processor_target_table[j].name))
516 {
517 if (ptr->set_tune_p)
518 rs6000_cpu = processor_target_table[j].processor;
519
520 if (ptr->set_arch_p)
521 {
522 target_flags |= processor_target_table[j].target_enable;
523 target_flags &= ~processor_target_table[j].target_disable;
524 }
525 break;
526 }
527
4406229e 528 if (j == ptt_size)
8e3f41e7 529 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
530 }
531 }
8a61d227 532
a3170dc6
AH
533 if (rs6000_cpu == PROCESSOR_PPC8540)
534 rs6000_isel = 1;
535
a4f6c312
SS
536 /* If we are optimizing big endian systems for space, use the store
537 multiple instructions. */
ef792183
MM
538 if (BYTES_BIG_ENDIAN && optimize_size)
539 target_flags |= MASK_MULTIPLE;
540
8a61d227
MM
541 /* If -mmultiple or -mno-multiple was explicitly used, don't
542 override with the processor default */
543 if (TARGET_MULTIPLE_SET)
544 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 545
a4f6c312
SS
546 /* If -mstring or -mno-string was explicitly used, don't override
547 with the processor default. */
938937d8 548 if (TARGET_STRING_SET)
1f5515bf 549 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 550
a4f6c312
SS
551 /* Don't allow -mmultiple or -mstring on little endian systems
552 unless the cpu is a 750, because the hardware doesn't support the
553 instructions used in little endian mode, and causes an alignment
554 trap. The 750 does not cause an alignment trap (except when the
555 target is unaligned). */
bef84347 556
bfc79d3b 557 if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
558 {
559 if (TARGET_MULTIPLE)
560 {
561 target_flags &= ~MASK_MULTIPLE;
562 if (TARGET_MULTIPLE_SET)
563 warning ("-mmultiple is not supported on little endian systems");
564 }
565
566 if (TARGET_STRING)
567 {
568 target_flags &= ~MASK_STRING;
938937d8
MM
569 if (TARGET_STRING_SET)
570 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
571 }
572 }
3933e0e1 573
ee2ca2a2 574 if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
a260abc9 575 {
ee2ca2a2
DE
576 flag_pic = 0;
577
894bdff6
AM
578 if (extra_warnings)
579 warning ("-f%s ignored (all code is position independent)",
580 (flag_pic > 1) ? "PIC" : "pic");
a260abc9
DE
581 }
582
2bfcf297 583#ifdef XCOFF_DEBUGGING_INFO
9861b0c9 584 if (flag_function_sections && (write_symbols != NO_DEBUG)
2bfcf297 585 && DEFAULT_ABI == ABI_AIX)
9861b0c9
DE
586 {
587 warning ("-ffunction-sections disabled on AIX when debugging");
588 flag_function_sections = 0;
589 }
590
591 if (flag_data_sections && (DEFAULT_ABI == ABI_AIX))
592 {
593 warning ("-fdata-sections not supported on AIX");
594 flag_data_sections = 0;
595 }
2bfcf297 596#endif
9861b0c9 597
38c1f2d7
MM
598 /* Set debug flags */
599 if (rs6000_debug_name)
600 {
bfc79d3b 601 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 602 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 603 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 604 rs6000_debug_stack = 1;
bfc79d3b 605 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
606 rs6000_debug_arg = 1;
607 else
c725bd79 608 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
609 }
610
57ac7be9
AM
611 if (rs6000_traceback_name)
612 {
613 if (! strncmp (rs6000_traceback_name, "full", 4))
614 rs6000_traceback = traceback_full;
615 else if (! strncmp (rs6000_traceback_name, "part", 4))
616 rs6000_traceback = traceback_part;
617 else if (! strncmp (rs6000_traceback_name, "no", 2))
618 rs6000_traceback = traceback_none;
619 else
620 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
621 rs6000_traceback_name);
622 }
623
6fa3f289
ZW
624 /* Set size of long double */
625 rs6000_long_double_type_size = 64;
626 if (rs6000_long_double_size_string)
627 {
628 char *tail;
629 int size = strtol (rs6000_long_double_size_string, &tail, 10);
630 if (*tail != '\0' || (size != 64 && size != 128))
631 error ("Unknown switch -mlong-double-%s",
632 rs6000_long_double_size_string);
633 else
634 rs6000_long_double_type_size = size;
635 }
636
0ac081f6
AH
637 /* Handle -mabi= options. */
638 rs6000_parse_abi_options ();
639
08b57fb3
AH
640 /* Handle -mvrsave= option. */
641 rs6000_parse_vrsave_option ();
642
a3170dc6
AH
643 /* Handle -misel= option. */
644 rs6000_parse_isel_option ();
645
a7ae18e2
AH
646#ifdef SUBTARGET_OVERRIDE_OPTIONS
647 SUBTARGET_OVERRIDE_OPTIONS;
648#endif
649#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
650 SUBSUBTARGET_OVERRIDE_OPTIONS;
651#endif
652
a5c76ee6
ZW
653 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
654 using TARGET_OPTIONS to handle a toggle switch, but we're out of
655 bits in target_flags so TARGET_SWITCHES cannot be used.
656 Assumption here is that rs6000_longcall_switch points into the
657 text of the complete option, rather than being a copy, so we can
658 scan back for the presence or absence of the no- modifier. */
659 if (rs6000_longcall_switch)
660 {
661 const char *base = rs6000_longcall_switch;
662 while (base[-1] != 'm') base--;
663
664 if (*rs6000_longcall_switch != '\0')
665 error ("invalid option `%s'", base);
666 rs6000_default_long_calls = (base[0] != 'n');
667 }
668
c81bebd7 669#ifdef TARGET_REGNAMES
a4f6c312
SS
670 /* If the user desires alternate register names, copy in the
671 alternate names now. */
c81bebd7 672 if (TARGET_REGNAMES)
4e135bdd 673 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
674#endif
675
6fa3f289
ZW
676 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
677 If -maix-struct-return or -msvr4-struct-return was explicitly
678 used, don't override with the ABI default. */
679 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
680 {
681 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
682 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
683 else
684 target_flags |= MASK_AIX_STRUCT_RET;
685 }
686
c8023011
MM
687 /* Register global variables with the garbage collector. */
688 rs6000_add_gc_roots ();
9ebbca7d
GK
689
690 /* Allocate an alias set for register saves & restores from stack. */
691 rs6000_sr_alias_set = new_alias_set ();
692
693 if (TARGET_TOC)
694 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 695
301d03af
RS
696 /* We can only guarantee the availability of DI pseudo-ops when
697 assembling for 64-bit targets. */
ae6c1efd 698 if (!TARGET_64BIT)
301d03af
RS
699 {
700 targetm.asm_out.aligned_op.di = NULL;
701 targetm.asm_out.unaligned_op.di = NULL;
702 }
703
71f123ca
FS
704 /* Arrange to save and restore machine status around nested functions. */
705 init_machine_status = rs6000_init_machine_status;
5248c961 706}
5accd822 707
a3170dc6
AH
708/* Handle -misel= option. */
709static void
710rs6000_parse_isel_option ()
711{
712 if (rs6000_isel_string == 0)
713 return;
714 else if (! strcmp (rs6000_isel_string, "yes"))
715 rs6000_isel = 1;
716 else if (! strcmp (rs6000_isel_string, "no"))
717 rs6000_isel = 0;
718 else
719 error ("unknown -misel= option specified: '%s'",
720 rs6000_isel_string);
721}
722
08b57fb3
AH
723/* Handle -mvrsave= options. */
724static void
725rs6000_parse_vrsave_option ()
726{
727 /* Generate VRSAVE instructions by default. */
728 if (rs6000_altivec_vrsave_string == 0
729 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
730 rs6000_altivec_vrsave = 1;
731 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
732 rs6000_altivec_vrsave = 0;
733 else
734 error ("unknown -mvrsave= option specified: '%s'",
735 rs6000_altivec_vrsave_string);
736}
737
0ac081f6 738/* Handle -mabi= options. */
00b960c7
AH
739static void
740rs6000_parse_abi_options ()
0ac081f6
AH
741{
742 if (rs6000_abi_string == 0)
743 return;
744 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 745 rs6000_altivec_abi = 1;
76a773f3
AH
746 else if (! strcmp (rs6000_abi_string, "no-altivec"))
747 rs6000_altivec_abi = 0;
a3170dc6
AH
748 else if (! strcmp (rs6000_abi_string, "spe"))
749 rs6000_spe_abi = 1;
750 else if (! strcmp (rs6000_abi_string, "no-spe"))
751 rs6000_spe_abi = 0;
0ac081f6 752 else
c725bd79 753 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
754}
755
5accd822
DE
756void
757optimization_options (level, size)
e2c953b6 758 int level ATTRIBUTE_UNUSED;
5accd822
DE
759 int size ATTRIBUTE_UNUSED;
760{
5accd822 761}
3cfa4909
MM
762\f
763/* Do anything needed at the start of the asm file. */
764
765void
766rs6000_file_start (file, default_cpu)
767 FILE *file;
d330fd93 768 const char *default_cpu;
3cfa4909 769{
c4d38ccb 770 size_t i;
3cfa4909 771 char buffer[80];
d330fd93 772 const char *start = buffer;
3cfa4909
MM
773 struct rs6000_cpu_select *ptr;
774
775 if (flag_verbose_asm)
776 {
777 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
778 rs6000_select[0].string = default_cpu;
779
b6a1cbae 780 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
781 {
782 ptr = &rs6000_select[i];
783 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
784 {
785 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
786 start = "";
787 }
788 }
789
b91da81f 790#ifdef USING_ELFOS_H
3cfa4909
MM
791 switch (rs6000_sdata)
792 {
793 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
794 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
795 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
796 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
797 }
798
799 if (rs6000_sdata && g_switch_value)
800 {
801 fprintf (file, "%s -G %d", start, g_switch_value);
802 start = "";
803 }
804#endif
805
806 if (*start == '\0')
949ea356 807 putc ('\n', file);
3cfa4909
MM
808 }
809}
5248c961 810\f
9878760c
RK
811/* Return non-zero if this function is known to have a null epilogue. */
812
813int
814direct_return ()
815{
4697a36c
MM
816 if (reload_completed)
817 {
818 rs6000_stack_t *info = rs6000_stack_info ();
819
820 if (info->first_gp_reg_save == 32
821 && info->first_fp_reg_save == 64
00b960c7 822 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
823 && ! info->lr_save_p
824 && ! info->cr_save_p
00b960c7 825 && info->vrsave_mask == 0
c81fc13e 826 && ! info->push_p)
4697a36c
MM
827 return 1;
828 }
829
830 return 0;
9878760c
RK
831}
832
833/* Returns 1 always. */
834
835int
836any_operand (op, mode)
592696dd 837 rtx op ATTRIBUTE_UNUSED;
296b8152 838 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
839{
840 return 1;
841}
842
a4f6c312 843/* Returns 1 if op is the count register. */
38c1f2d7 844int
a4f6c312 845count_register_operand (op, mode)
592696dd 846 rtx op;
296b8152 847 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
848{
849 if (GET_CODE (op) != REG)
850 return 0;
851
852 if (REGNO (op) == COUNT_REGISTER_REGNUM)
853 return 1;
854
855 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
856 return 1;
857
858 return 0;
859}
860
0ec4e2a8
AH
861/* Returns 1 if op is an altivec register. */
862int
863altivec_register_operand (op, mode)
864 rtx op;
865 enum machine_mode mode ATTRIBUTE_UNUSED;
866{
867
868 return (register_operand (op, mode)
869 && (GET_CODE (op) != REG
870 || REGNO (op) > FIRST_PSEUDO_REGISTER
871 || ALTIVEC_REGNO_P (REGNO (op))));
872}
873
38c1f2d7 874int
a4f6c312 875xer_operand (op, mode)
592696dd 876 rtx op;
296b8152 877 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
878{
879 if (GET_CODE (op) != REG)
880 return 0;
881
9ebbca7d 882 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
883 return 1;
884
802a0058
MM
885 return 0;
886}
887
c859cda6 888/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 889 by such constants completes more quickly. */
c859cda6
DJ
890
891int
892s8bit_cint_operand (op, mode)
893 rtx op;
894 enum machine_mode mode ATTRIBUTE_UNUSED;
895{
896 return ( GET_CODE (op) == CONST_INT
897 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
898}
899
9878760c
RK
900/* Return 1 if OP is a constant that can fit in a D field. */
901
902int
903short_cint_operand (op, mode)
592696dd 904 rtx op;
296b8152 905 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 906{
5f59ecb7
DE
907 return (GET_CODE (op) == CONST_INT
908 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
909}
910
5519a4f9 911/* Similar for an unsigned D field. */
9878760c
RK
912
913int
914u_short_cint_operand (op, mode)
592696dd 915 rtx op;
296b8152 916 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 917{
19684119 918 return (GET_CODE (op) == CONST_INT
c1f11548 919 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
920}
921
dcfedcd0
RK
922/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
923
924int
925non_short_cint_operand (op, mode)
592696dd 926 rtx op;
296b8152 927 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
928{
929 return (GET_CODE (op) == CONST_INT
a7653a2c 930 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
931}
932
2bfcf297
DB
933/* Returns 1 if OP is a CONST_INT that is a positive value
934 and an exact power of 2. */
935
936int
937exact_log2_cint_operand (op, mode)
592696dd 938 rtx op;
2bfcf297
DB
939 enum machine_mode mode ATTRIBUTE_UNUSED;
940{
941 return (GET_CODE (op) == CONST_INT
942 && INTVAL (op) > 0
943 && exact_log2 (INTVAL (op)) >= 0);
944}
945
9878760c
RK
946/* Returns 1 if OP is a register that is not special (i.e., not MQ,
947 ctr, or lr). */
948
949int
cd2b37d9 950gpc_reg_operand (op, mode)
592696dd 951 rtx op;
9878760c
RK
952 enum machine_mode mode;
953{
954 return (register_operand (op, mode)
802a0058 955 && (GET_CODE (op) != REG
9ebbca7d
GK
956 || (REGNO (op) >= ARG_POINTER_REGNUM
957 && !XER_REGNO_P (REGNO (op)))
958 || REGNO (op) < MQ_REGNO));
9878760c
RK
959}
960
961/* Returns 1 if OP is either a pseudo-register or a register denoting a
962 CR field. */
963
964int
965cc_reg_operand (op, mode)
592696dd 966 rtx op;
9878760c
RK
967 enum machine_mode mode;
968{
969 return (register_operand (op, mode)
970 && (GET_CODE (op) != REG
971 || REGNO (op) >= FIRST_PSEUDO_REGISTER
972 || CR_REGNO_P (REGNO (op))));
973}
974
815cdc52
MM
975/* Returns 1 if OP is either a pseudo-register or a register denoting a
976 CR field that isn't CR0. */
977
978int
979cc_reg_not_cr0_operand (op, mode)
592696dd 980 rtx op;
815cdc52
MM
981 enum machine_mode mode;
982{
983 return (register_operand (op, mode)
984 && (GET_CODE (op) != REG
985 || REGNO (op) >= FIRST_PSEUDO_REGISTER
986 || CR_REGNO_NOT_CR0_P (REGNO (op))));
987}
988
a4f6c312
SS
989/* Returns 1 if OP is either a constant integer valid for a D-field or
990 a non-special register. If a register, it must be in the proper
991 mode unless MODE is VOIDmode. */
9878760c
RK
992
993int
994reg_or_short_operand (op, mode)
592696dd 995 rtx op;
9878760c
RK
996 enum machine_mode mode;
997{
f5a28898 998 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
999}
1000
a4f6c312
SS
1001/* Similar, except check if the negation of the constant would be
1002 valid for a D-field. */
9878760c
RK
1003
1004int
1005reg_or_neg_short_operand (op, mode)
592696dd 1006 rtx op;
9878760c
RK
1007 enum machine_mode mode;
1008{
1009 if (GET_CODE (op) == CONST_INT)
1010 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1011
cd2b37d9 1012 return gpc_reg_operand (op, mode);
9878760c
RK
1013}
1014
768070a0
TR
1015/* Returns 1 if OP is either a constant integer valid for a DS-field or
1016 a non-special register. If a register, it must be in the proper
1017 mode unless MODE is VOIDmode. */
1018
1019int
1020reg_or_aligned_short_operand (op, mode)
1021 rtx op;
1022 enum machine_mode mode;
1023{
1024 if (gpc_reg_operand (op, mode))
1025 return 1;
1026 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1027 return 1;
1028
1029 return 0;
1030}
1031
1032
a4f6c312
SS
1033/* Return 1 if the operand is either a register or an integer whose
1034 high-order 16 bits are zero. */
9878760c
RK
1035
1036int
1037reg_or_u_short_operand (op, mode)
592696dd 1038 rtx op;
9878760c
RK
1039 enum machine_mode mode;
1040{
e675f625 1041 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1042}
1043
1044/* Return 1 is the operand is either a non-special register or ANY
1045 constant integer. */
1046
1047int
1048reg_or_cint_operand (op, mode)
592696dd 1049 rtx op;
9878760c
RK
1050 enum machine_mode mode;
1051{
a4f6c312 1052 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1053}
1054
1055/* Return 1 is the operand is either a non-special register or ANY
1056 32-bit signed constant integer. */
1057
1058int
1059reg_or_arith_cint_operand (op, mode)
592696dd 1060 rtx op;
f6bf7de2
DE
1061 enum machine_mode mode;
1062{
a4f6c312
SS
1063 return (gpc_reg_operand (op, mode)
1064 || (GET_CODE (op) == CONST_INT
f6bf7de2 1065#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1066 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1067 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1068#endif
a4f6c312 1069 ));
9878760c
RK
1070}
1071
2bfcf297
DB
1072/* Return 1 is the operand is either a non-special register or a 32-bit
1073 signed constant integer valid for 64-bit addition. */
1074
1075int
1076reg_or_add_cint64_operand (op, mode)
592696dd 1077 rtx op;
2bfcf297
DB
1078 enum machine_mode mode;
1079{
a4f6c312
SS
1080 return (gpc_reg_operand (op, mode)
1081 || (GET_CODE (op) == CONST_INT
a65c591c 1082#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1083 && INTVAL (op) < 0x7fff8000
a65c591c 1084#else
a4f6c312
SS
1085 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1086 < 0x100000000ll)
2bfcf297 1087#endif
a4f6c312 1088 ));
2bfcf297
DB
1089}
1090
1091/* Return 1 is the operand is either a non-special register or a 32-bit
1092 signed constant integer valid for 64-bit subtraction. */
1093
1094int
1095reg_or_sub_cint64_operand (op, mode)
592696dd 1096 rtx op;
2bfcf297
DB
1097 enum machine_mode mode;
1098{
a4f6c312
SS
1099 return (gpc_reg_operand (op, mode)
1100 || (GET_CODE (op) == CONST_INT
a65c591c 1101#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1102 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1103#else
a4f6c312
SS
1104 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1105 < 0x100000000ll)
2bfcf297 1106#endif
a4f6c312 1107 ));
2bfcf297
DB
1108}
1109
9ebbca7d
GK
1110/* Return 1 is the operand is either a non-special register or ANY
1111 32-bit unsigned constant integer. */
1112
1113int
1d328b19 1114reg_or_logical_cint_operand (op, mode)
592696dd 1115 rtx op;
9ebbca7d
GK
1116 enum machine_mode mode;
1117{
1d328b19
GK
1118 if (GET_CODE (op) == CONST_INT)
1119 {
1120 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1121 {
1122 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1123 abort ();
1d328b19
GK
1124
1125 if (INTVAL (op) < 0)
1126 return 0;
1127 }
1128
1129 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1130 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1131 }
1132 else if (GET_CODE (op) == CONST_DOUBLE)
1133 {
1134 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1135 || mode != DImode)
a4f6c312 1136 abort ();
1d328b19
GK
1137
1138 return CONST_DOUBLE_HIGH (op) == 0;
1139 }
1140 else
1141 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1142}
1143
51d3e7d6 1144/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1145
1146int
1147got_operand (op, mode)
592696dd 1148 rtx op;
296b8152 1149 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1150{
1151 return (GET_CODE (op) == SYMBOL_REF
1152 || GET_CODE (op) == CONST
1153 || GET_CODE (op) == LABEL_REF);
1154}
1155
38c1f2d7
MM
1156/* Return 1 if the operand is a simple references that can be loaded via
1157 the GOT (labels involving addition aren't allowed). */
1158
1159int
1160got_no_const_operand (op, mode)
592696dd 1161 rtx op;
296b8152 1162 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1163{
1164 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1165}
1166
4e74d8ec
MM
1167/* Return the number of instructions it takes to form a constant in an
1168 integer register. */
1169
1170static int
1171num_insns_constant_wide (value)
1172 HOST_WIDE_INT value;
1173{
1174 /* signed constant loadable with {cal|addi} */
5f59ecb7 1175 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1176 return 1;
1177
4e74d8ec 1178 /* constant loadable with {cau|addis} */
5f59ecb7 1179 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1180 return 1;
1181
5f59ecb7 1182#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1183 else if (TARGET_POWERPC64)
4e74d8ec 1184 {
a65c591c
DE
1185 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1186 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1187
a65c591c 1188 if (high == 0 || high == -1)
4e74d8ec
MM
1189 return 2;
1190
a65c591c 1191 high >>= 1;
4e74d8ec 1192
a65c591c 1193 if (low == 0)
4e74d8ec 1194 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1195 else
1196 return (num_insns_constant_wide (high)
e396202a 1197 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1198 }
1199#endif
1200
1201 else
1202 return 2;
1203}
1204
1205int
1206num_insns_constant (op, mode)
1207 rtx op;
1208 enum machine_mode mode;
1209{
4e74d8ec 1210 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1211 {
1212#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1213 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1214 && mask64_operand (op, mode))
0d30d435
DE
1215 return 2;
1216 else
1217#endif
1218 return num_insns_constant_wide (INTVAL (op));
1219 }
4e74d8ec 1220
6fc48950
MM
1221 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1222 {
1223 long l;
1224 REAL_VALUE_TYPE rv;
1225
1226 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1227 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1228 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1229 }
1230
47ad8c61 1231 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1232 {
47ad8c61
MM
1233 HOST_WIDE_INT low;
1234 HOST_WIDE_INT high;
1235 long l[2];
1236 REAL_VALUE_TYPE rv;
1237 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1238
47ad8c61
MM
1239 if (mode == VOIDmode || mode == DImode)
1240 {
1241 high = CONST_DOUBLE_HIGH (op);
1242 low = CONST_DOUBLE_LOW (op);
1243 }
1244 else
1245 {
1246 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1247 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1248 high = l[endian];
1249 low = l[1 - endian];
1250 }
4e74d8ec 1251
47ad8c61
MM
1252 if (TARGET_32BIT)
1253 return (num_insns_constant_wide (low)
1254 + num_insns_constant_wide (high));
4e74d8ec
MM
1255
1256 else
47ad8c61 1257 {
e72247f4 1258 if (high == 0 && low >= 0)
47ad8c61
MM
1259 return num_insns_constant_wide (low);
1260
e72247f4 1261 else if (high == -1 && low < 0)
47ad8c61
MM
1262 return num_insns_constant_wide (low);
1263
a260abc9
DE
1264 else if (mask64_operand (op, mode))
1265 return 2;
1266
47ad8c61
MM
1267 else if (low == 0)
1268 return num_insns_constant_wide (high) + 1;
1269
1270 else
1271 return (num_insns_constant_wide (high)
1272 + num_insns_constant_wide (low) + 1);
1273 }
4e74d8ec
MM
1274 }
1275
1276 else
1277 abort ();
1278}
1279
a4f6c312
SS
1280/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1281 register with one instruction per word. We only do this if we can
1282 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1283
1284int
1285easy_fp_constant (op, mode)
592696dd
SS
1286 rtx op;
1287 enum machine_mode mode;
9878760c 1288{
9878760c
RK
1289 if (GET_CODE (op) != CONST_DOUBLE
1290 || GET_MODE (op) != mode
4e74d8ec 1291 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1292 return 0;
1293
a4f6c312 1294 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1295 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1296 && mode != DImode)
b6c9286a
MM
1297 return 1;
1298
a4f6c312 1299 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1300 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1301 return 0;
1302
5ae4759c 1303#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1304 /* Similarly if we are using -mrelocatable, consider all constants
1305 to be hard. */
5ae4759c
MM
1306 if (TARGET_RELOCATABLE)
1307 return 0;
1308#endif
1309
042259f2
DE
1310 if (mode == DFmode)
1311 {
1312 long k[2];
1313 REAL_VALUE_TYPE rv;
1314
1315 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1316 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1317
a65c591c
DE
1318 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1319 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1320 }
4e74d8ec
MM
1321
1322 else if (mode == SFmode)
042259f2
DE
1323 {
1324 long l;
1325 REAL_VALUE_TYPE rv;
1326
1327 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1328 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1329
4e74d8ec 1330 return num_insns_constant_wide (l) == 1;
042259f2 1331 }
4e74d8ec 1332
a260abc9 1333 else if (mode == DImode)
c81fc13e 1334 return ((TARGET_POWERPC64
a260abc9
DE
1335 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1336 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1337
a9098fd0
GK
1338 else if (mode == SImode)
1339 return 1;
4e74d8ec
MM
1340 else
1341 abort ();
9878760c 1342}
8f75773e 1343
69ef87e2
AH
1344/* Return 1 if the operand is a CONST_INT and can be put into a
1345 register with one instruction. */
1346
1347static int
1348easy_vector_constant (op)
1349 rtx op;
1350{
1351 rtx elt;
1352 int units, i;
1353
1354 if (GET_CODE (op) != CONST_VECTOR)
1355 return 0;
1356
1357 units = CONST_VECTOR_NUNITS (op);
1358
1359 /* We can generate 0 easily. Look for that. */
1360 for (i = 0; i < units; ++i)
1361 {
1362 elt = CONST_VECTOR_ELT (op, i);
1363
1364 /* We could probably simplify this by just checking for equality
1365 with CONST0_RTX for the current mode, but let's be safe
1366 instead. */
1367
98ef3137
JJ
1368 switch (GET_CODE (elt))
1369 {
1370 case CONST_INT:
1371 if (INTVAL (elt) != 0)
1372 return 0;
1373 break;
1374 case CONST_DOUBLE:
1375 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1376 return 0;
1377 break;
1378 default:
1379 return 0;
1380 }
69ef87e2
AH
1381 }
1382
1383 /* We could probably generate a few other constants trivially, but
1384 gcc doesn't generate them yet. FIXME later. */
98ef3137 1385 return 1;
69ef87e2
AH
1386}
1387
1388/* Return 1 if the operand is the constant 0. This works for scalars
1389 as well as vectors. */
1390int
1391zero_constant (op, mode)
1392 rtx op;
1393 enum machine_mode mode;
1394{
1395 return op == CONST0_RTX (mode);
1396}
1397
50a0b056
GK
1398/* Return 1 if the operand is 0.0. */
1399int
1400zero_fp_constant (op, mode)
592696dd
SS
1401 rtx op;
1402 enum machine_mode mode;
50a0b056
GK
1403{
1404 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1405}
1406
a4f6c312
SS
1407/* Return 1 if the operand is in volatile memory. Note that during
1408 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1409 volatile memory references. So this function allows us to
1410 recognize volatile references where its safe. */
1411
1412int
1413volatile_mem_operand (op, mode)
592696dd 1414 rtx op;
b6c9286a
MM
1415 enum machine_mode mode;
1416{
1417 if (GET_CODE (op) != MEM)
1418 return 0;
1419
1420 if (!MEM_VOLATILE_P (op))
1421 return 0;
1422
1423 if (mode != GET_MODE (op))
1424 return 0;
1425
1426 if (reload_completed)
1427 return memory_operand (op, mode);
1428
1429 if (reload_in_progress)
1430 return strict_memory_address_p (mode, XEXP (op, 0));
1431
1432 return memory_address_p (mode, XEXP (op, 0));
1433}
1434
97f6e72f 1435/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1436
1437int
97f6e72f 1438offsettable_mem_operand (op, mode)
592696dd 1439 rtx op;
914c2e77
RK
1440 enum machine_mode mode;
1441{
97f6e72f 1442 return ((GET_CODE (op) == MEM)
677a9668 1443 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1444 mode, XEXP (op, 0)));
914c2e77
RK
1445}
1446
9878760c
RK
1447/* Return 1 if the operand is either an easy FP constant (see above) or
1448 memory. */
1449
1450int
1451mem_or_easy_const_operand (op, mode)
592696dd 1452 rtx op;
9878760c
RK
1453 enum machine_mode mode;
1454{
1455 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1456}
1457
1458/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1459 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1460
1461int
1462add_operand (op, mode)
592696dd 1463 rtx op;
9878760c
RK
1464 enum machine_mode mode;
1465{
2bfcf297 1466 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1467 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1468 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1469
1470 return gpc_reg_operand (op, mode);
9878760c
RK
1471}
1472
dcfedcd0
RK
1473/* Return 1 if OP is a constant but not a valid add_operand. */
1474
1475int
1476non_add_cint_operand (op, mode)
592696dd 1477 rtx op;
296b8152 1478 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1479{
1480 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1481 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1482 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1483}
1484
9878760c
RK
1485/* Return 1 if the operand is a non-special register or a constant that
1486 can be used as the operand of an OR or XOR insn on the RS/6000. */
1487
1488int
1489logical_operand (op, mode)
592696dd 1490 rtx op;
9878760c
RK
1491 enum machine_mode mode;
1492{
40501e5f 1493 HOST_WIDE_INT opl, oph;
1d328b19 1494
dfbdccdb
GK
1495 if (gpc_reg_operand (op, mode))
1496 return 1;
1d328b19 1497
dfbdccdb 1498 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1499 {
1500 opl = INTVAL (op) & GET_MODE_MASK (mode);
1501
1502#if HOST_BITS_PER_WIDE_INT <= 32
1503 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1504 return 0;
1505#endif
1506 }
dfbdccdb
GK
1507 else if (GET_CODE (op) == CONST_DOUBLE)
1508 {
1d328b19 1509 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1510 abort ();
1d328b19
GK
1511
1512 opl = CONST_DOUBLE_LOW (op);
1513 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1514 if (oph != 0)
38886f37 1515 return 0;
dfbdccdb
GK
1516 }
1517 else
1518 return 0;
1d328b19 1519
40501e5f
AM
1520 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1521 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1522}
1523
dcfedcd0 1524/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1525 above), but could be split into one. */
dcfedcd0
RK
1526
1527int
1528non_logical_cint_operand (op, mode)
592696dd 1529 rtx op;
5f59ecb7 1530 enum machine_mode mode;
dcfedcd0 1531{
dfbdccdb 1532 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1533 && ! logical_operand (op, mode)
1534 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1535}
1536
19ba8161 1537/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1538 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1539 Reject all ones and all zeros, since these should have been optimized
1540 away and confuse the making of MB and ME. */
1541
1542int
19ba8161 1543mask_operand (op, mode)
592696dd 1544 rtx op;
19ba8161 1545 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1546{
02071907 1547 HOST_WIDE_INT c, lsb;
9878760c 1548
19ba8161
DE
1549 if (GET_CODE (op) != CONST_INT)
1550 return 0;
1551
1552 c = INTVAL (op);
1553
57deb3a1
AM
1554 /* Fail in 64-bit mode if the mask wraps around because the upper
1555 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1556 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1557 return 0;
1558
c5059423
AM
1559 /* We don't change the number of transitions by inverting,
1560 so make sure we start with the LS bit zero. */
1561 if (c & 1)
1562 c = ~c;
1563
1564 /* Reject all zeros or all ones. */
1565 if (c == 0)
9878760c
RK
1566 return 0;
1567
c5059423
AM
1568 /* Find the first transition. */
1569 lsb = c & -c;
1570
1571 /* Invert to look for a second transition. */
1572 c = ~c;
9878760c 1573
c5059423
AM
1574 /* Erase first transition. */
1575 c &= -lsb;
9878760c 1576
c5059423
AM
1577 /* Find the second transition (if any). */
1578 lsb = c & -c;
1579
1580 /* Match if all the bits above are 1's (or c is zero). */
1581 return c == -lsb;
9878760c
RK
1582}
1583
0ba1b2ff
AM
1584/* Return 1 for the PowerPC64 rlwinm corner case. */
1585
1586int
1587mask_operand_wrap (op, mode)
1588 rtx op;
1589 enum machine_mode mode ATTRIBUTE_UNUSED;
1590{
1591 HOST_WIDE_INT c, lsb;
1592
1593 if (GET_CODE (op) != CONST_INT)
1594 return 0;
1595
1596 c = INTVAL (op);
1597
1598 if ((c & 0x80000001) != 0x80000001)
1599 return 0;
1600
1601 c = ~c;
1602 if (c == 0)
1603 return 0;
1604
1605 lsb = c & -c;
1606 c = ~c;
1607 c &= -lsb;
1608 lsb = c & -c;
1609 return c == -lsb;
1610}
1611
a260abc9
DE
1612/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1613 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1614 Reject all zeros, since zero should have been optimized away and
1615 confuses the making of MB and ME. */
9878760c
RK
1616
1617int
a260abc9 1618mask64_operand (op, mode)
592696dd 1619 rtx op;
0ba1b2ff 1620 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1621{
1622 if (GET_CODE (op) == CONST_INT)
1623 {
02071907 1624 HOST_WIDE_INT c, lsb;
a260abc9 1625
c5059423 1626 c = INTVAL (op);
a260abc9 1627
0ba1b2ff 1628 /* Reject all zeros. */
c5059423 1629 if (c == 0)
e2c953b6
DE
1630 return 0;
1631
0ba1b2ff
AM
1632 /* We don't change the number of transitions by inverting,
1633 so make sure we start with the LS bit zero. */
1634 if (c & 1)
1635 c = ~c;
1636
c5059423
AM
1637 /* Find the transition, and check that all bits above are 1's. */
1638 lsb = c & -c;
1639 return c == -lsb;
e2c953b6 1640 }
0ba1b2ff
AM
1641 return 0;
1642}
1643
1644/* Like mask64_operand, but allow up to three transitions. This
1645 predicate is used by insn patterns that generate two rldicl or
1646 rldicr machine insns. */
1647
1648int
1649mask64_2_operand (op, mode)
1650 rtx op;
1651 enum machine_mode mode ATTRIBUTE_UNUSED;
1652{
1653 if (GET_CODE (op) == CONST_INT)
a260abc9 1654 {
0ba1b2ff 1655 HOST_WIDE_INT c, lsb;
a260abc9 1656
0ba1b2ff 1657 c = INTVAL (op);
a260abc9 1658
0ba1b2ff
AM
1659 /* Disallow all zeros. */
1660 if (c == 0)
1661 return 0;
a260abc9 1662
0ba1b2ff
AM
1663 /* We don't change the number of transitions by inverting,
1664 so make sure we start with the LS bit zero. */
1665 if (c & 1)
1666 c = ~c;
a260abc9 1667
0ba1b2ff
AM
1668 /* Find the first transition. */
1669 lsb = c & -c;
a260abc9 1670
0ba1b2ff
AM
1671 /* Invert to look for a second transition. */
1672 c = ~c;
1673
1674 /* Erase first transition. */
1675 c &= -lsb;
1676
1677 /* Find the second transition. */
1678 lsb = c & -c;
1679
1680 /* Invert to look for a third transition. */
1681 c = ~c;
1682
1683 /* Erase second transition. */
1684 c &= -lsb;
1685
1686 /* Find the third transition (if any). */
1687 lsb = c & -c;
1688
1689 /* Match if all the bits above are 1's (or c is zero). */
1690 return c == -lsb;
1691 }
1692 return 0;
1693}
1694
1695/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1696 implement ANDing by the mask IN. */
1697void
1698build_mask64_2_operands (in, out)
1699 rtx in;
1700 rtx *out;
1701{
1702#if HOST_BITS_PER_WIDE_INT >= 64
1703 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1704 int shift;
1705
1706 if (GET_CODE (in) != CONST_INT)
1707 abort ();
1708
1709 c = INTVAL (in);
1710 if (c & 1)
1711 {
1712 /* Assume c initially something like 0x00fff000000fffff. The idea
1713 is to rotate the word so that the middle ^^^^^^ group of zeros
1714 is at the MS end and can be cleared with an rldicl mask. We then
1715 rotate back and clear off the MS ^^ group of zeros with a
1716 second rldicl. */
1717 c = ~c; /* c == 0xff000ffffff00000 */
1718 lsb = c & -c; /* lsb == 0x0000000000100000 */
1719 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1720 c = ~c; /* c == 0x00fff000000fffff */
1721 c &= -lsb; /* c == 0x00fff00000000000 */
1722 lsb = c & -c; /* lsb == 0x0000100000000000 */
1723 c = ~c; /* c == 0xff000fffffffffff */
1724 c &= -lsb; /* c == 0xff00000000000000 */
1725 shift = 0;
1726 while ((lsb >>= 1) != 0)
1727 shift++; /* shift == 44 on exit from loop */
1728 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1729 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1730 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1731 }
1732 else
0ba1b2ff
AM
1733 {
1734 /* Assume c initially something like 0xff000f0000000000. The idea
1735 is to rotate the word so that the ^^^ middle group of zeros
1736 is at the LS end and can be cleared with an rldicr mask. We then
1737 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1738 a second rldicr. */
1739 lsb = c & -c; /* lsb == 0x0000010000000000 */
1740 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1741 c = ~c; /* c == 0x00fff0ffffffffff */
1742 c &= -lsb; /* c == 0x00fff00000000000 */
1743 lsb = c & -c; /* lsb == 0x0000100000000000 */
1744 c = ~c; /* c == 0xff000fffffffffff */
1745 c &= -lsb; /* c == 0xff00000000000000 */
1746 shift = 0;
1747 while ((lsb >>= 1) != 0)
1748 shift++; /* shift == 44 on exit from loop */
1749 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1750 m1 >>= shift; /* m1 == 0x0000000000000fff */
1751 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1752 }
1753
1754 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1755 masks will be all 1's. We are guaranteed more than one transition. */
1756 out[0] = GEN_INT (64 - shift);
1757 out[1] = GEN_INT (m1);
1758 out[2] = GEN_INT (shift);
1759 out[3] = GEN_INT (m2);
1760#else
1761 abort ();
1762#endif
a260abc9
DE
1763}
1764
1765/* Return 1 if the operand is either a non-special register or a constant
1766 that can be used as the operand of a PowerPC64 logical AND insn. */
1767
1768int
1769and64_operand (op, mode)
592696dd 1770 rtx op;
9878760c
RK
1771 enum machine_mode mode;
1772{
a4f6c312 1773 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1774 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1775
1776 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1777}
1778
0ba1b2ff
AM
1779/* Like the above, but also match constants that can be implemented
1780 with two rldicl or rldicr insns. */
1781
1782int
1783and64_2_operand (op, mode)
1784 rtx op;
1785 enum machine_mode mode;
1786{
1787 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1788 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1789
1790 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1791}
1792
a260abc9
DE
1793/* Return 1 if the operand is either a non-special register or a
1794 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1795
1796int
a260abc9 1797and_operand (op, mode)
592696dd 1798 rtx op;
a260abc9 1799 enum machine_mode mode;
dcfedcd0 1800{
a4f6c312 1801 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1802 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1803
1804 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1805}
1806
9878760c
RK
1807/* Return 1 if the operand is a general register or memory operand. */
1808
1809int
1810reg_or_mem_operand (op, mode)
592696dd
SS
1811 rtx op;
1812 enum machine_mode mode;
9878760c 1813{
b6c9286a
MM
1814 return (gpc_reg_operand (op, mode)
1815 || memory_operand (op, mode)
1816 || volatile_mem_operand (op, mode));
9878760c
RK
1817}
1818
a7a813f7 1819/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1820 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1821 instruction. */
1822
1823int
1824lwa_operand (op, mode)
592696dd
SS
1825 rtx op;
1826 enum machine_mode mode;
a7a813f7
RK
1827{
1828 rtx inner = op;
1829
1830 if (reload_completed && GET_CODE (inner) == SUBREG)
1831 inner = SUBREG_REG (inner);
1832
1833 return gpc_reg_operand (inner, mode)
1834 || (memory_operand (inner, mode)
1835 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1836 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1837 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1838 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1839 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1840}
1841
cc4d5fec
JH
1842/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1843
1844int
1845symbol_ref_operand (op, mode)
1846 rtx op;
1847 enum machine_mode mode;
1848{
1849 if (mode != VOIDmode && GET_MODE (op) != mode)
1850 return 0;
1851
1852 return (GET_CODE (op) == SYMBOL_REF);
1853}
1854
9878760c 1855/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1856 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1857
1858int
1859call_operand (op, mode)
592696dd 1860 rtx op;
9878760c
RK
1861 enum machine_mode mode;
1862{
1863 if (mode != VOIDmode && GET_MODE (op) != mode)
1864 return 0;
1865
1866 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1867 || (GET_CODE (op) == REG
1868 && (REGNO (op) == LINK_REGISTER_REGNUM
1869 || REGNO (op) == COUNT_REGISTER_REGNUM
1870 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1871}
1872
2af3d377 1873/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1874 this file and the function is not weakly defined. */
2af3d377
RK
1875
1876int
1877current_file_function_operand (op, mode)
592696dd 1878 rtx op;
296b8152 1879 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1880{
1881 return (GET_CODE (op) == SYMBOL_REF
1882 && (SYMBOL_REF_FLAG (op)
8f1b829e 1883 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1884 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1885}
1886
9878760c
RK
1887/* Return 1 if this operand is a valid input for a move insn. */
1888
1889int
1890input_operand (op, mode)
592696dd 1891 rtx op;
9878760c
RK
1892 enum machine_mode mode;
1893{
eb4e8003 1894 /* Memory is always valid. */
9878760c
RK
1895 if (memory_operand (op, mode))
1896 return 1;
1897
34792e82 1898 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1899 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1900 return 1;
1901
eb4e8003
RK
1902 /* For floating-point, easy constants are valid. */
1903 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1904 && CONSTANT_P (op)
1905 && easy_fp_constant (op, mode))
1906 return 1;
1907
4e74d8ec
MM
1908 /* Allow any integer constant. */
1909 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1910 && (GET_CODE (op) == CONST_INT
e675f625 1911 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1912 return 1;
1913
eb4e8003
RK
1914 /* For floating-point or multi-word mode, the only remaining valid type
1915 is a register. */
9878760c
RK
1916 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1917 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1918 return register_operand (op, mode);
9878760c 1919
88fe15a1
RK
1920 /* The only cases left are integral modes one word or smaller (we
1921 do not get called for MODE_CC values). These can be in any
1922 register. */
1923 if (register_operand (op, mode))
a8b3aeda 1924 return 1;
88fe15a1 1925
84cf9dda 1926 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 1927 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
1928 return 1;
1929
9ebbca7d
GK
1930 /* A constant pool expression (relative to the TOC) is valid */
1931 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
1932 return 1;
1933
88228c4b
MM
1934 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1935 to be valid. */
f607bc57 1936 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
1937 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1938 && small_data_operand (op, Pmode))
1939 return 1;
1940
042259f2 1941 return 0;
9878760c 1942}
7509c759 1943
a4f6c312 1944/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
1945
1946int
1947small_data_operand (op, mode)
296b8152
KG
1948 rtx op ATTRIBUTE_UNUSED;
1949 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 1950{
38c1f2d7 1951#if TARGET_ELF
5f59ecb7 1952 rtx sym_ref;
7509c759 1953
d9407988 1954 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 1955 return 0;
a54d04b7 1956
f607bc57 1957 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
1958 return 0;
1959
88228c4b
MM
1960 if (GET_CODE (op) == SYMBOL_REF)
1961 sym_ref = op;
1962
1963 else if (GET_CODE (op) != CONST
1964 || GET_CODE (XEXP (op, 0)) != PLUS
1965 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
1966 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
1967 return 0;
1968
88228c4b 1969 else
dbf55e53
MM
1970 {
1971 rtx sum = XEXP (op, 0);
1972 HOST_WIDE_INT summand;
1973
1974 /* We have to be careful here, because it is the referenced address
1975 that must be 32k from _SDA_BASE_, not just the symbol. */
1976 summand = INTVAL (XEXP (sum, 1));
1977 if (summand < 0 || summand > g_switch_value)
1978 return 0;
1979
1980 sym_ref = XEXP (sum, 0);
1981 }
88228c4b
MM
1982
1983 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
1984 return 0;
1985
1986 return 1;
d9407988
MM
1987
1988#else
1989 return 0;
1990#endif
7509c759 1991}
9ebbca7d
GK
1992\f
1993static int
1994constant_pool_expr_1 (op, have_sym, have_toc)
1995 rtx op;
1996 int *have_sym;
1997 int *have_toc;
1998{
1999 switch (GET_CODE(op))
2000 {
2001 case SYMBOL_REF:
a4f6c312
SS
2002 if (CONSTANT_POOL_ADDRESS_P (op))
2003 {
2004 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2005 {
2006 *have_sym = 1;
2007 return 1;
2008 }
2009 else
2010 return 0;
2011 }
2012 else if (! strcmp (XSTR (op, 0), toc_label_name))
2013 {
2014 *have_toc = 1;
2015 return 1;
2016 }
2017 else
2018 return 0;
9ebbca7d
GK
2019 case PLUS:
2020 case MINUS:
c1f11548
DE
2021 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2022 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2023 case CONST:
a4f6c312 2024 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2025 case CONST_INT:
a4f6c312 2026 return 1;
9ebbca7d 2027 default:
a4f6c312 2028 return 0;
9ebbca7d
GK
2029 }
2030}
2031
2032int
2033constant_pool_expr_p (op)
2034 rtx op;
2035{
2036 int have_sym = 0;
2037 int have_toc = 0;
2038 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2039}
2040
2041int
2042toc_relative_expr_p (op)
2043 rtx op;
2044{
2045 int have_sym = 0;
2046 int have_toc = 0;
2047 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2048}
2049
2050/* Try machine-dependent ways of modifying an illegitimate address
2051 to be legitimate. If we find one, return the new, valid address.
2052 This is used from only one place: `memory_address' in explow.c.
2053
a4f6c312
SS
2054 OLDX is the address as it was before break_out_memory_refs was
2055 called. In some cases it is useful to look at this to decide what
2056 needs to be done.
9ebbca7d 2057
a4f6c312 2058 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2059
a4f6c312
SS
2060 It is always safe for this function to do nothing. It exists to
2061 recognize opportunities to optimize the output.
9ebbca7d
GK
2062
2063 On RS/6000, first check for the sum of a register with a constant
2064 integer that is out of range. If so, generate code to add the
2065 constant with the low-order 16 bits masked to the register and force
2066 this result into another register (this can be done with `cau').
2067 Then generate an address of REG+(CONST&0xffff), allowing for the
2068 possibility of bit 16 being a one.
2069
2070 Then check for the sum of a register and something not constant, try to
2071 load the other things into a register and return the sum. */
2072rtx
2073rs6000_legitimize_address (x, oldx, mode)
2074 rtx x;
2075 rtx oldx ATTRIBUTE_UNUSED;
2076 enum machine_mode mode;
0ac081f6 2077{
9ebbca7d
GK
2078 if (GET_CODE (x) == PLUS
2079 && GET_CODE (XEXP (x, 0)) == REG
2080 && GET_CODE (XEXP (x, 1)) == CONST_INT
2081 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2082 {
2083 HOST_WIDE_INT high_int, low_int;
2084 rtx sum;
a65c591c
DE
2085 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2086 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2087 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2088 GEN_INT (high_int)), 0);
2089 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2090 }
2091 else if (GET_CODE (x) == PLUS
2092 && GET_CODE (XEXP (x, 0)) == REG
2093 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2094 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2095 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2096 || TARGET_POWERPC64
2097 || mode != DFmode)
9ebbca7d
GK
2098 && (TARGET_POWERPC64 || mode != DImode)
2099 && mode != TImode)
2100 {
2101 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2102 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2103 }
0ac081f6
AH
2104 else if (ALTIVEC_VECTOR_MODE (mode))
2105 {
2106 rtx reg;
2107
2108 /* Make sure both operands are registers. */
2109 if (GET_CODE (x) == PLUS)
9f85ed45 2110 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2111 force_reg (Pmode, XEXP (x, 1)));
2112
2113 reg = force_reg (Pmode, x);
2114 return reg;
2115 }
a3170dc6
AH
2116 else if (SPE_VECTOR_MODE (mode))
2117 {
2118 /* We accept [reg + reg] and [reg + OFFSET]. */
2119
2120 if (GET_CODE (x) == PLUS)
2121 {
2122 rtx op1 = XEXP (x, 0);
2123 rtx op2 = XEXP (x, 1);
2124
2125 op1 = force_reg (Pmode, op1);
2126
2127 if (GET_CODE (op2) != REG
2128 && (GET_CODE (op2) != CONST_INT
2129 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2130 op2 = force_reg (Pmode, op2);
2131
2132 return gen_rtx_PLUS (Pmode, op1, op2);
2133 }
2134
2135 return force_reg (Pmode, x);
2136 }
9ebbca7d
GK
2137 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2138 && GET_CODE (x) != CONST_INT
2139 && GET_CODE (x) != CONST_DOUBLE
2140 && CONSTANT_P (x)
6ac7bf2c
GK
2141 && GET_MODE_NUNITS (mode) == 1
2142 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2143 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2144 {
2145 rtx reg = gen_reg_rtx (Pmode);
2146 emit_insn (gen_elf_high (reg, (x)));
2147 return gen_rtx_LO_SUM (Pmode, reg, (x));
2148 }
ee890fe2
SS
2149 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2150 && ! flag_pic
2151 && GET_CODE (x) != CONST_INT
2152 && GET_CODE (x) != CONST_DOUBLE
2153 && CONSTANT_P (x)
a3170dc6 2154 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2155 && mode != DImode
2156 && mode != TImode)
2157 {
2158 rtx reg = gen_reg_rtx (Pmode);
2159 emit_insn (gen_macho_high (reg, (x)));
2160 return gen_rtx_LO_SUM (Pmode, reg, (x));
2161 }
9ebbca7d
GK
2162 else if (TARGET_TOC
2163 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2164 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2165 {
2166 return create_TOC_reference (x);
2167 }
2168 else
2169 return NULL_RTX;
2170}
258bfae2 2171
24ea750e
DJ
2172/* The convention appears to be to define this wherever it is used.
2173 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2174 is now used here. */
2175#ifndef REG_MODE_OK_FOR_BASE_P
2176#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2177#endif
2178
2179/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2180 replace the input X, or the original X if no replacement is called for.
2181 The output parameter *WIN is 1 if the calling macro should goto WIN,
2182 0 if it should not.
2183
2184 For RS/6000, we wish to handle large displacements off a base
2185 register by splitting the addend across an addiu/addis and the mem insn.
2186 This cuts number of extra insns needed from 3 to 1.
2187
2188 On Darwin, we use this to generate code for floating point constants.
2189 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2190 The Darwin code is inside #if TARGET_MACHO because only then is
2191 machopic_function_base_name() defined. */
2192rtx
2193rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2194 rtx x;
2195 enum machine_mode mode;
2196 int opnum;
2197 int type;
2198 int ind_levels ATTRIBUTE_UNUSED;
2199 int *win;
2200{
2201 /* We must recognize output that we have already generated ourselves. */
2202 if (GET_CODE (x) == PLUS
2203 && GET_CODE (XEXP (x, 0)) == PLUS
2204 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2205 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2206 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2207 {
2208 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2209 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2210 opnum, (enum reload_type)type);
2211 *win = 1;
2212 return x;
2213 }
3deb2758 2214
24ea750e
DJ
2215#if TARGET_MACHO
2216 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2217 && GET_CODE (x) == LO_SUM
2218 && GET_CODE (XEXP (x, 0)) == PLUS
2219 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2220 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2221 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2222 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2223 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2224 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2225 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2226 {
2227 /* Result of previous invocation of this function on Darwin
6f317ef3 2228 floating point constant. */
24ea750e
DJ
2229 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2230 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2231 opnum, (enum reload_type)type);
2232 *win = 1;
2233 return x;
2234 }
2235#endif
2236 if (GET_CODE (x) == PLUS
2237 && GET_CODE (XEXP (x, 0)) == REG
2238 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2239 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2240 && GET_CODE (XEXP (x, 1)) == CONST_INT
a3170dc6 2241 && !SPE_VECTOR_MODE (mode)
78c875e8 2242 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2243 {
2244 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2245 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2246 HOST_WIDE_INT high
2247 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2248
2249 /* Check for 32-bit overflow. */
2250 if (high + low != val)
2251 {
2252 *win = 0;
2253 return x;
2254 }
2255
2256 /* Reload the high part into a base reg; leave the low part
2257 in the mem directly. */
2258
2259 x = gen_rtx_PLUS (GET_MODE (x),
2260 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2261 GEN_INT (high)),
2262 GEN_INT (low));
2263
2264 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2265 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2266 opnum, (enum reload_type)type);
2267 *win = 1;
2268 return x;
2269 }
2270#if TARGET_MACHO
2271 if (GET_CODE (x) == SYMBOL_REF
2272 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2273 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2274 && flag_pic)
2275 {
2276 /* Darwin load of floating point constant. */
2277 rtx offset = gen_rtx (CONST, Pmode,
2278 gen_rtx (MINUS, Pmode, x,
2279 gen_rtx (SYMBOL_REF, Pmode,
2280 machopic_function_base_name ())));
2281 x = gen_rtx (LO_SUM, GET_MODE (x),
2282 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2283 gen_rtx (HIGH, Pmode, offset)), offset);
2284 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2285 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2286 opnum, (enum reload_type)type);
2287 *win = 1;
2288 return x;
2289 }
2290#endif
2291 if (TARGET_TOC
c1f11548
DE
2292 && CONSTANT_POOL_EXPR_P (x)
2293 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2294 {
2295 (x) = create_TOC_reference (x);
2296 *win = 1;
2297 return x;
2298 }
2299 *win = 0;
2300 return x;
2301}
2302
258bfae2
FS
2303/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2304 that is a valid memory address for an instruction.
2305 The MODE argument is the machine mode for the MEM expression
2306 that wants to use this address.
2307
2308 On the RS/6000, there are four valid address: a SYMBOL_REF that
2309 refers to a constant pool entry of an address (or the sum of it
2310 plus a constant), a short (16-bit signed) constant plus a register,
2311 the sum of two registers, or a register indirect, possibly with an
2312 auto-increment. For DFmode and DImode with an constant plus register,
2313 we must ensure that both words are addressable or PowerPC64 with offset
2314 word aligned.
2315
2316 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2317 32-bit DImode, TImode), indexed addressing cannot be used because
2318 adjacent memory cells are accessed by adding word-sized offsets
2319 during assembly output. */
2320int
2321rs6000_legitimate_address (mode, x, reg_ok_strict)
2322 enum machine_mode mode;
2323 rtx x;
2324 int reg_ok_strict;
2325{
2326 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2327 return 1;
2328 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2329 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2330 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2331 && TARGET_UPDATE
2332 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2333 return 1;
2334 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2335 return 1;
2336 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2337 return 1;
2338 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2339 if (! reg_ok_strict
2340 && GET_CODE (x) == PLUS
2341 && GET_CODE (XEXP (x, 0)) == REG
2342 && XEXP (x, 0) == virtual_stack_vars_rtx
2343 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2344 return 1;
2345 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2346 return 1;
2347 if (mode != TImode
a3170dc6
AH
2348 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2349 || TARGET_POWERPC64
2350 || mode != DFmode)
258bfae2
FS
2351 && (TARGET_POWERPC64 || mode != DImode)
2352 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2353 return 1;
2354 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2355 return 1;
2356 return 0;
2357}
fb4d4348 2358\f
a4f6c312
SS
2359/* Try to output insns to set TARGET equal to the constant C if it can
2360 be done in less than N insns. Do all computations in MODE.
2361 Returns the place where the output has been placed if it can be
2362 done and the insns have been emitted. If it would take more than N
2363 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2364
2365rtx
2366rs6000_emit_set_const (dest, mode, source, n)
2367 rtx dest, source;
2368 enum machine_mode mode;
2369 int n ATTRIBUTE_UNUSED;
2370{
2371 HOST_WIDE_INT c0, c1;
2372
2373 if (mode == QImode || mode == HImode || mode == SImode)
2374 {
2375 if (dest == NULL)
2376 dest = gen_reg_rtx (mode);
2377 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2378 return dest;
2379 }
2380
2381 if (GET_CODE (source) == CONST_INT)
2382 {
2383 c0 = INTVAL (source);
2384 c1 = -(c0 < 0);
2385 }
2386 else if (GET_CODE (source) == CONST_DOUBLE)
2387 {
2388#if HOST_BITS_PER_WIDE_INT >= 64
2389 c0 = CONST_DOUBLE_LOW (source);
2390 c1 = -(c0 < 0);
2391#else
2392 c0 = CONST_DOUBLE_LOW (source);
2393 c1 = CONST_DOUBLE_HIGH (source);
2394#endif
2395 }
2396 else
a4f6c312 2397 abort ();
2bfcf297
DB
2398
2399 return rs6000_emit_set_long_const (dest, c0, c1);
2400}
2401
2402/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2403 fall back to a straight forward decomposition. We do this to avoid
2404 exponential run times encountered when looking for longer sequences
2405 with rs6000_emit_set_const. */
2406static rtx
2407rs6000_emit_set_long_const (dest, c1, c2)
2408 rtx dest;
2409 HOST_WIDE_INT c1, c2;
2410{
2411 if (!TARGET_POWERPC64)
2412 {
2413 rtx operand1, operand2;
2414
2415 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2416 DImode);
2417 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2418 DImode);
2419 emit_move_insn (operand1, GEN_INT (c1));
2420 emit_move_insn (operand2, GEN_INT (c2));
2421 }
2422 else
2423 {
bc06712d 2424 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2425
bc06712d
TR
2426 ud1 = c1 & 0xffff;
2427 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2428#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2429 c2 = c1 >> 32;
2bfcf297 2430#endif
bc06712d
TR
2431 ud3 = c2 & 0xffff;
2432 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2433
bc06712d
TR
2434 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2435 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2436 {
bc06712d
TR
2437 if (ud1 & 0x8000)
2438 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2439 else
2440 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2441 }
2bfcf297 2442
bc06712d
TR
2443 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2444 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2445 {
bc06712d
TR
2446 if (ud2 & 0x8000)
2447 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2448 - 0x80000000));
252b88f7 2449 else
bc06712d
TR
2450 emit_move_insn (dest, GEN_INT (ud2 << 16));
2451 if (ud1 != 0)
2452 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2453 }
bc06712d
TR
2454 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2455 || (ud4 == 0 && ! (ud3 & 0x8000)))
2456 {
2457 if (ud3 & 0x8000)
2458 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2459 - 0x80000000));
2460 else
2461 emit_move_insn (dest, GEN_INT (ud3 << 16));
2462
2463 if (ud2 != 0)
2464 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2465 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2466 if (ud1 != 0)
2467 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2468 }
2469 else
2470 {
2471 if (ud4 & 0x8000)
2472 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2473 - 0x80000000));
2474 else
2475 emit_move_insn (dest, GEN_INT (ud4 << 16));
2476
2477 if (ud3 != 0)
2478 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2479
bc06712d
TR
2480 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2481 if (ud2 != 0)
2482 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2483 GEN_INT (ud2 << 16)));
2484 if (ud1 != 0)
2485 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2486 }
2487 }
2bfcf297
DB
2488 return dest;
2489}
2490
fb4d4348
GK
2491/* Emit a move from SOURCE to DEST in mode MODE. */
2492void
2493rs6000_emit_move (dest, source, mode)
2494 rtx dest;
2495 rtx source;
2496 enum machine_mode mode;
2497{
2498 rtx operands[2];
2499 operands[0] = dest;
2500 operands[1] = source;
2501
2502 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2503 if (GET_CODE (operands[1]) == CONST_DOUBLE
2504 && ! FLOAT_MODE_P (mode)
2505 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2506 {
2507 /* FIXME. This should never happen. */
2508 /* Since it seems that it does, do the safe thing and convert
2509 to a CONST_INT. */
2496c7bd 2510 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2511 }
2512 if (GET_CODE (operands[1]) == CONST_DOUBLE
2513 && ! FLOAT_MODE_P (mode)
2514 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2515 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2516 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2517 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2518 abort ();
c9e8cb32
DD
2519
2520 /* Check if GCC is setting up a block move that will end up using FP
2521 registers as temporaries. We must make sure this is acceptable. */
2522 if (GET_CODE (operands[0]) == MEM
2523 && GET_CODE (operands[1]) == MEM
2524 && mode == DImode
41543739
GK
2525 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2526 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2527 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2528 ? 32 : MEM_ALIGN (operands[0])))
2529 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2530 ? 32
2531 : MEM_ALIGN (operands[1]))))
2532 && ! MEM_VOLATILE_P (operands [0])
2533 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2534 {
41543739
GK
2535 emit_move_insn (adjust_address (operands[0], SImode, 0),
2536 adjust_address (operands[1], SImode, 0));
2537 emit_move_insn (adjust_address (operands[0], SImode, 4),
2538 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2539 return;
2540 }
fb4d4348
GK
2541
2542 if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
2543 operands[1] = force_reg (mode, operands[1]);
a9098fd0 2544
a3170dc6
AH
2545 if (mode == SFmode && ! TARGET_POWERPC
2546 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2547 && GET_CODE (operands[0]) == MEM)
fb4d4348 2548 {
ffc14f31
GK
2549 int regnum;
2550
2551 if (reload_in_progress || reload_completed)
2552 regnum = true_regnum (operands[1]);
2553 else if (GET_CODE (operands[1]) == REG)
2554 regnum = REGNO (operands[1]);
2555 else
2556 regnum = -1;
fb4d4348
GK
2557
2558 /* If operands[1] is a register, on POWER it may have
2559 double-precision data in it, so truncate it to single
2560 precision. */
2561 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2562 {
2563 rtx newreg;
2564 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2565 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2566 operands[1] = newreg;
2567 }
2568 }
2569
a9098fd0
GK
2570 /* Handle the case where reload calls us with an invalid address;
2571 and the case of CONSTANT_P_RTX. */
16861f33 2572 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2573 && (! general_operand (operands[1], mode)
2574 || ! nonimmediate_operand (operands[0], mode)
2575 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2576 {
2577 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2578 return;
2579 }
a9098fd0 2580
fb4d4348
GK
2581 /* FIXME: In the long term, this switch statement should go away
2582 and be replaced by a sequence of tests based on things like
2583 mode == Pmode. */
2584 switch (mode)
2585 {
2586 case HImode:
2587 case QImode:
2588 if (CONSTANT_P (operands[1])
2589 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2590 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2591 break;
2592
06f4e019 2593 case TFmode:
fb4d4348
GK
2594 case DFmode:
2595 case SFmode:
2596 if (CONSTANT_P (operands[1])
2597 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2598 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2599 break;
2600
0ac081f6
AH
2601 case V16QImode:
2602 case V8HImode:
2603 case V4SFmode:
2604 case V4SImode:
a3170dc6
AH
2605 case V4HImode:
2606 case V2SFmode:
2607 case V2SImode:
69ef87e2
AH
2608 if (CONSTANT_P (operands[1])
2609 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2610 operands[1] = force_const_mem (mode, operands[1]);
2611 break;
2612
fb4d4348 2613 case SImode:
a9098fd0 2614 case DImode:
fb4d4348
GK
2615 /* Use default pattern for address of ELF small data */
2616 if (TARGET_ELF
a9098fd0 2617 && mode == Pmode
f607bc57 2618 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2619 && (GET_CODE (operands[1]) == SYMBOL_REF
2620 || GET_CODE (operands[1]) == CONST)
2621 && small_data_operand (operands[1], mode))
fb4d4348
GK
2622 {
2623 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2624 return;
2625 }
2626
f607bc57 2627 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2628 && mode == Pmode && mode == SImode
2629 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2630 {
2631 emit_insn (gen_movsi_got (operands[0], operands[1]));
2632 return;
2633 }
2634
ee890fe2
SS
2635 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2636 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2637 && mode == Pmode
fb4d4348
GK
2638 && CONSTANT_P (operands[1])
2639 && GET_CODE (operands[1]) != HIGH
2640 && GET_CODE (operands[1]) != CONST_INT)
2641 {
a9098fd0 2642 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2643
2644 /* If this is a function address on -mcall-aixdesc,
2645 convert it to the address of the descriptor. */
2646 if (DEFAULT_ABI == ABI_AIX
2647 && GET_CODE (operands[1]) == SYMBOL_REF
2648 && XSTR (operands[1], 0)[0] == '.')
2649 {
2650 const char *name = XSTR (operands[1], 0);
2651 rtx new_ref;
2652 while (*name == '.')
2653 name++;
2654 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2655 CONSTANT_POOL_ADDRESS_P (new_ref)
2656 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2657 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2658 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2659 operands[1] = new_ref;
2660 }
7509c759 2661
ee890fe2
SS
2662 if (DEFAULT_ABI == ABI_DARWIN)
2663 {
2664 emit_insn (gen_macho_high (target, operands[1]));
2665 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2666 return;
2667 }
2668
fb4d4348
GK
2669 emit_insn (gen_elf_high (target, operands[1]));
2670 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2671 return;
2672 }
2673
a9098fd0
GK
2674 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2675 and we have put it in the TOC, we just need to make a TOC-relative
2676 reference to it. */
2677 if (TARGET_TOC
2678 && GET_CODE (operands[1]) == SYMBOL_REF
2679 && CONSTANT_POOL_EXPR_P (operands[1])
2680 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2681 get_pool_mode (operands[1])))
fb4d4348 2682 {
a9098fd0 2683 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2684 }
a9098fd0
GK
2685 else if (mode == Pmode
2686 && CONSTANT_P (operands[1])
38886f37
AO
2687 && ((GET_CODE (operands[1]) != CONST_INT
2688 && ! easy_fp_constant (operands[1], mode))
2689 || (GET_CODE (operands[1]) == CONST_INT
2690 && num_insns_constant (operands[1], mode) > 2)
2691 || (GET_CODE (operands[0]) == REG
2692 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2693 && GET_CODE (operands[1]) != HIGH
2694 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2695 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2696 {
2697 /* Emit a USE operation so that the constant isn't deleted if
2698 expensive optimizations are turned on because nobody
2699 references it. This should only be done for operands that
2700 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2701 This should not be done for operands that contain LABEL_REFs.
2702 For now, we just handle the obvious case. */
2703 if (GET_CODE (operands[1]) != LABEL_REF)
2704 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2705
c859cda6 2706#if TARGET_MACHO
ee890fe2
SS
2707 /* Darwin uses a special PIC legitimizer. */
2708 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2709 {
ee890fe2
SS
2710 operands[1] =
2711 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2712 operands[0]);
2713 if (operands[0] != operands[1])
2714 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2715 return;
2716 }
c859cda6 2717#endif
ee890fe2 2718
fb4d4348
GK
2719 /* If we are to limit the number of things we put in the TOC and
2720 this is a symbol plus a constant we can add in one insn,
2721 just put the symbol in the TOC and add the constant. Don't do
2722 this if reload is in progress. */
2723 if (GET_CODE (operands[1]) == CONST
2724 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2725 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2726 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2727 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2728 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2729 && ! side_effects_p (operands[0]))
2730 {
a4f6c312
SS
2731 rtx sym =
2732 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2733 rtx other = XEXP (XEXP (operands[1], 0), 1);
2734
a9098fd0
GK
2735 sym = force_reg (mode, sym);
2736 if (mode == SImode)
2737 emit_insn (gen_addsi3 (operands[0], sym, other));
2738 else
2739 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2740 return;
2741 }
2742
a9098fd0 2743 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2744
2745 if (TARGET_TOC
d34c5b80
DE
2746 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2747 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2748 get_pool_constant (XEXP (operands[1], 0)),
2749 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2750 {
ba4828e0
RK
2751 operands[1]
2752 = gen_rtx_MEM (mode,
2753 create_TOC_reference (XEXP (operands[1], 0)));
2754 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2755 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2756 }
fb4d4348
GK
2757 }
2758 break;
a9098fd0 2759
fb4d4348
GK
2760 case TImode:
2761 if (GET_CODE (operands[0]) == MEM
2762 && GET_CODE (XEXP (operands[0], 0)) != REG
2763 && ! reload_in_progress)
792760b9
RK
2764 operands[0]
2765 = replace_equiv_address (operands[0],
2766 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2767
2768 if (GET_CODE (operands[1]) == MEM
2769 && GET_CODE (XEXP (operands[1], 0)) != REG
2770 && ! reload_in_progress)
792760b9
RK
2771 operands[1]
2772 = replace_equiv_address (operands[1],
2773 copy_addr_to_reg (XEXP (operands[1], 0)));
fb4d4348
GK
2774 break;
2775
2776 default:
2777 abort ();
2778 }
2779
a9098fd0
GK
2780 /* Above, we may have called force_const_mem which may have returned
2781 an invalid address. If we can, fix this up; otherwise, reload will
2782 have to deal with it. */
2783 if (GET_CODE (operands[1]) == MEM
2784 && ! memory_address_p (mode, XEXP (operands[1], 0))
2785 && ! reload_in_progress)
f4ef873c 2786 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2787
fb4d4348 2788 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2789 return;
fb4d4348 2790}
4697a36c
MM
2791\f
2792/* Initialize a variable CUM of type CUMULATIVE_ARGS
2793 for a call to a function whose data type is FNTYPE.
2794 For a library call, FNTYPE is 0.
2795
2796 For incoming args we set the number of arguments in the prototype large
1c20ae99 2797 so we never return a PARALLEL. */
4697a36c
MM
2798
2799void
2800init_cumulative_args (cum, fntype, libname, incoming)
2801 CUMULATIVE_ARGS *cum;
2802 tree fntype;
296b8152 2803 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2804 int incoming;
2805{
2806 static CUMULATIVE_ARGS zero_cumulative;
2807
2808 *cum = zero_cumulative;
2809 cum->words = 0;
2810 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2811 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2812 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2813 cum->call_cookie = CALL_NORMAL;
4cc833b7 2814 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2815
2816 if (incoming)
bd227acc 2817 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2818
2819 else if (cum->prototype)
2820 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2821 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2822 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2823
2824 else
2825 cum->nargs_prototype = 0;
2826
2827 cum->orig_nargs = cum->nargs_prototype;
7509c759 2828
a5c76ee6
ZW
2829 /* Check for a longcall attribute. */
2830 if (fntype
2831 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2832 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2833 cum->call_cookie = CALL_LONG;
2834
4697a36c
MM
2835 if (TARGET_DEBUG_ARG)
2836 {
2837 fprintf (stderr, "\ninit_cumulative_args:");
2838 if (fntype)
2839 {
2840 tree ret_type = TREE_TYPE (fntype);
2841 fprintf (stderr, " ret code = %s,",
2842 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2843 }
2844
6a4cee5f
MM
2845 if (cum->call_cookie & CALL_LONG)
2846 fprintf (stderr, " longcall,");
2847
4697a36c
MM
2848 fprintf (stderr, " proto = %d, nargs = %d\n",
2849 cum->prototype, cum->nargs_prototype);
2850 }
2851}
2852\f
c229cba9
DE
2853/* If defined, a C expression which determines whether, and in which
2854 direction, to pad out an argument with extra space. The value
2855 should be of type `enum direction': either `upward' to pad above
2856 the argument, `downward' to pad below, or `none' to inhibit
2857 padding.
2858
2859 For the AIX ABI structs are always stored left shifted in their
2860 argument slot. */
2861
9ebbca7d 2862enum direction
c229cba9
DE
2863function_arg_padding (mode, type)
2864 enum machine_mode mode;
2865 tree type;
2866{
c85f7c16 2867 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 2868 return upward;
c229cba9
DE
2869
2870 /* This is the default definition. */
2871 return (! BYTES_BIG_ENDIAN
9ebbca7d 2872 ? upward
c229cba9
DE
2873 : ((mode == BLKmode
2874 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2875 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2876 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 2877 ? downward : upward));
c229cba9
DE
2878}
2879
b6c9286a
MM
2880/* If defined, a C expression that gives the alignment boundary, in bits,
2881 of an argument with the specified mode and type. If it is not defined,
2882 PARM_BOUNDARY is used for all arguments.
2883
2310f99a 2884 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
2885
2886int
2887function_arg_boundary (mode, type)
2888 enum machine_mode mode;
9ebbca7d 2889 tree type ATTRIBUTE_UNUSED;
b6c9286a 2890{
f607bc57 2891 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 2892 return 64;
a3170dc6
AH
2893 else if (SPE_VECTOR_MODE (mode))
2894 return 64;
0ac081f6
AH
2895 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2896 return 128;
9ebbca7d 2897 else
b6c9286a 2898 return PARM_BOUNDARY;
b6c9286a
MM
2899}
2900\f
4697a36c
MM
2901/* Update the data in CUM to advance over an argument
2902 of mode MODE and data type TYPE.
2903 (TYPE is null for libcalls where that information may not be available.) */
2904
2905void
2906function_arg_advance (cum, mode, type, named)
2907 CUMULATIVE_ARGS *cum;
2908 enum machine_mode mode;
2909 tree type;
2910 int named;
2911{
2912 cum->nargs_prototype--;
2913
0ac081f6
AH
2914 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2915 {
2916 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2917 cum->vregno++;
2918 else
2919 cum->words += RS6000_ARG_SIZE (mode, type);
2920 }
a4b0320c
AH
2921 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
2922 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
2923 cum->sysv_gregno++;
f607bc57 2924 else if (DEFAULT_ABI == ABI_V4)
4697a36c 2925 {
a3170dc6 2926 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 2927 && (mode == SFmode || mode == DFmode))
4697a36c 2928 {
4cc833b7
RH
2929 if (cum->fregno <= FP_ARG_V4_MAX_REG)
2930 cum->fregno++;
2931 else
2932 {
2933 if (mode == DFmode)
2934 cum->words += cum->words & 1;
d34c5b80 2935 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 2936 }
4697a36c 2937 }
4cc833b7
RH
2938 else
2939 {
2940 int n_words;
2941 int gregno = cum->sysv_gregno;
2942
2943 /* Aggregates and IEEE quad get passed by reference. */
2944 if ((type && AGGREGATE_TYPE_P (type))
2945 || mode == TFmode)
2946 n_words = 1;
2947 else
d34c5b80 2948 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 2949
a4b0320c 2950 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
2951 if (n_words == 2 && (gregno & 1) == 0)
2952 gregno += 1;
2953
a4b0320c
AH
2954 /* Long long and SPE vectors are not split between registers
2955 and stack. */
4cc833b7
RH
2956 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
2957 {
2958 /* Long long is aligned on the stack. */
2959 if (n_words == 2)
2960 cum->words += cum->words & 1;
2961 cum->words += n_words;
2962 }
4697a36c 2963
4cc833b7
RH
2964 /* Note: continuing to accumulate gregno past when we've started
2965 spilling to the stack indicates the fact that we've started
2966 spilling to the stack to expand_builtin_saveregs. */
2967 cum->sysv_gregno = gregno + n_words;
2968 }
4697a36c 2969
4cc833b7
RH
2970 if (TARGET_DEBUG_ARG)
2971 {
2972 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
2973 cum->words, cum->fregno);
2974 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
2975 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
2976 fprintf (stderr, "mode = %4s, named = %d\n",
2977 GET_MODE_NAME (mode), named);
2978 }
4697a36c
MM
2979 }
2980 else
4cc833b7
RH
2981 {
2982 int align = (TARGET_32BIT && (cum->words & 1) != 0
2983 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 2984
d34c5b80 2985 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 2986
a3170dc6
AH
2987 if (GET_MODE_CLASS (mode) == MODE_FLOAT
2988 && TARGET_HARD_FLOAT && TARGET_FPRS)
d34c5b80 2989 cum->fregno++;
4cc833b7
RH
2990
2991 if (TARGET_DEBUG_ARG)
2992 {
2993 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
2994 cum->words, cum->fregno);
2995 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
2996 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
2997 fprintf (stderr, "named = %d, align = %d\n", named, align);
2998 }
2999 }
4697a36c
MM
3000}
3001\f
3002/* Determine where to put an argument to a function.
3003 Value is zero to push the argument on the stack,
3004 or a hard register in which to store the argument.
3005
3006 MODE is the argument's machine mode.
3007 TYPE is the data type of the argument (as a tree).
3008 This is null for libcalls where that information may
3009 not be available.
3010 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3011 the preceding args and about the function being called.
3012 NAMED is nonzero if this argument is a named parameter
3013 (otherwise it is an extra parameter matching an ellipsis).
3014
3015 On RS/6000 the first eight words of non-FP are normally in registers
3016 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3017 Under V.4, the first 8 FP args are in registers.
3018
3019 If this is floating-point and no prototype is specified, we use
3020 both an FP and integer register (or possibly FP reg and stack). Library
3021 functions (when TYPE is zero) always have the proper types for args,
3022 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3023 doesn't support PARALLEL anyway. */
4697a36c
MM
3024
3025struct rtx_def *
3026function_arg (cum, mode, type, named)
3027 CUMULATIVE_ARGS *cum;
3028 enum machine_mode mode;
3029 tree type;
20c29ebe 3030 int named;
4697a36c 3031{
4cc833b7 3032 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3033
a4f6c312
SS
3034 /* Return a marker to indicate whether CR1 needs to set or clear the
3035 bit that V.4 uses to say fp args were passed in registers.
3036 Assume that we don't need the marker for software floating point,
3037 or compiler generated library calls. */
4697a36c
MM
3038 if (mode == VOIDmode)
3039 {
f607bc57 3040 if (abi == ABI_V4
7509c759 3041 && cum->nargs_prototype < 0
4697a36c 3042 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3043 {
a3170dc6
AH
3044 /* For the SPE, we need to crxor CR6 always. */
3045 if (TARGET_SPE_ABI)
3046 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3047 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3048 return GEN_INT (cum->call_cookie
3049 | ((cum->fregno == FP_ARG_MIN_REG)
3050 ? CALL_V4_SET_FP_ARGS
3051 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3052 }
4697a36c 3053
7509c759 3054 return GEN_INT (cum->call_cookie);
4697a36c
MM
3055 }
3056
0ac081f6
AH
3057 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3058 {
20c29ebe 3059 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3060 return gen_rtx_REG (mode, cum->vregno);
3061 else
3062 return NULL;
3063 }
a4b0320c 3064 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3065 {
a4b0320c 3066 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3067 return gen_rtx_REG (mode, cum->sysv_gregno);
3068 else
3069 return NULL;
3070 }
f607bc57 3071 else if (abi == ABI_V4)
4697a36c 3072 {
a3170dc6 3073 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3074 && (mode == SFmode || mode == DFmode))
3075 {
3076 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3077 return gen_rtx_REG (mode, cum->fregno);
3078 else
3079 return NULL;
3080 }
3081 else
3082 {
3083 int n_words;
3084 int gregno = cum->sysv_gregno;
3085
3086 /* Aggregates and IEEE quad get passed by reference. */
3087 if ((type && AGGREGATE_TYPE_P (type))
3088 || mode == TFmode)
3089 n_words = 1;
3090 else
d34c5b80 3091 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3092
a4b0320c 3093 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3094 if (n_words == 2 && (gregno & 1) == 0)
3095 gregno += 1;
3096
a4b0320c
AH
3097 /* Long long and SPE vectors are not split between registers
3098 and stack. */
4cc833b7 3099 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3100 {
3101 /* SPE vectors in ... get split into 2 registers. */
3102 if (TARGET_SPE && TARGET_SPE_ABI
3103 && SPE_VECTOR_MODE (mode) && !named)
3104 {
3105 rtx r1, r2;
3106 enum machine_mode m = GET_MODE_INNER (mode);
3107
3108 r1 = gen_rtx_REG (m, gregno);
3109 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3110 r2 = gen_rtx_REG (m, gregno + 1);
3111 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3112 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3113 }
3114 return gen_rtx_REG (mode, gregno);
3115 }
4cc833b7
RH
3116 else
3117 return NULL;
3118 }
4697a36c 3119 }
4cc833b7
RH
3120 else
3121 {
3122 int align = (TARGET_32BIT && (cum->words & 1) != 0
3123 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3124 int align_words = cum->words + align;
4697a36c 3125
4cc833b7
RH
3126 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3127 return NULL_RTX;
3128
3129 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3130 {
3131 if (! type
3132 || ((cum->nargs_prototype > 0)
3133 /* IBM AIX extended its linkage convention definition always
3134 to require FP args after register save area hole on the
3135 stack. */
3136 && (DEFAULT_ABI != ABI_AIX
3137 || ! TARGET_XL_CALL
3138 || (align_words < GP_ARG_NUM_REG))))
3139 return gen_rtx_REG (mode, cum->fregno);
3140
3141 return gen_rtx_PARALLEL (mode,
3142 gen_rtvec (2,
39403d82 3143 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3144 ((align_words >= GP_ARG_NUM_REG)
3145 ? NULL_RTX
3146 : (align_words
d34c5b80 3147 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3148 > GP_ARG_NUM_REG
3149 /* If this is partially on the stack, then
3150 we only include the portion actually
3151 in registers here. */
39403d82 3152 ? gen_rtx_REG (SImode,
1c20ae99 3153 GP_ARG_MIN_REG + align_words)
39403d82 3154 : gen_rtx_REG (mode,
1c20ae99
JW
3155 GP_ARG_MIN_REG + align_words))),
3156 const0_rtx),
39403d82
DE
3157 gen_rtx_EXPR_LIST (VOIDmode,
3158 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3159 const0_rtx)));
4cc833b7
RH
3160 }
3161 else if (align_words < GP_ARG_NUM_REG)
3162 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3163 else
3164 return NULL_RTX;
4697a36c 3165 }
4697a36c
MM
3166}
3167\f
3168/* For an arg passed partly in registers and partly in memory,
3169 this is the number of registers used.
3170 For args passed entirely in registers or entirely in memory, zero. */
3171
3172int
3173function_arg_partial_nregs (cum, mode, type, named)
3174 CUMULATIVE_ARGS *cum;
3175 enum machine_mode mode;
3176 tree type;
d34c5b80 3177 int named ATTRIBUTE_UNUSED;
4697a36c 3178{
f607bc57 3179 if (DEFAULT_ABI == ABI_V4)
4697a36c 3180 return 0;
4697a36c 3181
0ac081f6
AH
3182 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3183 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3184 {
3185 if (cum->nargs_prototype >= 0)
3186 return 0;
3187 }
3188
3189 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3190 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3191 {
3192 int ret = GP_ARG_NUM_REG - cum->words;
3193 if (ret && TARGET_DEBUG_ARG)
3194 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3195
3196 return ret;
3197 }
3198
3199 return 0;
3200}
3201\f
3202/* A C expression that indicates when an argument must be passed by
3203 reference. If nonzero for an argument, a copy of that argument is
3204 made in memory and a pointer to the argument is passed instead of
3205 the argument itself. The pointer is passed in whatever way is
3206 appropriate for passing a pointer to that type.
3207
3208 Under V.4, structures and unions are passed by reference. */
3209
3210int
3211function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3212 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3213 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3214 tree type;
296b8152 3215 int named ATTRIBUTE_UNUSED;
4697a36c 3216{
f607bc57 3217 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3218 && ((type && AGGREGATE_TYPE_P (type))
3219 || mode == TFmode))
4697a36c
MM
3220 {
3221 if (TARGET_DEBUG_ARG)
3222 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3223
3224 return 1;
3225 }
4697a36c
MM
3226
3227 return 0;
3228}
4697a36c
MM
3229\f
3230/* Perform any needed actions needed for a function that is receiving a
3231 variable number of arguments.
3232
3233 CUM is as above.
3234
3235 MODE and TYPE are the mode and type of the current parameter.
3236
3237 PRETEND_SIZE is a variable that should be set to the amount of stack
3238 that must be pushed by the prolog to pretend that our caller pushed
3239 it.
3240
3241 Normally, this macro will push all remaining incoming registers on the
3242 stack and set PRETEND_SIZE to the length of the registers pushed. */
3243
3244void
3245setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3246 CUMULATIVE_ARGS *cum;
3247 enum machine_mode mode;
3248 tree type;
3249 int *pretend_size;
3250 int no_rtl;
3251
3252{
4cc833b7
RH
3253 CUMULATIVE_ARGS next_cum;
3254 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3255 rtx save_area = NULL_RTX, mem;
dfafc897 3256 int first_reg_offset, set;
d34c5b80
DE
3257 tree fntype;
3258 int stdarg_p;
4697a36c 3259
d34c5b80
DE
3260 fntype = TREE_TYPE (current_function_decl);
3261 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3262 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3263 != void_type_node));
4cc833b7 3264
d34c5b80
DE
3265 /* For varargs, we do not want to skip the dummy va_dcl argument.
3266 For stdargs, we do want to skip the last named argument. */
3267 next_cum = *cum;
3268 if (stdarg_p)
3269 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3270
f607bc57 3271 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3272 {
4cc833b7 3273 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3274 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3275 if (! no_rtl)
2c4974b7 3276 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3277 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3278
3279 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3280 }
60e2d0ca 3281 else
4697a36c 3282 {
d34c5b80 3283 first_reg_offset = next_cum.words;
4cc833b7 3284 save_area = virtual_incoming_args_rtx;
00dba523 3285 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3286
3287 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3288 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3289 }
4697a36c 3290
dfafc897 3291 set = get_varargs_alias_set ();
c81fc13e 3292 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3293 {
dfafc897
FS
3294 mem = gen_rtx_MEM (BLKmode,
3295 plus_constant (save_area,
3296 first_reg_offset * reg_size)),
ba4828e0 3297 set_mem_alias_set (mem, set);
8ac61af7 3298 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3299
4cc833b7 3300 move_block_from_reg
dfafc897 3301 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3302 GP_ARG_NUM_REG - first_reg_offset,
3303 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
3304
3305 /* ??? Does ABI_V4 need this at all? */
4697a36c
MM
3306 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
3307 }
3308
4697a36c 3309 /* Save FP registers if needed. */
f607bc57 3310 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3311 && TARGET_HARD_FLOAT && TARGET_FPRS
3312 && ! no_rtl
4cc833b7 3313 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3314 {
4cc833b7 3315 int fregno = next_cum.fregno;
9ebbca7d 3316 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3317 rtx lab = gen_label_rtx ();
3318 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3319
4cc833b7 3320 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3321 pc_rtx,
39403d82 3322 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3323 gen_rtx_NE (VOIDmode, cr1,
3324 const0_rtx),
39403d82 3325 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3326 pc_rtx)));
3327
4cc833b7
RH
3328 while (fregno <= FP_ARG_V4_MAX_REG)
3329 {
dfafc897 3330 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3331 set_mem_alias_set (mem, set);
dfafc897 3332 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3333 fregno++;
3334 off += 8;
4697a36c 3335 }
4cc833b7
RH
3336
3337 emit_label (lab);
4697a36c 3338 }
4697a36c 3339}
4697a36c 3340
dfafc897 3341/* Create the va_list data type. */
2c4974b7 3342
dfafc897
FS
3343tree
3344rs6000_build_va_list ()
3345{
bab45a51 3346 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3347
9ebbca7d
GK
3348 /* For AIX, prefer 'char *' because that's what the system
3349 header files like. */
f607bc57 3350 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3351 return build_pointer_type (char_type_node);
dfafc897 3352
f1e639b1 3353 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3354 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3355
9ebbca7d
GK
3356 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3357 unsigned_char_type_node);
3358 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3359 unsigned_char_type_node);
dfafc897
FS
3360 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3361 ptr_type_node);
3362 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3363 ptr_type_node);
3364
3365 DECL_FIELD_CONTEXT (f_gpr) = record;
3366 DECL_FIELD_CONTEXT (f_fpr) = record;
3367 DECL_FIELD_CONTEXT (f_ovf) = record;
3368 DECL_FIELD_CONTEXT (f_sav) = record;
3369
bab45a51
FS
3370 TREE_CHAIN (record) = type_decl;
3371 TYPE_NAME (record) = type_decl;
dfafc897
FS
3372 TYPE_FIELDS (record) = f_gpr;
3373 TREE_CHAIN (f_gpr) = f_fpr;
3374 TREE_CHAIN (f_fpr) = f_ovf;
3375 TREE_CHAIN (f_ovf) = f_sav;
3376
3377 layout_type (record);
3378
3379 /* The correct type is an array type of one element. */
3380 return build_array_type (record, build_index_type (size_zero_node));
3381}
3382
3383/* Implement va_start. */
3384
3385void
e5faf155 3386rs6000_va_start (valist, nextarg)
dfafc897
FS
3387 tree valist;
3388 rtx nextarg;
4697a36c 3389{
dfafc897
FS
3390 HOST_WIDE_INT words, n_gpr, n_fpr;
3391 tree f_gpr, f_fpr, f_ovf, f_sav;
3392 tree gpr, fpr, ovf, sav, t;
2c4974b7 3393
dfafc897 3394 /* Only SVR4 needs something special. */
f607bc57 3395 if (DEFAULT_ABI != ABI_V4)
dfafc897 3396 {
e5faf155 3397 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3398 return;
3399 }
3400
973a648b 3401 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3402 f_fpr = TREE_CHAIN (f_gpr);
3403 f_ovf = TREE_CHAIN (f_fpr);
3404 f_sav = TREE_CHAIN (f_ovf);
3405
8ebecc3b 3406 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3407 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3408 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3409 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3410 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3411
3412 /* Count number of gp and fp argument registers used. */
4cc833b7 3413 words = current_function_args_info.words;
dfafc897
FS
3414 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3415 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3416
3417 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3418 {
3419 fputs ("va_start: words = ", stderr);
3420 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3421 fputs (", n_gpr = ", stderr);
3422 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3423 fputs (", n_fpr = ", stderr);
3424 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3425 putc ('\n', stderr);
3426 }
dfafc897
FS
3427
3428 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3429 TREE_SIDE_EFFECTS (t) = 1;
3430 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3431
3432 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3433 TREE_SIDE_EFFECTS (t) = 1;
3434 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3435
3436 /* Find the overflow area. */
3437 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3438 if (words != 0)
3439 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3440 build_int_2 (words * UNITS_PER_WORD, 0));
3441 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3442 TREE_SIDE_EFFECTS (t) = 1;
3443 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3444
3445 /* Find the register save area. */
3446 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3447 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3448 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3449 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3450 TREE_SIDE_EFFECTS (t) = 1;
3451 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3452}
3453
3454/* Implement va_arg. */
3455
3456rtx
3457rs6000_va_arg (valist, type)
3458 tree valist, type;
3459{
3460 tree f_gpr, f_fpr, f_ovf, f_sav;
3461 tree gpr, fpr, ovf, sav, reg, t, u;
3462 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3463 rtx lab_false, lab_over, addr_rtx, r;
3464
f607bc57 3465 if (DEFAULT_ABI != ABI_V4)
2a55fd42 3466 return std_expand_builtin_va_arg (valist, type);
dfafc897 3467
973a648b 3468 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3469 f_fpr = TREE_CHAIN (f_gpr);
3470 f_ovf = TREE_CHAIN (f_fpr);
3471 f_sav = TREE_CHAIN (f_ovf);
3472
8ebecc3b 3473 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3474 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3475 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3476 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3477 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3478
3479 size = int_size_in_bytes (type);
3480 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3481
dfafc897 3482 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3483 {
dfafc897
FS
3484 /* Aggregates and long doubles are passed by reference. */
3485 indirect_p = 1;
3486 reg = gpr;
3487 n_reg = 1;
3488 sav_ofs = 0;
3489 sav_scale = 4;
d3294cd9
FS
3490 size = UNITS_PER_WORD;
3491 rsize = 1;
dfafc897 3492 }
a3170dc6 3493 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3494 {
3495 /* FP args go in FP registers, if present. */
3496 indirect_p = 0;
3497 reg = fpr;
3498 n_reg = 1;
3499 sav_ofs = 8*4;
3500 sav_scale = 8;
4cc833b7 3501 }
dfafc897
FS
3502 else
3503 {
3504 /* Otherwise into GP registers. */
3505 indirect_p = 0;
3506 reg = gpr;
3507 n_reg = rsize;
3508 sav_ofs = 0;
3509 sav_scale = 4;
3510 }
3511
a4f6c312 3512 /* Pull the value out of the saved registers ... */
dfafc897
FS
3513
3514 lab_false = gen_label_rtx ();
3515 lab_over = gen_label_rtx ();
3516 addr_rtx = gen_reg_rtx (Pmode);
3517
16861f33
AH
3518 /* AltiVec vectors never go in registers. */
3519 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3520 {
41daaf0e
AH
3521 TREE_THIS_VOLATILE (reg) = 1;
3522 emit_cmp_and_jump_insns
3523 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3524 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3525 lab_false);
dfafc897 3526
41daaf0e
AH
3527 /* Long long is aligned in the registers. */
3528 if (n_reg > 1)
3529 {
3530 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3531 build_int_2 (n_reg - 1, 0));
3532 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3533 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3534 TREE_SIDE_EFFECTS (u) = 1;
3535 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3536 }
2c4974b7 3537
41daaf0e
AH
3538 if (sav_ofs)
3539 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3540 else
3541 t = sav;
2c4974b7 3542
41daaf0e
AH
3543 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3544 build_int_2 (n_reg, 0));
3545 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3546
41daaf0e
AH
3547 u = build1 (CONVERT_EXPR, integer_type_node, u);
3548 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3549
41daaf0e
AH
3550 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3551 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3552
41daaf0e
AH
3553 t = build (PLUS_EXPR, ptr_type_node, t, u);
3554 TREE_SIDE_EFFECTS (t) = 1;
3555
3556 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3557 if (r != addr_rtx)
3558 emit_move_insn (addr_rtx, r);
3559
3560 emit_jump_insn (gen_jump (lab_over));
3561 emit_barrier ();
3562 }
dfafc897 3563
dfafc897
FS
3564 emit_label (lab_false);
3565
a4f6c312 3566 /* ... otherwise out of the overflow area. */
dfafc897 3567
41daaf0e
AH
3568 /* Make sure we don't find reg 7 for the next int arg.
3569
3570 All AltiVec vectors go in the overflow area. So in the AltiVec
3571 case we need to get the vectors from the overflow area, but
3572 remember where the GPRs and FPRs are. */
16861f33
AH
3573 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3574 || !TARGET_ALTIVEC))
dfafc897
FS
3575 {
3576 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3577 TREE_SIDE_EFFECTS (t) = 1;
3578 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3579 }
3580
3581 /* Care for on-stack alignment if needed. */
3582 if (rsize <= 1)
3583 t = ovf;
3584 else
3585 {
41daaf0e
AH
3586 int align;
3587
16861f33
AH
3588 /* AltiVec vectors are 16 byte aligned. */
3589 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3590 align = 15;
3591 else
3592 align = 7;
3593
3594 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3595 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3596 }
3597 t = save_expr (t);
3598
3599 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3600 if (r != addr_rtx)
3601 emit_move_insn (addr_rtx, r);
3602
3603 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3604 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3605 TREE_SIDE_EFFECTS (t) = 1;
3606 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3607
3608 emit_label (lab_over);
3609
3610 if (indirect_p)
3611 {
3612 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3613 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3614 emit_move_insn (addr_rtx, r);
3615 }
3616
3617 return addr_rtx;
4697a36c 3618}
0ac081f6
AH
3619
3620/* Builtins. */
3621
6a2dd09a
RS
3622#define def_builtin(MASK, NAME, TYPE, CODE) \
3623do { \
3624 if ((MASK) & target_flags) \
3625 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3626 NULL, NULL_TREE); \
0ac081f6
AH
3627} while (0)
3628
24408032
AH
3629/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3630
2212663f 3631static const struct builtin_description bdesc_3arg[] =
24408032
AH
3632{
3633 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3634 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3635 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3636 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3637 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3638 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3639 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3640 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3641 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3642 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3643 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3644 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3645 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3646 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3647 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3648 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3649 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3650 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3651 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3652 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3653 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3654 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3655 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3656};
2212663f 3657
95385cbb
AH
3658/* DST operations: void foo (void *, const int, const char). */
3659
3660static const struct builtin_description bdesc_dst[] =
3661{
3662 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3663 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3664 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3665 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3666};
3667
2212663f 3668/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3669
a3170dc6 3670static struct builtin_description bdesc_2arg[] =
0ac081f6 3671{
f18c054f
DB
3672 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3673 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3674 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3675 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3676 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3677 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3678 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3679 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3680 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3681 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3682 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3683 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3684 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3685 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3686 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3687 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3688 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3689 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3690 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3691 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3692 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3693 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3694 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3695 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3696 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3697 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3698 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3699 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3700 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3701 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3702 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3703 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3704 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3705 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3706 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3707 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3708 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3709 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
3710 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3711 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3712 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3713 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3714 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3715 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3716 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3717 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3718 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3719 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3720 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3721 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3722 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3723 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3724 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3725 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3726 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3727 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3728 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3729 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3730 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3731 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3732 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3733 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3734 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3735 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3736 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3737 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3738 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3739 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3740 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3741 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3742 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3743 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3744 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3745 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3746 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3747 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3748 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3749 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3750 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3751 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3752 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3753 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3754 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3755 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3756 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3757 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3758 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3759 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3760 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3761 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3762 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3763 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3764 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3765 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3766 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3767 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3768 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3769 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3770 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3771 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3772 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3773 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3774 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3775 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3776 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3777 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3778 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3779 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3780 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3781 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3782 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3783 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3784 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
3785
3786 /* Place holder, leave as first spe builtin. */
3787 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3788 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3789 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3790 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3791 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3792 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3793 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3794 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3795 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3796 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3797 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3798 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3799 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3800 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3801 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3802 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3803 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3804 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3805 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3806 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3807 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3808 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3809 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3810 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3811 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3812 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3813 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3814 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3815 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3816 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3817 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3818 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3819 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3820 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3821 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3822 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3823 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3824 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3825 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
3826 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
3827 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
3828 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
3829 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
3830 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
3831 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
3832 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
3833 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
3834 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
3835 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
3836 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
3837 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
3838 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
3839 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
3840 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
3841 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
3842 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
3843 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
3844 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
3845 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
3846 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
3847 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
3848 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
3849 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
3850 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
3851 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
3852 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
3853 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
3854 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
3855 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
3856 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
3857 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
3858 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
3859 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
3860 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
3861 { 0, CODE_FOR_spe_evmwlsmf, "__builtin_spe_evmwlsmf", SPE_BUILTIN_EVMWLSMF },
3862 { 0, CODE_FOR_spe_evmwlsmfa, "__builtin_spe_evmwlsmfa", SPE_BUILTIN_EVMWLSMFA },
3863 { 0, CODE_FOR_spe_evmwlsmfaaw, "__builtin_spe_evmwlsmfaaw", SPE_BUILTIN_EVMWLSMFAAW },
3864 { 0, CODE_FOR_spe_evmwlsmfanw, "__builtin_spe_evmwlsmfanw", SPE_BUILTIN_EVMWLSMFANW },
3865 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
3866 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
3867 { 0, CODE_FOR_spe_evmwlssf, "__builtin_spe_evmwlssf", SPE_BUILTIN_EVMWLSSF },
3868 { 0, CODE_FOR_spe_evmwlssfa, "__builtin_spe_evmwlssfa", SPE_BUILTIN_EVMWLSSFA },
3869 { 0, CODE_FOR_spe_evmwlssfaaw, "__builtin_spe_evmwlssfaaw", SPE_BUILTIN_EVMWLSSFAAW },
3870 { 0, CODE_FOR_spe_evmwlssfanw, "__builtin_spe_evmwlssfanw", SPE_BUILTIN_EVMWLSSFANW },
3871 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
3872 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
3873 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
3874 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
3875 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
3876 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
3877 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
3878 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
3879 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
3880 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
3881 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
3882 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
3883 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
3884 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
3885 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
3886 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
3887 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
3888 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
3889 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
3890 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
3891 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
3892 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
3893 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
3894 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
3895 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
3896 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
3897 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
3898 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
3899 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
3900 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
3901 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
3902 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
3903 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
3904
3905 /* SPE binary operations expecting a 5-bit unsigned literal. */
3906 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
3907
3908 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
3909 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
3910 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
3911 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
3912 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
3913 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
3914 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
3915 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
3916 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
3917 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
3918 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
3919 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
3920 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
3921 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
3922 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
3923 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
3924 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
3925 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
3926 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
3927 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
3928 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
3929 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
3930 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
3931 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
3932 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
3933 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
3934
3935 /* Place-holder. Leave as last binary SPE builtin. */
3936 { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
3937};
3938
3939/* AltiVec predicates. */
3940
3941struct builtin_description_predicates
3942{
3943 const unsigned int mask;
3944 const enum insn_code icode;
3945 const char *opcode;
3946 const char *const name;
3947 const enum rs6000_builtins code;
3948};
3949
3950static const struct builtin_description_predicates bdesc_altivec_preds[] =
3951{
3952 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
3953 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
3954 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
3955 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
3956 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
3957 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
3958 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
3959 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
3960 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
3961 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
3962 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
3963 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
3964 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 3965};
24408032 3966
a3170dc6
AH
3967/* SPE predicates. */
3968static struct builtin_description bdesc_spe_predicates[] =
3969{
3970 /* Place-holder. Leave as first. */
3971 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
3972 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
3973 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
3974 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
3975 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
3976 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
3977 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
3978 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
3979 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
3980 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
3981 /* Place-holder. Leave as last. */
3982 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
3983};
3984
3985/* SPE evsel predicates. */
3986static struct builtin_description bdesc_spe_evsel[] =
3987{
3988 /* Place-holder. Leave as first. */
3989 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
3990 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
3991 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
3992 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
3993 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
3994 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
3995 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
3996 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
3997 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
3998 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
3999 /* Place-holder. Leave as last. */
4000 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4001};
4002
100c4561
AH
4003/* ABS* opreations. */
4004
4005static const struct builtin_description bdesc_abs[] =
4006{
4007 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4008 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4009 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4010 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4011 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4012 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4013 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4014};
4015
617e0e1d
DB
4016/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4017 foo (VECa). */
24408032 4018
a3170dc6 4019static struct builtin_description bdesc_1arg[] =
2212663f 4020{
617e0e1d
DB
4021 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4022 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4023 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4024 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4025 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4026 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4027 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4028 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4029 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4030 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4031 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4032 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4033 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4034 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4035 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4036 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4037 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4038
4039 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4040 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4041 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4042 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4043 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4044 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4045 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4046 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4047 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4048 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4049 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4050 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4051 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4052 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4053 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4054 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4055 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4056 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4057 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4058 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4059 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4060 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4061 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4062 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4063 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4064 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4065 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4066 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4067 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4068 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4069 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4070 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4071
4072 /* Place-holder. Leave as last unary SPE builtin. */
4073 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4074};
4075
4076static rtx
92898235 4077rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4078 enum insn_code icode;
4079 tree arglist;
4080 rtx target;
4081{
4082 rtx pat;
4083 tree arg0 = TREE_VALUE (arglist);
4084 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4085 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4086 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4087
0559cc77
DE
4088 if (icode == CODE_FOR_nothing)
4089 /* Builtin not supported on this processor. */
4090 return 0;
4091
20e26713
AH
4092 /* If we got invalid arguments bail out before generating bad rtl. */
4093 if (arg0 == error_mark_node)
9a171fcd 4094 return const0_rtx;
20e26713 4095
0559cc77
DE
4096 if (icode == CODE_FOR_altivec_vspltisb
4097 || icode == CODE_FOR_altivec_vspltish
4098 || icode == CODE_FOR_altivec_vspltisw
4099 || icode == CODE_FOR_spe_evsplatfi
4100 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4101 {
4102 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4103 if (GET_CODE (op0) != CONST_INT
4104 || INTVAL (op0) > 0x1f
4105 || INTVAL (op0) < -0x1f)
4106 {
4107 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4108 return const0_rtx;
b44140e7 4109 }
b44140e7
AH
4110 }
4111
c62f2db5 4112 if (target == 0
2212663f
DB
4113 || GET_MODE (target) != tmode
4114 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4115 target = gen_reg_rtx (tmode);
4116
4117 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4118 op0 = copy_to_mode_reg (mode0, op0);
4119
4120 pat = GEN_FCN (icode) (target, op0);
4121 if (! pat)
4122 return 0;
4123 emit_insn (pat);
0ac081f6 4124
2212663f
DB
4125 return target;
4126}
ae4b4a02 4127
100c4561
AH
4128static rtx
4129altivec_expand_abs_builtin (icode, arglist, target)
4130 enum insn_code icode;
4131 tree arglist;
4132 rtx target;
4133{
4134 rtx pat, scratch1, scratch2;
4135 tree arg0 = TREE_VALUE (arglist);
4136 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4137 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4138 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4139
4140 /* If we have invalid arguments, bail out before generating bad rtl. */
4141 if (arg0 == error_mark_node)
9a171fcd 4142 return const0_rtx;
100c4561
AH
4143
4144 if (target == 0
4145 || GET_MODE (target) != tmode
4146 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4147 target = gen_reg_rtx (tmode);
4148
4149 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4150 op0 = copy_to_mode_reg (mode0, op0);
4151
4152 scratch1 = gen_reg_rtx (mode0);
4153 scratch2 = gen_reg_rtx (mode0);
4154
4155 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4156 if (! pat)
4157 return 0;
4158 emit_insn (pat);
4159
4160 return target;
4161}
4162
0ac081f6 4163static rtx
92898235 4164rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4165 enum insn_code icode;
4166 tree arglist;
4167 rtx target;
4168{
4169 rtx pat;
4170 tree arg0 = TREE_VALUE (arglist);
4171 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4172 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4173 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4174 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4175 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4176 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4177
0559cc77
DE
4178 if (icode == CODE_FOR_nothing)
4179 /* Builtin not supported on this processor. */
4180 return 0;
4181
20e26713
AH
4182 /* If we got invalid arguments bail out before generating bad rtl. */
4183 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4184 return const0_rtx;
20e26713 4185
0559cc77
DE
4186 if (icode == CODE_FOR_altivec_vcfux
4187 || icode == CODE_FOR_altivec_vcfsx
4188 || icode == CODE_FOR_altivec_vctsxs
4189 || icode == CODE_FOR_altivec_vctuxs
4190 || icode == CODE_FOR_altivec_vspltb
4191 || icode == CODE_FOR_altivec_vsplth
4192 || icode == CODE_FOR_altivec_vspltw
4193 || icode == CODE_FOR_spe_evaddiw
4194 || icode == CODE_FOR_spe_evldd
4195 || icode == CODE_FOR_spe_evldh
4196 || icode == CODE_FOR_spe_evldw
4197 || icode == CODE_FOR_spe_evlhhesplat
4198 || icode == CODE_FOR_spe_evlhhossplat
4199 || icode == CODE_FOR_spe_evlhhousplat
4200 || icode == CODE_FOR_spe_evlwhe
4201 || icode == CODE_FOR_spe_evlwhos
4202 || icode == CODE_FOR_spe_evlwhou
4203 || icode == CODE_FOR_spe_evlwhsplat
4204 || icode == CODE_FOR_spe_evlwwsplat
4205 || icode == CODE_FOR_spe_evrlwi
4206 || icode == CODE_FOR_spe_evslwi
4207 || icode == CODE_FOR_spe_evsrwis
4208 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4209 {
4210 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4211 if (TREE_CODE (arg1) != INTEGER_CST
4212 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4213 {
4214 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4215 return const0_rtx;
b44140e7 4216 }
b44140e7
AH
4217 }
4218
c62f2db5 4219 if (target == 0
0ac081f6
AH
4220 || GET_MODE (target) != tmode
4221 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4222 target = gen_reg_rtx (tmode);
4223
4224 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4225 op0 = copy_to_mode_reg (mode0, op0);
4226 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4227 op1 = copy_to_mode_reg (mode1, op1);
4228
4229 pat = GEN_FCN (icode) (target, op0, op1);
4230 if (! pat)
4231 return 0;
4232 emit_insn (pat);
4233
4234 return target;
4235}
6525c0e7 4236
ae4b4a02
AH
4237static rtx
4238altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4239 enum insn_code icode;
4240 const char *opcode;
4241 tree arglist;
4242 rtx target;
4243{
4244 rtx pat, scratch;
4245 tree cr6_form = TREE_VALUE (arglist);
4246 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4247 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4248 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4249 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4250 enum machine_mode tmode = SImode;
4251 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4252 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4253 int cr6_form_int;
4254
4255 if (TREE_CODE (cr6_form) != INTEGER_CST)
4256 {
4257 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4258 return const0_rtx;
ae4b4a02
AH
4259 }
4260 else
4261 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4262
4263 if (mode0 != mode1)
4264 abort ();
4265
4266 /* If we have invalid arguments, bail out before generating bad rtl. */
4267 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4268 return const0_rtx;
ae4b4a02
AH
4269
4270 if (target == 0
4271 || GET_MODE (target) != tmode
4272 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4273 target = gen_reg_rtx (tmode);
4274
4275 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4276 op0 = copy_to_mode_reg (mode0, op0);
4277 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4278 op1 = copy_to_mode_reg (mode1, op1);
4279
4280 scratch = gen_reg_rtx (mode0);
4281
4282 pat = GEN_FCN (icode) (scratch, op0, op1,
4283 gen_rtx (SYMBOL_REF, Pmode, opcode));
4284 if (! pat)
4285 return 0;
4286 emit_insn (pat);
4287
4288 /* The vec_any* and vec_all* predicates use the same opcodes for two
4289 different operations, but the bits in CR6 will be different
4290 depending on what information we want. So we have to play tricks
4291 with CR6 to get the right bits out.
4292
4293 If you think this is disgusting, look at the specs for the
4294 AltiVec predicates. */
4295
4296 switch (cr6_form_int)
4297 {
4298 case 0:
4299 emit_insn (gen_cr6_test_for_zero (target));
4300 break;
4301 case 1:
4302 emit_insn (gen_cr6_test_for_zero_reverse (target));
4303 break;
4304 case 2:
4305 emit_insn (gen_cr6_test_for_lt (target));
4306 break;
4307 case 3:
4308 emit_insn (gen_cr6_test_for_lt_reverse (target));
4309 break;
4310 default:
4311 error ("argument 1 of __builtin_altivec_predicate is out of range");
4312 break;
4313 }
4314
4315 return target;
4316}
4317
6525c0e7
AH
4318static rtx
4319altivec_expand_stv_builtin (icode, arglist)
4320 enum insn_code icode;
4321 tree arglist;
4322{
4323 tree arg0 = TREE_VALUE (arglist);
4324 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4325 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4326 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4327 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4328 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4329 rtx pat;
4330 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4331 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4332 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4333
4334 /* Invalid arguments. Bail before doing anything stoopid! */
4335 if (arg0 == error_mark_node
4336 || arg1 == error_mark_node
4337 || arg2 == error_mark_node)
9a171fcd 4338 return const0_rtx;
6525c0e7
AH
4339
4340 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4341 op0 = copy_to_mode_reg (mode2, op0);
4342 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4343 op1 = copy_to_mode_reg (mode0, op1);
4344 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4345 op2 = copy_to_mode_reg (mode1, op2);
4346
4347 pat = GEN_FCN (icode) (op1, op2, op0);
4348 if (pat)
4349 emit_insn (pat);
4350 return NULL_RTX;
4351}
4352
2212663f 4353static rtx
92898235 4354rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4355 enum insn_code icode;
4356 tree arglist;
4357 rtx target;
4358{
4359 rtx pat;
4360 tree arg0 = TREE_VALUE (arglist);
4361 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4362 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4363 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4364 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4365 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4366 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4367 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4368 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4369 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4370
774b5662
DE
4371 if (icode == CODE_FOR_nothing)
4372 /* Builtin not supported on this processor. */
4373 return 0;
4374
20e26713
AH
4375 /* If we got invalid arguments bail out before generating bad rtl. */
4376 if (arg0 == error_mark_node
4377 || arg1 == error_mark_node
4378 || arg2 == error_mark_node)
9a171fcd 4379 return const0_rtx;
20e26713 4380
774b5662
DE
4381 if (icode == CODE_FOR_altivec_vsldoi_4sf
4382 || icode == CODE_FOR_altivec_vsldoi_4si
4383 || icode == CODE_FOR_altivec_vsldoi_8hi
4384 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4385 {
4386 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4387 if (TREE_CODE (arg2) != INTEGER_CST
4388 || TREE_INT_CST_LOW (arg2) & ~0xf)
4389 {
4390 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4391 return const0_rtx;
b44140e7 4392 }
b44140e7
AH
4393 }
4394
c62f2db5 4395 if (target == 0
2212663f
DB
4396 || GET_MODE (target) != tmode
4397 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4398 target = gen_reg_rtx (tmode);
4399
4400 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4401 op0 = copy_to_mode_reg (mode0, op0);
4402 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4403 op1 = copy_to_mode_reg (mode1, op1);
4404 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4405 op2 = copy_to_mode_reg (mode2, op2);
4406
4407 pat = GEN_FCN (icode) (target, op0, op1, op2);
4408 if (! pat)
4409 return 0;
4410 emit_insn (pat);
4411
4412 return target;
4413}
92898235 4414
3a9b8c7e 4415/* Expand the lvx builtins. */
0ac081f6 4416static rtx
3a9b8c7e 4417altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4418 tree exp;
4419 rtx target;
92898235 4420 bool *expandedp;
0ac081f6 4421{
0ac081f6
AH
4422 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4423 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4424 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4425 tree arg0;
4426 enum machine_mode tmode, mode0;
7c3abc73 4427 rtx pat, op0;
3a9b8c7e 4428 enum insn_code icode;
92898235 4429
0ac081f6
AH
4430 switch (fcode)
4431 {
f18c054f
DB
4432 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4433 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4434 break;
f18c054f
DB
4435 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4436 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4437 break;
4438 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4439 icode = CODE_FOR_altivec_lvx_4si;
4440 break;
4441 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4442 icode = CODE_FOR_altivec_lvx_4sf;
4443 break;
4444 default:
4445 *expandedp = false;
4446 return NULL_RTX;
4447 }
0ac081f6 4448
3a9b8c7e 4449 *expandedp = true;
f18c054f 4450
3a9b8c7e
AH
4451 arg0 = TREE_VALUE (arglist);
4452 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4453 tmode = insn_data[icode].operand[0].mode;
4454 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4455
3a9b8c7e
AH
4456 if (target == 0
4457 || GET_MODE (target) != tmode
4458 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4459 target = gen_reg_rtx (tmode);
24408032 4460
3a9b8c7e
AH
4461 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4462 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4463
3a9b8c7e
AH
4464 pat = GEN_FCN (icode) (target, op0);
4465 if (! pat)
4466 return 0;
4467 emit_insn (pat);
4468 return target;
4469}
f18c054f 4470
3a9b8c7e
AH
4471/* Expand the stvx builtins. */
4472static rtx
4473altivec_expand_st_builtin (exp, target, expandedp)
4474 tree exp;
7c3abc73 4475 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4476 bool *expandedp;
4477{
4478 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4479 tree arglist = TREE_OPERAND (exp, 1);
4480 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4481 tree arg0, arg1;
4482 enum machine_mode mode0, mode1;
7c3abc73 4483 rtx pat, op0, op1;
3a9b8c7e 4484 enum insn_code icode;
f18c054f 4485
3a9b8c7e
AH
4486 switch (fcode)
4487 {
4488 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4489 icode = CODE_FOR_altivec_stvx_16qi;
4490 break;
4491 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4492 icode = CODE_FOR_altivec_stvx_8hi;
4493 break;
4494 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4495 icode = CODE_FOR_altivec_stvx_4si;
4496 break;
4497 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4498 icode = CODE_FOR_altivec_stvx_4sf;
4499 break;
4500 default:
4501 *expandedp = false;
4502 return NULL_RTX;
4503 }
24408032 4504
3a9b8c7e
AH
4505 arg0 = TREE_VALUE (arglist);
4506 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4507 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4508 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4509 mode0 = insn_data[icode].operand[0].mode;
4510 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4511
3a9b8c7e
AH
4512 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4513 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4514 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4515 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4516
3a9b8c7e
AH
4517 pat = GEN_FCN (icode) (op0, op1);
4518 if (pat)
4519 emit_insn (pat);
f18c054f 4520
3a9b8c7e
AH
4521 *expandedp = true;
4522 return NULL_RTX;
4523}
f18c054f 4524
3a9b8c7e
AH
4525/* Expand the dst builtins. */
4526static rtx
4527altivec_expand_dst_builtin (exp, target, expandedp)
4528 tree exp;
7c3abc73 4529 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4530 bool *expandedp;
4531{
4532 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4533 tree arglist = TREE_OPERAND (exp, 1);
4534 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4535 tree arg0, arg1, arg2;
4536 enum machine_mode mode0, mode1, mode2;
7c3abc73 4537 rtx pat, op0, op1, op2;
3a9b8c7e 4538 struct builtin_description *d;
a3170dc6 4539 size_t i;
f18c054f 4540
3a9b8c7e 4541 *expandedp = false;
f18c054f 4542
3a9b8c7e
AH
4543 /* Handle DST variants. */
4544 d = (struct builtin_description *) bdesc_dst;
4545 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4546 if (d->code == fcode)
4547 {
4548 arg0 = TREE_VALUE (arglist);
4549 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4550 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4551 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4552 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4553 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4554 mode0 = insn_data[d->icode].operand[0].mode;
4555 mode1 = insn_data[d->icode].operand[1].mode;
4556 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4557
3a9b8c7e
AH
4558 /* Invalid arguments, bail out before generating bad rtl. */
4559 if (arg0 == error_mark_node
4560 || arg1 == error_mark_node
4561 || arg2 == error_mark_node)
4562 return const0_rtx;
f18c054f 4563
3a9b8c7e
AH
4564 if (TREE_CODE (arg2) != INTEGER_CST
4565 || TREE_INT_CST_LOW (arg2) & ~0x3)
4566 {
4567 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4568 return const0_rtx;
4569 }
f18c054f 4570
3a9b8c7e
AH
4571 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4572 op0 = copy_to_mode_reg (mode0, op0);
4573 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4574 op1 = copy_to_mode_reg (mode1, op1);
24408032 4575
3a9b8c7e
AH
4576 pat = GEN_FCN (d->icode) (op0, op1, op2);
4577 if (pat != 0)
4578 emit_insn (pat);
f18c054f 4579
3a9b8c7e
AH
4580 *expandedp = true;
4581 return NULL_RTX;
4582 }
f18c054f 4583
3a9b8c7e
AH
4584 return NULL_RTX;
4585}
24408032 4586
3a9b8c7e
AH
4587/* Expand the builtin in EXP and store the result in TARGET. Store
4588 true in *EXPANDEDP if we found a builtin to expand. */
4589static rtx
4590altivec_expand_builtin (exp, target, expandedp)
4591 tree exp;
4592 rtx target;
4593 bool *expandedp;
4594{
4595 struct builtin_description *d;
4596 struct builtin_description_predicates *dp;
4597 size_t i;
4598 enum insn_code icode;
4599 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4600 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4601 tree arg0;
4602 rtx op0, pat;
4603 enum machine_mode tmode, mode0;
3a9b8c7e 4604 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4605
3a9b8c7e
AH
4606 target = altivec_expand_ld_builtin (exp, target, expandedp);
4607 if (*expandedp)
4608 return target;
0ac081f6 4609
3a9b8c7e
AH
4610 target = altivec_expand_st_builtin (exp, target, expandedp);
4611 if (*expandedp)
4612 return target;
4613
4614 target = altivec_expand_dst_builtin (exp, target, expandedp);
4615 if (*expandedp)
4616 return target;
4617
4618 *expandedp = true;
95385cbb 4619
3a9b8c7e
AH
4620 switch (fcode)
4621 {
6525c0e7
AH
4622 case ALTIVEC_BUILTIN_STVX:
4623 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4624 case ALTIVEC_BUILTIN_STVEBX:
4625 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4626 case ALTIVEC_BUILTIN_STVEHX:
4627 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4628 case ALTIVEC_BUILTIN_STVEWX:
4629 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4630 case ALTIVEC_BUILTIN_STVXL:
4631 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4632
95385cbb
AH
4633 case ALTIVEC_BUILTIN_MFVSCR:
4634 icode = CODE_FOR_altivec_mfvscr;
4635 tmode = insn_data[icode].operand[0].mode;
4636
4637 if (target == 0
4638 || GET_MODE (target) != tmode
4639 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4640 target = gen_reg_rtx (tmode);
4641
4642 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4643 if (! pat)
4644 return 0;
4645 emit_insn (pat);
95385cbb
AH
4646 return target;
4647
4648 case ALTIVEC_BUILTIN_MTVSCR:
4649 icode = CODE_FOR_altivec_mtvscr;
4650 arg0 = TREE_VALUE (arglist);
4651 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4652 mode0 = insn_data[icode].operand[0].mode;
4653
4654 /* If we got invalid arguments bail out before generating bad rtl. */
4655 if (arg0 == error_mark_node)
9a171fcd 4656 return const0_rtx;
95385cbb
AH
4657
4658 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4659 op0 = copy_to_mode_reg (mode0, op0);
4660
4661 pat = GEN_FCN (icode) (op0);
4662 if (pat)
4663 emit_insn (pat);
4664 return NULL_RTX;
3a9b8c7e 4665
95385cbb
AH
4666 case ALTIVEC_BUILTIN_DSSALL:
4667 emit_insn (gen_altivec_dssall ());
4668 return NULL_RTX;
4669
4670 case ALTIVEC_BUILTIN_DSS:
4671 icode = CODE_FOR_altivec_dss;
4672 arg0 = TREE_VALUE (arglist);
4673 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4674 mode0 = insn_data[icode].operand[0].mode;
4675
4676 /* If we got invalid arguments bail out before generating bad rtl. */
4677 if (arg0 == error_mark_node)
9a171fcd 4678 return const0_rtx;
95385cbb 4679
b44140e7
AH
4680 if (TREE_CODE (arg0) != INTEGER_CST
4681 || TREE_INT_CST_LOW (arg0) & ~0x3)
4682 {
4683 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4684 return const0_rtx;
b44140e7
AH
4685 }
4686
95385cbb
AH
4687 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4688 op0 = copy_to_mode_reg (mode0, op0);
4689
4690 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4691 return NULL_RTX;
4692 }
24408032 4693
100c4561
AH
4694 /* Expand abs* operations. */
4695 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4696 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4697 if (d->code == fcode)
4698 return altivec_expand_abs_builtin (d->icode, arglist, target);
4699
ae4b4a02
AH
4700 /* Expand the AltiVec predicates. */
4701 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4702 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4703 if (dp->code == fcode)
4704 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4705
6525c0e7
AH
4706 /* LV* are funky. We initialized them differently. */
4707 switch (fcode)
4708 {
4709 case ALTIVEC_BUILTIN_LVSL:
92898235 4710 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
4711 arglist, target);
4712 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
4713 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4714 arglist, target);
6525c0e7 4715 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
4716 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4717 arglist, target);
6525c0e7 4718 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
4719 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4720 arglist, target);
6525c0e7 4721 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
4722 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4723 arglist, target);
6525c0e7 4724 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
4725 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4726 arglist, target);
6525c0e7 4727 case ALTIVEC_BUILTIN_LVX:
92898235
AH
4728 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4729 arglist, target);
6525c0e7
AH
4730 default:
4731 break;
4732 /* Fall through. */
4733 }
95385cbb 4734
92898235 4735 *expandedp = false;
0ac081f6
AH
4736 return NULL_RTX;
4737}
4738
a3170dc6
AH
4739/* Binops that need to be initialized manually, but can be expanded
4740 automagically by rs6000_expand_binop_builtin. */
4741static struct builtin_description bdesc_2arg_spe[] =
4742{
4743 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4744 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4745 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4746 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4747 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4748 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4749 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4750 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4751 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4752 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4753 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4754 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4755 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4756 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4757 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4758 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4759 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4760 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4761 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4762 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4763 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4764 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4765};
4766
4767/* Expand the builtin in EXP and store the result in TARGET. Store
4768 true in *EXPANDEDP if we found a builtin to expand.
4769
4770 This expands the SPE builtins that are not simple unary and binary
4771 operations. */
4772static rtx
4773spe_expand_builtin (exp, target, expandedp)
4774 tree exp;
4775 rtx target;
4776 bool *expandedp;
4777{
4778 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4779 tree arglist = TREE_OPERAND (exp, 1);
4780 tree arg1, arg0;
4781 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4782 enum insn_code icode;
4783 enum machine_mode tmode, mode0;
4784 rtx pat, op0;
4785 struct builtin_description *d;
4786 size_t i;
4787
4788 *expandedp = true;
4789
4790 /* Syntax check for a 5-bit unsigned immediate. */
4791 switch (fcode)
4792 {
4793 case SPE_BUILTIN_EVSTDD:
4794 case SPE_BUILTIN_EVSTDH:
4795 case SPE_BUILTIN_EVSTDW:
4796 case SPE_BUILTIN_EVSTWHE:
4797 case SPE_BUILTIN_EVSTWHO:
4798 case SPE_BUILTIN_EVSTWWE:
4799 case SPE_BUILTIN_EVSTWWO:
4800 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4801 if (TREE_CODE (arg1) != INTEGER_CST
4802 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4803 {
4804 error ("argument 2 must be a 5-bit unsigned literal");
4805 return const0_rtx;
4806 }
4807 break;
4808 default:
4809 break;
4810 }
4811
4812 d = (struct builtin_description *) bdesc_2arg_spe;
4813 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4814 if (d->code == fcode)
4815 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4816
4817 d = (struct builtin_description *) bdesc_spe_predicates;
4818 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4819 if (d->code == fcode)
4820 return spe_expand_predicate_builtin (d->icode, arglist, target);
4821
4822 d = (struct builtin_description *) bdesc_spe_evsel;
4823 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4824 if (d->code == fcode)
4825 return spe_expand_evsel_builtin (d->icode, arglist, target);
4826
4827 switch (fcode)
4828 {
4829 case SPE_BUILTIN_EVSTDDX:
4830 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4831 case SPE_BUILTIN_EVSTDHX:
4832 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4833 case SPE_BUILTIN_EVSTDWX:
4834 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
4835 case SPE_BUILTIN_EVSTWHEX:
4836 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
4837 case SPE_BUILTIN_EVSTWHOX:
4838 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
4839 case SPE_BUILTIN_EVSTWWEX:
4840 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
4841 case SPE_BUILTIN_EVSTWWOX:
4842 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
4843 case SPE_BUILTIN_EVSTDD:
4844 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
4845 case SPE_BUILTIN_EVSTDH:
4846 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
4847 case SPE_BUILTIN_EVSTDW:
4848 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
4849 case SPE_BUILTIN_EVSTWHE:
4850 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
4851 case SPE_BUILTIN_EVSTWHO:
4852 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
4853 case SPE_BUILTIN_EVSTWWE:
4854 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
4855 case SPE_BUILTIN_EVSTWWO:
4856 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
4857 case SPE_BUILTIN_MFSPEFSCR:
4858 icode = CODE_FOR_spe_mfspefscr;
4859 tmode = insn_data[icode].operand[0].mode;
4860
4861 if (target == 0
4862 || GET_MODE (target) != tmode
4863 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4864 target = gen_reg_rtx (tmode);
4865
4866 pat = GEN_FCN (icode) (target);
4867 if (! pat)
4868 return 0;
4869 emit_insn (pat);
4870 return target;
4871 case SPE_BUILTIN_MTSPEFSCR:
4872 icode = CODE_FOR_spe_mtspefscr;
4873 arg0 = TREE_VALUE (arglist);
4874 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4875 mode0 = insn_data[icode].operand[0].mode;
4876
4877 if (arg0 == error_mark_node)
4878 return const0_rtx;
4879
4880 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4881 op0 = copy_to_mode_reg (mode0, op0);
4882
4883 pat = GEN_FCN (icode) (op0);
4884 if (pat)
4885 emit_insn (pat);
4886 return NULL_RTX;
4887 default:
4888 break;
4889 }
4890
4891 *expandedp = false;
4892 return NULL_RTX;
4893}
4894
4895static rtx
4896spe_expand_predicate_builtin (icode, arglist, target)
4897 enum insn_code icode;
4898 tree arglist;
4899 rtx target;
4900{
4901 rtx pat, scratch, tmp;
4902 tree form = TREE_VALUE (arglist);
4903 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4904 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4905 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4906 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4907 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4908 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4909 int form_int;
4910 enum rtx_code code;
4911
4912 if (TREE_CODE (form) != INTEGER_CST)
4913 {
4914 error ("argument 1 of __builtin_spe_predicate must be a constant");
4915 return const0_rtx;
4916 }
4917 else
4918 form_int = TREE_INT_CST_LOW (form);
4919
4920 if (mode0 != mode1)
4921 abort ();
4922
4923 if (arg0 == error_mark_node || arg1 == error_mark_node)
4924 return const0_rtx;
4925
4926 if (target == 0
4927 || GET_MODE (target) != SImode
4928 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
4929 target = gen_reg_rtx (SImode);
4930
4931 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4932 op0 = copy_to_mode_reg (mode0, op0);
4933 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4934 op1 = copy_to_mode_reg (mode1, op1);
4935
4936 scratch = gen_reg_rtx (CCmode);
4937
4938 pat = GEN_FCN (icode) (scratch, op0, op1);
4939 if (! pat)
4940 return const0_rtx;
4941 emit_insn (pat);
4942
4943 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
4944 _lower_. We use one compare, but look in different bits of the
4945 CR for each variant.
4946
4947 There are 2 elements in each SPE simd type (upper/lower). The CR
4948 bits are set as follows:
4949
4950 BIT0 | BIT 1 | BIT 2 | BIT 3
4951 U | L | (U | L) | (U & L)
4952
4953 So, for an "all" relationship, BIT 3 would be set.
4954 For an "any" relationship, BIT 2 would be set. Etc.
4955
4956 Following traditional nomenclature, these bits map to:
4957
4958 BIT0 | BIT 1 | BIT 2 | BIT 3
4959 LT | GT | EQ | OV
4960
4961 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
4962 */
4963
4964 switch (form_int)
4965 {
4966 /* All variant. OV bit. */
4967 case 0:
4968 /* We need to get to the OV bit, which is the ORDERED bit. We
4969 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
4970 that's ugly and will trigger a validate_condition_mode abort.
4971 So let's just use another pattern. */
4972 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
4973 return target;
4974 /* Any variant. EQ bit. */
4975 case 1:
4976 code = EQ;
4977 break;
4978 /* Upper variant. LT bit. */
4979 case 2:
4980 code = LT;
4981 break;
4982 /* Lower variant. GT bit. */
4983 case 3:
4984 code = GT;
4985 break;
4986 default:
4987 error ("argument 1 of __builtin_spe_predicate is out of range");
4988 return const0_rtx;
4989 }
4990
4991 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
4992 emit_move_insn (target, tmp);
4993
4994 return target;
4995}
4996
4997/* The evsel builtins look like this:
4998
4999 e = __builtin_spe_evsel_OP (a, b, c, d);
5000
5001 and work like this:
5002
5003 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5004 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5005*/
5006
5007static rtx
5008spe_expand_evsel_builtin (icode, arglist, target)
5009 enum insn_code icode;
5010 tree arglist;
5011 rtx target;
5012{
5013 rtx pat, scratch;
5014 tree arg0 = TREE_VALUE (arglist);
5015 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5016 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5017 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5018 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5019 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5020 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5021 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5022 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5023 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5024
5025 if (mode0 != mode1)
5026 abort ();
5027
5028 if (arg0 == error_mark_node || arg1 == error_mark_node
5029 || arg2 == error_mark_node || arg3 == error_mark_node)
5030 return const0_rtx;
5031
5032 if (target == 0
5033 || GET_MODE (target) != mode0
5034 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5035 target = gen_reg_rtx (mode0);
5036
5037 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5038 op0 = copy_to_mode_reg (mode0, op0);
5039 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5040 op1 = copy_to_mode_reg (mode0, op1);
5041 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5042 op2 = copy_to_mode_reg (mode0, op2);
5043 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5044 op3 = copy_to_mode_reg (mode0, op3);
5045
5046 /* Generate the compare. */
5047 scratch = gen_reg_rtx (CCmode);
5048 pat = GEN_FCN (icode) (scratch, op0, op1);
5049 if (! pat)
5050 return const0_rtx;
5051 emit_insn (pat);
5052
5053 if (mode0 == V2SImode)
5054 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5055 else
5056 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5057
5058 return target;
5059}
5060
0ac081f6
AH
5061/* Expand an expression EXP that calls a built-in function,
5062 with result going to TARGET if that's convenient
5063 (and in mode MODE if that's convenient).
5064 SUBTARGET may be used as the target for computing one of EXP's operands.
5065 IGNORE is nonzero if the value is to be ignored. */
5066
5067static rtx
5068rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5069 tree exp;
5070 rtx target;
00b960c7
AH
5071 rtx subtarget ATTRIBUTE_UNUSED;
5072 enum machine_mode mode ATTRIBUTE_UNUSED;
5073 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5074{
92898235
AH
5075 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5076 tree arglist = TREE_OPERAND (exp, 1);
5077 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5078 struct builtin_description *d;
5079 size_t i;
5080 rtx ret;
5081 bool success;
5082
0ac081f6 5083 if (TARGET_ALTIVEC)
92898235
AH
5084 {
5085 ret = altivec_expand_builtin (exp, target, &success);
5086
a3170dc6
AH
5087 if (success)
5088 return ret;
5089 }
5090 if (TARGET_SPE)
5091 {
5092 ret = spe_expand_builtin (exp, target, &success);
5093
92898235
AH
5094 if (success)
5095 return ret;
5096 }
5097
0559cc77
DE
5098 if (TARGET_ALTIVEC || TARGET_SPE)
5099 {
5100 /* Handle simple unary operations. */
5101 d = (struct builtin_description *) bdesc_1arg;
5102 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5103 if (d->code == fcode)
5104 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5105
5106 /* Handle simple binary operations. */
5107 d = (struct builtin_description *) bdesc_2arg;
5108 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5109 if (d->code == fcode)
5110 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5111
5112 /* Handle simple ternary operations. */
5113 d = (struct builtin_description *) bdesc_3arg;
5114 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5115 if (d->code == fcode)
5116 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5117 }
0ac081f6
AH
5118
5119 abort ();
92898235 5120 return NULL_RTX;
0ac081f6
AH
5121}
5122
5123static void
6fa3f289 5124rs6000_init_builtins ()
0ac081f6 5125{
a3170dc6
AH
5126 if (TARGET_SPE)
5127 spe_init_builtins ();
0ac081f6
AH
5128 if (TARGET_ALTIVEC)
5129 altivec_init_builtins ();
0559cc77
DE
5130 if (TARGET_ALTIVEC || TARGET_SPE)
5131 rs6000_common_init_builtins ();
0ac081f6
AH
5132}
5133
a3170dc6
AH
5134/* Search through a set of builtins and enable the mask bits.
5135 DESC is an array of builtins.
5136 SIZE is the totaly number of builtins.
5137 START is the builtin enum at which to start.
5138 END is the builtin enum at which to end. */
0ac081f6 5139static void
a3170dc6
AH
5140enable_mask_for_builtins (desc, size, start, end)
5141 struct builtin_description *desc;
5142 int size;
5143 enum rs6000_builtins start, end;
5144{
5145 int i;
5146
5147 for (i = 0; i < size; ++i)
5148 if (desc[i].code == start)
5149 break;
5150
5151 if (i == size)
5152 return;
5153
5154 for (; i < size; ++i)
5155 {
5156 /* Flip all the bits on. */
5157 desc[i].mask = target_flags;
5158 if (desc[i].code == end)
5159 break;
5160 }
5161}
5162
5163static void
b24c9d35 5164spe_init_builtins ()
0ac081f6 5165{
a3170dc6
AH
5166 tree endlink = void_list_node;
5167 tree puint_type_node = build_pointer_type (unsigned_type_node);
5168 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5169 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5170 struct builtin_description *d;
0ac081f6
AH
5171 size_t i;
5172
a3170dc6
AH
5173 tree v2si_ftype_4_v2si
5174 = build_function_type
5175 (V2SI_type_node,
5176 tree_cons (NULL_TREE, V2SI_type_node,
5177 tree_cons (NULL_TREE, V2SI_type_node,
5178 tree_cons (NULL_TREE, V2SI_type_node,
5179 tree_cons (NULL_TREE, V2SI_type_node,
5180 endlink)))));
5181
5182 tree v2sf_ftype_4_v2sf
5183 = build_function_type
5184 (V2SF_type_node,
5185 tree_cons (NULL_TREE, V2SF_type_node,
5186 tree_cons (NULL_TREE, V2SF_type_node,
5187 tree_cons (NULL_TREE, V2SF_type_node,
5188 tree_cons (NULL_TREE, V2SF_type_node,
5189 endlink)))));
5190
5191 tree int_ftype_int_v2si_v2si
5192 = build_function_type
5193 (integer_type_node,
5194 tree_cons (NULL_TREE, integer_type_node,
5195 tree_cons (NULL_TREE, V2SI_type_node,
5196 tree_cons (NULL_TREE, V2SI_type_node,
5197 endlink))));
5198
5199 tree int_ftype_int_v2sf_v2sf
5200 = build_function_type
5201 (integer_type_node,
5202 tree_cons (NULL_TREE, integer_type_node,
5203 tree_cons (NULL_TREE, V2SF_type_node,
5204 tree_cons (NULL_TREE, V2SF_type_node,
5205 endlink))));
5206
5207 tree void_ftype_v2si_puint_int
5208 = build_function_type (void_type_node,
5209 tree_cons (NULL_TREE, V2SI_type_node,
5210 tree_cons (NULL_TREE, puint_type_node,
5211 tree_cons (NULL_TREE,
5212 integer_type_node,
5213 endlink))));
5214
5215 tree void_ftype_v2si_puint_char
5216 = build_function_type (void_type_node,
5217 tree_cons (NULL_TREE, V2SI_type_node,
5218 tree_cons (NULL_TREE, puint_type_node,
5219 tree_cons (NULL_TREE,
5220 char_type_node,
5221 endlink))));
5222
5223 tree void_ftype_v2si_pv2si_int
5224 = build_function_type (void_type_node,
5225 tree_cons (NULL_TREE, V2SI_type_node,
5226 tree_cons (NULL_TREE, pv2si_type_node,
5227 tree_cons (NULL_TREE,
5228 integer_type_node,
5229 endlink))));
5230
5231 tree void_ftype_v2si_pv2si_char
5232 = build_function_type (void_type_node,
5233 tree_cons (NULL_TREE, V2SI_type_node,
5234 tree_cons (NULL_TREE, pv2si_type_node,
5235 tree_cons (NULL_TREE,
5236 char_type_node,
5237 endlink))));
5238
5239 tree void_ftype_int
5240 = build_function_type (void_type_node,
5241 tree_cons (NULL_TREE, integer_type_node, endlink));
5242
5243 tree int_ftype_void
5244 = build_function_type (integer_type_node,
5245 tree_cons (NULL_TREE, void_type_node, endlink));
5246
5247 tree v2si_ftype_pv2si_int
5248 = build_function_type (V2SI_type_node,
5249 tree_cons (NULL_TREE, pv2si_type_node,
5250 tree_cons (NULL_TREE, integer_type_node,
5251 endlink)));
5252
5253 tree v2si_ftype_puint_int
5254 = build_function_type (V2SI_type_node,
5255 tree_cons (NULL_TREE, puint_type_node,
5256 tree_cons (NULL_TREE, integer_type_node,
5257 endlink)));
5258
5259 tree v2si_ftype_pushort_int
5260 = build_function_type (V2SI_type_node,
5261 tree_cons (NULL_TREE, pushort_type_node,
5262 tree_cons (NULL_TREE, integer_type_node,
5263 endlink)));
5264
5265 /* The initialization of the simple binary and unary builtins is
5266 done in rs6000_common_init_builtins, but we have to enable the
5267 mask bits here manually because we have run out of `target_flags'
5268 bits. We really need to redesign this mask business. */
5269
5270 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5271 ARRAY_SIZE (bdesc_2arg),
5272 SPE_BUILTIN_EVADDW,
5273 SPE_BUILTIN_EVXOR);
5274 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5275 ARRAY_SIZE (bdesc_1arg),
5276 SPE_BUILTIN_EVABS,
5277 SPE_BUILTIN_EVSUBFUSIAAW);
5278 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5279 ARRAY_SIZE (bdesc_spe_predicates),
5280 SPE_BUILTIN_EVCMPEQ,
5281 SPE_BUILTIN_EVFSTSTLT);
5282 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5283 ARRAY_SIZE (bdesc_spe_evsel),
5284 SPE_BUILTIN_EVSEL_CMPGTS,
5285 SPE_BUILTIN_EVSEL_FSTSTEQ);
5286
5287 /* Initialize irregular SPE builtins. */
5288
5289 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5290 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5291 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5292 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5293 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5294 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5295 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5296 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5297 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5298 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5299 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5300 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5301 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5302 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5303 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5304 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5305
5306 /* Loads. */
5307 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5308 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5309 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5310 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5311 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5312 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5313 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5314 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5315 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5316 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5317 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5318 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5319 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5320 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5321 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5322 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5323 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5324 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5325 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5326 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5327 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5328 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5329
5330 /* Predicates. */
5331 d = (struct builtin_description *) bdesc_spe_predicates;
5332 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5333 {
5334 tree type;
5335
5336 switch (insn_data[d->icode].operand[1].mode)
5337 {
5338 case V2SImode:
5339 type = int_ftype_int_v2si_v2si;
5340 break;
5341 case V2SFmode:
5342 type = int_ftype_int_v2sf_v2sf;
5343 break;
5344 default:
5345 abort ();
5346 }
5347
5348 def_builtin (d->mask, d->name, type, d->code);
5349 }
5350
5351 /* Evsel predicates. */
5352 d = (struct builtin_description *) bdesc_spe_evsel;
5353 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5354 {
5355 tree type;
5356
5357 switch (insn_data[d->icode].operand[1].mode)
5358 {
5359 case V2SImode:
5360 type = v2si_ftype_4_v2si;
5361 break;
5362 case V2SFmode:
5363 type = v2sf_ftype_4_v2sf;
5364 break;
5365 default:
5366 abort ();
5367 }
5368
5369 def_builtin (d->mask, d->name, type, d->code);
5370 }
5371}
5372
5373static void
b24c9d35 5374altivec_init_builtins ()
a3170dc6
AH
5375{
5376 struct builtin_description *d;
5377 struct builtin_description_predicates *dp;
5378 size_t i;
5379 tree pfloat_type_node = build_pointer_type (float_type_node);
5380 tree pint_type_node = build_pointer_type (integer_type_node);
5381 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5382 tree pchar_type_node = build_pointer_type (char_type_node);
5383
5384 tree pvoid_type_node = build_pointer_type (void_type_node);
5385
5386 tree int_ftype_int_v4si_v4si
5387 = build_function_type_list (integer_type_node,
5388 integer_type_node, V4SI_type_node,
5389 V4SI_type_node, NULL_TREE);
f18c054f 5390 tree v4sf_ftype_pfloat
b4de2f7d 5391 = build_function_type_list (V4SF_type_node, pfloat_type_node, NULL_TREE);
a3170dc6 5392 tree void_ftype_pfloat_v4sf
b4de2f7d 5393 = build_function_type_list (void_type_node,
a3170dc6
AH
5394 pfloat_type_node, V4SF_type_node, NULL_TREE);
5395 tree v4si_ftype_pint
5396 = build_function_type_list (V4SI_type_node, pint_type_node, NULL_TREE); tree void_ftype_pint_v4si
b4de2f7d
AH
5397 = build_function_type_list (void_type_node,
5398 pint_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5399 tree v8hi_ftype_pshort
5400 = build_function_type_list (V8HI_type_node, pshort_type_node, NULL_TREE);
f18c054f 5401 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5402 = build_function_type_list (void_type_node,
5403 pshort_type_node, V8HI_type_node, NULL_TREE);
a3170dc6
AH
5404 tree v16qi_ftype_pchar
5405 = build_function_type_list (V16QI_type_node, pchar_type_node, NULL_TREE);
f18c054f 5406 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5407 = build_function_type_list (void_type_node,
5408 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5409 tree void_ftype_v4si
b4de2f7d 5410 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5411 tree v8hi_ftype_void
5412 = build_function_type (V8HI_type_node, void_list_node);
5413 tree void_ftype_void
5414 = build_function_type (void_type_node, void_list_node);
5415 tree void_ftype_qi
5416 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
5417 tree v16qi_ftype_int_pvoid
5418 = build_function_type_list (V16QI_type_node,
5419 integer_type_node, pvoid_type_node, NULL_TREE);
5420 tree v8hi_ftype_int_pvoid
5421 = build_function_type_list (V8HI_type_node,
5422 integer_type_node, pvoid_type_node, NULL_TREE);
5423 tree v4si_ftype_int_pvoid
5424 = build_function_type_list (V4SI_type_node,
5425 integer_type_node, pvoid_type_node, NULL_TREE);
14b32f4e 5426 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5427 = build_function_type_list (void_type_node,
5428 V4SI_type_node, integer_type_node,
5429 pvoid_type_node, NULL_TREE);
6525c0e7 5430 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5431 = build_function_type_list (void_type_node,
5432 V16QI_type_node, integer_type_node,
5433 pvoid_type_node, NULL_TREE);
6525c0e7 5434 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5435 = build_function_type_list (void_type_node,
5436 V8HI_type_node, integer_type_node,
5437 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5438 tree int_ftype_int_v8hi_v8hi
5439 = build_function_type_list (integer_type_node,
5440 integer_type_node, V8HI_type_node,
5441 V8HI_type_node, NULL_TREE);
5442 tree int_ftype_int_v16qi_v16qi
5443 = build_function_type_list (integer_type_node,
5444 integer_type_node, V16QI_type_node,
5445 V16QI_type_node, NULL_TREE);
5446 tree int_ftype_int_v4sf_v4sf
5447 = build_function_type_list (integer_type_node,
5448 integer_type_node, V4SF_type_node,
5449 V4SF_type_node, NULL_TREE);
5450 tree v4si_ftype_v4si
5451 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5452 tree v8hi_ftype_v8hi
5453 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5454 tree v16qi_ftype_v16qi
5455 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5456 tree v4sf_ftype_v4sf
5457 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5458 tree void_ftype_pvoid_int_char
5459 = build_function_type_list (void_type_node,
5460 pvoid_type_node, integer_type_node,
5461 char_type_node, NULL_TREE);
5462
5463 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pfloat, ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5464 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf, ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5465 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5466 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5467 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pshort, ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5468 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi, ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5469 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pchar, ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5470 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi, ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
5471 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5472 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5473 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5474 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
5475 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
5476 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
5477 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEBX);
5478 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEHX);
5479 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEWX);
5480 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVXL);
5481 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVX);
5482 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5483 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5484 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5485 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5486 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5487
5488 /* Add the DST variants. */
5489 d = (struct builtin_description *) bdesc_dst;
5490 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
5491 def_builtin (d->mask, d->name, void_ftype_pvoid_int_char, d->code);
5492
5493 /* Initialize the predicates. */
5494 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5495 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5496 {
5497 enum machine_mode mode1;
5498 tree type;
5499
5500 mode1 = insn_data[dp->icode].operand[1].mode;
5501
5502 switch (mode1)
5503 {
5504 case V4SImode:
5505 type = int_ftype_int_v4si_v4si;
5506 break;
5507 case V8HImode:
5508 type = int_ftype_int_v8hi_v8hi;
5509 break;
5510 case V16QImode:
5511 type = int_ftype_int_v16qi_v16qi;
5512 break;
5513 case V4SFmode:
5514 type = int_ftype_int_v4sf_v4sf;
5515 break;
5516 default:
5517 abort ();
5518 }
5519
5520 def_builtin (dp->mask, dp->name, type, dp->code);
5521 }
5522
5523 /* Initialize the abs* operators. */
5524 d = (struct builtin_description *) bdesc_abs;
5525 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5526 {
5527 enum machine_mode mode0;
5528 tree type;
5529
5530 mode0 = insn_data[d->icode].operand[0].mode;
5531
5532 switch (mode0)
5533 {
5534 case V4SImode:
5535 type = v4si_ftype_v4si;
5536 break;
5537 case V8HImode:
5538 type = v8hi_ftype_v8hi;
5539 break;
5540 case V16QImode:
5541 type = v16qi_ftype_v16qi;
5542 break;
5543 case V4SFmode:
5544 type = v4sf_ftype_v4sf;
5545 break;
5546 default:
5547 abort ();
5548 }
5549
5550 def_builtin (d->mask, d->name, type, d->code);
5551 }
5552}
5553
5554static void
b24c9d35 5555rs6000_common_init_builtins ()
a3170dc6
AH
5556{
5557 struct builtin_description *d;
5558 size_t i;
5559
5560 tree v4sf_ftype_v4sf_v4sf_v16qi
5561 = build_function_type_list (V4SF_type_node,
5562 V4SF_type_node, V4SF_type_node,
5563 V16QI_type_node, NULL_TREE);
5564 tree v4si_ftype_v4si_v4si_v16qi
5565 = build_function_type_list (V4SI_type_node,
5566 V4SI_type_node, V4SI_type_node,
5567 V16QI_type_node, NULL_TREE);
5568 tree v8hi_ftype_v8hi_v8hi_v16qi
5569 = build_function_type_list (V8HI_type_node,
5570 V8HI_type_node, V8HI_type_node,
5571 V16QI_type_node, NULL_TREE);
5572 tree v16qi_ftype_v16qi_v16qi_v16qi
5573 = build_function_type_list (V16QI_type_node,
5574 V16QI_type_node, V16QI_type_node,
5575 V16QI_type_node, NULL_TREE);
5576 tree v4si_ftype_char
5577 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5578 tree v8hi_ftype_char
5579 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5580 tree v16qi_ftype_char
5581 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5582 tree v8hi_ftype_v16qi
5583 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5584 tree v4sf_ftype_v4sf
5585 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5586
5587 tree v2si_ftype_v2si_v2si
5588 = build_function_type_list (V2SI_type_node,
5589 V2SI_type_node, V2SI_type_node, NULL_TREE);
5590
5591 tree v2sf_ftype_v2sf_v2sf
5592 = build_function_type_list (V2SF_type_node,
5593 V2SF_type_node, V2SF_type_node, NULL_TREE);
5594
5595 tree v2si_ftype_int_int
5596 = build_function_type_list (V2SI_type_node,
5597 integer_type_node, integer_type_node,
5598 NULL_TREE);
5599
5600 tree v2si_ftype_v2si
5601 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5602
5603 tree v2sf_ftype_v2sf
5604 = build_function_type_list (V2SF_type_node,
5605 V2SF_type_node, NULL_TREE);
5606
5607 tree v2sf_ftype_v2si
5608 = build_function_type_list (V2SF_type_node,
5609 V2SI_type_node, NULL_TREE);
5610
5611 tree v2si_ftype_v2sf
5612 = build_function_type_list (V2SI_type_node,
5613 V2SF_type_node, NULL_TREE);
5614
5615 tree v2si_ftype_v2si_char
5616 = build_function_type_list (V2SI_type_node,
5617 V2SI_type_node, char_type_node, NULL_TREE);
5618
5619 tree v2si_ftype_int_char
5620 = build_function_type_list (V2SI_type_node,
5621 integer_type_node, char_type_node, NULL_TREE);
5622
5623 tree v2si_ftype_char
5624 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5625
5626 tree int_ftype_int_int
5627 = build_function_type_list (integer_type_node,
5628 integer_type_node, integer_type_node,
5629 NULL_TREE);
95385cbb 5630
0ac081f6 5631 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5632 = build_function_type_list (V4SI_type_node,
5633 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5634 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5635 = build_function_type_list (V4SF_type_node,
5636 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5637 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5638 = build_function_type_list (V4SI_type_node,
5639 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5640 tree v4si_ftype_v4si_char
b4de2f7d
AH
5641 = build_function_type_list (V4SI_type_node,
5642 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5643 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5644 = build_function_type_list (V8HI_type_node,
5645 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5646 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5647 = build_function_type_list (V16QI_type_node,
5648 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5649 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5650 = build_function_type_list (V16QI_type_node,
5651 V16QI_type_node, V16QI_type_node,
5652 char_type_node, NULL_TREE);
24408032 5653 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5654 = build_function_type_list (V8HI_type_node,
5655 V8HI_type_node, V8HI_type_node,
5656 char_type_node, NULL_TREE);
24408032 5657 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5658 = build_function_type_list (V4SI_type_node,
5659 V4SI_type_node, V4SI_type_node,
5660 char_type_node, NULL_TREE);
24408032 5661 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5662 = build_function_type_list (V4SF_type_node,
5663 V4SF_type_node, V4SF_type_node,
5664 char_type_node, NULL_TREE);
0ac081f6 5665 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5666 = build_function_type_list (V4SF_type_node,
5667 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5668 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5669 = build_function_type_list (V4SF_type_node,
5670 V4SF_type_node, V4SF_type_node,
5671 V4SI_type_node, NULL_TREE);
2212663f 5672 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5673 = build_function_type_list (V4SF_type_node,
5674 V4SF_type_node, V4SF_type_node,
5675 V4SF_type_node, NULL_TREE);
617e0e1d 5676 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
5677 = build_function_type_list (V4SI_type_node,
5678 V4SI_type_node, V4SI_type_node,
5679 V4SI_type_node, NULL_TREE);
0ac081f6 5680 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
5681 = build_function_type_list (V8HI_type_node,
5682 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 5683 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
5684 = build_function_type_list (V8HI_type_node,
5685 V8HI_type_node, V8HI_type_node,
5686 V8HI_type_node, NULL_TREE);
2212663f 5687 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
5688 = build_function_type_list (V4SI_type_node,
5689 V8HI_type_node, V8HI_type_node,
5690 V4SI_type_node, NULL_TREE);
2212663f 5691 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
5692 = build_function_type_list (V4SI_type_node,
5693 V16QI_type_node, V16QI_type_node,
5694 V4SI_type_node, NULL_TREE);
0ac081f6 5695 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
5696 = build_function_type_list (V16QI_type_node,
5697 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5698 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
5699 = build_function_type_list (V4SI_type_node,
5700 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 5701 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
5702 = build_function_type_list (V8HI_type_node,
5703 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5704 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
5705 = build_function_type_list (V4SI_type_node,
5706 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5707 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
5708 = build_function_type_list (V8HI_type_node,
5709 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 5710 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
5711 = build_function_type_list (V16QI_type_node,
5712 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5713 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
5714 = build_function_type_list (V4SI_type_node,
5715 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 5716 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
5717 = build_function_type_list (V4SI_type_node,
5718 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5719 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
5720 = build_function_type_list (V4SI_type_node,
5721 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5722 tree v4si_ftype_v8hi
5723 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5724 tree int_ftype_v4si_v4si
5725 = build_function_type_list (integer_type_node,
5726 V4SI_type_node, V4SI_type_node, NULL_TREE);
5727 tree int_ftype_v4sf_v4sf
5728 = build_function_type_list (integer_type_node,
5729 V4SF_type_node, V4SF_type_node, NULL_TREE);
5730 tree int_ftype_v16qi_v16qi
5731 = build_function_type_list (integer_type_node,
5732 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5733 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
5734 = build_function_type_list (integer_type_node,
5735 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5736
6f317ef3 5737 /* Add the simple ternary operators. */
2212663f 5738 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 5739 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
5740 {
5741
5742 enum machine_mode mode0, mode1, mode2, mode3;
5743 tree type;
5744
0559cc77 5745 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5746 continue;
5747
5748 mode0 = insn_data[d->icode].operand[0].mode;
5749 mode1 = insn_data[d->icode].operand[1].mode;
5750 mode2 = insn_data[d->icode].operand[2].mode;
5751 mode3 = insn_data[d->icode].operand[3].mode;
5752
5753 /* When all four are of the same mode. */
5754 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5755 {
5756 switch (mode0)
5757 {
617e0e1d
DB
5758 case V4SImode:
5759 type = v4si_ftype_v4si_v4si_v4si;
5760 break;
2212663f
DB
5761 case V4SFmode:
5762 type = v4sf_ftype_v4sf_v4sf_v4sf;
5763 break;
5764 case V8HImode:
5765 type = v8hi_ftype_v8hi_v8hi_v8hi;
5766 break;
5767 case V16QImode:
5768 type = v16qi_ftype_v16qi_v16qi_v16qi;
5769 break;
5770 default:
5771 abort();
5772 }
5773 }
5774 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5775 {
5776 switch (mode0)
5777 {
5778 case V4SImode:
5779 type = v4si_ftype_v4si_v4si_v16qi;
5780 break;
5781 case V4SFmode:
5782 type = v4sf_ftype_v4sf_v4sf_v16qi;
5783 break;
5784 case V8HImode:
5785 type = v8hi_ftype_v8hi_v8hi_v16qi;
5786 break;
5787 case V16QImode:
5788 type = v16qi_ftype_v16qi_v16qi_v16qi;
5789 break;
5790 default:
5791 abort();
5792 }
5793 }
5794 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5795 && mode3 == V4SImode)
24408032 5796 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
5797 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5798 && mode3 == V4SImode)
24408032 5799 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
5800 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5801 && mode3 == V4SImode)
24408032
AH
5802 type = v4sf_ftype_v4sf_v4sf_v4si;
5803
5804 /* vchar, vchar, vchar, 4 bit literal. */
5805 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5806 && mode3 == QImode)
5807 type = v16qi_ftype_v16qi_v16qi_char;
5808
5809 /* vshort, vshort, vshort, 4 bit literal. */
5810 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5811 && mode3 == QImode)
5812 type = v8hi_ftype_v8hi_v8hi_char;
5813
5814 /* vint, vint, vint, 4 bit literal. */
5815 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
5816 && mode3 == QImode)
5817 type = v4si_ftype_v4si_v4si_char;
5818
5819 /* vfloat, vfloat, vfloat, 4 bit literal. */
5820 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
5821 && mode3 == QImode)
5822 type = v4sf_ftype_v4sf_v4sf_char;
5823
2212663f
DB
5824 else
5825 abort ();
5826
5827 def_builtin (d->mask, d->name, type, d->code);
5828 }
5829
0ac081f6 5830 /* Add the simple binary operators. */
00b960c7 5831 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 5832 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
5833 {
5834 enum machine_mode mode0, mode1, mode2;
5835 tree type;
5836
0559cc77 5837 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
5838 continue;
5839
5840 mode0 = insn_data[d->icode].operand[0].mode;
5841 mode1 = insn_data[d->icode].operand[1].mode;
5842 mode2 = insn_data[d->icode].operand[2].mode;
5843
5844 /* When all three operands are of the same mode. */
5845 if (mode0 == mode1 && mode1 == mode2)
5846 {
5847 switch (mode0)
5848 {
5849 case V4SFmode:
5850 type = v4sf_ftype_v4sf_v4sf;
5851 break;
5852 case V4SImode:
5853 type = v4si_ftype_v4si_v4si;
5854 break;
5855 case V16QImode:
5856 type = v16qi_ftype_v16qi_v16qi;
5857 break;
5858 case V8HImode:
5859 type = v8hi_ftype_v8hi_v8hi;
5860 break;
a3170dc6
AH
5861 case V2SImode:
5862 type = v2si_ftype_v2si_v2si;
5863 break;
5864 case V2SFmode:
5865 type = v2sf_ftype_v2sf_v2sf;
5866 break;
5867 case SImode:
5868 type = int_ftype_int_int;
5869 break;
0ac081f6
AH
5870 default:
5871 abort ();
5872 }
5873 }
5874
5875 /* A few other combos we really don't want to do manually. */
5876
5877 /* vint, vfloat, vfloat. */
5878 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
5879 type = v4si_ftype_v4sf_v4sf;
5880
5881 /* vshort, vchar, vchar. */
5882 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
5883 type = v8hi_ftype_v16qi_v16qi;
5884
5885 /* vint, vshort, vshort. */
5886 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
5887 type = v4si_ftype_v8hi_v8hi;
5888
5889 /* vshort, vint, vint. */
5890 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
5891 type = v8hi_ftype_v4si_v4si;
5892
5893 /* vchar, vshort, vshort. */
5894 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
5895 type = v16qi_ftype_v8hi_v8hi;
5896
5897 /* vint, vchar, vint. */
5898 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
5899 type = v4si_ftype_v16qi_v4si;
5900
fa066a23
AH
5901 /* vint, vchar, vchar. */
5902 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
5903 type = v4si_ftype_v16qi_v16qi;
5904
0ac081f6
AH
5905 /* vint, vshort, vint. */
5906 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
5907 type = v4si_ftype_v8hi_v4si;
2212663f
DB
5908
5909 /* vint, vint, 5 bit literal. */
5910 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
5911 type = v4si_ftype_v4si_char;
5912
5913 /* vshort, vshort, 5 bit literal. */
5914 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
5915 type = v8hi_ftype_v8hi_char;
5916
5917 /* vchar, vchar, 5 bit literal. */
5918 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
5919 type = v16qi_ftype_v16qi_char;
0ac081f6 5920
617e0e1d
DB
5921 /* vfloat, vint, 5 bit literal. */
5922 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
5923 type = v4sf_ftype_v4si_char;
5924
5925 /* vint, vfloat, 5 bit literal. */
5926 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
5927 type = v4si_ftype_v4sf_char;
5928
a3170dc6
AH
5929 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
5930 type = v2si_ftype_int_int;
5931
5932 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
5933 type = v2si_ftype_v2si_char;
5934
5935 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
5936 type = v2si_ftype_int_char;
5937
0ac081f6
AH
5938 /* int, x, x. */
5939 else if (mode0 == SImode)
5940 {
5941 switch (mode1)
5942 {
5943 case V4SImode:
5944 type = int_ftype_v4si_v4si;
5945 break;
5946 case V4SFmode:
5947 type = int_ftype_v4sf_v4sf;
5948 break;
5949 case V16QImode:
5950 type = int_ftype_v16qi_v16qi;
5951 break;
5952 case V8HImode:
5953 type = int_ftype_v8hi_v8hi;
5954 break;
5955 default:
5956 abort ();
5957 }
5958 }
5959
5960 else
5961 abort ();
5962
2212663f
DB
5963 def_builtin (d->mask, d->name, type, d->code);
5964 }
24408032 5965
2212663f
DB
5966 /* Add the simple unary operators. */
5967 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 5968 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
5969 {
5970 enum machine_mode mode0, mode1;
5971 tree type;
5972
0559cc77 5973 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5974 continue;
5975
5976 mode0 = insn_data[d->icode].operand[0].mode;
5977 mode1 = insn_data[d->icode].operand[1].mode;
5978
5979 if (mode0 == V4SImode && mode1 == QImode)
5980 type = v4si_ftype_char;
5981 else if (mode0 == V8HImode && mode1 == QImode)
5982 type = v8hi_ftype_char;
5983 else if (mode0 == V16QImode && mode1 == QImode)
5984 type = v16qi_ftype_char;
617e0e1d
DB
5985 else if (mode0 == V4SFmode && mode1 == V4SFmode)
5986 type = v4sf_ftype_v4sf;
20e26713
AH
5987 else if (mode0 == V8HImode && mode1 == V16QImode)
5988 type = v8hi_ftype_v16qi;
5989 else if (mode0 == V4SImode && mode1 == V8HImode)
5990 type = v4si_ftype_v8hi;
a3170dc6
AH
5991 else if (mode0 == V2SImode && mode1 == V2SImode)
5992 type = v2si_ftype_v2si;
5993 else if (mode0 == V2SFmode && mode1 == V2SFmode)
5994 type = v2sf_ftype_v2sf;
5995 else if (mode0 == V2SFmode && mode1 == V2SImode)
5996 type = v2sf_ftype_v2si;
5997 else if (mode0 == V2SImode && mode1 == V2SFmode)
5998 type = v2si_ftype_v2sf;
5999 else if (mode0 == V2SImode && mode1 == QImode)
6000 type = v2si_ftype_char;
2212663f
DB
6001 else
6002 abort ();
6003
0ac081f6
AH
6004 def_builtin (d->mask, d->name, type, d->code);
6005 }
6006}
6007
5b5040b9
RK
6008/* Generate a memory reference for expand_block_move, copying volatile,
6009 and other bits from an original memory reference. */
6010
6011static rtx
6012expand_block_move_mem (mode, addr, orig_mem)
6013 enum machine_mode mode;
6014 rtx addr;
6015 rtx orig_mem;
6016{
39403d82 6017 rtx mem = gen_rtx_MEM (mode, addr);
b6c9286a 6018
c6df88cb 6019 MEM_COPY_ATTRIBUTES (mem, orig_mem);
5b5040b9
RK
6020 return mem;
6021}
6022
7e69e155
MM
6023/* Expand a block move operation, and return 1 if successful. Return 0
6024 if we should let the compiler generate normal code.
6025
6026 operands[0] is the destination
6027 operands[1] is the source
6028 operands[2] is the length
6029 operands[3] is the alignment */
6030
3933e0e1
MM
6031#define MAX_MOVE_REG 4
6032
7e69e155
MM
6033int
6034expand_block_move (operands)
6035 rtx operands[];
6036{
b6c9286a
MM
6037 rtx orig_dest = operands[0];
6038 rtx orig_src = operands[1];
7e69e155 6039 rtx bytes_rtx = operands[2];
7e69e155 6040 rtx align_rtx = operands[3];
3933e0e1 6041 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6042 int align;
3933e0e1
MM
6043 int bytes;
6044 int offset;
6045 int num_reg;
6046 int i;
7e69e155
MM
6047 rtx src_reg;
6048 rtx dest_reg;
3933e0e1
MM
6049 rtx src_addr;
6050 rtx dest_addr;
7e69e155 6051 rtx tmp_reg;
3933e0e1 6052 rtx stores[MAX_MOVE_REG];
7e69e155
MM
6053 int move_bytes;
6054
3933e0e1 6055 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6056 if (! constp)
3933e0e1
MM
6057 return 0;
6058
5ee95df6
FS
6059 /* If this is not a fixed size alignment, abort */
6060 if (GET_CODE (align_rtx) != CONST_INT)
6061 abort ();
6062 align = INTVAL (align_rtx);
6063
7e69e155 6064 /* Anything to move? */
3933e0e1
MM
6065 bytes = INTVAL (bytes_rtx);
6066 if (bytes <= 0)
7e69e155
MM
6067 return 1;
6068
ea9982a8 6069 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6070 reg_parm_stack_space. */
ea9982a8 6071 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6072 return 0;
6073
6074 /* Move the address into scratch registers. */
b6c9286a
MM
6075 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
6076 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
7e69e155 6077
3933e0e1 6078 if (TARGET_STRING) /* string instructions are available */
7e69e155 6079 {
3933e0e1 6080 for ( ; bytes > 0; bytes -= move_bytes)
7e69e155 6081 {
3933e0e1 6082 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6083 && ! fixed_regs[5]
6084 && ! fixed_regs[6]
6085 && ! fixed_regs[7]
6086 && ! fixed_regs[8]
6087 && ! fixed_regs[9]
6088 && ! fixed_regs[10]
6089 && ! fixed_regs[11]
6090 && ! fixed_regs[12])
3933e0e1
MM
6091 {
6092 move_bytes = (bytes > 32) ? 32 : bytes;
cc0d9ba8
DE
6093 emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode,
6094 dest_reg,
6095 orig_dest),
6096 expand_block_move_mem (BLKmode,
6097 src_reg,
6098 orig_src),
6099 GEN_INT ((move_bytes == 32)
6100 ? 0 : move_bytes),
4c64a852 6101 align_rtx));
3933e0e1
MM
6102 }
6103 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6104 && ! fixed_regs[5]
6105 && ! fixed_regs[6]
cc0d9ba8
DE
6106 && ! fixed_regs[7]
6107 && ! fixed_regs[8]
6108 && ! fixed_regs[9]
f9562f27 6109 && ! fixed_regs[10])
3933e0e1
MM
6110 {
6111 move_bytes = (bytes > 24) ? 24 : bytes;
cc0d9ba8
DE
6112 emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode,
6113 dest_reg,
6114 orig_dest),
6115 expand_block_move_mem (BLKmode,
6116 src_reg,
6117 orig_src),
3933e0e1 6118 GEN_INT (move_bytes),
4c64a852 6119 align_rtx));
3933e0e1
MM
6120 }
6121 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6122 && ! fixed_regs[5]
6123 && ! fixed_regs[6]
6124 && ! fixed_regs[7]
6125 && ! fixed_regs[8])
3933e0e1
MM
6126 {
6127 move_bytes = (bytes > 16) ? 16 : bytes;
cc0d9ba8
DE
6128 emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode,
6129 dest_reg,
6130 orig_dest),
6131 expand_block_move_mem (BLKmode,
6132 src_reg,
6133 orig_src),
3933e0e1 6134 GEN_INT (move_bytes),
4c64a852 6135 align_rtx));
3933e0e1 6136 }
acad7ed3 6137 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6138 /* 64-bit loads and stores require word-aligned
82e41834 6139 displacements. */
a4f6c312 6140 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6141 {
6142 move_bytes = 8;
6143 tmp_reg = gen_reg_rtx (DImode);
6144 emit_move_insn (tmp_reg,
6145 expand_block_move_mem (DImode,
2eba1afa 6146 src_reg, orig_src));
acad7ed3 6147 emit_move_insn (expand_block_move_mem (DImode,
2eba1afa 6148 dest_reg, orig_dest),
acad7ed3
DE
6149 tmp_reg);
6150 }
09a625f7 6151 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6152 { /* move up to 8 bytes at a time */
6153 move_bytes = (bytes > 8) ? 8 : bytes;
cc0d9ba8
DE
6154 emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode,
6155 dest_reg,
6156 orig_dest),
6157 expand_block_move_mem (BLKmode,
6158 src_reg,
6159 orig_src),
3933e0e1 6160 GEN_INT (move_bytes),
4c64a852 6161 align_rtx));
3933e0e1 6162 }
cc0d9ba8 6163 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6164 { /* move 4 bytes */
6165 move_bytes = 4;
6166 tmp_reg = gen_reg_rtx (SImode);
cc0d9ba8
DE
6167 emit_move_insn (tmp_reg,
6168 expand_block_move_mem (SImode,
6169 src_reg, orig_src));
6170 emit_move_insn (expand_block_move_mem (SImode,
6171 dest_reg, orig_dest),
6172 tmp_reg);
3933e0e1 6173 }
cc0d9ba8 6174 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6175 { /* move 2 bytes */
6176 move_bytes = 2;
6177 tmp_reg = gen_reg_rtx (HImode);
cc0d9ba8
DE
6178 emit_move_insn (tmp_reg,
6179 expand_block_move_mem (HImode,
6180 src_reg, orig_src));
6181 emit_move_insn (expand_block_move_mem (HImode,
6182 dest_reg, orig_dest),
6183 tmp_reg);
3933e0e1
MM
6184 }
6185 else if (bytes == 1) /* move 1 byte */
6186 {
6187 move_bytes = 1;
6188 tmp_reg = gen_reg_rtx (QImode);
cc0d9ba8
DE
6189 emit_move_insn (tmp_reg,
6190 expand_block_move_mem (QImode,
6191 src_reg, orig_src));
6192 emit_move_insn (expand_block_move_mem (QImode,
6193 dest_reg, orig_dest),
6194 tmp_reg);
3933e0e1
MM
6195 }
6196 else
6197 { /* move up to 4 bytes at a time */
6198 move_bytes = (bytes > 4) ? 4 : bytes;
cc0d9ba8
DE
6199 emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode,
6200 dest_reg,
6201 orig_dest),
6202 expand_block_move_mem (BLKmode,
6203 src_reg,
6204 orig_src),
3933e0e1 6205 GEN_INT (move_bytes),
4c64a852 6206 align_rtx));
3933e0e1 6207 }
4c64a852 6208
015892ee
RK
6209 if (bytes > move_bytes)
6210 {
cc0d9ba8
DE
6211 if (! TARGET_POWERPC64)
6212 {
6213 emit_insn (gen_addsi3 (src_reg, src_reg,
6214 GEN_INT (move_bytes)));
6215 emit_insn (gen_addsi3 (dest_reg, dest_reg,
6216 GEN_INT (move_bytes)));
6217 }
6218 else
6219 {
6220 emit_insn (gen_adddi3 (src_reg, src_reg,
6221 GEN_INT (move_bytes)));
6222 emit_insn (gen_adddi3 (dest_reg, dest_reg,
6223 GEN_INT (move_bytes)));
6224 }
015892ee 6225 }
4c64a852 6226 }
3933e0e1
MM
6227 }
6228
6229 else /* string instructions not available */
6230 {
6231 num_reg = offset = 0;
6232 for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
7e69e155 6233 {
3933e0e1
MM
6234 /* Calculate the correct offset for src/dest */
6235 if (offset == 0)
7e69e155 6236 {
3933e0e1
MM
6237 src_addr = src_reg;
6238 dest_addr = dest_reg;
6239 }
6240 else
6241 {
c5c76735
JL
6242 src_addr = plus_constant (src_reg, offset);
6243 dest_addr = plus_constant (dest_reg, offset);
3933e0e1
MM
6244 }
6245
cc0d9ba8
DE
6246 /* Generate the appropriate load and store, saving the stores
6247 for later. */
6248 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6249 /* 64-bit loads and stores require word-aligned
6250 displacements. */
cc0d9ba8 6251 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6252 {
6253 move_bytes = 8;
6254 tmp_reg = gen_reg_rtx (DImode);
cc0d9ba8
DE
6255 emit_insn (gen_movdi (tmp_reg,
6256 expand_block_move_mem (DImode,
6257 src_addr,
6258 orig_src)));
6259 stores[num_reg++] = gen_movdi (expand_block_move_mem (DImode,
6260 dest_addr,
6261 orig_dest),
6262 tmp_reg);
b6c9286a 6263 }
cc0d9ba8 6264 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6265 {
6266 move_bytes = 4;
6267 tmp_reg = gen_reg_rtx (SImode);
cc0d9ba8
DE
6268 emit_insn (gen_movsi (tmp_reg,
6269 expand_block_move_mem (SImode,
6270 src_addr,
6271 orig_src)));
6272 stores[num_reg++] = gen_movsi (expand_block_move_mem (SImode,
6273 dest_addr,
6274 orig_dest),
6275 tmp_reg);
3933e0e1 6276 }
cc0d9ba8 6277 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6278 {
6279 move_bytes = 2;
6280 tmp_reg = gen_reg_rtx (HImode);
c81fc13e 6281 emit_insn (gen_movhi (tmp_reg,
cc0d9ba8
DE
6282 expand_block_move_mem (HImode,
6283 src_addr,
6284 orig_src)));
6285 stores[num_reg++] = gen_movhi (expand_block_move_mem (HImode,
6286 dest_addr,
6287 orig_dest),
6288 tmp_reg);
3933e0e1
MM
6289 }
6290 else
6291 {
6292 move_bytes = 1;
6293 tmp_reg = gen_reg_rtx (QImode);
c81fc13e 6294 emit_insn (gen_movqi (tmp_reg,
cc0d9ba8
DE
6295 expand_block_move_mem (QImode,
6296 src_addr,
6297 orig_src)));
6298 stores[num_reg++] = gen_movqi (expand_block_move_mem (QImode,
6299 dest_addr,
6300 orig_dest),
a4f6c312 6301 tmp_reg);
3933e0e1
MM
6302 }
6303
6304 if (num_reg >= MAX_MOVE_REG)
6305 {
6306 for (i = 0; i < num_reg; i++)
6307 emit_insn (stores[i]);
6308 num_reg = 0;
7e69e155
MM
6309 }
6310 }
3933e0e1 6311
b6c9286a
MM
6312 for (i = 0; i < num_reg; i++)
6313 emit_insn (stores[i]);
7e69e155
MM
6314 }
6315
6316 return 1;
6317}
6318
9878760c
RK
6319\f
6320/* Return 1 if OP is a load multiple operation. It is known to be a
6321 PARALLEL and the first section will be tested. */
6322
6323int
6324load_multiple_operation (op, mode)
6325 rtx op;
296b8152 6326 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6327{
6328 int count = XVECLEN (op, 0);
e2c953b6 6329 unsigned int dest_regno;
9878760c
RK
6330 rtx src_addr;
6331 int i;
6332
6333 /* Perform a quick check so we don't blow up below. */
6334 if (count <= 1
6335 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6336 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6337 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6338 return 0;
6339
6340 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6341 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6342
6343 for (i = 1; i < count; i++)
6344 {
6345 rtx elt = XVECEXP (op, 0, i);
6346
6347 if (GET_CODE (elt) != SET
6348 || GET_CODE (SET_DEST (elt)) != REG
6349 || GET_MODE (SET_DEST (elt)) != SImode
6350 || REGNO (SET_DEST (elt)) != dest_regno + i
6351 || GET_CODE (SET_SRC (elt)) != MEM
6352 || GET_MODE (SET_SRC (elt)) != SImode
6353 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6354 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6355 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6356 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6357 return 0;
6358 }
6359
6360 return 1;
6361}
6362
6363/* Similar, but tests for store multiple. Here, the second vector element
6364 is a CLOBBER. It will be tested later. */
6365
6366int
6367store_multiple_operation (op, mode)
6368 rtx op;
296b8152 6369 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6370{
6371 int count = XVECLEN (op, 0) - 1;
e2c953b6 6372 unsigned int src_regno;
9878760c
RK
6373 rtx dest_addr;
6374 int i;
6375
6376 /* Perform a quick check so we don't blow up below. */
6377 if (count <= 1
6378 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6379 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6380 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6381 return 0;
6382
6383 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6384 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6385
6386 for (i = 1; i < count; i++)
6387 {
6388 rtx elt = XVECEXP (op, 0, i + 1);
6389
6390 if (GET_CODE (elt) != SET
6391 || GET_CODE (SET_SRC (elt)) != REG
6392 || GET_MODE (SET_SRC (elt)) != SImode
6393 || REGNO (SET_SRC (elt)) != src_regno + i
6394 || GET_CODE (SET_DEST (elt)) != MEM
6395 || GET_MODE (SET_DEST (elt)) != SImode
6396 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6397 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6398 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6399 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6400 return 0;
6401 }
6402
6403 return 1;
6404}
9ebbca7d 6405
00b960c7
AH
6406/* Return 1 for a parallel vrsave operation. */
6407
6408int
6409vrsave_operation (op, mode)
6410 rtx op;
6411 enum machine_mode mode ATTRIBUTE_UNUSED;
6412{
6413 int count = XVECLEN (op, 0);
6414 unsigned int dest_regno, src_regno;
6415 int i;
6416
6417 if (count <= 1
6418 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6419 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6420 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6421 return 0;
6422
6423 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6424 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6425
6426 if (dest_regno != VRSAVE_REGNO
6427 && src_regno != VRSAVE_REGNO)
6428 return 0;
6429
6430 for (i = 1; i < count; i++)
6431 {
6432 rtx elt = XVECEXP (op, 0, i);
6433
9aa86737
AH
6434 if (GET_CODE (elt) != CLOBBER
6435 && GET_CODE (elt) != SET)
00b960c7
AH
6436 return 0;
6437 }
6438
6439 return 1;
6440}
6441
a4f6c312 6442/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6443
6444int
6445mtcrf_operation (op, mode)
6446 rtx op;
6447 enum machine_mode mode ATTRIBUTE_UNUSED;
6448{
6449 int count = XVECLEN (op, 0);
6450 int i;
9ebbca7d
GK
6451 rtx src_reg;
6452
6453 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6454 if (count < 1
6455 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6456 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6457 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6458 return 0;
e35b9579 6459 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6460
6461 if (GET_CODE (src_reg) != REG
6462 || GET_MODE (src_reg) != SImode
6463 || ! INT_REGNO_P (REGNO (src_reg)))
6464 return 0;
6465
e35b9579 6466 for (i = 0; i < count; i++)
9ebbca7d
GK
6467 {
6468 rtx exp = XVECEXP (op, 0, i);
6469 rtx unspec;
6470 int maskval;
6471
6472 if (GET_CODE (exp) != SET
6473 || GET_CODE (SET_DEST (exp)) != REG
6474 || GET_MODE (SET_DEST (exp)) != CCmode
6475 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6476 return 0;
6477 unspec = SET_SRC (exp);
6478 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6479
6480 if (GET_CODE (unspec) != UNSPEC
6481 || XINT (unspec, 1) != 20
6482 || XVECLEN (unspec, 0) != 2
6483 || XVECEXP (unspec, 0, 0) != src_reg
6484 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6485 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6486 return 0;
6487 }
e35b9579 6488 return 1;
9ebbca7d
GK
6489}
6490
a4f6c312 6491/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6492
6493int
6494lmw_operation (op, mode)
6495 rtx op;
6496 enum machine_mode mode ATTRIBUTE_UNUSED;
6497{
6498 int count = XVECLEN (op, 0);
e2c953b6 6499 unsigned int dest_regno;
9ebbca7d 6500 rtx src_addr;
e2c953b6 6501 unsigned int base_regno;
9ebbca7d
GK
6502 HOST_WIDE_INT offset;
6503 int i;
6504
6505 /* Perform a quick check so we don't blow up below. */
6506 if (count <= 1
6507 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6508 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6509 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6510 return 0;
6511
6512 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6513 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6514
6515 if (dest_regno > 31
e2c953b6 6516 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6517 return 0;
6518
258bfae2 6519 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6520 {
6521 offset = 0;
6522 base_regno = REGNO (src_addr);
6523 if (base_regno == 0)
6524 return 0;
6525 }
258bfae2 6526 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6527 {
6528 offset = INTVAL (XEXP (src_addr, 1));
6529 base_regno = REGNO (XEXP (src_addr, 0));
6530 }
6531 else
6532 return 0;
6533
6534 for (i = 0; i < count; i++)
6535 {
6536 rtx elt = XVECEXP (op, 0, i);
6537 rtx newaddr;
6538 rtx addr_reg;
6539 HOST_WIDE_INT newoffset;
6540
6541 if (GET_CODE (elt) != SET
6542 || GET_CODE (SET_DEST (elt)) != REG
6543 || GET_MODE (SET_DEST (elt)) != SImode
6544 || REGNO (SET_DEST (elt)) != dest_regno + i
6545 || GET_CODE (SET_SRC (elt)) != MEM
6546 || GET_MODE (SET_SRC (elt)) != SImode)
6547 return 0;
6548 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6549 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6550 {
6551 newoffset = 0;
6552 addr_reg = newaddr;
6553 }
258bfae2 6554 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6555 {
6556 addr_reg = XEXP (newaddr, 0);
6557 newoffset = INTVAL (XEXP (newaddr, 1));
6558 }
6559 else
6560 return 0;
6561 if (REGNO (addr_reg) != base_regno
6562 || newoffset != offset + 4 * i)
6563 return 0;
6564 }
6565
6566 return 1;
6567}
6568
a4f6c312 6569/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6570
6571int
6572stmw_operation (op, mode)
6573 rtx op;
6574 enum machine_mode mode ATTRIBUTE_UNUSED;
6575{
6576 int count = XVECLEN (op, 0);
e2c953b6 6577 unsigned int src_regno;
9ebbca7d 6578 rtx dest_addr;
e2c953b6 6579 unsigned int base_regno;
9ebbca7d
GK
6580 HOST_WIDE_INT offset;
6581 int i;
6582
6583 /* Perform a quick check so we don't blow up below. */
6584 if (count <= 1
6585 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6586 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6587 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6588 return 0;
6589
6590 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6591 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6592
6593 if (src_regno > 31
e2c953b6 6594 || count != 32 - (int) src_regno)
9ebbca7d
GK
6595 return 0;
6596
258bfae2 6597 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6598 {
6599 offset = 0;
6600 base_regno = REGNO (dest_addr);
6601 if (base_regno == 0)
6602 return 0;
6603 }
258bfae2 6604 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6605 {
6606 offset = INTVAL (XEXP (dest_addr, 1));
6607 base_regno = REGNO (XEXP (dest_addr, 0));
6608 }
6609 else
6610 return 0;
6611
6612 for (i = 0; i < count; i++)
6613 {
6614 rtx elt = XVECEXP (op, 0, i);
6615 rtx newaddr;
6616 rtx addr_reg;
6617 HOST_WIDE_INT newoffset;
6618
6619 if (GET_CODE (elt) != SET
6620 || GET_CODE (SET_SRC (elt)) != REG
6621 || GET_MODE (SET_SRC (elt)) != SImode
6622 || REGNO (SET_SRC (elt)) != src_regno + i
6623 || GET_CODE (SET_DEST (elt)) != MEM
6624 || GET_MODE (SET_DEST (elt)) != SImode)
6625 return 0;
6626 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6627 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6628 {
6629 newoffset = 0;
6630 addr_reg = newaddr;
6631 }
258bfae2 6632 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6633 {
6634 addr_reg = XEXP (newaddr, 0);
6635 newoffset = INTVAL (XEXP (newaddr, 1));
6636 }
6637 else
6638 return 0;
6639 if (REGNO (addr_reg) != base_regno
6640 || newoffset != offset + 4 * i)
6641 return 0;
6642 }
6643
6644 return 1;
6645}
9878760c 6646\f
a4f6c312
SS
6647/* A validation routine: say whether CODE, a condition code, and MODE
6648 match. The other alternatives either don't make sense or should
6649 never be generated. */
39a10a29 6650
39a10a29
GK
6651static void
6652validate_condition_mode (code, mode)
6653 enum rtx_code code;
6654 enum machine_mode mode;
6655{
6656 if (GET_RTX_CLASS (code) != '<'
6657 || GET_MODE_CLASS (mode) != MODE_CC)
6658 abort ();
6659
6660 /* These don't make sense. */
6661 if ((code == GT || code == LT || code == GE || code == LE)
6662 && mode == CCUNSmode)
6663 abort ();
6664
6665 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6666 && mode != CCUNSmode)
6667 abort ();
6668
6669 if (mode != CCFPmode
6670 && (code == ORDERED || code == UNORDERED
6671 || code == UNEQ || code == LTGT
6672 || code == UNGT || code == UNLT
6673 || code == UNGE || code == UNLE))
a4f6c312 6674 abort ();
39a10a29 6675
de6c5979 6676 /* These should never be generated except for
ad72b533 6677 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6678 if (mode == CCFPmode
de6c5979 6679 && ! flag_unsafe_math_optimizations
ad72b533 6680 && ! flag_finite_math_only
39a10a29
GK
6681 && (code == LE || code == GE
6682 || code == UNEQ || code == LTGT
6683 || code == UNGT || code == UNLT))
6684 abort ();
6685
6686 /* These are invalid; the information is not there. */
6687 if (mode == CCEQmode
6688 && code != EQ && code != NE)
6689 abort ();
6690}
6691
9878760c
RK
6692/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6693 We only check the opcode against the mode of the CC value here. */
6694
6695int
6696branch_comparison_operator (op, mode)
592696dd 6697 rtx op;
296b8152 6698 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6699{
6700 enum rtx_code code = GET_CODE (op);
6701 enum machine_mode cc_mode;
6702
6703 if (GET_RTX_CLASS (code) != '<')
6704 return 0;
6705
6706 cc_mode = GET_MODE (XEXP (op, 0));
6707 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6708 return 0;
6709
39a10a29 6710 validate_condition_mode (code, cc_mode);
9878760c 6711
39a10a29
GK
6712 return 1;
6713}
6714
6715/* Return 1 if OP is a comparison operation that is valid for a branch
6716 insn and which is true if the corresponding bit in the CC register
6717 is set. */
6718
6719int
6720branch_positive_comparison_operator (op, mode)
592696dd 6721 rtx op;
39a10a29
GK
6722 enum machine_mode mode;
6723{
6724 enum rtx_code code;
6725
6726 if (! branch_comparison_operator (op, mode))
9878760c
RK
6727 return 0;
6728
39a10a29
GK
6729 code = GET_CODE (op);
6730 return (code == EQ || code == LT || code == GT
a3170dc6 6731 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
6732 || code == LTU || code == GTU
6733 || code == UNORDERED);
9878760c
RK
6734}
6735
6736/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6737 We check the opcode against the mode of the CC value and disallow EQ or
6738 NE comparisons for integers. */
6739
6740int
6741scc_comparison_operator (op, mode)
592696dd 6742 rtx op;
9878760c
RK
6743 enum machine_mode mode;
6744{
6745 enum rtx_code code = GET_CODE (op);
6746 enum machine_mode cc_mode;
6747
6748 if (GET_MODE (op) != mode && mode != VOIDmode)
6749 return 0;
6750
6751 if (GET_RTX_CLASS (code) != '<')
6752 return 0;
6753
6754 cc_mode = GET_MODE (XEXP (op, 0));
6755 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6756 return 0;
6757
39a10a29 6758 validate_condition_mode (code, cc_mode);
9878760c 6759
39a10a29 6760 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
6761 return 0;
6762
9878760c
RK
6763 return 1;
6764}
e0cd0770
JC
6765
6766int
6767trap_comparison_operator (op, mode)
6768 rtx op;
6769 enum machine_mode mode;
6770{
6771 if (mode != VOIDmode && mode != GET_MODE (op))
6772 return 0;
39a10a29 6773 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 6774}
dfbdccdb
GK
6775
6776int
6777boolean_operator (op, mode)
6778 rtx op;
6779 enum machine_mode mode ATTRIBUTE_UNUSED;
6780{
6781 enum rtx_code code = GET_CODE (op);
6782 return (code == AND || code == IOR || code == XOR);
6783}
1d328b19
GK
6784
6785int
6786boolean_or_operator (op, mode)
6787 rtx op;
6788 enum machine_mode mode ATTRIBUTE_UNUSED;
6789{
6790 enum rtx_code code = GET_CODE (op);
6791 return (code == IOR || code == XOR);
6792}
50a0b056
GK
6793
6794int
6795min_max_operator (op, mode)
6796 rtx op;
6797 enum machine_mode mode ATTRIBUTE_UNUSED;
6798{
6799 enum rtx_code code = GET_CODE (op);
6800 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6801}
9878760c
RK
6802\f
6803/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6804 mask required to convert the result of a rotate insn into a shift
b1765bde 6805 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
6806
6807int
6808includes_lshift_p (shiftop, andop)
592696dd
SS
6809 rtx shiftop;
6810 rtx andop;
9878760c 6811{
e2c953b6
DE
6812 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6813
6814 shift_mask <<= INTVAL (shiftop);
9878760c 6815
b1765bde 6816 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
6817}
6818
6819/* Similar, but for right shift. */
6820
6821int
6822includes_rshift_p (shiftop, andop)
592696dd
SS
6823 rtx shiftop;
6824 rtx andop;
9878760c 6825{
a7653a2c 6826 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
6827
6828 shift_mask >>= INTVAL (shiftop);
6829
b1765bde 6830 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
6831}
6832
c5059423
AM
6833/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6834 to perform a left shift. It must have exactly SHIFTOP least
6835 signifigant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
6836
6837int
c5059423 6838includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
6839 rtx shiftop;
6840 rtx andop;
e2c953b6 6841{
c5059423
AM
6842 if (GET_CODE (andop) == CONST_INT)
6843 {
02071907 6844 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 6845
c5059423 6846 c = INTVAL (andop);
02071907 6847 if (c == 0 || c == ~0)
c5059423 6848 return 0;
e2c953b6 6849
02071907 6850 shift_mask = ~0;
c5059423
AM
6851 shift_mask <<= INTVAL (shiftop);
6852
6853 /* Find the least signifigant one bit. */
6854 lsb = c & -c;
6855
6856 /* It must coincide with the LSB of the shift mask. */
6857 if (-lsb != shift_mask)
6858 return 0;
e2c953b6 6859
c5059423
AM
6860 /* Invert to look for the next transition (if any). */
6861 c = ~c;
6862
6863 /* Remove the low group of ones (originally low group of zeros). */
6864 c &= -lsb;
6865
6866 /* Again find the lsb, and check we have all 1's above. */
6867 lsb = c & -c;
6868 return c == -lsb;
6869 }
6870 else if (GET_CODE (andop) == CONST_DOUBLE
6871 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6872 {
02071907
AM
6873 HOST_WIDE_INT low, high, lsb;
6874 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
6875
6876 low = CONST_DOUBLE_LOW (andop);
6877 if (HOST_BITS_PER_WIDE_INT < 64)
6878 high = CONST_DOUBLE_HIGH (andop);
6879
6880 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 6881 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
6882 return 0;
6883
6884 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6885 {
02071907 6886 shift_mask_high = ~0;
c5059423
AM
6887 if (INTVAL (shiftop) > 32)
6888 shift_mask_high <<= INTVAL (shiftop) - 32;
6889
6890 lsb = high & -high;
6891
6892 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
6893 return 0;
6894
6895 high = ~high;
6896 high &= -lsb;
6897
6898 lsb = high & -high;
6899 return high == -lsb;
6900 }
6901
02071907 6902 shift_mask_low = ~0;
c5059423
AM
6903 shift_mask_low <<= INTVAL (shiftop);
6904
6905 lsb = low & -low;
6906
6907 if (-lsb != shift_mask_low)
6908 return 0;
6909
6910 if (HOST_BITS_PER_WIDE_INT < 64)
6911 high = ~high;
6912 low = ~low;
6913 low &= -lsb;
6914
6915 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6916 {
6917 lsb = high & -high;
6918 return high == -lsb;
6919 }
6920
6921 lsb = low & -low;
6922 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
6923 }
6924 else
6925 return 0;
6926}
e2c953b6 6927
c5059423
AM
6928/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
6929 to perform a left shift. It must have SHIFTOP or more least
6930 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 6931
c5059423
AM
6932int
6933includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
6934 rtx shiftop;
6935 rtx andop;
c5059423 6936{
e2c953b6 6937 if (GET_CODE (andop) == CONST_INT)
c5059423 6938 {
02071907 6939 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 6940
02071907 6941 shift_mask = ~0;
c5059423
AM
6942 shift_mask <<= INTVAL (shiftop);
6943 c = INTVAL (andop);
6944
6945 /* Find the least signifigant one bit. */
6946 lsb = c & -c;
6947
6948 /* It must be covered by the shift mask.
a4f6c312 6949 This test also rejects c == 0. */
c5059423
AM
6950 if ((lsb & shift_mask) == 0)
6951 return 0;
6952
6953 /* Check we have all 1's above the transition, and reject all 1's. */
6954 return c == -lsb && lsb != 1;
6955 }
6956 else if (GET_CODE (andop) == CONST_DOUBLE
6957 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6958 {
02071907 6959 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
6960
6961 low = CONST_DOUBLE_LOW (andop);
6962
6963 if (HOST_BITS_PER_WIDE_INT < 64)
6964 {
02071907 6965 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
6966
6967 high = CONST_DOUBLE_HIGH (andop);
6968
6969 if (low == 0)
6970 {
02071907 6971 shift_mask_high = ~0;
c5059423
AM
6972 if (INTVAL (shiftop) > 32)
6973 shift_mask_high <<= INTVAL (shiftop) - 32;
6974
6975 lsb = high & -high;
6976
6977 if ((lsb & shift_mask_high) == 0)
6978 return 0;
6979
6980 return high == -lsb;
6981 }
6982 if (high != ~0)
6983 return 0;
6984 }
6985
02071907 6986 shift_mask_low = ~0;
c5059423
AM
6987 shift_mask_low <<= INTVAL (shiftop);
6988
6989 lsb = low & -low;
6990
6991 if ((lsb & shift_mask_low) == 0)
6992 return 0;
6993
6994 return low == -lsb && lsb != 1;
6995 }
e2c953b6 6996 else
c5059423 6997 return 0;
9878760c 6998}
35068b43
RK
6999
7000/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
7001 for lfq and stfq insns.
7002
7003 Note reg1 and reg2 *must* be hard registers. To be sure we will
7004 abort if we are passed pseudo registers. */
7005
7006int
7007registers_ok_for_quad_peep (reg1, reg2)
7008 rtx reg1, reg2;
7009{
7010 /* We might have been passed a SUBREG. */
7011 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
7012 return 0;
7013
7014 return (REGNO (reg1) == REGNO (reg2) - 1);
7015}
7016
a4f6c312
SS
7017/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
7018 addr1 and addr2 must be in consecutive memory locations
7019 (addr2 == addr1 + 8). */
35068b43
RK
7020
7021int
7022addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
7023 rtx addr1;
7024 rtx addr2;
35068b43 7025{
e2c953b6 7026 unsigned int reg1;
35068b43
RK
7027 int offset1;
7028
7029 /* Extract an offset (if used) from the first addr. */
7030 if (GET_CODE (addr1) == PLUS)
7031 {
7032 /* If not a REG, return zero. */
7033 if (GET_CODE (XEXP (addr1, 0)) != REG)
7034 return 0;
7035 else
7036 {
7037 reg1 = REGNO (XEXP (addr1, 0));
7038 /* The offset must be constant! */
7039 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7040 return 0;
7041 offset1 = INTVAL (XEXP (addr1, 1));
7042 }
7043 }
7044 else if (GET_CODE (addr1) != REG)
7045 return 0;
7046 else
7047 {
7048 reg1 = REGNO (addr1);
7049 /* This was a simple (mem (reg)) expression. Offset is 0. */
7050 offset1 = 0;
7051 }
7052
acad7ed3 7053 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
7054 if (GET_CODE (addr2) != PLUS)
7055 return 0;
7056
7057 if (GET_CODE (XEXP (addr2, 0)) != REG
7058 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7059 return 0;
7060
7061 if (reg1 != REGNO (XEXP (addr2, 0)))
7062 return 0;
7063
7064 /* The offset for the second addr must be 8 more than the first addr. */
7065 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7066 return 0;
7067
7068 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7069 instructions. */
7070 return 1;
7071}
9878760c
RK
7072\f
7073/* Return the register class of a scratch register needed to copy IN into
7074 or out of a register in CLASS in MODE. If it can be done directly,
7075 NO_REGS is returned. */
7076
7077enum reg_class
7078secondary_reload_class (class, mode, in)
7079 enum reg_class class;
296b8152 7080 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7081 rtx in;
7082{
5accd822 7083 int regno;
9878760c 7084
46fad5b7
DJ
7085 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
7086 {
7087 /* We cannot copy a symbolic operand directly into anything
7088 other than BASE_REGS for TARGET_ELF. So indicate that a
7089 register from BASE_REGS is needed as an intermediate
7090 register.
7091
7092 On Darwin, pic addresses require a load from memory, which
7093 needs a base register. */
7094 if (class != BASE_REGS
7095 && (GET_CODE (in) == SYMBOL_REF
7096 || GET_CODE (in) == HIGH
7097 || GET_CODE (in) == LABEL_REF
7098 || GET_CODE (in) == CONST))
7099 return BASE_REGS;
7100 }
e7b7998a 7101
5accd822
DE
7102 if (GET_CODE (in) == REG)
7103 {
7104 regno = REGNO (in);
7105 if (regno >= FIRST_PSEUDO_REGISTER)
7106 {
7107 regno = true_regnum (in);
7108 if (regno >= FIRST_PSEUDO_REGISTER)
7109 regno = -1;
7110 }
7111 }
7112 else if (GET_CODE (in) == SUBREG)
7113 {
7114 regno = true_regnum (in);
7115 if (regno >= FIRST_PSEUDO_REGISTER)
7116 regno = -1;
7117 }
7118 else
7119 regno = -1;
7120
9878760c
RK
7121 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7122 into anything. */
7123 if (class == GENERAL_REGS || class == BASE_REGS
7124 || (regno >= 0 && INT_REGNO_P (regno)))
7125 return NO_REGS;
7126
7127 /* Constants, memory, and FP registers can go into FP registers. */
7128 if ((regno == -1 || FP_REGNO_P (regno))
7129 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7130 return NO_REGS;
7131
0ac081f6
AH
7132 /* Memory, and AltiVec registers can go into AltiVec registers. */
7133 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7134 && class == ALTIVEC_REGS)
7135 return NO_REGS;
7136
9878760c
RK
7137 /* We can copy among the CR registers. */
7138 if ((class == CR_REGS || class == CR0_REGS)
7139 && regno >= 0 && CR_REGNO_P (regno))
7140 return NO_REGS;
7141
7142 /* Otherwise, we need GENERAL_REGS. */
7143 return GENERAL_REGS;
7144}
7145\f
7146/* Given a comparison operation, return the bit number in CCR to test. We
7147 know this is a valid comparison.
7148
7149 SCC_P is 1 if this is for an scc. That means that %D will have been
7150 used instead of %C, so the bits will be in different places.
7151
b4ac57ab 7152 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7153
7154int
7155ccr_bit (op, scc_p)
592696dd 7156 rtx op;
9878760c
RK
7157 int scc_p;
7158{
7159 enum rtx_code code = GET_CODE (op);
7160 enum machine_mode cc_mode;
7161 int cc_regnum;
7162 int base_bit;
9ebbca7d 7163 rtx reg;
9878760c
RK
7164
7165 if (GET_RTX_CLASS (code) != '<')
7166 return -1;
7167
9ebbca7d
GK
7168 reg = XEXP (op, 0);
7169
7170 if (GET_CODE (reg) != REG
7171 || ! CR_REGNO_P (REGNO (reg)))
7172 abort ();
7173
7174 cc_mode = GET_MODE (reg);
7175 cc_regnum = REGNO (reg);
7176 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7177
39a10a29 7178 validate_condition_mode (code, cc_mode);
c5defebb 7179
9878760c
RK
7180 switch (code)
7181 {
7182 case NE:
a3170dc6
AH
7183 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7184 return base_bit + 1;
9878760c
RK
7185 return scc_p ? base_bit + 3 : base_bit + 2;
7186 case EQ:
a3170dc6
AH
7187 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7188 return base_bit + 1;
9878760c 7189 return base_bit + 2;
1c882ea4 7190 case GT: case GTU: case UNLE:
9878760c 7191 return base_bit + 1;
1c882ea4 7192 case LT: case LTU: case UNGE:
9878760c 7193 return base_bit;
1c882ea4
GK
7194 case ORDERED: case UNORDERED:
7195 return base_bit + 3;
9878760c
RK
7196
7197 case GE: case GEU:
39a10a29 7198 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7199 unordered position. So test that bit. For integer, this is ! LT
7200 unless this is an scc insn. */
39a10a29 7201 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7202
7203 case LE: case LEU:
39a10a29 7204 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7205
9878760c
RK
7206 default:
7207 abort ();
7208 }
7209}
1ff7789b 7210\f
8d30c4ee 7211/* Return the GOT register. */
1ff7789b
MM
7212
7213struct rtx_def *
7214rs6000_got_register (value)
5f59ecb7 7215 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7216{
a4f6c312
SS
7217 /* The second flow pass currently (June 1999) can't update
7218 regs_ever_live without disturbing other parts of the compiler, so
7219 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7220 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7221 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7222
8d30c4ee 7223 current_function_uses_pic_offset_table = 1;
3cb999d8 7224
1ff7789b
MM
7225 return pic_offset_table_rtx;
7226}
a7df97e6 7227\f
e2500fed
GK
7228/* Function to init struct machine_function.
7229 This will be called, via a pointer variable,
7230 from push_function_context. */
a7df97e6 7231
e2500fed
GK
7232static struct machine_function *
7233rs6000_init_machine_status ()
a7df97e6 7234{
e2500fed 7235 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7236}
9878760c 7237\f
0ba1b2ff
AM
7238/* These macros test for integers and extract the low-order bits. */
7239#define INT_P(X) \
7240((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7241 && GET_MODE (X) == VOIDmode)
7242
7243#define INT_LOWPART(X) \
7244 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7245
7246int
7247extract_MB (op)
7248 rtx op;
7249{
7250 int i;
7251 unsigned long val = INT_LOWPART (op);
7252
7253 /* If the high bit is zero, the value is the first 1 bit we find
7254 from the left. */
7255 if ((val & 0x80000000) == 0)
7256 {
7257 if ((val & 0xffffffff) == 0)
7258 abort ();
7259
7260 i = 1;
7261 while (((val <<= 1) & 0x80000000) == 0)
7262 ++i;
7263 return i;
7264 }
7265
7266 /* If the high bit is set and the low bit is not, or the mask is all
7267 1's, the value is zero. */
7268 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7269 return 0;
7270
7271 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7272 from the right. */
7273 i = 31;
7274 while (((val >>= 1) & 1) != 0)
7275 --i;
7276
7277 return i;
7278}
7279
7280int
7281extract_ME (op)
7282 rtx op;
7283{
7284 int i;
7285 unsigned long val = INT_LOWPART (op);
7286
7287 /* If the low bit is zero, the value is the first 1 bit we find from
7288 the right. */
7289 if ((val & 1) == 0)
7290 {
7291 if ((val & 0xffffffff) == 0)
7292 abort ();
7293
7294 i = 30;
7295 while (((val >>= 1) & 1) == 0)
7296 --i;
7297
7298 return i;
7299 }
7300
7301 /* If the low bit is set and the high bit is not, or the mask is all
7302 1's, the value is 31. */
7303 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7304 return 31;
7305
7306 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7307 from the left. */
7308 i = 0;
7309 while (((val <<= 1) & 0x80000000) != 0)
7310 ++i;
7311
7312 return i;
7313}
7314
9878760c
RK
7315/* Print an operand. Recognize special options, documented below. */
7316
38c1f2d7 7317#if TARGET_ELF
d9407988 7318#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7319#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7320#else
7321#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7322#define SMALL_DATA_REG 0
ba5e43aa
MM
7323#endif
7324
9878760c
RK
7325void
7326print_operand (file, x, code)
7327 FILE *file;
7328 rtx x;
9ebbca7d 7329 int code;
9878760c
RK
7330{
7331 int i;
a260abc9 7332 HOST_WIDE_INT val;
0ba1b2ff 7333 unsigned HOST_WIDE_INT uval;
9878760c
RK
7334
7335 switch (code)
7336 {
a8b3aeda 7337 case '.':
a85d226b
RK
7338 /* Write out an instruction after the call which may be replaced
7339 with glue code by the loader. This depends on the AIX version. */
7340 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7341 return;
7342
81eace42
GK
7343 /* %a is output_address. */
7344
9854d9ed
RK
7345 case 'A':
7346 /* If X is a constant integer whose low-order 5 bits are zero,
7347 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7348 in the AIX assembler where "sri" with a zero shift count
20e26713 7349 writes a trash instruction. */
9854d9ed 7350 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7351 putc ('l', file);
9854d9ed 7352 else
76229ac8 7353 putc ('r', file);
9854d9ed
RK
7354 return;
7355
7356 case 'b':
e2c953b6
DE
7357 /* If constant, low-order 16 bits of constant, unsigned.
7358 Otherwise, write normally. */
7359 if (INT_P (x))
7360 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7361 else
7362 print_operand (file, x, 0);
cad12a8d
RK
7363 return;
7364
a260abc9
DE
7365 case 'B':
7366 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7367 for 64-bit mask direction. */
296b8152 7368 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7369 return;
a260abc9 7370
81eace42
GK
7371 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7372 output_operand. */
7373
9854d9ed 7374 case 'D':
39a10a29
GK
7375 /* There used to be a comment for 'C' reading "This is an
7376 optional cror needed for certain floating-point
7377 comparisons. Otherwise write nothing." */
7378
9854d9ed
RK
7379 /* Similar, except that this is for an scc, so we must be able to
7380 encode the test in a single bit that is one. We do the above
7381 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7382 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7383 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7384 {
9ebbca7d 7385 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7386
7387 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7388 base_bit + 2,
7389 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7390 }
7391
7392 else if (GET_CODE (x) == NE)
7393 {
9ebbca7d 7394 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7395
7396 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7397 base_bit + 2, base_bit + 2);
7398 }
a3170dc6
AH
7399 else if (TARGET_SPE && TARGET_HARD_FLOAT
7400 && GET_CODE (x) == EQ
7401 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7402 {
7403 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7404
7405 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7406 base_bit + 1, base_bit + 1);
7407 }
9854d9ed
RK
7408 return;
7409
7410 case 'E':
39a10a29 7411 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7412 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7413 output_operand_lossage ("invalid %%E value");
78fbdbf7 7414 else
39a10a29 7415 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7416 return;
9854d9ed
RK
7417
7418 case 'f':
7419 /* X is a CR register. Print the shift count needed to move it
7420 to the high-order four bits. */
7421 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7422 output_operand_lossage ("invalid %%f value");
7423 else
9ebbca7d 7424 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7425 return;
7426
7427 case 'F':
7428 /* Similar, but print the count for the rotate in the opposite
7429 direction. */
7430 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7431 output_operand_lossage ("invalid %%F value");
7432 else
9ebbca7d 7433 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7434 return;
7435
7436 case 'G':
7437 /* X is a constant integer. If it is negative, print "m",
7438 otherwise print "z". This is to make a aze or ame insn. */
7439 if (GET_CODE (x) != CONST_INT)
7440 output_operand_lossage ("invalid %%G value");
7441 else if (INTVAL (x) >= 0)
76229ac8 7442 putc ('z', file);
9854d9ed 7443 else
76229ac8 7444 putc ('m', file);
9854d9ed 7445 return;
e2c953b6 7446
9878760c 7447 case 'h':
a4f6c312
SS
7448 /* If constant, output low-order five bits. Otherwise, write
7449 normally. */
9878760c 7450 if (INT_P (x))
5f59ecb7 7451 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7452 else
7453 print_operand (file, x, 0);
7454 return;
7455
64305719 7456 case 'H':
a4f6c312
SS
7457 /* If constant, output low-order six bits. Otherwise, write
7458 normally. */
64305719 7459 if (INT_P (x))
5f59ecb7 7460 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7461 else
7462 print_operand (file, x, 0);
7463 return;
7464
9854d9ed
RK
7465 case 'I':
7466 /* Print `i' if this is a constant, else nothing. */
9878760c 7467 if (INT_P (x))
76229ac8 7468 putc ('i', file);
9878760c
RK
7469 return;
7470
9854d9ed
RK
7471 case 'j':
7472 /* Write the bit number in CCR for jump. */
7473 i = ccr_bit (x, 0);
7474 if (i == -1)
7475 output_operand_lossage ("invalid %%j code");
9878760c 7476 else
9854d9ed 7477 fprintf (file, "%d", i);
9878760c
RK
7478 return;
7479
9854d9ed
RK
7480 case 'J':
7481 /* Similar, but add one for shift count in rlinm for scc and pass
7482 scc flag to `ccr_bit'. */
7483 i = ccr_bit (x, 1);
7484 if (i == -1)
7485 output_operand_lossage ("invalid %%J code");
7486 else
a0466a68
RK
7487 /* If we want bit 31, write a shift count of zero, not 32. */
7488 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7489 return;
7490
9854d9ed
RK
7491 case 'k':
7492 /* X must be a constant. Write the 1's complement of the
7493 constant. */
9878760c 7494 if (! INT_P (x))
9854d9ed 7495 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7496 else
7497 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7498 return;
7499
81eace42 7500 case 'K':
9ebbca7d
GK
7501 /* X must be a symbolic constant on ELF. Write an
7502 expression suitable for an 'addi' that adds in the low 16
7503 bits of the MEM. */
7504 if (GET_CODE (x) != CONST)
7505 {
7506 print_operand_address (file, x);
7507 fputs ("@l", file);
7508 }
7509 else
7510 {
7511 if (GET_CODE (XEXP (x, 0)) != PLUS
7512 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7513 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7514 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7515 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7516 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7517 fputs ("@l", file);
ed8d2920
MM
7518 /* For GNU as, there must be a non-alphanumeric character
7519 between 'l' and the number. The '-' is added by
7520 print_operand() already. */
7521 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7522 fputs ("+", file);
9ebbca7d
GK
7523 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7524 }
81eace42
GK
7525 return;
7526
7527 /* %l is output_asm_label. */
9ebbca7d 7528
9854d9ed
RK
7529 case 'L':
7530 /* Write second word of DImode or DFmode reference. Works on register
7531 or non-indexed memory only. */
7532 if (GET_CODE (x) == REG)
5ebfb2ba 7533 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7534 else if (GET_CODE (x) == MEM)
7535 {
7536 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7537 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7538 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7539 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7540 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7541 UNITS_PER_WORD));
9854d9ed 7542 else
d7624dc0
RK
7543 output_address (XEXP (adjust_address_nv (x, SImode,
7544 UNITS_PER_WORD),
7545 0));
ed8908e7 7546
ba5e43aa 7547 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7548 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7549 reg_names[SMALL_DATA_REG]);
9854d9ed 7550 }
9878760c 7551 return;
9854d9ed 7552
9878760c
RK
7553 case 'm':
7554 /* MB value for a mask operand. */
b1765bde 7555 if (! mask_operand (x, SImode))
9878760c
RK
7556 output_operand_lossage ("invalid %%m value");
7557
0ba1b2ff 7558 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7559 return;
7560
7561 case 'M':
7562 /* ME value for a mask operand. */
b1765bde 7563 if (! mask_operand (x, SImode))
a260abc9 7564 output_operand_lossage ("invalid %%M value");
9878760c 7565
0ba1b2ff 7566 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7567 return;
7568
81eace42
GK
7569 /* %n outputs the negative of its operand. */
7570
9878760c
RK
7571 case 'N':
7572 /* Write the number of elements in the vector times 4. */
7573 if (GET_CODE (x) != PARALLEL)
7574 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7575 else
7576 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7577 return;
7578
7579 case 'O':
7580 /* Similar, but subtract 1 first. */
7581 if (GET_CODE (x) != PARALLEL)
1427100a 7582 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7583 else
7584 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7585 return;
7586
9854d9ed
RK
7587 case 'p':
7588 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7589 if (! INT_P (x)
2bfcf297 7590 || INT_LOWPART (x) < 0
9854d9ed
RK
7591 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7592 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7593 else
7594 fprintf (file, "%d", i);
9854d9ed
RK
7595 return;
7596
9878760c
RK
7597 case 'P':
7598 /* The operand must be an indirect memory reference. The result
a4f6c312 7599 is the register number. */
9878760c
RK
7600 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7601 || REGNO (XEXP (x, 0)) >= 32)
7602 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7603 else
7604 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7605 return;
7606
dfbdccdb
GK
7607 case 'q':
7608 /* This outputs the logical code corresponding to a boolean
7609 expression. The expression may have one or both operands
39a10a29
GK
7610 negated (if one, only the first one). For condition register
7611 logical operations, it will also treat the negated
7612 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7613 {
63bc1d05 7614 const char *const *t = 0;
dfbdccdb
GK
7615 const char *s;
7616 enum rtx_code code = GET_CODE (x);
7617 static const char * const tbl[3][3] = {
7618 { "and", "andc", "nor" },
7619 { "or", "orc", "nand" },
7620 { "xor", "eqv", "xor" } };
7621
7622 if (code == AND)
7623 t = tbl[0];
7624 else if (code == IOR)
7625 t = tbl[1];
7626 else if (code == XOR)
7627 t = tbl[2];
7628 else
7629 output_operand_lossage ("invalid %%q value");
7630
7631 if (GET_CODE (XEXP (x, 0)) != NOT)
7632 s = t[0];
7633 else
7634 {
7635 if (GET_CODE (XEXP (x, 1)) == NOT)
7636 s = t[2];
7637 else
7638 s = t[1];
7639 }
7640
7641 fputs (s, file);
7642 }
7643 return;
7644
9854d9ed
RK
7645 case 'R':
7646 /* X is a CR register. Print the mask for `mtcrf'. */
7647 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7648 output_operand_lossage ("invalid %%R value");
7649 else
9ebbca7d 7650 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7651 return;
9854d9ed
RK
7652
7653 case 's':
7654 /* Low 5 bits of 32 - value */
7655 if (! INT_P (x))
7656 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7657 else
7658 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7659 return;
9854d9ed 7660
a260abc9 7661 case 'S':
0ba1b2ff 7662 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7663 CONST_INT 32-bit mask is considered sign-extended so any
7664 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7665 if (! mask64_operand (x, DImode))
a260abc9
DE
7666 output_operand_lossage ("invalid %%S value");
7667
0ba1b2ff 7668 uval = INT_LOWPART (x);
a260abc9 7669
0ba1b2ff 7670 if (uval & 1) /* Clear Left */
a260abc9 7671 {
0ba1b2ff
AM
7672 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7673 i = 64;
a260abc9 7674 }
0ba1b2ff 7675 else /* Clear Right */
a260abc9 7676 {
0ba1b2ff
AM
7677 uval = ~uval;
7678 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7679 i = 63;
a260abc9 7680 }
0ba1b2ff
AM
7681 while (uval != 0)
7682 --i, uval >>= 1;
7683 if (i < 0)
7684 abort ();
7685 fprintf (file, "%d", i);
7686 return;
a260abc9 7687
a3170dc6
AH
7688 case 't':
7689 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7690 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7691 abort ();
7692
7693 /* Bit 3 is OV bit. */
7694 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7695
7696 /* If we want bit 31, write a shift count of zero, not 32. */
7697 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7698 return;
7699
cccf3bdc
DE
7700 case 'T':
7701 /* Print the symbolic name of a branch target register. */
7702 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7703 && REGNO (x) != COUNT_REGISTER_REGNUM))
7704 output_operand_lossage ("invalid %%T value");
e2c953b6 7705 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
7706 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7707 else
7708 fputs ("ctr", file);
7709 return;
7710
9854d9ed 7711 case 'u':
802a0058 7712 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
7713 if (! INT_P (x))
7714 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
7715 else
7716 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7717 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
7718 return;
7719
802a0058
MM
7720 case 'v':
7721 /* High-order 16 bits of constant for use in signed operand. */
7722 if (! INT_P (x))
7723 output_operand_lossage ("invalid %%v value");
e2c953b6 7724 else
134c32f6
DE
7725 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7726 (INT_LOWPART (x) >> 16) & 0xffff);
7727 return;
802a0058 7728
9854d9ed
RK
7729 case 'U':
7730 /* Print `u' if this has an auto-increment or auto-decrement. */
7731 if (GET_CODE (x) == MEM
7732 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7733 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 7734 putc ('u', file);
9854d9ed 7735 return;
9878760c 7736
e0cd0770
JC
7737 case 'V':
7738 /* Print the trap code for this operand. */
7739 switch (GET_CODE (x))
7740 {
7741 case EQ:
7742 fputs ("eq", file); /* 4 */
7743 break;
7744 case NE:
7745 fputs ("ne", file); /* 24 */
7746 break;
7747 case LT:
7748 fputs ("lt", file); /* 16 */
7749 break;
7750 case LE:
7751 fputs ("le", file); /* 20 */
7752 break;
7753 case GT:
7754 fputs ("gt", file); /* 8 */
7755 break;
7756 case GE:
7757 fputs ("ge", file); /* 12 */
7758 break;
7759 case LTU:
7760 fputs ("llt", file); /* 2 */
7761 break;
7762 case LEU:
7763 fputs ("lle", file); /* 6 */
7764 break;
7765 case GTU:
7766 fputs ("lgt", file); /* 1 */
7767 break;
7768 case GEU:
7769 fputs ("lge", file); /* 5 */
7770 break;
7771 default:
7772 abort ();
7773 }
7774 break;
7775
9854d9ed
RK
7776 case 'w':
7777 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7778 normally. */
7779 if (INT_P (x))
5f59ecb7
DE
7780 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7781 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
7782 else
7783 print_operand (file, x, 0);
9878760c
RK
7784 return;
7785
9854d9ed 7786 case 'W':
e2c953b6 7787 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
7788 val = (GET_CODE (x) == CONST_INT
7789 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7790
7791 if (val < 0)
7792 i = -1;
9854d9ed 7793 else
e2c953b6
DE
7794 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7795 if ((val <<= 1) < 0)
7796 break;
7797
7798#if HOST_BITS_PER_WIDE_INT == 32
7799 if (GET_CODE (x) == CONST_INT && i >= 0)
7800 i += 32; /* zero-extend high-part was all 0's */
7801 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7802 {
7803 val = CONST_DOUBLE_LOW (x);
7804
7805 if (val == 0)
a4f6c312 7806 abort ();
e2c953b6
DE
7807 else if (val < 0)
7808 --i;
7809 else
7810 for ( ; i < 64; i++)
7811 if ((val <<= 1) < 0)
7812 break;
7813 }
7814#endif
7815
7816 fprintf (file, "%d", i + 1);
9854d9ed 7817 return;
9878760c 7818
9854d9ed
RK
7819 case 'X':
7820 if (GET_CODE (x) == MEM
258bfae2 7821 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 7822 putc ('x', file);
9854d9ed 7823 return;
9878760c 7824
9854d9ed
RK
7825 case 'Y':
7826 /* Like 'L', for third word of TImode */
7827 if (GET_CODE (x) == REG)
5ebfb2ba 7828 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 7829 else if (GET_CODE (x) == MEM)
9878760c 7830 {
9854d9ed
RK
7831 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7832 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7833 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 7834 else
d7624dc0 7835 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 7836 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7837 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7838 reg_names[SMALL_DATA_REG]);
9878760c
RK
7839 }
7840 return;
9854d9ed 7841
9878760c 7842 case 'z':
b4ac57ab
RS
7843 /* X is a SYMBOL_REF. Write out the name preceded by a
7844 period and without any trailing data in brackets. Used for function
4d30c363
MM
7845 names. If we are configured for System V (or the embedded ABI) on
7846 the PowerPC, do not emit the period, since those systems do not use
7847 TOCs and the like. */
9878760c
RK
7848 if (GET_CODE (x) != SYMBOL_REF)
7849 abort ();
7850
b6c9286a
MM
7851 if (XSTR (x, 0)[0] != '.')
7852 {
7853 switch (DEFAULT_ABI)
7854 {
7855 default:
7856 abort ();
7857
7858 case ABI_AIX:
7859 putc ('.', file);
7860 break;
7861
7862 case ABI_V4:
7863 case ABI_AIX_NODESC:
ee890fe2 7864 case ABI_DARWIN:
b6c9286a 7865 break;
b6c9286a
MM
7866 }
7867 }
54ee9799
DE
7868#if TARGET_AIX
7869 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
7870#else
9ebbca7d 7871 assemble_name (file, XSTR (x, 0));
54ee9799 7872#endif
9878760c
RK
7873 return;
7874
9854d9ed
RK
7875 case 'Z':
7876 /* Like 'L', for last word of TImode. */
7877 if (GET_CODE (x) == REG)
5ebfb2ba 7878 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
7879 else if (GET_CODE (x) == MEM)
7880 {
7881 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7882 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7883 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 7884 else
d7624dc0 7885 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 7886 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7887 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7888 reg_names[SMALL_DATA_REG]);
9854d9ed 7889 }
5c23c401 7890 return;
0ac081f6 7891
a3170dc6 7892 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
7893 case 'y':
7894 {
7895 rtx tmp;
7896
7897 if (GET_CODE (x) != MEM)
7898 abort ();
7899
7900 tmp = XEXP (x, 0);
7901
a3170dc6
AH
7902 if (TARGET_SPE)
7903 {
7904 /* Handle [reg]. */
7905 if (GET_CODE (tmp) == REG)
7906 {
7907 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
7908 break;
7909 }
7910 /* Handle [reg+UIMM]. */
7911 else if (GET_CODE (tmp) == PLUS &&
7912 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
7913 {
7914 int x;
7915
7916 if (GET_CODE (XEXP (tmp, 0)) != REG)
7917 abort ();
7918
7919 x = INTVAL (XEXP (tmp, 1));
7920 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
7921 break;
7922 }
7923
7924 /* Fall through. Must be [reg+reg]. */
7925 }
0ac081f6 7926 if (GET_CODE (tmp) == REG)
c62f2db5 7927 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
7928 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
7929 {
7930 if (REGNO (XEXP (tmp, 0)) == 0)
7931 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
7932 reg_names[ REGNO (XEXP (tmp, 0)) ]);
7933 else
7934 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
7935 reg_names[ REGNO (XEXP (tmp, 1)) ]);
7936 }
7937 else
7938 abort ();
7939 break;
7940 }
9854d9ed 7941
9878760c
RK
7942 case 0:
7943 if (GET_CODE (x) == REG)
7944 fprintf (file, "%s", reg_names[REGNO (x)]);
7945 else if (GET_CODE (x) == MEM)
7946 {
7947 /* We need to handle PRE_INC and PRE_DEC here, since we need to
7948 know the width from the mode. */
7949 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
7950 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
7951 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7952 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
7953 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
7954 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7955 else
a54d04b7 7956 output_address (XEXP (x, 0));
9878760c
RK
7957 }
7958 else
a54d04b7 7959 output_addr_const (file, x);
a85d226b 7960 return;
9878760c
RK
7961
7962 default:
7963 output_operand_lossage ("invalid %%xn code");
7964 }
7965}
7966\f
7967/* Print the address of an operand. */
7968
7969void
7970print_operand_address (file, x)
7971 FILE *file;
592696dd 7972 rtx x;
9878760c
RK
7973{
7974 if (GET_CODE (x) == REG)
4697a36c 7975 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
7976 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
7977 || GET_CODE (x) == LABEL_REF)
9878760c
RK
7978 {
7979 output_addr_const (file, x);
ba5e43aa 7980 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7981 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7982 reg_names[SMALL_DATA_REG]);
9ebbca7d 7983 else if (TARGET_TOC)
a4f6c312 7984 abort ();
9878760c
RK
7985 }
7986 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
7987 {
7988 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
7989 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
7990 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 7991 else
4697a36c
MM
7992 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
7993 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
7994 }
7995 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
7996 {
7997 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
7998 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7999 }
3cb999d8
DE
8000#if TARGET_ELF
8001 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8002 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
8003 {
8004 output_addr_const (file, XEXP (x, 1));
8005 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8006 }
c859cda6
DJ
8007#endif
8008#if TARGET_MACHO
8009 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8010 && CONSTANT_P (XEXP (x, 1)))
8011 {
8012 fprintf (file, "lo16(");
8013 output_addr_const (file, XEXP (x, 1));
8014 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8015 }
3cb999d8 8016#endif
9ebbca7d
GK
8017 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
8018 {
2bfcf297 8019 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 8020 {
2bfcf297
DB
8021 rtx contains_minus = XEXP (x, 1);
8022 rtx minus, symref;
8023 const char *name;
9ebbca7d
GK
8024
8025 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 8026 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
8027 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8028 contains_minus = XEXP (contains_minus, 0);
8029
2bfcf297
DB
8030 minus = XEXP (contains_minus, 0);
8031 symref = XEXP (minus, 0);
8032 XEXP (contains_minus, 0) = symref;
8033 if (TARGET_ELF)
8034 {
8035 char *newname;
8036
8037 name = XSTR (symref, 0);
8038 newname = alloca (strlen (name) + sizeof ("@toc"));
8039 strcpy (newname, name);
8040 strcat (newname, "@toc");
8041 XSTR (symref, 0) = newname;
8042 }
8043 output_addr_const (file, XEXP (x, 1));
8044 if (TARGET_ELF)
8045 XSTR (symref, 0) = name;
9ebbca7d
GK
8046 XEXP (contains_minus, 0) = minus;
8047 }
8048 else
8049 output_addr_const (file, XEXP (x, 1));
8050
8051 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8052 }
9878760c
RK
8053 else
8054 abort ();
8055}
8056\f
301d03af
RS
8057/* Target hook for assembling integer objects. The powerpc version has
8058 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8059 is defined. It also needs to handle DI-mode objects on 64-bit
8060 targets. */
8061
8062static bool
8063rs6000_assemble_integer (x, size, aligned_p)
8064 rtx x;
8065 unsigned int size;
8066 int aligned_p;
8067{
8068#ifdef RELOCATABLE_NEEDS_FIXUP
8069 /* Special handling for SI values. */
8070 if (size == 4 && aligned_p)
8071 {
8072 extern int in_toc_section PARAMS ((void));
8073 static int recurse = 0;
8074
8075 /* For -mrelocatable, we mark all addresses that need to be fixed up
8076 in the .fixup section. */
8077 if (TARGET_RELOCATABLE
8078 && !in_toc_section ()
8079 && !in_text_section ()
8080 && !recurse
8081 && GET_CODE (x) != CONST_INT
8082 && GET_CODE (x) != CONST_DOUBLE
8083 && CONSTANT_P (x))
8084 {
8085 char buf[256];
8086
8087 recurse = 1;
8088 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8089 fixuplabelno++;
8090 ASM_OUTPUT_LABEL (asm_out_file, buf);
8091 fprintf (asm_out_file, "\t.long\t(");
8092 output_addr_const (asm_out_file, x);
8093 fprintf (asm_out_file, ")@fixup\n");
8094 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8095 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8096 fprintf (asm_out_file, "\t.long\t");
8097 assemble_name (asm_out_file, buf);
8098 fprintf (asm_out_file, "\n\t.previous\n");
8099 recurse = 0;
8100 return true;
8101 }
8102 /* Remove initial .'s to turn a -mcall-aixdesc function
8103 address into the address of the descriptor, not the function
8104 itself. */
8105 else if (GET_CODE (x) == SYMBOL_REF
8106 && XSTR (x, 0)[0] == '.'
8107 && DEFAULT_ABI == ABI_AIX)
8108 {
8109 const char *name = XSTR (x, 0);
8110 while (*name == '.')
8111 name++;
8112
8113 fprintf (asm_out_file, "\t.long\t%s\n", name);
8114 return true;
8115 }
8116 }
8117#endif /* RELOCATABLE_NEEDS_FIXUP */
8118 return default_assemble_integer (x, size, aligned_p);
8119}
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
8371 REVERSED is non-zero if we should reverse the sense of the comparison.
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
8551 know that the the operand is finite and the comparison
8552 would treat EQ different to UNORDERED, we can't do it. */
8553 if (! flag_unsafe_math_optimizations
8554 && code != GT && code != UNGE
8555 && (GET_CODE (op1) != CONST_DOUBLE || target_isinf (c1))
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
SS
8754#if TARGET_MACHO
8755 if (flag_pic && current_function_uses_pic_offset_table &&
1db02437
FS
8756 (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM))
8757 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
8758#endif
8759
9878760c
RK
8760 return first_reg;
8761}
8762
8763/* Similar, for FP regs. */
8764
8765int
8766first_fp_reg_to_save ()
8767{
8768 int first_reg;
8769
8770 /* Find lowest numbered live register. */
8771 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8772 if (regs_ever_live[first_reg])
8773 break;
8774
8775 return first_reg;
8776}
00b960c7
AH
8777
8778/* Similar, for AltiVec regs. */
8779
8780static int
8781first_altivec_reg_to_save ()
8782{
8783 int i;
8784
8785 /* Stack frame remains as is unless we are in AltiVec ABI. */
8786 if (! TARGET_ALTIVEC_ABI)
8787 return LAST_ALTIVEC_REGNO + 1;
8788
8789 /* Find lowest numbered live register. */
8790 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8791 if (regs_ever_live[i])
8792 break;
8793
8794 return i;
8795}
8796
8797/* Return a 32-bit mask of the AltiVec registers we need to set in
8798 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
8799 the 32-bit word is 0. */
8800
8801static unsigned int
8802compute_vrsave_mask ()
8803{
8804 unsigned int i, mask = 0;
8805
8806 /* First, find out if we use _any_ altivec registers. */
8807 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8808 if (regs_ever_live[i])
8809 mask |= ALTIVEC_REG_BIT (i);
8810
8811 if (mask == 0)
8812 return mask;
8813
8814 /* Next, add all registers that are call-clobbered. We do this
8815 because post-reload register optimizers such as regrename_optimize
8816 may choose to use them. They never change the register class
8817 chosen by reload, so cannot create new uses of altivec registers
8818 if there were none before, so the early exit above is safe. */
8819 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
8820 altivec registers not saved in the mask, which might well make the
8821 adjustments below more effective in eliding the save/restore of
8822 VRSAVE in small functions. */
8823 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8824 if (call_used_regs[i])
8825 mask |= ALTIVEC_REG_BIT (i);
8826
8827 /* Next, remove the argument registers from the set. These must
8828 be in the VRSAVE mask set by the caller, so we don't need to add
8829 them in again. More importantly, the mask we compute here is
8830 used to generate CLOBBERs in the set_vrsave insn, and we do not
8831 wish the argument registers to die. */
8832 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
8833 mask &= ~ALTIVEC_REG_BIT (i);
8834
8835 /* Similarly, remove the return value from the set. */
8836 {
8837 bool yes = false;
8838 diddle_return_value (is_altivec_return_reg, &yes);
8839 if (yes)
8840 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
8841 }
8842
8843 return mask;
8844}
8845
8846static void
8847is_altivec_return_reg (reg, xyes)
8848 rtx reg;
8849 void *xyes;
8850{
8851 bool *yes = (bool *) xyes;
8852 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
8853 *yes = true;
8854}
8855
4697a36c
MM
8856\f
8857/* Calculate the stack information for the current function. This is
8858 complicated by having two separate calling sequences, the AIX calling
8859 sequence and the V.4 calling sequence.
8860
592696dd 8861 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 8862 32-bit 64-bit
4697a36c 8863 SP----> +---------------------------------------+
a260abc9 8864 | back chain to caller | 0 0
4697a36c 8865 +---------------------------------------+
a260abc9 8866 | saved CR | 4 8 (8-11)
4697a36c 8867 +---------------------------------------+
a260abc9 8868 | saved LR | 8 16
4697a36c 8869 +---------------------------------------+
a260abc9 8870 | reserved for compilers | 12 24
4697a36c 8871 +---------------------------------------+
a260abc9 8872 | reserved for binders | 16 32
4697a36c 8873 +---------------------------------------+
a260abc9 8874 | saved TOC pointer | 20 40
4697a36c 8875 +---------------------------------------+
a260abc9 8876 | Parameter save area (P) | 24 48
4697a36c 8877 +---------------------------------------+
a260abc9 8878 | Alloca space (A) | 24+P etc.
802a0058 8879 +---------------------------------------+
a7df97e6 8880 | Local variable space (L) | 24+P+A
4697a36c 8881 +---------------------------------------+
a7df97e6 8882 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 8883 +---------------------------------------+
00b960c7
AH
8884 | Save area for AltiVec registers (W) | 24+P+A+L+X
8885 +---------------------------------------+
8886 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
8887 +---------------------------------------+
8888 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 8889 +---------------------------------------+
00b960c7
AH
8890 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
8891 +---------------------------------------+
8892 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
8893 +---------------------------------------+
8894 old SP->| back chain to caller's caller |
8895 +---------------------------------------+
8896
5376a30c
KR
8897 The required alignment for AIX configurations is two words (i.e., 8
8898 or 16 bytes).
8899
8900
4697a36c
MM
8901 V.4 stack frames look like:
8902
8903 SP----> +---------------------------------------+
8904 | back chain to caller | 0
8905 +---------------------------------------+
5eb387b8 8906 | caller's saved LR | 4
4697a36c
MM
8907 +---------------------------------------+
8908 | Parameter save area (P) | 8
8909 +---------------------------------------+
a7df97e6
MM
8910 | Alloca space (A) | 8+P
8911 +---------------------------------------+
8912 | Varargs save area (V) | 8+P+A
8913 +---------------------------------------+
8914 | Local variable space (L) | 8+P+A+V
8915 +---------------------------------------+
8916 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 8917 +---------------------------------------+
00b960c7
AH
8918 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
8919 +---------------------------------------+
8920 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
8921 +---------------------------------------+
8922 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
8923 +---------------------------------------+
a3170dc6
AH
8924 | SPE: area for 64-bit GP registers |
8925 +---------------------------------------+
8926 | SPE alignment padding |
8927 +---------------------------------------+
00b960c7 8928 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 8929 +---------------------------------------+
00b960c7 8930 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 8931 +---------------------------------------+
00b960c7 8932 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
8933 +---------------------------------------+
8934 old SP->| back chain to caller's caller |
8935 +---------------------------------------+
b6c9286a 8936
5376a30c
KR
8937 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
8938 given. (But note below and in sysv4.h that we require only 8 and
8939 may round up the size of our stack frame anyways. The historical
8940 reason is early versions of powerpc-linux which didn't properly
8941 align the stack at program startup. A happy side-effect is that
8942 -mno-eabi libraries can be used with -meabi programs.)
8943
5376a30c
KR
8944 The EABI configuration defaults to the V.4 layout, unless
8945 -mcall-aix is used, in which case the AIX layout is used. However,
8946 the stack alignment requirements may differ. If -mno-eabi is not
8947 given, the required stack alignment is 8 bytes; if -mno-eabi is
8948 given, the required alignment is 16 bytes. (But see V.4 comment
8949 above.) */
4697a36c 8950
61b2fbe7
MM
8951#ifndef ABI_STACK_BOUNDARY
8952#define ABI_STACK_BOUNDARY STACK_BOUNDARY
8953#endif
8954
4697a36c
MM
8955rs6000_stack_t *
8956rs6000_stack_info ()
8957{
8958 static rs6000_stack_t info, zero_info;
8959 rs6000_stack_t *info_ptr = &info;
9ebbca7d 8960 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 8961 enum rs6000_abi abi;
83720594 8962 int ehrd_size;
b6c9286a 8963 int total_raw_size;
4697a36c 8964
a4f6c312 8965 /* Zero all fields portably. */
4697a36c
MM
8966 info = zero_info;
8967
a4f6c312 8968 /* Select which calling sequence. */
b6c9286a 8969 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 8970
a4f6c312 8971 /* Calculate which registers need to be saved & save area size. */
4697a36c 8972 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 8973 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 8974 even if it currently looks like we won't. */
2bfcf297 8975 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
8976 || (flag_pic == 1 && abi == ABI_V4)
8977 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
8978 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
8979 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
8980 else
8981 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 8982
a3170dc6
AH
8983 /* For the SPE, we have an additional upper 32-bits on each GPR.
8984 Ideally we should save the entire 64-bits only when the upper
8985 half is used in SIMD instructions. Since we only record
8986 registers live (not the size they are used in), this proves
8987 difficult because we'd have to traverse the instruction chain at
8988 the right time, taking reload into account. This is a real pain,
8989 so we opt to save the GPRs in 64-bits always. Anyone overly
8990 concerned with frame size can fix this. ;-).
8991
8992 So... since we save all GPRs (except the SP) in 64-bits, the
8993 traditional GP save area will be empty. */
8994 if (TARGET_SPE_ABI)
8995 info_ptr->gp_size = 0;
8996
4697a36c
MM
8997 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
8998 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
8999
00b960c7
AH
9000 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9001 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9002 - info_ptr->first_altivec_reg_save);
9003
592696dd 9004 /* Does this function call anything? */
71f123ca
FS
9005 info_ptr->calls_p = (! current_function_is_leaf
9006 || cfun->machine->ra_needs_full_frame);
b6c9286a 9007
a4f6c312 9008 /* Determine if we need to save the link register. */
71f123ca 9009 if (rs6000_ra_ever_killed ()
70f4f91c 9010 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
9011#ifdef TARGET_RELOCATABLE
9012 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9013#endif
9014 || (info_ptr->first_fp_reg_save != 64
9015 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 9016 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 9017 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
9018 || (DEFAULT_ABI == ABI_DARWIN
9019 && flag_pic
9020 && current_function_uses_pic_offset_table)
4697a36c
MM
9021 || info_ptr->calls_p)
9022 {
9023 info_ptr->lr_save_p = 1;
9ebbca7d 9024 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9025 }
9026
9ebbca7d
GK
9027 /* Determine if we need to save the condition code registers. */
9028 if (regs_ever_live[CR2_REGNO]
9029 || regs_ever_live[CR3_REGNO]
9030 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9031 {
9032 info_ptr->cr_save_p = 1;
f607bc57 9033 if (abi == ABI_V4)
4697a36c
MM
9034 info_ptr->cr_size = reg_size;
9035 }
9036
83720594
RH
9037 /* If the current function calls __builtin_eh_return, then we need
9038 to allocate stack space for registers that will hold data for
9039 the exception handler. */
9040 if (current_function_calls_eh_return)
9041 {
9042 unsigned int i;
9043 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9044 continue;
a3170dc6
AH
9045
9046 /* SPE saves EH registers in 64-bits. */
9047 ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9048 }
9049 else
9050 ehrd_size = 0;
9051
592696dd 9052 /* Determine various sizes. */
4697a36c
MM
9053 info_ptr->reg_size = reg_size;
9054 info_ptr->fixed_size = RS6000_SAVE_AREA;
9055 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9056 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9057 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9058 8);
00b960c7 9059
a3170dc6
AH
9060 if (TARGET_SPE_ABI)
9061 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9062 else
9063 info_ptr->spe_gp_size = 0;
9064
08b57fb3 9065 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9066 {
9067 info_ptr->vrsave_mask = compute_vrsave_mask ();
9068 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9069 }
9070 else
9071 {
9072 info_ptr->vrsave_mask = 0;
9073 info_ptr->vrsave_size = 0;
9074 }
b6c9286a 9075
592696dd 9076 /* Calculate the offsets. */
24d304eb 9077 switch (abi)
4697a36c 9078 {
b6c9286a 9079 case ABI_NONE:
24d304eb 9080 default:
b6c9286a
MM
9081 abort ();
9082
9083 case ABI_AIX:
9084 case ABI_AIX_NODESC:
ee890fe2 9085 case ABI_DARWIN:
b6c9286a
MM
9086 info_ptr->fp_save_offset = - info_ptr->fp_size;
9087 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9088
9089 if (TARGET_ALTIVEC_ABI)
9090 {
9091 info_ptr->vrsave_save_offset
9092 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9093
9094 /* Align stack so vector save area is on a quadword boundary. */
9095 if (info_ptr->altivec_size != 0)
9096 info_ptr->altivec_padding_size
9097 = 16 - (-info_ptr->vrsave_save_offset % 16);
9098 else
9099 info_ptr->altivec_padding_size = 0;
9100
9101 info_ptr->altivec_save_offset
9102 = info_ptr->vrsave_save_offset
9103 - info_ptr->altivec_padding_size
9104 - info_ptr->altivec_size;
9105
9106 /* Adjust for AltiVec case. */
9107 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9108 }
9109 else
9110 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9111 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9112 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9113 break;
9114
9115 case ABI_V4:
b6c9286a
MM
9116 info_ptr->fp_save_offset = - info_ptr->fp_size;
9117 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9118 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9119
a3170dc6
AH
9120 if (TARGET_SPE_ABI)
9121 {
9122 /* Align stack so SPE GPR save area is aligned on a
9123 double-word boundary. */
9124 if (info_ptr->spe_gp_size != 0)
9125 info_ptr->spe_padding_size
9126 = 8 - (-info_ptr->cr_save_offset % 8);
9127 else
9128 info_ptr->spe_padding_size = 0;
9129
9130 info_ptr->spe_gp_save_offset
9131 = info_ptr->cr_save_offset
9132 - info_ptr->spe_padding_size
9133 - info_ptr->spe_gp_size;
9134
9135 /* Adjust for SPE case. */
9136 info_ptr->toc_save_offset
9137 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9138 }
9139 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9140 {
9141 info_ptr->vrsave_save_offset
9142 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9143
9144 /* Align stack so vector save area is on a quadword boundary. */
9145 if (info_ptr->altivec_size != 0)
9146 info_ptr->altivec_padding_size
9147 = 16 - (-info_ptr->vrsave_save_offset % 16);
9148 else
9149 info_ptr->altivec_padding_size = 0;
9150
9151 info_ptr->altivec_save_offset
9152 = info_ptr->vrsave_save_offset
9153 - info_ptr->altivec_padding_size
9154 - info_ptr->altivec_size;
9155
9156 /* Adjust for AltiVec case. */
9157 info_ptr->toc_save_offset
9158 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9159 }
9160 else
9161 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9162 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9163 info_ptr->lr_save_offset = reg_size;
9164 break;
4697a36c
MM
9165 }
9166
00b960c7
AH
9167 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9168 + info_ptr->gp_size
9169 + info_ptr->altivec_size
9170 + info_ptr->altivec_padding_size
9171 + info_ptr->vrsave_size
a3170dc6
AH
9172 + info_ptr->spe_gp_size
9173 + info_ptr->spe_padding_size
00b960c7
AH
9174 + ehrd_size
9175 + info_ptr->cr_size
9176 + info_ptr->lr_size
9177 + info_ptr->vrsave_size
9178 + info_ptr->toc_size,
9179 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9180 ? 16 : 8);
9181
ff381587
MM
9182 total_raw_size = (info_ptr->vars_size
9183 + info_ptr->parm_size
ff381587
MM
9184 + info_ptr->save_size
9185 + info_ptr->varargs_size
9186 + info_ptr->fixed_size);
9187
a4f6c312
SS
9188 info_ptr->total_size =
9189 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9190
9191 /* Determine if we need to allocate any stack frame:
9192
a4f6c312
SS
9193 For AIX we need to push the stack if a frame pointer is needed
9194 (because the stack might be dynamically adjusted), if we are
9195 debugging, if we make calls, or if the sum of fp_save, gp_save,
9196 and local variables are more than the space needed to save all
9197 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9198 + 18*8 = 288 (GPR13 reserved).
ff381587 9199
a4f6c312
SS
9200 For V.4 we don't have the stack cushion that AIX uses, but assume
9201 that the debugger can handle stackless frames. */
ff381587
MM
9202
9203 if (info_ptr->calls_p)
9204 info_ptr->push_p = 1;
9205
f607bc57 9206 else if (abi == ABI_V4)
e72247f4 9207 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
9208
9209 else
9210 info_ptr->push_p = (frame_pointer_needed
ee890fe2 9211 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 9212 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 9213 > (TARGET_32BIT ? 220 : 288)));
ff381587 9214
a4f6c312 9215 /* Zero offsets if we're not saving those registers. */
8dda1a21 9216 if (info_ptr->fp_size == 0)
4697a36c
MM
9217 info_ptr->fp_save_offset = 0;
9218
8dda1a21 9219 if (info_ptr->gp_size == 0)
4697a36c
MM
9220 info_ptr->gp_save_offset = 0;
9221
00b960c7
AH
9222 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9223 info_ptr->altivec_save_offset = 0;
9224
9225 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9226 info_ptr->vrsave_save_offset = 0;
9227
a3170dc6
AH
9228 if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
9229 info_ptr->spe_gp_save_offset = 0;
9230
c81fc13e 9231 if (! info_ptr->lr_save_p)
4697a36c
MM
9232 info_ptr->lr_save_offset = 0;
9233
c81fc13e 9234 if (! info_ptr->cr_save_p)
4697a36c
MM
9235 info_ptr->cr_save_offset = 0;
9236
c81fc13e 9237 if (! info_ptr->toc_save_p)
b6c9286a
MM
9238 info_ptr->toc_save_offset = 0;
9239
4697a36c
MM
9240 return info_ptr;
9241}
9242
9243void
9244debug_stack_info (info)
9245 rs6000_stack_t *info;
9878760c 9246{
d330fd93 9247 const char *abi_string;
24d304eb 9248
c81fc13e 9249 if (! info)
4697a36c
MM
9250 info = rs6000_stack_info ();
9251
9252 fprintf (stderr, "\nStack information for function %s:\n",
9253 ((current_function_decl && DECL_NAME (current_function_decl))
9254 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9255 : "<unknown>"));
9256
24d304eb
RK
9257 switch (info->abi)
9258 {
b6c9286a
MM
9259 default: abi_string = "Unknown"; break;
9260 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9261 case ABI_AIX:
b6c9286a 9262 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9263 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9264 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9265 }
9266
9267 fprintf (stderr, "\tABI = %5s\n", abi_string);
9268
00b960c7
AH
9269 if (TARGET_ALTIVEC_ABI)
9270 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9271
a3170dc6
AH
9272 if (TARGET_SPE_ABI)
9273 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9274
4697a36c
MM
9275 if (info->first_gp_reg_save != 32)
9276 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9277
9278 if (info->first_fp_reg_save != 64)
9279 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9280
00b960c7
AH
9281 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9282 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9283 info->first_altivec_reg_save);
9284
4697a36c
MM
9285 if (info->lr_save_p)
9286 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9287
4697a36c
MM
9288 if (info->cr_save_p)
9289 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9290
b6c9286a
MM
9291 if (info->toc_save_p)
9292 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9293
00b960c7
AH
9294 if (info->vrsave_mask)
9295 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9296
4697a36c
MM
9297 if (info->push_p)
9298 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9299
9300 if (info->calls_p)
9301 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9302
4697a36c
MM
9303 if (info->gp_save_offset)
9304 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9305
9306 if (info->fp_save_offset)
9307 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9308
00b960c7
AH
9309 if (info->altivec_save_offset)
9310 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9311 info->altivec_save_offset);
9312
a3170dc6
AH
9313 if (info->spe_gp_save_offset)
9314 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9315 info->spe_gp_save_offset);
9316
00b960c7
AH
9317 if (info->vrsave_save_offset)
9318 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9319 info->vrsave_save_offset);
9320
4697a36c
MM
9321 if (info->lr_save_offset)
9322 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9323
9324 if (info->cr_save_offset)
9325 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9326
b6c9286a
MM
9327 if (info->toc_save_offset)
9328 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9329
4697a36c
MM
9330 if (info->varargs_save_offset)
9331 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9332
9333 if (info->total_size)
9334 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9335
9336 if (info->varargs_size)
9337 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9338
9339 if (info->vars_size)
9340 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9341
9342 if (info->parm_size)
9343 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9344
9345 if (info->fixed_size)
9346 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9347
9348 if (info->gp_size)
9349 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9350
a3170dc6
AH
9351 if (info->spe_gp_size)
9352 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9353
4697a36c
MM
9354 if (info->fp_size)
9355 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9356
00b960c7
AH
9357 if (info->altivec_size)
9358 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9359
9360 if (info->vrsave_size)
9361 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9362
9363 if (info->altivec_padding_size)
9364 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9365 info->altivec_padding_size);
9366
a3170dc6
AH
9367 if (info->spe_padding_size)
9368 fprintf (stderr, "\tspe_padding_size = %5d\n",
9369 info->spe_padding_size);
9370
a4f6c312 9371 if (info->lr_size)
ed947a96 9372 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9373
4697a36c
MM
9374 if (info->cr_size)
9375 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9376
a4f6c312 9377 if (info->toc_size)
b6c9286a
MM
9378 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9379
4697a36c
MM
9380 if (info->save_size)
9381 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9382
9383 if (info->reg_size != 4)
9384 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9385
9386 fprintf (stderr, "\n");
9878760c 9387}
71f123ca
FS
9388
9389rtx
9390rs6000_return_addr (count, frame)
9391 int count;
9392 rtx frame;
9393{
a4f6c312
SS
9394 /* Currently we don't optimize very well between prolog and body
9395 code and for PIC code the code can be actually quite bad, so
9396 don't try to be too clever here. */
f585a356 9397 if (count != 0 || flag_pic != 0)
71f123ca
FS
9398 {
9399 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9400
9401 return
9402 gen_rtx_MEM
9403 (Pmode,
9404 memory_address
9405 (Pmode,
9406 plus_constant (copy_to_reg
9407 (gen_rtx_MEM (Pmode,
9408 memory_address (Pmode, frame))),
9409 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9410 }
9411
9e2f7ec7 9412 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9413}
9414
5e1bf043
DJ
9415/* Say whether a function is a candidate for sibcall handling or not.
9416 We do not allow indirect calls to be optimized into sibling calls.
9417 Also, we can't do it if there are any vector parameters; there's
9418 nowhere to put the VRsave code so it works; note that functions with
9419 vector parameters are required to have a prototype, so the argument
9420 type info must be available here. (The tail recursion case can work
9421 with vector parameters, but there's no way to distinguish here.) */
9422int
9423function_ok_for_sibcall (fndecl)
9424 tree fndecl;
9425{
9426 tree type;
9427 if (fndecl)
9428 {
9429 if (TARGET_ALTIVEC_VRSAVE)
9430 {
9431 for (type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
9432 type; type = TREE_CHAIN (type))
9433 {
9434 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE )
9435 return 0;
9436 }
9437 }
9438 if (DEFAULT_ABI == ABI_DARWIN
9439 || (TREE_ASM_WRITTEN (fndecl) && !flag_pic) || !TREE_PUBLIC (fndecl))
9440 return 1;
9441 }
9442 return 0;
9443}
9444
9445/* function rewritten to handle sibcalls */
71f123ca
FS
9446static int
9447rs6000_ra_ever_killed ()
9448{
9449 rtx top;
5e1bf043
DJ
9450 rtx reg;
9451 rtx insn;
71f123ca
FS
9452
9453#ifdef ASM_OUTPUT_MI_THUNK
9454 if (current_function_is_thunk)
9455 return 0;
9456#endif
5e1bf043
DJ
9457 /* regs_ever_live has LR marked as used if any sibcalls
9458 are present. Which it is, but this should not force
9459 saving and restoring in the prologue/epilog. Likewise,
9460 reg_set_between_p thinks a sibcall clobbers LR, so
9461 that is inappropriate. */
9462 /* Also, the prologue can generate a store into LR that
9463 doesn't really count, like this:
9464 move LR->R0
9465 bcl to set PIC register
9466 move LR->R31
9467 move R0->LR
9468 When we're called from the epilog, we need to avoid counting
9469 this as a store; thus we ignore any insns with a REG_MAYBE_DEAD note. */
9470
71f123ca
FS
9471 push_topmost_sequence ();
9472 top = get_insns ();
9473 pop_topmost_sequence ();
5e1bf043 9474 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9475
5e1bf043
DJ
9476 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9477 {
9478 if (INSN_P (insn))
9479 {
9480 if (FIND_REG_INC_NOTE (insn, reg))
9481 return 1;
9482 else if (GET_CODE (insn) == CALL_INSN
9483 && !SIBLING_CALL_P (insn))
9484 return 1;
9485 else if (set_of (reg, insn) != NULL_RTX
9486 && find_reg_note (insn, REG_MAYBE_DEAD, NULL_RTX) == 0)
9487 return 1;
9488 }
9489 }
9490 return 0;
71f123ca 9491}
4697a36c 9492\f
8cd8f856
GK
9493/* Add a REG_MAYBE_DEAD note to the insn. */
9494static void
9495rs6000_maybe_dead (insn)
9496 rtx insn;
9497{
9498 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9499 const0_rtx,
9500 REG_NOTES (insn));
9501}
9502
9ebbca7d 9503/* Emit instructions needed to load the TOC register.
c7ca610e 9504 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9505 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9506
9507void
9ebbca7d
GK
9508rs6000_emit_load_toc_table (fromprolog)
9509 int fromprolog;
c7ca610e 9510{
9ebbca7d 9511 rtx dest;
1db02437 9512 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9513
2bfcf297 9514 if (TARGET_ELF && DEFAULT_ABI != ABI_AIX)
c7ca610e 9515 {
f607bc57 9516 if (DEFAULT_ABI == ABI_V4 && flag_pic == 1)
38c1f2d7 9517 {
9ebbca7d
GK
9518 rtx temp = (fromprolog
9519 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9520 : gen_reg_rtx (Pmode));
2bfcf297 9521 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
8cd8f856 9522 rs6000_maybe_dead (emit_move_insn (dest, temp));
38c1f2d7 9523 }
9ebbca7d
GK
9524 else if (flag_pic == 2)
9525 {
9526 char buf[30];
9527 rtx tempLR = (fromprolog
9528 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9529 : gen_reg_rtx (Pmode));
9530 rtx temp0 = (fromprolog
9531 ? gen_rtx_REG (Pmode, 0)
9532 : gen_reg_rtx (Pmode));
9533 rtx symF;
9534
9535 /* possibly create the toc section */
9536 if (! toc_initialized)
9537 {
9538 toc_section ();
9539 function_section (current_function_decl);
9540 }
9541
9542 if (fromprolog)
9543 {
9544 rtx symL;
9545
9546 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
a8a05998 9547 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
38c1f2d7 9548
9ebbca7d 9549 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
a8a05998 9550 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
38c1f2d7 9551
8cd8f856
GK
9552 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9553 symF)));
9554 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9555 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9556 symL,
9557 symF)));
9ebbca7d
GK
9558 }
9559 else
9560 {
9561 rtx tocsym;
9562 static int reload_toc_labelno = 0;
9563
b999aaeb 9564 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
38c1f2d7 9565
9ebbca7d 9566 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
a8a05998 9567 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9568
8cd8f856
GK
9569 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9570 symF,
9571 tocsym)));
9572 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9573 rs6000_maybe_dead (emit_move_insn (temp0,
9574 gen_rtx_MEM (Pmode, dest)));
9ebbca7d 9575 }
8cd8f856 9576 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d
GK
9577 }
9578 else if (flag_pic == 0 && TARGET_MINIMAL_TOC)
9579 {
9580 /* This is for AIX code running in non-PIC ELF. */
9581 char buf[30];
9582 rtx realsym;
38c1f2d7 9583 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
a8a05998 9584 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9585
8cd8f856
GK
9586 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9587 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9ebbca7d
GK
9588 }
9589 else
a4f6c312 9590 abort ();
9ebbca7d
GK
9591 }
9592 else
9593 {
9594 if (TARGET_32BIT)
8cd8f856 9595 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 9596 else
8cd8f856 9597 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d
GK
9598 }
9599}
9600
9601int
9602get_TOC_alias_set ()
9603{
9604 static int set = -1;
9605 if (set == -1)
9606 set = new_alias_set ();
9607 return set;
9608}
9609
9610/* This retuns nonzero if the current function uses the TOC. This is
9611 determined by the presence of (unspec ... 7), which is generated by
9612 the various load_toc_* patterns. */
a4f6c312 9613
9ebbca7d
GK
9614int
9615uses_TOC ()
9616{
9617 rtx insn;
38c1f2d7 9618
9ebbca7d 9619 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 9620 if (INSN_P (insn))
9ebbca7d
GK
9621 {
9622 rtx pat = PATTERN (insn);
9623 int i;
9624
8cd8f856 9625 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
9626 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9627 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9628 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9629 return 1;
38c1f2d7 9630 }
9ebbca7d
GK
9631 return 0;
9632}
38c1f2d7 9633
9ebbca7d 9634rtx
a4f6c312 9635create_TOC_reference (symbol)
9ebbca7d
GK
9636 rtx symbol;
9637{
a8a05998
ZW
9638 return gen_rtx_PLUS (Pmode,
9639 gen_rtx_REG (Pmode, TOC_REGISTER),
9640 gen_rtx_CONST (Pmode,
9641 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 9642 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 9643}
38c1f2d7 9644
9ebbca7d
GK
9645#if TARGET_AIX
9646/* __throw will restore its own return address to be the same as the
9647 return address of the function that the throw is being made to.
9648 This is unfortunate, because we want to check the original
9649 return address to see if we need to restore the TOC.
9650 So we have to squirrel it away here.
9651 This is used only in compiling __throw and __rethrow.
c7ca610e 9652
9ebbca7d
GK
9653 Most of this code should be removed by CSE. */
9654static rtx insn_after_throw;
c7ca610e 9655
a4f6c312 9656/* This does the saving... */
9ebbca7d
GK
9657void
9658rs6000_aix_emit_builtin_unwind_init ()
9659{
9660 rtx mem;
9661 rtx stack_top = gen_reg_rtx (Pmode);
9662 rtx opcode_addr = gen_reg_rtx (Pmode);
9663
9664 insn_after_throw = gen_reg_rtx (SImode);
9665
9666 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9667 emit_move_insn (stack_top, mem);
9668
9669 mem = gen_rtx_MEM (Pmode,
9670 gen_rtx_PLUS (Pmode, stack_top,
9671 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9672 emit_move_insn (opcode_addr, mem);
9673 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
9674}
9675
a4f6c312
SS
9676/* Emit insns to _restore_ the TOC register, at runtime (specifically
9677 in _eh.o). Only used on AIX.
9ebbca7d
GK
9678
9679 The idea is that on AIX, function calls look like this:
9680 bl somefunction-trampoline
9681 lwz r2,20(sp)
9682
a4f6c312 9683 and later,
9ebbca7d
GK
9684 somefunction-trampoline:
9685 stw r2,20(sp)
9686 ... load function address in the count register ...
9687 bctr
9688 or like this, if the linker determines that this is not a cross-module call
9689 and so the TOC need not be restored:
9690 bl somefunction
9691 nop
9692 or like this, if the compiler could determine that this is not a
9693 cross-module call:
9694 bl somefunction
9695 now, the tricky bit here is that register 2 is saved and restored
9696 by the _linker_, so we can't readily generate debugging information
9697 for it. So we need to go back up the call chain looking at the
9698 insns at return addresses to see which calls saved the TOC register
9699 and so see where it gets restored from.
9700
9701 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9702 just before the actual epilogue.
9703
9704 On the bright side, this incurs no space or time overhead unless an
9705 exception is thrown, except for the extra code in libgcc.a.
9706
9707 The parameter STACKSIZE is a register containing (at runtime)
9708 the amount to be popped off the stack in addition to the stack frame
9709 of this routine (which will be __throw or __rethrow, and so is
9710 guaranteed to have a stack frame). */
a4f6c312 9711
9ebbca7d
GK
9712void
9713rs6000_emit_eh_toc_restore (stacksize)
9714 rtx stacksize;
9715{
9716 rtx top_of_stack;
9717 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9718 rtx tocompare = gen_reg_rtx (SImode);
9719 rtx opcode = gen_reg_rtx (SImode);
9720 rtx opcode_addr = gen_reg_rtx (Pmode);
9721 rtx mem;
9722 rtx loop_start = gen_label_rtx ();
9723 rtx no_toc_restore_needed = gen_label_rtx ();
9724 rtx loop_exit = gen_label_rtx ();
9725
9726 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 9727 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9728 emit_move_insn (bottom_of_stack, mem);
9729
9730 top_of_stack = expand_binop (Pmode, add_optab,
9731 bottom_of_stack, stacksize,
9732 NULL_RTX, 1, OPTAB_WIDEN);
9733
2496c7bd
LB
9734 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9735 : 0xE8410028, SImode));
9ebbca7d
GK
9736
9737 if (insn_after_throw == NULL_RTX)
a4f6c312 9738 abort ();
9ebbca7d
GK
9739 emit_move_insn (opcode, insn_after_throw);
9740
6496a589 9741 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
9742 emit_label (loop_start);
9743
9744 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 9745 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9746 no_toc_restore_needed);
9747
9748 mem = gen_rtx_MEM (Pmode,
9749 gen_rtx_PLUS (Pmode, bottom_of_stack,
9750 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
9751 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
9752
9753 emit_label (no_toc_restore_needed);
9754 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 9755 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9756 loop_exit);
9757
9758 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 9759 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9760 emit_move_insn (bottom_of_stack, mem);
9761
9762 mem = gen_rtx_MEM (Pmode,
9763 gen_rtx_PLUS (Pmode, bottom_of_stack,
9764 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9765 emit_move_insn (opcode_addr, mem);
9766 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
9767
6496a589 9768 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 9769 emit_jump (loop_start);
6496a589 9770 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
9771 emit_label (loop_exit);
9772}
9773#endif /* TARGET_AIX */
38c1f2d7 9774\f
ba4828e0
RK
9775/* This ties together stack memory (MEM with an alias set of
9776 rs6000_sr_alias_set) and the change to the stack pointer. */
9777
9ebbca7d
GK
9778static void
9779rs6000_emit_stack_tie ()
9780{
ba4828e0
RK
9781 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
9782
9783 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9784 emit_insn (gen_stack_tie (mem));
9785}
38c1f2d7 9786
9ebbca7d
GK
9787/* Emit the correct code for allocating stack space, as insns.
9788 If COPY_R12, make sure a copy of the old frame is left in r12.
9789 The generated code may use hard register 0 as a temporary. */
9790
9791static void
9792rs6000_emit_allocate_stack (size, copy_r12)
9793 HOST_WIDE_INT size;
38c1f2d7
MM
9794 int copy_r12;
9795{
9ebbca7d
GK
9796 rtx insn;
9797 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9798 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
9799 rtx todec = GEN_INT (-size);
a157febd
GK
9800
9801 if (current_function_limit_stack)
9802 {
9803 if (REG_P (stack_limit_rtx)
9804 && REGNO (stack_limit_rtx) > 1
9805 && REGNO (stack_limit_rtx) <= 31)
9806 {
9ebbca7d
GK
9807 emit_insn (Pmode == SImode
9808 ? gen_addsi3 (tmp_reg,
9809 stack_limit_rtx,
9810 GEN_INT (size))
9811 : gen_adddi3 (tmp_reg,
9812 stack_limit_rtx,
9813 GEN_INT (size)));
9814
9815 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9816 const0_rtx));
a157febd
GK
9817 }
9818 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 9819 && TARGET_32BIT
f607bc57 9820 && DEFAULT_ABI == ABI_V4)
a157febd 9821 {
9ebbca7d
GK
9822 rtx toload = gen_rtx_CONST (VOIDmode,
9823 gen_rtx_PLUS (Pmode,
9824 stack_limit_rtx,
9825 GEN_INT (size)));
9826
9827 emit_insn (gen_elf_high (tmp_reg, toload));
9828 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
9829 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9830 const0_rtx));
a157febd
GK
9831 }
9832 else
9833 warning ("stack limit expression is not supported");
9834 }
9835
9ebbca7d
GK
9836 if (copy_r12 || ! TARGET_UPDATE)
9837 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
9838
38c1f2d7
MM
9839 if (TARGET_UPDATE)
9840 {
9ebbca7d 9841 if (size > 32767)
38c1f2d7 9842 {
9ebbca7d
GK
9843 /* Need a note here so that try_split doesn't get confused. */
9844 if (get_last_insn() == NULL_RTX)
9845 emit_note (0, NOTE_INSN_DELETED);
9846 insn = emit_move_insn (tmp_reg, todec);
9847 try_split (PATTERN (insn), insn, 0);
9848 todec = tmp_reg;
38c1f2d7 9849 }
9ebbca7d
GK
9850
9851 if (Pmode == SImode)
9852 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
9853 todec, stack_reg));
9854 else
9855 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
9856 todec, stack_reg));
38c1f2d7
MM
9857 }
9858 else
9859 {
9ebbca7d
GK
9860 if (Pmode == SImode)
9861 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
38c1f2d7 9862 else
9ebbca7d
GK
9863 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
9864 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
9865 gen_rtx_REG (Pmode, 12));
9866 }
9867
9868 RTX_FRAME_RELATED_P (insn) = 1;
9869 REG_NOTES (insn) =
9870 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9871 gen_rtx_SET (VOIDmode, stack_reg,
9872 gen_rtx_PLUS (Pmode, stack_reg,
9873 GEN_INT (-size))),
9874 REG_NOTES (insn));
9875}
9876
9aa86737
AH
9877/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
9878 knows that:
9879
9880 (mem (plus (blah) (regXX)))
9881
9882 is really:
9883
9884 (mem (plus (blah) (const VALUE_OF_REGXX))). */
9885
9886static void
9887altivec_frame_fixup (insn, reg, val)
9888 rtx insn, reg;
9889 HOST_WIDE_INT val;
9890{
9891 rtx real;
9892
9893 real = copy_rtx (PATTERN (insn));
9894
9895 real = replace_rtx (real, reg, GEN_INT (val));
9896
9897 RTX_FRAME_RELATED_P (insn) = 1;
9898 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9899 real,
9900 REG_NOTES (insn));
9901}
9902
a4f6c312
SS
9903/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
9904 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
9905 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
9906 deduce these equivalences by itself so it wasn't necessary to hold
9907 its hand so much. */
9ebbca7d
GK
9908
9909static void
9910rs6000_frame_related (insn, reg, val, reg2, rreg)
9911 rtx insn;
9912 rtx reg;
9913 HOST_WIDE_INT val;
9914 rtx reg2;
9915 rtx rreg;
9916{
9917 rtx real, temp;
9918
e56c4463
JL
9919 /* copy_rtx will not make unique copies of registers, so we need to
9920 ensure we don't have unwanted sharing here. */
9921 if (reg == reg2)
9922 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9923
9924 if (reg == rreg)
9925 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9926
9ebbca7d
GK
9927 real = copy_rtx (PATTERN (insn));
9928
89e7058f
AH
9929 if (reg2 != NULL_RTX)
9930 real = replace_rtx (real, reg2, rreg);
9931
9ebbca7d
GK
9932 real = replace_rtx (real, reg,
9933 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
9934 STACK_POINTER_REGNUM),
9935 GEN_INT (val)));
9936
9937 /* We expect that 'real' is either a SET or a PARALLEL containing
9938 SETs (and possibly other stuff). In a PARALLEL, all the SETs
9939 are important so they all have to be marked RTX_FRAME_RELATED_P. */
9940
9941 if (GET_CODE (real) == SET)
9942 {
9943 rtx set = real;
9944
9945 temp = simplify_rtx (SET_SRC (set));
9946 if (temp)
9947 SET_SRC (set) = temp;
9948 temp = simplify_rtx (SET_DEST (set));
9949 if (temp)
9950 SET_DEST (set) = temp;
9951 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 9952 {
9ebbca7d
GK
9953 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9954 if (temp)
9955 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 9956 }
38c1f2d7 9957 }
9ebbca7d
GK
9958 else if (GET_CODE (real) == PARALLEL)
9959 {
9960 int i;
9961 for (i = 0; i < XVECLEN (real, 0); i++)
9962 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
9963 {
9964 rtx set = XVECEXP (real, 0, i);
9965
9966 temp = simplify_rtx (SET_SRC (set));
9967 if (temp)
9968 SET_SRC (set) = temp;
9969 temp = simplify_rtx (SET_DEST (set));
9970 if (temp)
9971 SET_DEST (set) = temp;
9972 if (GET_CODE (SET_DEST (set)) == MEM)
9973 {
9974 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9975 if (temp)
9976 XEXP (SET_DEST (set), 0) = temp;
9977 }
9978 RTX_FRAME_RELATED_P (set) = 1;
9979 }
9980 }
9981 else
a4f6c312 9982 abort ();
9ebbca7d 9983
9ebbca7d
GK
9984 RTX_FRAME_RELATED_P (insn) = 1;
9985 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9986 real,
9987 REG_NOTES (insn));
38c1f2d7
MM
9988}
9989
00b960c7
AH
9990/* Returns an insn that has a vrsave set operation with the
9991 appropriate CLOBBERs. */
9992
9993static rtx
9aa86737 9994generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
9995 rtx reg;
9996 rs6000_stack_t *info;
9aa86737 9997 int epiloguep;
00b960c7
AH
9998{
9999 int nclobs, i;
10000 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 10001 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 10002
a004eb82
AH
10003 clobs[0]
10004 = gen_rtx_SET (VOIDmode,
10005 vrsave,
10006 gen_rtx_UNSPEC_VOLATILE (SImode,
10007 gen_rtvec (2, reg, vrsave),
10008 30));
00b960c7
AH
10009
10010 nclobs = 1;
10011
9aa86737
AH
10012 /* We need to clobber the registers in the mask so the scheduler
10013 does not move sets to VRSAVE before sets of AltiVec registers.
10014
10015 However, if the function receives nonlocal gotos, reload will set
10016 all call saved registers live. We will end up with:
10017
10018 (set (reg 999) (mem))
10019 (parallel [ (set (reg vrsave) (unspec blah))
10020 (clobber (reg 999))])
10021
10022 The clobber will cause the store into reg 999 to be dead, and
10023 flow will attempt to delete an epilogue insn. In this case, we
10024 need an unspec use/set of the register. */
00b960c7
AH
10025
10026 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10027 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10028 {
10029 if (!epiloguep || call_used_regs [i])
10030 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10031 gen_rtx_REG (V4SImode, i));
10032 else
10033 {
10034 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10035
10036 clobs[nclobs++]
a004eb82
AH
10037 = gen_rtx_SET (VOIDmode,
10038 reg,
10039 gen_rtx_UNSPEC (V4SImode,
10040 gen_rtvec (1, reg), 27));
9aa86737
AH
10041 }
10042 }
00b960c7
AH
10043
10044 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10045
10046 for (i = 0; i < nclobs; ++i)
10047 XVECEXP (insn, 0, i) = clobs[i];
10048
10049 return insn;
10050}
10051
89e7058f
AH
10052/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10053 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10054
10055static void
10056emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10057 rtx frame_reg;
10058 rtx frame_ptr;
10059 enum machine_mode mode;
10060 unsigned int regno;
10061 int offset;
10062 int total_size;
10063{
10064 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10065 rtx replacea, replaceb;
10066
10067 int_rtx = GEN_INT (offset);
10068
10069 /* Some cases that need register indexed addressing. */
10070 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10071 || (TARGET_SPE_ABI
10072 && SPE_VECTOR_MODE (mode)
10073 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10074 {
10075 /* Whomever calls us must make sure r11 is available in the
10076 flow path of instructions in the prologue. */
10077 offset_rtx = gen_rtx_REG (Pmode, 11);
10078 emit_move_insn (offset_rtx, int_rtx);
10079
10080 replacea = offset_rtx;
10081 replaceb = int_rtx;
10082 }
10083 else
10084 {
10085 offset_rtx = int_rtx;
10086 replacea = NULL_RTX;
10087 replaceb = NULL_RTX;
10088 }
10089
10090 reg = gen_rtx_REG (mode, regno);
10091 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10092 mem = gen_rtx_MEM (mode, addr);
10093 set_mem_alias_set (mem, rs6000_sr_alias_set);
10094
10095 insn = emit_move_insn (mem, reg);
10096
10097 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10098}
10099
a3170dc6
AH
10100/* Emit an offset memory reference suitable for a frame store, while
10101 converting to a valid addressing mode. */
10102
10103static rtx
10104gen_frame_mem_offset (mode, reg, offset)
10105 enum machine_mode mode;
10106 rtx reg;
10107 int offset;
10108{
10109 rtx int_rtx, offset_rtx;
10110
10111 int_rtx = GEN_INT (offset);
10112
10113 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10114 {
10115 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10116 emit_move_insn (offset_rtx, int_rtx);
10117 }
10118 else
10119 offset_rtx = int_rtx;
10120
10121 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10122}
10123
9ebbca7d
GK
10124/* Emit function prologue as insns. */
10125
9878760c 10126void
83720594 10127rs6000_emit_prologue ()
9878760c 10128{
4697a36c 10129 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10130 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10131 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10132 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10133 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10134 rtx frame_reg_rtx = sp_reg_rtx;
10135 rtx cr_save_rtx = NULL;
10136 rtx insn;
10137 int saving_FPRs_inline;
10138 int using_store_multiple;
10139 HOST_WIDE_INT sp_offset = 0;
10140
a3170dc6
AH
10141 if (TARGET_SPE_ABI)
10142 {
10143 reg_mode = V2SImode;
10144 reg_size = 8;
10145 }
10146
9ebbca7d 10147 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10148 && !TARGET_SPE_ABI
9ebbca7d
GK
10149 && info->first_gp_reg_save < 31);
10150 saving_FPRs_inline = (info->first_fp_reg_save == 64
10151 || FP_SAVE_INLINE (info->first_fp_reg_save));
10152
10153 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10154 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10155 {
10156 if (info->total_size < 32767)
10157 sp_offset = info->total_size;
10158 else
10159 frame_reg_rtx = frame_ptr_rtx;
10160 rs6000_emit_allocate_stack (info->total_size,
10161 (frame_reg_rtx != sp_reg_rtx
10162 && (info->cr_save_p
10163 || info->lr_save_p
10164 || info->first_fp_reg_save < 64
10165 || info->first_gp_reg_save < 32
10166 )));
10167 if (frame_reg_rtx != sp_reg_rtx)
10168 rs6000_emit_stack_tie ();
10169 }
10170
9aa86737
AH
10171 /* Save AltiVec registers if needed. */
10172 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10173 {
10174 int i;
10175
10176 /* There should be a non inline version of this, for when we
10177 are saving lots of vector registers. */
10178 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10179 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10180 {
10181 rtx areg, savereg, mem;
10182 int offset;
10183
10184 offset = info->altivec_save_offset + sp_offset
10185 + 16 * (i - info->first_altivec_reg_save);
10186
10187 savereg = gen_rtx_REG (V4SImode, i);
10188
10189 areg = gen_rtx_REG (Pmode, 0);
10190 emit_move_insn (areg, GEN_INT (offset));
10191
10192 /* AltiVec addressing mode is [reg+reg]. */
10193 mem = gen_rtx_MEM (V4SImode,
10194 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10195
10196 set_mem_alias_set (mem, rs6000_sr_alias_set);
10197
10198 insn = emit_move_insn (mem, savereg);
10199
10200 altivec_frame_fixup (insn, areg, offset);
10201 }
10202 }
10203
10204 /* VRSAVE is a bit vector representing which AltiVec registers
10205 are used. The OS uses this to determine which vector
10206 registers to save on a context switch. We need to save
10207 VRSAVE on the stack frame, add whatever AltiVec registers we
10208 used in this function, and do the corresponding magic in the
10209 epilogue. */
10210
10211 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10212 {
a004eb82 10213 rtx reg, mem, vrsave;
9aa86737
AH
10214 int offset;
10215
10216 /* Get VRSAVE onto a GPR. */
10217 reg = gen_rtx_REG (SImode, 12);
a004eb82 10218 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10219 if (TARGET_MACHO)
10220 emit_insn (gen_get_vrsave_internal (reg));
10221 else
10222 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10223
10224 /* Save VRSAVE. */
10225 offset = info->vrsave_save_offset + sp_offset;
10226 mem
10227 = gen_rtx_MEM (SImode,
10228 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10229 set_mem_alias_set (mem, rs6000_sr_alias_set);
10230 insn = emit_move_insn (mem, reg);
10231
10232 /* Include the registers in the mask. */
10233 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10234
10235 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10236 }
10237
9ebbca7d
GK
10238 /* If we use the link register, get it into r0. */
10239 if (info->lr_save_p)
71f123ca 10240 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10241 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10242
10243 /* If we need to save CR, put it into r12. */
10244 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10245 {
10246 cr_save_rtx = gen_rtx_REG (SImode, 12);
10247 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10248 }
10249
a4f6c312
SS
10250 /* Do any required saving of fpr's. If only one or two to save, do
10251 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10252 if (saving_FPRs_inline)
10253 {
10254 int i;
10255 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10256 if ((regs_ever_live[info->first_fp_reg_save+i]
10257 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10258 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10259 info->first_fp_reg_save + i,
10260 info->fp_save_offset + sp_offset + 8 * i,
10261 info->total_size);
9ebbca7d
GK
10262 }
10263 else if (info->first_fp_reg_save != 64)
10264 {
10265 int i;
10266 char rname[30];
520a57c8 10267 const char *alloc_rname;
9ebbca7d
GK
10268 rtvec p;
10269 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10270
10271 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10272 gen_rtx_REG (Pmode,
10273 LINK_REGISTER_REGNUM));
10274 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10275 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10276 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10277 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10278 gen_rtx_SYMBOL_REF (Pmode,
10279 alloc_rname));
10280 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10281 {
10282 rtx addr, reg, mem;
10283 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10284 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10285 GEN_INT (info->fp_save_offset
10286 + sp_offset + 8*i));
10287 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10288 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10289
10290 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10291 }
10292 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10293 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10294 NULL_RTX, NULL_RTX);
10295 }
b6c9286a 10296
9ebbca7d
GK
10297 /* Save GPRs. This is done as a PARALLEL if we are using
10298 the store-multiple instructions. */
10299 if (using_store_multiple)
b6c9286a 10300 {
308c142a 10301 rtvec p;
9ebbca7d
GK
10302 int i;
10303 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10304 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10305 {
10306 rtx addr, reg, mem;
10307 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10308 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10309 GEN_INT (info->gp_save_offset
10310 + sp_offset
10311 + reg_size * i));
10312 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10313 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10314
10315 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10316 }
10317 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10318 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10319 NULL_RTX, NULL_RTX);
b6c9286a
MM
10320 }
10321 else
10322 {
9ebbca7d
GK
10323 int i;
10324 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10325 if ((regs_ever_live[info->first_gp_reg_save+i]
10326 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10327 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10328 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10329 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10330 {
10331 rtx addr, reg, mem;
10332 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10333
10334 if (TARGET_SPE_ABI)
10335 {
10336 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10337 rtx b;
10338
10339 if (!SPE_CONST_OFFSET_OK (offset))
10340 {
10341 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10342 emit_move_insn (b, GEN_INT (offset));
10343 }
10344 else
10345 b = GEN_INT (offset);
10346
10347 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10348 mem = gen_rtx_MEM (V2SImode, addr);
10349 set_mem_alias_set (mem, rs6000_sr_alias_set);
10350 insn = emit_move_insn (mem, reg);
10351
10352 if (GET_CODE (b) == CONST_INT)
10353 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10354 NULL_RTX, NULL_RTX);
10355 else
10356 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10357 b, GEN_INT (offset));
10358 }
10359 else
10360 {
10361 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10362 GEN_INT (info->gp_save_offset
10363 + sp_offset
10364 + reg_size * i));
10365 mem = gen_rtx_MEM (reg_mode, addr);
10366 set_mem_alias_set (mem, rs6000_sr_alias_set);
10367
10368 insn = emit_move_insn (mem, reg);
10369 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10370 NULL_RTX, NULL_RTX);
10371 }
10372 }
9ebbca7d
GK
10373 }
10374
83720594
RH
10375 /* ??? There's no need to emit actual instructions here, but it's the
10376 easiest way to get the frame unwind information emitted. */
10377 if (current_function_calls_eh_return)
10378 {
78e1b90d
DE
10379 unsigned int i, regno;
10380
83720594
RH
10381 for (i = 0; ; ++i)
10382 {
83720594
RH
10383 regno = EH_RETURN_DATA_REGNO (i);
10384 if (regno == INVALID_REGNUM)
10385 break;
10386
89e7058f
AH
10387 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10388 info->ehrd_offset + sp_offset
10389 + reg_size * (int) i,
10390 info->total_size);
83720594
RH
10391 }
10392 }
10393
9ebbca7d
GK
10394 /* Save lr if we used it. */
10395 if (info->lr_save_p)
10396 {
10397 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10398 GEN_INT (info->lr_save_offset + sp_offset));
10399 rtx reg = gen_rtx_REG (Pmode, 0);
10400 rtx mem = gen_rtx_MEM (Pmode, addr);
10401 /* This should not be of rs6000_sr_alias_set, because of
10402 __builtin_return_address. */
10403
10404 insn = emit_move_insn (mem, reg);
10405 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10406 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10407 }
10408
10409 /* Save CR if we use any that must be preserved. */
10410 if (info->cr_save_p)
10411 {
10412 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10413 GEN_INT (info->cr_save_offset + sp_offset));
10414 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10415
10416 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10417
10418 /* If r12 was used to hold the original sp, copy cr into r0 now
10419 that it's free. */
10420 if (REGNO (frame_reg_rtx) == 12)
10421 {
10422 cr_save_rtx = gen_rtx_REG (SImode, 0);
10423 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10424 }
10425 insn = emit_move_insn (mem, cr_save_rtx);
10426
10427 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10428 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10429 OK. All we have to do is specify that _one_ condition code
10430 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10431 will then restore all the call-saved registers.
10432 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10433 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10434 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10435 }
10436
10437 /* Update stack and set back pointer unless this is V.4,
10438 for which it was done previously. */
f607bc57 10439 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10440 rs6000_emit_allocate_stack (info->total_size, FALSE);
10441
10442 /* Set frame pointer, if needed. */
10443 if (frame_pointer_needed)
10444 {
a3170dc6 10445 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10446 sp_reg_rtx);
10447 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10448 }
9878760c 10449
1db02437 10450 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10451 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10452 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10453 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10454 {
10455 /* If emit_load_toc_table will use the link register, we need to save
10456 it. We use R11 for this purpose because emit_load_toc_table
10457 can use register 0. This allows us to use a plain 'blr' to return
10458 from the procedure more often. */
d5fa86ba
GK
10459 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10460 && ! info->lr_save_p
10461 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10462 if (save_LR_around_toc_setup)
10463 emit_move_insn (gen_rtx_REG (Pmode, 11),
10464 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10465
10466 rs6000_emit_load_toc_table (TRUE);
10467
10468 if (save_LR_around_toc_setup)
10469 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10470 gen_rtx_REG (Pmode, 11));
10471 }
ee890fe2
SS
10472
10473 if (DEFAULT_ABI == ABI_DARWIN
10474 && flag_pic && current_function_uses_pic_offset_table)
10475 {
10476 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
10477
10478 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest)));
10479
10480 rs6000_maybe_dead (
1db02437 10481 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10482 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10483 }
9ebbca7d
GK
10484}
10485
9ebbca7d 10486/* Write function prologue. */
a4f6c312 10487
08c148a8
NB
10488static void
10489rs6000_output_function_prologue (file, size)
9ebbca7d 10490 FILE *file;
08c148a8 10491 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10492{
10493 rs6000_stack_t *info = rs6000_stack_info ();
10494
4697a36c
MM
10495 if (TARGET_DEBUG_STACK)
10496 debug_stack_info (info);
9878760c 10497
a4f6c312
SS
10498 /* Write .extern for any function we will call to save and restore
10499 fp values. */
10500 if (info->first_fp_reg_save < 64
10501 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10502 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10503 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10504 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10505 RESTORE_FP_SUFFIX);
9878760c 10506
c764f757
RK
10507 /* Write .extern for AIX common mode routines, if needed. */
10508 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10509 {
f6709c70
JW
10510 fputs ("\t.extern __mulh\n", file);
10511 fputs ("\t.extern __mull\n", file);
10512 fputs ("\t.extern __divss\n", file);
10513 fputs ("\t.extern __divus\n", file);
10514 fputs ("\t.extern __quoss\n", file);
10515 fputs ("\t.extern __quous\n", file);
c764f757
RK
10516 common_mode_defined = 1;
10517 }
9878760c 10518
9ebbca7d 10519 if (! HAVE_prologue)
979721f8 10520 {
9ebbca7d 10521 start_sequence ();
9dda4cc8 10522
a4f6c312
SS
10523 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10524 the "toplevel" insn chain. */
9ebbca7d
GK
10525 emit_note (0, NOTE_INSN_DELETED);
10526 rs6000_emit_prologue ();
10527 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10528
10529 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10530 {
10531 rtx insn;
10532 unsigned addr = 0;
10533 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10534 {
10535 INSN_ADDRESSES_NEW (insn, addr);
10536 addr += 4;
10537 }
10538 }
9dda4cc8 10539
9ebbca7d 10540 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10541 debug_rtx_list (get_insns (), 100);
10542 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10543 end_sequence ();
979721f8
MM
10544 }
10545
9ebbca7d
GK
10546 rs6000_pic_labelno++;
10547}
10548
10549/* Emit function epilogue as insns.
9878760c 10550
9ebbca7d
GK
10551 At present, dwarf2out_frame_debug_expr doesn't understand
10552 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10553 anywhere in the epilogue. Most of the insns below would in any case
10554 need special notes to explain where r11 is in relation to the stack. */
9878760c 10555
9ebbca7d 10556void
83720594 10557rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
10558 int sibcall;
10559{
10560 rs6000_stack_t *info;
10561 int restoring_FPRs_inline;
10562 int using_load_multiple;
10563 int using_mfcr_multiple;
10564 int use_backchain_to_restore_sp;
10565 int sp_offset = 0;
10566 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10567 rtx frame_reg_rtx = sp_reg_rtx;
10568 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10569 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10570 int i;
10571
a3170dc6
AH
10572 if (TARGET_SPE_ABI)
10573 {
10574 reg_mode = V2SImode;
10575 reg_size = 8;
10576 }
10577
9ebbca7d
GK
10578 info = rs6000_stack_info ();
10579 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10580 && !TARGET_SPE_ABI
9ebbca7d
GK
10581 && info->first_gp_reg_save < 31);
10582 restoring_FPRs_inline = (sibcall
83720594 10583 || current_function_calls_eh_return
9ebbca7d
GK
10584 || info->first_fp_reg_save == 64
10585 || FP_SAVE_INLINE (info->first_fp_reg_save));
10586 use_backchain_to_restore_sp = (frame_pointer_needed
10587 || current_function_calls_alloca
10588 || info->total_size > 32767);
10589 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10590 || rs6000_cpu == PROCESSOR_PPC603
10591 || rs6000_cpu == PROCESSOR_PPC750
10592 || optimize_size);
10593
10594 /* If we have a frame pointer, a call to alloca, or a large stack
10595 frame, restore the old stack pointer using the backchain. Otherwise,
10596 we know what size to update it with. */
10597 if (use_backchain_to_restore_sp)
bacbde18 10598 {
9ebbca7d
GK
10599 /* Under V.4, don't reset the stack pointer until after we're done
10600 loading the saved registers. */
f607bc57 10601 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 10602 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 10603
9ebbca7d
GK
10604 emit_move_insn (frame_reg_rtx,
10605 gen_rtx_MEM (Pmode, sp_reg_rtx));
10606
bacbde18 10607 }
9ebbca7d 10608 else if (info->push_p)
85638c0d 10609 {
f607bc57 10610 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10611 sp_offset = info->total_size;
10612 else
10613 {
10614 emit_insn (TARGET_32BIT
10615 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10616 GEN_INT (info->total_size))
10617 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10618 GEN_INT (info->total_size)));
10619 }
85638c0d 10620 }
9ebbca7d 10621
9aa86737
AH
10622 /* Restore AltiVec registers if needed. */
10623 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10624 {
10625 int i;
10626
10627 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10628 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10629 {
10630 rtx addr, areg, mem;
10631
10632 areg = gen_rtx_REG (Pmode, 0);
10633 emit_move_insn
10634 (areg, GEN_INT (info->altivec_save_offset
10635 + sp_offset
10636 + 16 * (i - info->first_altivec_reg_save)));
10637
10638 /* AltiVec addressing mode is [reg+reg]. */
10639 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10640 mem = gen_rtx_MEM (V4SImode, addr);
10641 set_mem_alias_set (mem, rs6000_sr_alias_set);
10642
10643 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10644 }
10645 }
10646
10647 /* Restore VRSAVE if needed. */
10648 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10649 {
10650 rtx addr, mem, reg;
10651
10652 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10653 GEN_INT (info->vrsave_save_offset + sp_offset));
10654 mem = gen_rtx_MEM (SImode, addr);
10655 set_mem_alias_set (mem, rs6000_sr_alias_set);
10656 reg = gen_rtx_REG (SImode, 12);
10657 emit_move_insn (reg, mem);
10658
10659 emit_insn (generate_set_vrsave (reg, info, 1));
10660 }
10661
9ebbca7d
GK
10662 /* Get the old lr if we saved it. */
10663 if (info->lr_save_p)
b6c9286a 10664 {
a3170dc6
AH
10665 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10666 info->lr_save_offset + sp_offset);
ba4828e0
RK
10667
10668 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10669
9ebbca7d 10670 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 10671 }
9ebbca7d
GK
10672
10673 /* Get the old cr if we saved it. */
10674 if (info->cr_save_p)
10675 {
10676 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10677 GEN_INT (info->cr_save_offset + sp_offset));
10678 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10679
10680 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10681
9ebbca7d
GK
10682 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10683 }
10684
10685 /* Set LR here to try to overlap restores below. */
4697a36c 10686 if (info->lr_save_p)
9ebbca7d
GK
10687 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10688 gen_rtx_REG (Pmode, 0));
10689
83720594
RH
10690 /* Load exception handler data registers, if needed. */
10691 if (current_function_calls_eh_return)
10692 {
78e1b90d
DE
10693 unsigned int i, regno;
10694
83720594
RH
10695 for (i = 0; ; ++i)
10696 {
a3170dc6 10697 rtx mem;
83720594
RH
10698
10699 regno = EH_RETURN_DATA_REGNO (i);
10700 if (regno == INVALID_REGNUM)
10701 break;
10702
a3170dc6
AH
10703 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
10704 info->ehrd_offset + sp_offset
10705 + reg_size * (int) i);
ba4828e0 10706 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
10707
10708 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
10709 }
10710 }
9ebbca7d
GK
10711
10712 /* Restore GPRs. This is done as a PARALLEL if we are using
10713 the load-multiple instructions. */
10714 if (using_load_multiple)
979721f8 10715 {
9ebbca7d
GK
10716 rtvec p;
10717 p = rtvec_alloc (32 - info->first_gp_reg_save);
10718 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 10719 {
9ebbca7d
GK
10720 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10721 GEN_INT (info->gp_save_offset
10722 + sp_offset
10723 + reg_size * i));
10724 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
10725
10726 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10727
10728 RTVEC_ELT (p, i) =
10729 gen_rtx_SET (VOIDmode,
10730 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
10731 mem);
979721f8 10732 }
9ebbca7d 10733 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 10734 }
9ebbca7d
GK
10735 else
10736 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10737 if ((regs_ever_live[info->first_gp_reg_save+i]
10738 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10739 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10740 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10741 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
10742 {
10743 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10744 GEN_INT (info->gp_save_offset
10745 + sp_offset
10746 + reg_size * i));
10747 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10748
a3170dc6
AH
10749 /* Restore 64-bit quantities for SPE. */
10750 if (TARGET_SPE_ABI)
10751 {
10752 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10753 rtx b;
10754
10755 if (!SPE_CONST_OFFSET_OK (offset))
10756 {
10757 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10758 emit_move_insn (b, GEN_INT (offset));
10759 }
10760 else
10761 b = GEN_INT (offset);
10762
10763 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10764 mem = gen_rtx_MEM (V2SImode, addr);
10765 }
10766
ba4828e0 10767 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10768
10769 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 10770 info->first_gp_reg_save + i), mem);
9ebbca7d 10771 }
9878760c 10772
9ebbca7d
GK
10773 /* Restore fpr's if we need to do it without calling a function. */
10774 if (restoring_FPRs_inline)
10775 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10776 if ((regs_ever_live[info->first_fp_reg_save+i]
10777 && ! call_used_regs[info->first_fp_reg_save+i]))
10778 {
10779 rtx addr, mem;
10780 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10781 GEN_INT (info->fp_save_offset
10782 + sp_offset
a4f6c312 10783 + 8 * i));
9ebbca7d 10784 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10785 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10786
10787 emit_move_insn (gen_rtx_REG (DFmode,
10788 info->first_fp_reg_save + i),
10789 mem);
10790 }
8d30c4ee 10791
9ebbca7d
GK
10792 /* If we saved cr, restore it here. Just those that were used. */
10793 if (info->cr_save_p)
979721f8 10794 {
9ebbca7d 10795 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 10796 int count = 0;
9ebbca7d
GK
10797
10798 if (using_mfcr_multiple)
979721f8 10799 {
9ebbca7d
GK
10800 for (i = 0; i < 8; i++)
10801 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 10802 count++;
9ebbca7d 10803 if (count == 0)
e35b9579
GK
10804 abort ();
10805 }
10806
10807 if (using_mfcr_multiple && count > 1)
10808 {
10809 rtvec p;
10810 int ndx;
9ebbca7d 10811
e35b9579 10812 p = rtvec_alloc (count);
9ebbca7d 10813
e35b9579 10814 ndx = 0;
9ebbca7d
GK
10815 for (i = 0; i < 8; i++)
10816 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
10817 {
10818 rtvec r = rtvec_alloc (2);
10819 RTVEC_ELT (r, 0) = r12_rtx;
10820 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 10821 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
10822 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
10823 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 10824 ndx++;
9ebbca7d
GK
10825 }
10826 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
10827 if (ndx != count)
10828 abort ();
979721f8
MM
10829 }
10830 else
9ebbca7d
GK
10831 for (i = 0; i < 8; i++)
10832 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 10833 {
9ebbca7d
GK
10834 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
10835 CR0_REGNO+i),
10836 r12_rtx));
979721f8 10837 }
979721f8
MM
10838 }
10839
9ebbca7d
GK
10840 /* If this is V.4, unwind the stack pointer after all of the loads
10841 have been done. We need to emit a block here so that sched
10842 doesn't decide to move the sp change before the register restores
10843 (which may not have any obvious dependency on the stack). This
10844 doesn't hurt performance, because there is no scheduling that can
10845 be done after this point. */
f607bc57 10846 if (DEFAULT_ABI == ABI_V4)
b6c9286a 10847 {
9ebbca7d
GK
10848 if (frame_reg_rtx != sp_reg_rtx)
10849 rs6000_emit_stack_tie ();
b6c9286a 10850
9ebbca7d 10851 if (use_backchain_to_restore_sp)
b6c9286a 10852 {
9ebbca7d 10853 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 10854 }
9ebbca7d 10855 else if (sp_offset != 0)
13f1623b 10856 {
9ebbca7d
GK
10857 emit_insn (Pmode == SImode
10858 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10859 GEN_INT (sp_offset))
10860 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10861 GEN_INT (sp_offset)));
13f1623b 10862 }
9ebbca7d 10863 }
b6c9286a 10864
83720594
RH
10865 if (current_function_calls_eh_return)
10866 {
10867 rtx sa = EH_RETURN_STACKADJ_RTX;
10868 emit_insn (Pmode == SImode
10869 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
10870 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
10871 }
10872
9ebbca7d
GK
10873 if (!sibcall)
10874 {
10875 rtvec p;
10876 if (! restoring_FPRs_inline)
10877 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
10878 else
10879 p = rtvec_alloc (2);
b6c9286a 10880
e35b9579
GK
10881 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
10882 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
10883 gen_rtx_REG (Pmode,
10884 LINK_REGISTER_REGNUM));
9ebbca7d
GK
10885
10886 /* If we have to restore more than two FP registers, branch to the
10887 restore function. It will return to our caller. */
10888 if (! restoring_FPRs_inline)
10889 {
10890 int i;
10891 char rname[30];
520a57c8 10892 const char *alloc_rname;
979721f8 10893
9ebbca7d
GK
10894 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
10895 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 10896 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10897 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
10898 gen_rtx_SYMBOL_REF (Pmode,
10899 alloc_rname));
b6c9286a 10900
9ebbca7d
GK
10901 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10902 {
10903 rtx addr, mem;
10904 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
10905 GEN_INT (info->fp_save_offset + 8*i));
10906 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10907 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10908
10909 RTVEC_ELT (p, i+3) =
10910 gen_rtx_SET (VOIDmode,
10911 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
10912 mem);
b6c9286a
MM
10913 }
10914 }
9ebbca7d
GK
10915
10916 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 10917 }
9878760c
RK
10918}
10919
10920/* Write function epilogue. */
10921
08c148a8
NB
10922static void
10923rs6000_output_function_epilogue (file, size)
9878760c 10924 FILE *file;
08c148a8 10925 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 10926{
4697a36c 10927 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 10928
9ebbca7d 10929 if (! HAVE_epilogue)
9878760c 10930 {
9ebbca7d
GK
10931 rtx insn = get_last_insn ();
10932 /* If the last insn was a BARRIER, we don't have to write anything except
10933 the trace table. */
10934 if (GET_CODE (insn) == NOTE)
10935 insn = prev_nonnote_insn (insn);
10936 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 10937 {
9ebbca7d
GK
10938 /* This is slightly ugly, but at least we don't have two
10939 copies of the epilogue-emitting code. */
10940 start_sequence ();
10941
10942 /* A NOTE_INSN_DELETED is supposed to be at the start
10943 and end of the "toplevel" insn chain. */
10944 emit_note (0, NOTE_INSN_DELETED);
10945 rs6000_emit_epilogue (FALSE);
10946 emit_note (0, NOTE_INSN_DELETED);
10947
178c3eff
DJ
10948 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10949 {
10950 rtx insn;
10951 unsigned addr = 0;
10952 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10953 {
10954 INSN_ADDRESSES_NEW (insn, addr);
10955 addr += 4;
10956 }
10957 }
10958
9ebbca7d 10959 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10960 debug_rtx_list (get_insns (), 100);
10961 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10962 end_sequence ();
4697a36c 10963 }
9878760c 10964 }
b4ac57ab 10965
9b30bae2 10966 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
10967 on its format.
10968
10969 We don't output a traceback table if -finhibit-size-directive was
10970 used. The documentation for -finhibit-size-directive reads
10971 ``don't output a @code{.size} assembler directive, or anything
10972 else that would cause trouble if the function is split in the
10973 middle, and the two halves are placed at locations far apart in
10974 memory.'' The traceback table has this property, since it
10975 includes the offset from the start of the function to the
4d30c363
MM
10976 traceback table itself.
10977
10978 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 10979 different traceback table. */
57ac7be9
AM
10980 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
10981 && rs6000_traceback != traceback_none)
9b30bae2 10982 {
3cce094d 10983 const char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
3ac88239 10984 const char *language_string = lang_hooks.name;
6041bf2f 10985 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 10986 int i;
57ac7be9
AM
10987 int optional_tbtab;
10988
10989 if (rs6000_traceback == traceback_full)
10990 optional_tbtab = 1;
10991 else if (rs6000_traceback == traceback_part)
10992 optional_tbtab = 0;
10993 else
10994 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 10995
b6c9286a
MM
10996 while (*fname == '.') /* V.4 encodes . in the name */
10997 fname++;
10998
314fc5a9
ILT
10999 /* Need label immediately before tbtab, so we can compute its offset
11000 from the function start. */
11001 if (*fname == '*')
11002 ++fname;
11003 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11004 ASM_OUTPUT_LABEL (file, fname);
11005
11006 /* The .tbtab pseudo-op can only be used for the first eight
11007 expressions, since it can't handle the possibly variable
11008 length fields that follow. However, if you omit the optional
11009 fields, the assembler outputs zeros for all optional fields
11010 anyways, giving each variable length field is minimum length
11011 (as defined in sys/debug.h). Thus we can not use the .tbtab
11012 pseudo-op at all. */
11013
11014 /* An all-zero word flags the start of the tbtab, for debuggers
11015 that have to find it by searching forward from the entry
11016 point or from the current pc. */
19d2d16f 11017 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11018
11019 /* Tbtab format type. Use format type 0. */
19d2d16f 11020 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11021
11022 /* Language type. Unfortunately, there doesn't seem to be any
11023 official way to get this info, so we use language_string. C
11024 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11025 value for C for now. There is no official value for Java,
6f573ff9 11026 although IBM appears to be using 13. There is no official value
f710504c 11027 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11028 if (! strcmp (language_string, "GNU C")
e2c953b6 11029 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11030 i = 0;
11031 else if (! strcmp (language_string, "GNU F77"))
11032 i = 1;
11033 else if (! strcmp (language_string, "GNU Ada"))
11034 i = 3;
8b83775b 11035 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11036 i = 2;
11037 else if (! strcmp (language_string, "GNU C++"))
11038 i = 9;
9517ead8
AG
11039 else if (! strcmp (language_string, "GNU Java"))
11040 i = 13;
6f573ff9
JL
11041 else if (! strcmp (language_string, "GNU CHILL"))
11042 i = 44;
314fc5a9
ILT
11043 else
11044 abort ();
11045 fprintf (file, "%d,", i);
11046
11047 /* 8 single bit fields: global linkage (not set for C extern linkage,
11048 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11049 from start of procedure stored in tbtab, internal function, function
11050 has controlled storage, function has no toc, function uses fp,
11051 function logs/aborts fp operations. */
11052 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11053 fprintf (file, "%d,",
11054 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11055
11056 /* 6 bitfields: function is interrupt handler, name present in
11057 proc table, function calls alloca, on condition directives
11058 (controls stack walks, 3 bits), saves condition reg, saves
11059 link reg. */
11060 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11061 set up as a frame pointer, even when there is no alloca call. */
11062 fprintf (file, "%d,",
6041bf2f
DE
11063 ((optional_tbtab << 6)
11064 | ((optional_tbtab & frame_pointer_needed) << 5)
11065 | (info->cr_save_p << 1)
11066 | (info->lr_save_p)));
314fc5a9 11067
6041bf2f 11068 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11069 (6 bits). */
11070 fprintf (file, "%d,",
4697a36c 11071 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11072
11073 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11074 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11075
6041bf2f
DE
11076 if (optional_tbtab)
11077 {
11078 /* Compute the parameter info from the function decl argument
11079 list. */
11080 tree decl;
11081 int next_parm_info_bit = 31;
314fc5a9 11082
6041bf2f
DE
11083 for (decl = DECL_ARGUMENTS (current_function_decl);
11084 decl; decl = TREE_CHAIN (decl))
11085 {
11086 rtx parameter = DECL_INCOMING_RTL (decl);
11087 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11088
6041bf2f
DE
11089 if (GET_CODE (parameter) == REG)
11090 {
11091 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11092 {
11093 int bits;
11094
11095 float_parms++;
11096
11097 if (mode == SFmode)
11098 bits = 0x2;
11099 else if (mode == DFmode)
11100 bits = 0x3;
11101 else
11102 abort ();
11103
11104 /* If only one bit will fit, don't or in this entry. */
11105 if (next_parm_info_bit > 0)
11106 parm_info |= (bits << (next_parm_info_bit - 1));
11107 next_parm_info_bit -= 2;
11108 }
11109 else
11110 {
11111 fixed_parms += ((GET_MODE_SIZE (mode)
11112 + (UNITS_PER_WORD - 1))
11113 / UNITS_PER_WORD);
11114 next_parm_info_bit -= 1;
11115 }
11116 }
11117 }
11118 }
314fc5a9
ILT
11119
11120 /* Number of fixed point parameters. */
11121 /* This is actually the number of words of fixed point parameters; thus
11122 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11123 fprintf (file, "%d,", fixed_parms);
11124
11125 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11126 all on stack. */
11127 /* This is actually the number of fp registers that hold parameters;
11128 and thus the maximum value is 13. */
11129 /* Set parameters on stack bit if parameters are not in their original
11130 registers, regardless of whether they are on the stack? Xlc
11131 seems to set the bit when not optimizing. */
11132 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11133
6041bf2f
DE
11134 if (! optional_tbtab)
11135 return;
11136
314fc5a9
ILT
11137 /* Optional fields follow. Some are variable length. */
11138
11139 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11140 11 double float. */
11141 /* There is an entry for each parameter in a register, in the order that
11142 they occur in the parameter list. Any intervening arguments on the
11143 stack are ignored. If the list overflows a long (max possible length
11144 34 bits) then completely leave off all elements that don't fit. */
11145 /* Only emit this long if there was at least one parameter. */
11146 if (fixed_parms || float_parms)
11147 fprintf (file, "\t.long %d\n", parm_info);
11148
11149 /* Offset from start of code to tb table. */
19d2d16f 11150 fputs ("\t.long ", file);
314fc5a9 11151 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11152#if TARGET_AIX
11153 RS6000_OUTPUT_BASENAME (file, fname);
11154#else
9ebbca7d 11155 assemble_name (file, fname);
54ee9799 11156#endif
19d2d16f 11157 fputs ("-.", file);
54ee9799
DE
11158#if TARGET_AIX
11159 RS6000_OUTPUT_BASENAME (file, fname);
11160#else
9ebbca7d 11161 assemble_name (file, fname);
54ee9799 11162#endif
19d2d16f 11163 putc ('\n', file);
314fc5a9
ILT
11164
11165 /* Interrupt handler mask. */
11166 /* Omit this long, since we never set the interrupt handler bit
11167 above. */
11168
11169 /* Number of CTL (controlled storage) anchors. */
11170 /* Omit this long, since the has_ctl bit is never set above. */
11171
11172 /* Displacement into stack of each CTL anchor. */
11173 /* Omit this list of longs, because there are no CTL anchors. */
11174
11175 /* Length of function name. */
296b8152 11176 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11177
11178 /* Function name. */
11179 assemble_string (fname, strlen (fname));
11180
11181 /* Register for alloca automatic storage; this is always reg 31.
11182 Only emit this if the alloca bit was set above. */
11183 if (frame_pointer_needed)
19d2d16f 11184 fputs ("\t.byte 31\n", file);
b1765bde
DE
11185
11186 fputs ("\t.align 2\n", file);
9b30bae2 11187 }
9878760c 11188}
17167fd8 11189\f
a4f6c312
SS
11190/* A C compound statement that outputs the assembler code for a thunk
11191 function, used to implement C++ virtual function calls with
11192 multiple inheritance. The thunk acts as a wrapper around a virtual
11193 function, adjusting the implicit object parameter before handing
11194 control off to the real function.
11195
11196 First, emit code to add the integer DELTA to the location that
11197 contains the incoming first argument. Assume that this argument
11198 contains a pointer, and is the one used to pass the `this' pointer
11199 in C++. This is the incoming argument *before* the function
11200 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11201 values of all other incoming arguments.
17167fd8
MM
11202
11203 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11204 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11205 not touch the return address. Hence returning from FUNCTION will
11206 return to whoever called the current `thunk'.
17167fd8 11207
a4f6c312
SS
11208 The effect must be as if FUNCTION had been called directly with the
11209 adjusted first argument. This macro is responsible for emitting
11210 all of the code for a thunk function; output_function_prologue()
11211 and output_function_epilogue() are not invoked.
17167fd8 11212
a4f6c312
SS
11213 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11214 been extracted from it.) It might possibly be useful on some
11215 targets, but probably not.
17167fd8 11216
a4f6c312
SS
11217 If you do not define this macro, the target-independent code in the
11218 C++ frontend will generate a less efficient heavyweight thunk that
11219 calls FUNCTION instead of jumping to it. The generic approach does
11220 not support varargs. */
17167fd8
MM
11221
11222void
11223output_mi_thunk (file, thunk_fndecl, delta, function)
11224 FILE *file;
d330fd93 11225 tree thunk_fndecl ATTRIBUTE_UNUSED;
17167fd8
MM
11226 int delta;
11227 tree function;
11228{
a4f6c312
SS
11229 const char *this_reg =
11230 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
d330fd93 11231 const char *prefix;
3cce094d 11232 const char *fname;
d330fd93 11233 const char *r0 = reg_names[0];
d330fd93
KG
11234 const char *toc = reg_names[2];
11235 const char *schain = reg_names[11];
11236 const char *r12 = reg_names[12];
17167fd8
MM
11237 char buf[512];
11238 static int labelno = 0;
11239
a4f6c312 11240 /* Small constants that can be done by one add instruction. */
17167fd8
MM
11241 if (delta >= -32768 && delta <= 32767)
11242 {
22b4a3b0 11243 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11244 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta, this_reg);
11245 else
11246 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
11247 }
11248
a4f6c312 11249 /* Large constants that can be done by one addis instruction. */
17167fd8
MM
11250 else if ((delta & 0xffff) == 0 && num_insns_constant_wide (delta) == 1)
11251 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11252 delta >> 16);
11253
11254 /* 32-bit constants that can be done by an add and addis instruction. */
11255 else if (TARGET_32BIT || num_insns_constant_wide (delta) == 1)
11256 {
a4f6c312
SS
11257 /* Break into two pieces, propagating the sign bit from the low
11258 word to the upper word. */
17167fd8
MM
11259 int delta_high = delta >> 16;
11260 int delta_low = delta & 0xffff;
11261 if ((delta_low & 0x8000) != 0)
11262 {
11263 delta_high++;
11264 delta_low = (delta_low ^ 0x8000) - 0x8000; /* sign extend */
11265 }
11266
11267 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11268 delta_high);
11269
22b4a3b0 11270 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11271 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
11272 else
11273 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
11274 }
11275
11276 /* 64-bit constants, fixme */
11277 else
11278 abort ();
11279
11280 /* Get the prefix in front of the names. */
11281 switch (DEFAULT_ABI)
11282 {
11283 default:
11284 abort ();
11285
11286 case ABI_AIX:
11287 prefix = ".";
11288 break;
11289
11290 case ABI_V4:
11291 case ABI_AIX_NODESC:
17167fd8
MM
11292 prefix = "";
11293 break;
17167fd8
MM
11294 }
11295
11296 /* If the function is compiled in this module, jump to it directly.
11297 Otherwise, load up its address and jump to it. */
11298
11299 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
42820a49 11300
9ebbca7d 11301 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
a5c76ee6
ZW
11302 && (! lookup_attribute ("longcall",
11303 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11304 || lookup_attribute ("shortcall",
11305 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
11306
17167fd8
MM
11307 {
11308 fprintf (file, "\tb %s", prefix);
11309 assemble_name (file, fname);
22b4a3b0 11310 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
949ea356 11311 putc ('\n', file);
17167fd8
MM
11312 }
11313
11314 else
11315 {
11316 switch (DEFAULT_ABI)
11317 {
11318 default:
17167fd8
MM
11319 abort ();
11320
11321 case ABI_AIX:
11322 /* Set up a TOC entry for the function. */
11323 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
11324 toc_section ();
11325 ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
11326 labelno++;
11327
fa9b5c6b
DE
11328 if (TARGET_MINIMAL_TOC)
11329 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
11330 else
11331 {
11332 fputs ("\t.tc ", file);
11333 assemble_name (file, fname);
11334 fputs ("[TC],", file);
11335 }
11336 assemble_name (file, fname);
17167fd8
MM
11337 putc ('\n', file);
11338 text_section ();
468e8dba
DE
11339 if (TARGET_MINIMAL_TOC)
11340 asm_fprintf (file, (TARGET_32BIT)
11341 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
11342 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
d2574c50 11343 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
17167fd8 11344 assemble_name (file, buf);
468e8dba
DE
11345 if (TARGET_ELF && TARGET_MINIMAL_TOC)
11346 fputs ("-(.LCTOC1)", file);
11347 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
17167fd8
MM
11348 asm_fprintf (file,
11349 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
11350 r0, r12);
11351
11352 asm_fprintf (file,
11353 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
11354 toc, r12);
11355
11356 asm_fprintf (file, "\tmtctr %s\n", r0);
11357 asm_fprintf (file,
11358 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
11359 schain, r12);
11360
11361 asm_fprintf (file, "\tbctr\n");
11362 break;
11363
9ebbca7d 11364 case ABI_AIX_NODESC:
17167fd8 11365 case ABI_V4:
22b4a3b0
FS
11366 fprintf (file, "\tb %s", prefix);
11367 assemble_name (file, fname);
11368 if (flag_pic) fputs ("@plt", file);
949ea356 11369 putc ('\n', file);
22b4a3b0 11370 break;
ee890fe2
SS
11371
11372#if TARGET_MACHO
11373 case ABI_DARWIN:
11374 fprintf (file, "\tb %s", prefix);
11375 if (flag_pic && !machopic_name_defined_p (fname))
11376 assemble_name (file, machopic_stub_name (fname));
11377 else
11378 assemble_name (file, fname);
11379 putc ('\n', file);
11380 break;
11381#endif
9ebbca7d
GK
11382 }
11383 }
11384}
42820a49 11385
9ebbca7d
GK
11386\f
11387/* A quick summary of the various types of 'constant-pool tables'
11388 under PowerPC:
11389
11390 Target Flags Name One table per
11391 AIX (none) AIX TOC object file
11392 AIX -mfull-toc AIX TOC object file
11393 AIX -mminimal-toc AIX minimal TOC translation unit
11394 SVR4/EABI (none) SVR4 SDATA object file
11395 SVR4/EABI -fpic SVR4 pic object file
11396 SVR4/EABI -fPIC SVR4 PIC translation unit
11397 SVR4/EABI -mrelocatable EABI TOC function
11398 SVR4/EABI -maix AIX TOC object file
11399 SVR4/EABI -maix -mminimal-toc
11400 AIX minimal TOC translation unit
11401
11402 Name Reg. Set by entries contains:
11403 made by addrs? fp? sum?
11404
11405 AIX TOC 2 crt0 as Y option option
11406 AIX minimal TOC 30 prolog gcc Y Y option
11407 SVR4 SDATA 13 crt0 gcc N Y N
11408 SVR4 pic 30 prolog ld Y not yet N
11409 SVR4 PIC 30 prolog gcc Y option option
11410 EABI TOC 30 prolog gcc Y option option
11411
11412*/
11413
11414/* Hash table stuff for keeping track of TOC entries. */
11415
11416struct toc_hash_struct
11417{
11418 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
11419 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
11420 rtx key;
a9098fd0 11421 enum machine_mode key_mode;
9ebbca7d
GK
11422 int labelno;
11423};
17167fd8 11424
9ebbca7d
GK
11425static htab_t toc_hash_table;
11426
11427/* Hash functions for the hash table. */
11428
11429static unsigned
11430rs6000_hash_constant (k)
11431 rtx k;
11432{
a9098fd0 11433 unsigned result = (GET_CODE (k) << 3) ^ GET_MODE (k);
9ebbca7d
GK
11434 const char *format = GET_RTX_FORMAT (GET_CODE (k));
11435 int flen = strlen (format);
11436 int fidx;
11437
11438 if (GET_CODE (k) == LABEL_REF)
b3a646eb 11439 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
9ebbca7d 11440
5692c7bc 11441 if (GET_CODE (k) == CODE_LABEL)
9ebbca7d
GK
11442 fidx = 3;
11443 else
11444 fidx = 0;
11445
11446 for (; fidx < flen; fidx++)
11447 switch (format[fidx])
11448 {
11449 case 's':
11450 {
11451 unsigned i, len;
11452 const char *str = XSTR (k, fidx);
11453 len = strlen (str);
11454 result = result * 613 + len;
11455 for (i = 0; i < len; i++)
11456 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11457 break;
11458 }
9ebbca7d
GK
11459 case 'u':
11460 case 'e':
11461 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11462 break;
11463 case 'i':
11464 case 'n':
11465 result = result * 613 + (unsigned) XINT (k, fidx);
11466 break;
11467 case 'w':
11468 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11469 result = result * 613 + (unsigned) XWINT (k, fidx);
11470 else
11471 {
11472 size_t i;
11473 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11474 result = result * 613 + (unsigned) (XWINT (k, fidx)
11475 >> CHAR_BIT * i);
11476 }
11477 break;
11478 default:
a4f6c312 11479 abort ();
9ebbca7d
GK
11480 }
11481 return result;
11482}
11483
11484static unsigned
11485toc_hash_function (hash_entry)
11486 const void * hash_entry;
11487{
a9098fd0
GK
11488 const struct toc_hash_struct *thc =
11489 (const struct toc_hash_struct *) hash_entry;
11490 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11491}
11492
11493/* Compare H1 and H2 for equivalence. */
11494
11495static int
11496toc_hash_eq (h1, h2)
11497 const void * h1;
11498 const void * h2;
11499{
11500 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11501 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11502
a9098fd0
GK
11503 if (((const struct toc_hash_struct *) h1)->key_mode
11504 != ((const struct toc_hash_struct *) h2)->key_mode)
11505 return 0;
11506
5692c7bc 11507 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11508}
11509
11510/* Mark the hash table-entry HASH_ENTRY. */
11511
11512static int
11513toc_hash_mark_entry (hash_slot, unused)
2eba1afa 11514 void ** hash_slot;
9ebbca7d
GK
11515 void * unused ATTRIBUTE_UNUSED;
11516{
11517 const struct toc_hash_struct * hash_entry =
11518 *(const struct toc_hash_struct **) hash_slot;
11519 rtx r = hash_entry->key;
11520 ggc_set_mark (hash_entry);
a4f6c312 11521 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
9ebbca7d
GK
11522 if (GET_CODE (r) == LABEL_REF)
11523 {
11524 ggc_set_mark (r);
11525 ggc_set_mark (XEXP (r, 0));
11526 }
11527 else
11528 ggc_mark_rtx (r);
11529 return 1;
11530}
11531
11532/* Mark all the elements of the TOC hash-table *HT. */
11533
11534static void
11535toc_hash_mark_table (vht)
11536 void *vht;
11537{
11538 htab_t *ht = vht;
11539
11540 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
17167fd8
MM
11541}
11542
28e510bd
MM
11543/* These are the names given by the C++ front-end to vtables, and
11544 vtable-like objects. Ideally, this logic should not be here;
11545 instead, there should be some programmatic way of inquiring as
11546 to whether or not an object is a vtable. */
11547
11548#define VTABLE_NAME_P(NAME) \
11549 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11550 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11551 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11552 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11553
11554void
11555rs6000_output_symbol_ref (file, x)
11556 FILE *file;
11557 rtx x;
11558{
11559 /* Currently C++ toc references to vtables can be emitted before it
11560 is decided whether the vtable is public or private. If this is
11561 the case, then the linker will eventually complain that there is
11562 a reference to an unknown section. Thus, for vtables only,
11563 we emit the TOC reference to reference the symbol and not the
11564 section. */
11565 const char *name = XSTR (x, 0);
54ee9799
DE
11566
11567 if (VTABLE_NAME_P (name))
11568 {
11569 RS6000_OUTPUT_BASENAME (file, name);
11570 }
11571 else
11572 assemble_name (file, name);
28e510bd
MM
11573}
11574
a4f6c312
SS
11575/* Output a TOC entry. We derive the entry name from what is being
11576 written. */
9878760c
RK
11577
11578void
a9098fd0 11579output_toc (file, x, labelno, mode)
9878760c
RK
11580 FILE *file;
11581 rtx x;
11582 int labelno;
a9098fd0 11583 enum machine_mode mode;
9878760c
RK
11584{
11585 char buf[256];
3cce094d 11586 const char *name = buf;
ec940faa 11587 const char *real_name;
9878760c
RK
11588 rtx base = x;
11589 int offset = 0;
11590
4697a36c
MM
11591 if (TARGET_NO_TOC)
11592 abort ();
11593
9ebbca7d
GK
11594 /* When the linker won't eliminate them, don't output duplicate
11595 TOC entries (this happens on AIX if there is any kind of TOC,
1f8f4a0b
MM
11596 and on SVR4 under -fPIC or -mrelocatable). */
11597 if (TARGET_TOC)
9ebbca7d
GK
11598 {
11599 struct toc_hash_struct *h;
11600 void * * found;
11601
11602 h = ggc_alloc (sizeof (*h));
11603 h->key = x;
a9098fd0 11604 h->key_mode = mode;
9ebbca7d
GK
11605 h->labelno = labelno;
11606
11607 found = htab_find_slot (toc_hash_table, h, 1);
11608 if (*found == NULL)
11609 *found = h;
11610 else /* This is indeed a duplicate.
11611 Set this label equal to that label. */
11612 {
11613 fputs ("\t.set ", file);
11614 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11615 fprintf (file, "%d,", labelno);
11616 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11617 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11618 found)->labelno));
11619 return;
11620 }
11621 }
11622
11623 /* If we're going to put a double constant in the TOC, make sure it's
11624 aligned properly when strict alignment is on. */
ff1720ed
RK
11625 if (GET_CODE (x) == CONST_DOUBLE
11626 && STRICT_ALIGNMENT
a9098fd0 11627 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
11628 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11629 ASM_OUTPUT_ALIGN (file, 3);
11630 }
11631
9ebbca7d 11632 ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
9878760c 11633
37c37a57
RK
11634 /* Handle FP constants specially. Note that if we have a minimal
11635 TOC, things we put here aren't actually in the TOC, so we can allow
11636 FP constants. */
a9098fd0 11637 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 11638 {
042259f2
DE
11639 REAL_VALUE_TYPE rv;
11640 long k[2];
0adc764e 11641
042259f2
DE
11642 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11643 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 11644
13ded975
DE
11645 if (TARGET_64BIT)
11646 {
11647 if (TARGET_MINIMAL_TOC)
2bfcf297 11648 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11649 else
2f0552b6
AM
11650 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11651 k[0] & 0xffffffff, k[1] & 0xffffffff);
11652 fprintf (file, "0x%lx%08lx\n",
11653 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11654 return;
11655 }
1875cc88 11656 else
13ded975
DE
11657 {
11658 if (TARGET_MINIMAL_TOC)
2bfcf297 11659 fputs ("\t.long ", file);
13ded975 11660 else
2f0552b6
AM
11661 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11662 k[0] & 0xffffffff, k[1] & 0xffffffff);
11663 fprintf (file, "0x%lx,0x%lx\n",
11664 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11665 return;
11666 }
9878760c 11667 }
a9098fd0 11668 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 11669 {
042259f2
DE
11670 REAL_VALUE_TYPE rv;
11671 long l;
9878760c 11672
042259f2
DE
11673 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11674 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11675
31bfaa0b
DE
11676 if (TARGET_64BIT)
11677 {
11678 if (TARGET_MINIMAL_TOC)
2bfcf297 11679 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 11680 else
2f0552b6
AM
11681 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11682 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
11683 return;
11684 }
042259f2 11685 else
31bfaa0b
DE
11686 {
11687 if (TARGET_MINIMAL_TOC)
2bfcf297 11688 fputs ("\t.long ", file);
31bfaa0b 11689 else
2f0552b6
AM
11690 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11691 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
11692 return;
11693 }
042259f2 11694 }
f176e826 11695 else if (GET_MODE (x) == VOIDmode
a9098fd0 11696 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 11697 {
e2c953b6 11698 unsigned HOST_WIDE_INT low;
042259f2
DE
11699 HOST_WIDE_INT high;
11700
11701 if (GET_CODE (x) == CONST_DOUBLE)
11702 {
11703 low = CONST_DOUBLE_LOW (x);
11704 high = CONST_DOUBLE_HIGH (x);
11705 }
11706 else
11707#if HOST_BITS_PER_WIDE_INT == 32
11708 {
11709 low = INTVAL (x);
0858c623 11710 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
11711 }
11712#else
11713 {
0858c623 11714 low = INTVAL (x) & 0xffffffff;
042259f2
DE
11715 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11716 }
11717#endif
9878760c 11718
a9098fd0
GK
11719 /* TOC entries are always Pmode-sized, but since this
11720 is a bigendian machine then if we're putting smaller
11721 integer constants in the TOC we have to pad them.
11722 (This is still a win over putting the constants in
11723 a separate constant pool, because then we'd have
02a4ec28
FS
11724 to have both a TOC entry _and_ the actual constant.)
11725
11726 For a 32-bit target, CONST_INT values are loaded and shifted
11727 entirely within `low' and can be stored in one TOC entry. */
11728
11729 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 11730 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
11731
11732 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
11733 {
11734#if HOST_BITS_PER_WIDE_INT == 32
11735 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11736 POINTER_SIZE, &low, &high, 0);
11737#else
11738 low |= high << 32;
11739 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11740 high = (HOST_WIDE_INT) low >> 32;
11741 low &= 0xffffffff;
11742#endif
11743 }
a9098fd0 11744
13ded975
DE
11745 if (TARGET_64BIT)
11746 {
11747 if (TARGET_MINIMAL_TOC)
2bfcf297 11748 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11749 else
2f0552b6
AM
11750 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
11751 (long) high & 0xffffffff, (long) low & 0xffffffff);
11752 fprintf (file, "0x%lx%08lx\n",
11753 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
11754 return;
11755 }
1875cc88 11756 else
13ded975 11757 {
02a4ec28
FS
11758 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
11759 {
11760 if (TARGET_MINIMAL_TOC)
2bfcf297 11761 fputs ("\t.long ", file);
02a4ec28 11762 else
2bfcf297 11763 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
11764 (long) high & 0xffffffff, (long) low & 0xffffffff);
11765 fprintf (file, "0x%lx,0x%lx\n",
11766 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 11767 }
13ded975 11768 else
02a4ec28
FS
11769 {
11770 if (TARGET_MINIMAL_TOC)
2bfcf297 11771 fputs ("\t.long ", file);
02a4ec28 11772 else
2f0552b6
AM
11773 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
11774 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 11775 }
13ded975
DE
11776 return;
11777 }
9878760c
RK
11778 }
11779
11780 if (GET_CODE (x) == CONST)
11781 {
2bfcf297
DB
11782 if (GET_CODE (XEXP (x, 0)) != PLUS)
11783 abort ();
11784
9878760c
RK
11785 base = XEXP (XEXP (x, 0), 0);
11786 offset = INTVAL (XEXP (XEXP (x, 0), 1));
11787 }
11788
11789 if (GET_CODE (base) == SYMBOL_REF)
11790 name = XSTR (base, 0);
11791 else if (GET_CODE (base) == LABEL_REF)
11792 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
11793 else if (GET_CODE (base) == CODE_LABEL)
11794 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
11795 else
11796 abort ();
11797
772c5265 11798 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 11799 if (TARGET_MINIMAL_TOC)
2bfcf297 11800 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
11801 else
11802 {
b6c9286a 11803 fprintf (file, "\t.tc %s", real_name);
9878760c 11804
1875cc88
JW
11805 if (offset < 0)
11806 fprintf (file, ".N%d", - offset);
11807 else if (offset)
11808 fprintf (file, ".P%d", offset);
9878760c 11809
19d2d16f 11810 fputs ("[TC],", file);
1875cc88 11811 }
581bc4de
MM
11812
11813 /* Currently C++ toc references to vtables can be emitted before it
11814 is decided whether the vtable is public or private. If this is
11815 the case, then the linker will eventually complain that there is
11816 a TOC reference to an unknown section. Thus, for vtables only,
11817 we emit the TOC reference to reference the symbol and not the
11818 section. */
28e510bd 11819 if (VTABLE_NAME_P (name))
581bc4de 11820 {
54ee9799 11821 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
11822 if (offset < 0)
11823 fprintf (file, "%d", offset);
11824 else if (offset > 0)
11825 fprintf (file, "+%d", offset);
11826 }
11827 else
11828 output_addr_const (file, x);
19d2d16f 11829 putc ('\n', file);
9878760c
RK
11830}
11831\f
11832/* Output an assembler pseudo-op to write an ASCII string of N characters
11833 starting at P to FILE.
11834
11835 On the RS/6000, we have to do this using the .byte operation and
11836 write out special characters outside the quoted string.
11837 Also, the assembler is broken; very long strings are truncated,
a4f6c312 11838 so we must artificially break them up early. */
9878760c
RK
11839
11840void
11841output_ascii (file, p, n)
11842 FILE *file;
d330fd93 11843 const char *p;
9878760c
RK
11844 int n;
11845{
11846 char c;
11847 int i, count_string;
d330fd93
KG
11848 const char *for_string = "\t.byte \"";
11849 const char *for_decimal = "\t.byte ";
11850 const char *to_close = NULL;
9878760c
RK
11851
11852 count_string = 0;
11853 for (i = 0; i < n; i++)
11854 {
11855 c = *p++;
11856 if (c >= ' ' && c < 0177)
11857 {
11858 if (for_string)
11859 fputs (for_string, file);
11860 putc (c, file);
11861
11862 /* Write two quotes to get one. */
11863 if (c == '"')
11864 {
11865 putc (c, file);
11866 ++count_string;
11867 }
11868
11869 for_string = NULL;
11870 for_decimal = "\"\n\t.byte ";
11871 to_close = "\"\n";
11872 ++count_string;
11873
11874 if (count_string >= 512)
11875 {
11876 fputs (to_close, file);
11877
11878 for_string = "\t.byte \"";
11879 for_decimal = "\t.byte ";
11880 to_close = NULL;
11881 count_string = 0;
11882 }
11883 }
11884 else
11885 {
11886 if (for_decimal)
11887 fputs (for_decimal, file);
11888 fprintf (file, "%d", c);
11889
11890 for_string = "\n\t.byte \"";
11891 for_decimal = ", ";
11892 to_close = "\n";
11893 count_string = 0;
11894 }
11895 }
11896
11897 /* Now close the string if we have written one. Then end the line. */
11898 if (to_close)
9ebbca7d 11899 fputs (to_close, file);
9878760c
RK
11900}
11901\f
11902/* Generate a unique section name for FILENAME for a section type
11903 represented by SECTION_DESC. Output goes into BUF.
11904
11905 SECTION_DESC can be any string, as long as it is different for each
11906 possible section type.
11907
11908 We name the section in the same manner as xlc. The name begins with an
11909 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
11910 names) with the last period replaced by the string SECTION_DESC. If
11911 FILENAME does not contain a period, SECTION_DESC is appended to the end of
11912 the name. */
9878760c
RK
11913
11914void
11915rs6000_gen_section_name (buf, filename, section_desc)
11916 char **buf;
9ebbca7d
GK
11917 const char *filename;
11918 const char *section_desc;
9878760c 11919{
9ebbca7d 11920 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
11921 char *p;
11922 int len;
9878760c
RK
11923
11924 after_last_slash = filename;
11925 for (q = filename; *q; q++)
11e5fe42
RK
11926 {
11927 if (*q == '/')
11928 after_last_slash = q + 1;
11929 else if (*q == '.')
11930 last_period = q;
11931 }
9878760c 11932
11e5fe42 11933 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 11934 *buf = (char *) xmalloc (len);
9878760c
RK
11935
11936 p = *buf;
11937 *p++ = '_';
11938
11939 for (q = after_last_slash; *q; q++)
11940 {
11e5fe42 11941 if (q == last_period)
9878760c
RK
11942 {
11943 strcpy (p, section_desc);
11944 p += strlen (section_desc);
9878760c
RK
11945 }
11946
e9a780ec 11947 else if (ISALNUM (*q))
9878760c
RK
11948 *p++ = *q;
11949 }
11950
11e5fe42 11951 if (last_period == 0)
9878760c
RK
11952 strcpy (p, section_desc);
11953 else
11954 *p = '\0';
11955}
e165f3f0 11956\f
a4f6c312 11957/* Emit profile function. */
411707f4 11958
411707f4
CC
11959void
11960output_profile_hook (labelno)
57ac7be9 11961 int labelno ATTRIBUTE_UNUSED;
411707f4 11962{
8480e480
CC
11963 if (DEFAULT_ABI == ABI_AIX)
11964 {
57ac7be9
AM
11965#ifdef NO_PROFILE_COUNTERS
11966 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
11967#else
8480e480 11968 char buf[30];
40501e5f 11969 const char *label_name;
8480e480 11970 rtx fun;
411707f4 11971
8480e480 11972 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 11973 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 11974 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 11975
8480e480
CC
11976 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
11977 fun, Pmode);
57ac7be9 11978#endif
8480e480 11979 }
ee890fe2
SS
11980 else if (DEFAULT_ABI == ABI_DARWIN)
11981 {
d5fa86ba 11982 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
11983 int caller_addr_regno = LINK_REGISTER_REGNUM;
11984
11985 /* Be conservative and always set this, at least for now. */
11986 current_function_uses_pic_offset_table = 1;
11987
11988#if TARGET_MACHO
11989 /* For PIC code, set up a stub and collect the caller's address
11990 from r0, which is where the prologue puts it. */
11991 if (flag_pic)
11992 {
11993 mcount_name = machopic_stub_name (mcount_name);
11994 if (current_function_uses_pic_offset_table)
11995 caller_addr_regno = 0;
11996 }
11997#endif
11998 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
11999 0, VOIDmode, 1,
12000 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12001 }
411707f4
CC
12002}
12003
a4f6c312 12004/* Write function profiler code. */
e165f3f0
RK
12005
12006void
12007output_function_profiler (file, labelno)
12008 FILE *file;
12009 int labelno;
12010{
3daf36a4 12011 char buf[100];
09eeeacb 12012 int save_lr = 8;
e165f3f0 12013
3daf36a4 12014 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 12015 switch (DEFAULT_ABI)
3daf36a4 12016 {
38c1f2d7
MM
12017 default:
12018 abort ();
12019
12020 case ABI_V4:
09eeeacb
AM
12021 save_lr = 4;
12022 /* Fall through. */
12023
38c1f2d7 12024 case ABI_AIX_NODESC:
09eeeacb
AM
12025 if (!TARGET_32BIT)
12026 {
12027 warning ("no profiling of 64-bit code for this ABI");
12028 return;
12029 }
38c1f2d7
MM
12030 fprintf (file, "\tmflr %s\n", reg_names[0]);
12031 if (flag_pic == 1)
12032 {
dfdfa60f 12033 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12034 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12035 reg_names[0], save_lr, reg_names[1]);
17167fd8 12036 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12037 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12038 assemble_name (file, buf);
17167fd8 12039 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12040 }
9ebbca7d 12041 else if (flag_pic > 1)
38c1f2d7 12042 {
09eeeacb
AM
12043 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12044 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12045 /* Now, we need to get the address of the label. */
12046 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12047 assemble_name (file, buf);
9ebbca7d
GK
12048 fputs ("-.\n1:", file);
12049 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12050 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12051 reg_names[0], reg_names[11]);
12052 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12053 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12054 }
38c1f2d7
MM
12055 else
12056 {
17167fd8 12057 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12058 assemble_name (file, buf);
dfdfa60f 12059 fputs ("@ha\n", file);
09eeeacb
AM
12060 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12061 reg_names[0], save_lr, reg_names[1]);
a260abc9 12062 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12063 assemble_name (file, buf);
17167fd8 12064 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12065 }
12066
09eeeacb
AM
12067 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12068 {
12069 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12070 reg_names[STATIC_CHAIN_REGNUM],
12071 12, reg_names[1]);
12072 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12073 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12074 reg_names[STATIC_CHAIN_REGNUM],
12075 12, reg_names[1]);
12076 }
12077 else
12078 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12079 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12080 break;
12081
12082 case ABI_AIX:
ee890fe2 12083 case ABI_DARWIN:
a4f6c312 12084 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7
MM
12085 break;
12086 }
e165f3f0 12087}
a251ffd0
TG
12088
12089/* Adjust the cost of a scheduling dependency. Return the new cost of
12090 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12091
c237e94a 12092static int
a06faf84 12093rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12094 rtx insn;
12095 rtx link;
296b8152 12096 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12097 int cost;
12098{
12099 if (! recog_memoized (insn))
12100 return 0;
12101
12102 if (REG_NOTE_KIND (link) != 0)
12103 return 0;
12104
12105 if (REG_NOTE_KIND (link) == 0)
12106 {
ed947a96
DJ
12107 /* Data dependency; DEP_INSN writes a register that INSN reads
12108 some cycles later. */
12109 switch (get_attr_type (insn))
12110 {
12111 case TYPE_JMPREG:
309323c2 12112 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12113 a mtctr and bctr (and mtlr and br/blr). The first
12114 scheduling pass will not know about this latency since
12115 the mtctr instruction, which has the latency associated
12116 to it, will be generated by reload. */
309323c2 12117 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12118 case TYPE_BRANCH:
12119 /* Leave some extra cycles between a compare and its
12120 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12121 if ((rs6000_cpu_attr == CPU_PPC603
12122 || rs6000_cpu_attr == CPU_PPC604
12123 || rs6000_cpu_attr == CPU_PPC604E
12124 || rs6000_cpu_attr == CPU_PPC620
12125 || rs6000_cpu_attr == CPU_PPC630
12126 || rs6000_cpu_attr == CPU_PPC750
12127 || rs6000_cpu_attr == CPU_PPC7400
12128 || rs6000_cpu_attr == CPU_PPC7450
12129 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12130 && recog_memoized (dep_insn)
12131 && (INSN_CODE (dep_insn) >= 0)
12132 && (get_attr_type (dep_insn) == TYPE_COMPARE
12133 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12134 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
12135 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
12136 return cost + 2;
12137 default:
12138 break;
12139 }
a251ffd0
TG
12140 /* Fall out to return default cost. */
12141 }
12142
12143 return cost;
12144}
b6c9286a 12145
a4f6c312
SS
12146/* A C statement (sans semicolon) to update the integer scheduling
12147 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12148 INSN earlier, increase the priority to execute INSN later. Do not
12149 define this macro if you do not need to adjust the scheduling
12150 priorities of insns. */
bef84347 12151
c237e94a 12152static int
bef84347 12153rs6000_adjust_priority (insn, priority)
d330fd93 12154 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12155 int priority;
12156{
a4f6c312
SS
12157 /* On machines (like the 750) which have asymmetric integer units,
12158 where one integer unit can do multiply and divides and the other
12159 can't, reduce the priority of multiply/divide so it is scheduled
12160 before other integer operations. */
bef84347
VM
12161
12162#if 0
2c3c49de 12163 if (! INSN_P (insn))
bef84347
VM
12164 return priority;
12165
12166 if (GET_CODE (PATTERN (insn)) == USE)
12167 return priority;
12168
12169 switch (rs6000_cpu_attr) {
12170 case CPU_PPC750:
12171 switch (get_attr_type (insn))
12172 {
12173 default:
12174 break;
12175
12176 case TYPE_IMUL:
12177 case TYPE_IDIV:
3cb999d8
DE
12178 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12179 priority, priority);
bef84347
VM
12180 if (priority >= 0 && priority < 0x01000000)
12181 priority >>= 3;
12182 break;
12183 }
12184 }
12185#endif
12186
12187 return priority;
12188}
12189
a4f6c312
SS
12190/* Return how many instructions the machine can issue per cycle. */
12191
c237e94a
ZW
12192static int
12193rs6000_issue_rate ()
b6c9286a
MM
12194{
12195 switch (rs6000_cpu_attr) {
3cb999d8
DE
12196 case CPU_RIOS1: /* ? */
12197 case CPU_RS64A:
12198 case CPU_PPC601: /* ? */
ed947a96 12199 case CPU_PPC7450:
3cb999d8 12200 return 3;
b6c9286a 12201 case CPU_PPC603:
bef84347 12202 case CPU_PPC750:
ed947a96 12203 case CPU_PPC7400:
bef84347 12204 return 2;
3cb999d8 12205 case CPU_RIOS2:
b6c9286a 12206 case CPU_PPC604:
19684119 12207 case CPU_PPC604E:
b6c9286a 12208 case CPU_PPC620:
3cb999d8 12209 case CPU_PPC630:
309323c2 12210 case CPU_POWER4:
b6c9286a
MM
12211 return 4;
12212 default:
12213 return 1;
12214 }
12215}
12216
b6c9286a 12217\f
b6c9286a
MM
12218/* Length in units of the trampoline for entering a nested function. */
12219
12220int
12221rs6000_trampoline_size ()
12222{
12223 int ret = 0;
12224
12225 switch (DEFAULT_ABI)
12226 {
12227 default:
12228 abort ();
12229
12230 case ABI_AIX:
8f802bfb 12231 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12232 break;
12233
4dabc42d 12234 case ABI_DARWIN:
b6c9286a
MM
12235 case ABI_V4:
12236 case ABI_AIX_NODESC:
03a7e1a5 12237 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12238 break;
b6c9286a
MM
12239 }
12240
12241 return ret;
12242}
12243
12244/* Emit RTL insns to initialize the variable parts of a trampoline.
12245 FNADDR is an RTX for the address of the function's pure code.
12246 CXT is an RTX for the static chain value for the function. */
12247
12248void
12249rs6000_initialize_trampoline (addr, fnaddr, cxt)
12250 rtx addr;
12251 rtx fnaddr;
12252 rtx cxt;
12253{
ac2a93a1 12254 enum machine_mode pmode = Pmode;
8bd04c56
MM
12255 int regsize = (TARGET_32BIT) ? 4 : 8;
12256 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12257
12258 switch (DEFAULT_ABI)
12259 {
12260 default:
12261 abort ();
12262
8bd04c56 12263/* Macros to shorten the code expansions below. */
39403d82 12264#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12265#define MEM_PLUS(addr,offset) \
12266 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12267
b6c9286a
MM
12268 /* Under AIX, just build the 3 word function descriptor */
12269 case ABI_AIX:
8bd04c56
MM
12270 {
12271 rtx fn_reg = gen_reg_rtx (pmode);
12272 rtx toc_reg = gen_reg_rtx (pmode);
12273 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12274 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12275 emit_move_insn (MEM_DEREF (addr), fn_reg);
12276 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12277 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12278 }
b6c9286a
MM
12279 break;
12280
4dabc42d
TC
12281 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12282 case ABI_DARWIN:
b6c9286a
MM
12283 case ABI_V4:
12284 case ABI_AIX_NODESC:
39403d82 12285 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12286 FALSE, VOIDmode, 4,
12287 addr, pmode,
12288 GEN_INT (rs6000_trampoline_size ()), SImode,
12289 fnaddr, pmode,
12290 ctx_reg, pmode);
b6c9286a 12291 break;
b6c9286a
MM
12292 }
12293
12294 return;
12295}
7509c759
MM
12296
12297\f
91d231cb 12298/* Table of valid machine attributes. */
a4f6c312 12299
91d231cb 12300const struct attribute_spec rs6000_attribute_table[] =
7509c759 12301{
91d231cb 12302 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12303 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12304 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12305 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12306};
7509c759 12307
a5c76ee6
ZW
12308/* Handle a "longcall" or "shortcall" attribute; arguments as in
12309 struct attribute_spec.handler. */
a4f6c312 12310
91d231cb
JM
12311static tree
12312rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12313 tree *node;
12314 tree name;
12315 tree args ATTRIBUTE_UNUSED;
12316 int flags ATTRIBUTE_UNUSED;
12317 bool *no_add_attrs;
12318{
12319 if (TREE_CODE (*node) != FUNCTION_TYPE
12320 && TREE_CODE (*node) != FIELD_DECL
12321 && TREE_CODE (*node) != TYPE_DECL)
12322 {
12323 warning ("`%s' attribute only applies to functions",
12324 IDENTIFIER_POINTER (name));
12325 *no_add_attrs = true;
12326 }
6a4cee5f 12327
91d231cb 12328 return NULL_TREE;
7509c759
MM
12329}
12330
a5c76ee6
ZW
12331/* Set longcall attributes on all functions declared when
12332 rs6000_default_long_calls is true. */
12333static void
12334rs6000_set_default_type_attributes (type)
12335 tree type;
12336{
12337 if (rs6000_default_long_calls
12338 && (TREE_CODE (type) == FUNCTION_TYPE
12339 || TREE_CODE (type) == METHOD_TYPE))
12340 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12341 NULL_TREE,
12342 TYPE_ATTRIBUTES (type));
12343}
12344
3cb999d8
DE
12345/* Return a reference suitable for calling a function with the
12346 longcall attribute. */
a4f6c312 12347
6a4cee5f
MM
12348struct rtx_def *
12349rs6000_longcall_ref (call_ref)
12350 rtx call_ref;
12351{
d330fd93 12352 const char *call_name;
6a4cee5f
MM
12353 tree node;
12354
12355 if (GET_CODE (call_ref) != SYMBOL_REF)
12356 return call_ref;
12357
12358 /* System V adds '.' to the internal name, so skip them. */
12359 call_name = XSTR (call_ref, 0);
12360 if (*call_name == '.')
12361 {
12362 while (*call_name == '.')
12363 call_name++;
12364
12365 node = get_identifier (call_name);
39403d82 12366 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12367 }
12368
12369 return force_reg (Pmode, call_ref);
12370}
12371
7509c759 12372\f
b64a1b53
RH
12373#ifdef USING_ELFOS_H
12374
7509c759
MM
12375/* A C statement or statements to switch to the appropriate section
12376 for output of RTX in mode MODE. You can assume that RTX is some
12377 kind of constant in RTL. The argument MODE is redundant except in
12378 the case of a `const_int' rtx. Select the section by calling
12379 `text_section' or one of the alternatives for other sections.
12380
12381 Do not define this macro if you put all constants in the read-only
12382 data section. */
12383
b64a1b53
RH
12384static void
12385rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12386 enum machine_mode mode;
7509c759 12387 rtx x;
b64a1b53 12388 unsigned HOST_WIDE_INT align;
7509c759 12389{
a9098fd0 12390 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12391 toc_section ();
7509c759 12392 else
b64a1b53 12393 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12394}
12395
12396/* A C statement or statements to switch to the appropriate
12397 section for output of DECL. DECL is either a `VAR_DECL' node
12398 or a constant of some sort. RELOC indicates whether forming
12399 the initial value of DECL requires link-time relocations. */
12400
ae46c4e0
RH
12401static void
12402rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12403 tree decl;
12404 int reloc;
ae46c4e0 12405 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
7509c759
MM
12406{
12407 int size = int_size_in_bytes (TREE_TYPE (decl));
63019373
GK
12408 int needs_sdata;
12409 int readonly;
12410 static void (* const sec_funcs[4]) PARAMS ((void)) = {
d48bc59a 12411 &readonly_data_section,
63019373
GK
12412 &sdata2_section,
12413 &data_section,
12414 &sdata_section
12415 };
12416
12417 needs_sdata = (size > 0
12418 && size <= g_switch_value
12419 && rs6000_sdata != SDATA_NONE
12420 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
7509c759
MM
12421
12422 if (TREE_CODE (decl) == STRING_CST)
63019373 12423 readonly = ! flag_writable_strings;
a9098fd0 12424 else if (TREE_CODE (decl) == VAR_DECL)
63019373
GK
12425 readonly = (! (flag_pic && reloc)
12426 && TREE_READONLY (decl)
12427 && ! TREE_SIDE_EFFECTS (decl)
12428 && DECL_INITIAL (decl)
12429 && DECL_INITIAL (decl) != error_mark_node
12430 && TREE_CONSTANT (DECL_INITIAL (decl)));
ac4f7ad9
GK
12431 else if (TREE_CODE (decl) == CONSTRUCTOR)
12432 readonly = (! (flag_pic && reloc)
ac4f7ad9 12433 && ! TREE_SIDE_EFFECTS (decl)
f3afc192 12434 && TREE_CONSTANT (decl));
7509c759 12435 else
63019373
GK
12436 readonly = 1;
12437 if (needs_sdata && rs6000_sdata != SDATA_EABI)
12438 readonly = 0;
12439
12440 (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
12441}
12442
12443/* A C statement to build up a unique section name, expressed as a
12444 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12445 RELOC indicates whether the initial value of EXP requires
12446 link-time relocations. If you do not define this macro, GCC will use
12447 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12448 macro can now be called for uninitialized data items as well as
63019373
GK
12449 initialised data and functions. */
12450
ae46c4e0
RH
12451static void
12452rs6000_elf_unique_section (decl, reloc)
63019373
GK
12453 tree decl;
12454 int reloc;
12455{
63019373
GK
12456 int len;
12457 int sec;
12458 const char *name;
12459 char *string;
12460 const char *prefix;
12461
12462 static const char *const prefixes[7][2] =
12463 {
63019373
GK
12464 { ".rodata.", ".gnu.linkonce.r." },
12465 { ".sdata2.", ".gnu.linkonce.s2." },
12466 { ".data.", ".gnu.linkonce.d." },
12467 { ".sdata.", ".gnu.linkonce.s." },
12468 { ".bss.", ".gnu.linkonce.b." },
5b8c2356
AM
12469 { ".sbss.", ".gnu.linkonce.sb." },
12470 { ".text.", ".gnu.linkonce.t." }
63019373 12471 };
63019373 12472
5b8c2356
AM
12473 if (TREE_CODE (decl) == FUNCTION_DECL)
12474 sec = 6;
63019373 12475 else
5b8c2356
AM
12476 {
12477 int readonly;
12478 int needs_sdata;
12479 int size;
12480
12481 readonly = 1;
12482 if (TREE_CODE (decl) == STRING_CST)
12483 readonly = ! flag_writable_strings;
12484 else if (TREE_CODE (decl) == VAR_DECL)
12485 readonly = (! (flag_pic && reloc)
12486 && TREE_READONLY (decl)
12487 && ! TREE_SIDE_EFFECTS (decl)
12488 && TREE_CONSTANT (DECL_INITIAL (decl)));
12489
12490 size = int_size_in_bytes (TREE_TYPE (decl));
12491 needs_sdata = (size > 0
12492 && size <= g_switch_value
12493 && rs6000_sdata != SDATA_NONE
12494 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
12495
12496 if (DECL_INITIAL (decl) == 0
12497 || DECL_INITIAL (decl) == error_mark_node)
12498 sec = 4;
12499 else if (! readonly)
12500 sec = 2;
12501 else
12502 sec = 0;
63019373 12503
5b8c2356
AM
12504 if (needs_sdata)
12505 {
12506 /* .sdata2 is only for EABI. */
12507 if (sec == 0 && rs6000_sdata != SDATA_EABI)
12508 sec = 2;
12509 sec += 1;
12510 }
12511 }
63019373 12512
772c5265
RH
12513 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
12514 name = (*targetm.strip_name_encoding) (name);
63019373
GK
12515 prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
12516 len = strlen (name) + strlen (prefix);
12517 string = alloca (len + 1);
12518
12519 sprintf (string, "%s%s", prefix, name);
12520
12521 DECL_SECTION_NAME (decl) = build_string (len, string);
7509c759 12522}
d9407988
MM
12523
12524\f
d9407988
MM
12525/* If we are referencing a function that is static or is known to be
12526 in this file, make the SYMBOL_REF special. We can use this to indicate
12527 that we can branch to this function without emitting a no-op after the
9ebbca7d 12528 call. For real AIX calling sequences, we also replace the
d9407988
MM
12529 function name with the real name (1 or 2 leading .'s), rather than
12530 the function descriptor name. This saves a lot of overriding code
a260abc9 12531 to read the prefixes. */
d9407988 12532
fb49053f
RH
12533static void
12534rs6000_elf_encode_section_info (decl, first)
d9407988 12535 tree decl;
b2003250 12536 int first;
d9407988 12537{
b2003250
RH
12538 if (!first)
12539 return;
12540
d9407988
MM
12541 if (TREE_CODE (decl) == FUNCTION_DECL)
12542 {
12543 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
8f1b829e 12544 if ((TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
c81fc13e 12545 && ! DECL_WEAK (decl))
d9407988
MM
12546 SYMBOL_REF_FLAG (sym_ref) = 1;
12547
9ebbca7d 12548 if (DEFAULT_ABI == ABI_AIX)
d9407988 12549 {
ff669a6c
RH
12550 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12551 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12552 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12553 str[0] = '.';
12554 str[1] = '.';
12555 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12556
520a57c8 12557 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12558 }
12559 }
12560 else if (rs6000_sdata != SDATA_NONE
f607bc57 12561 && DEFAULT_ABI == ABI_V4
d9407988
MM
12562 && TREE_CODE (decl) == VAR_DECL)
12563 {
12564 int size = int_size_in_bytes (TREE_TYPE (decl));
12565 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12566 const char *name = (char *)0;
d9407988
MM
12567 int len = 0;
12568
12569 if (section_name)
12570 {
12571 if (TREE_CODE (section_name) == STRING_CST)
12572 {
12573 name = TREE_STRING_POINTER (section_name);
12574 len = TREE_STRING_LENGTH (section_name);
12575 }
12576 else
12577 abort ();
12578 }
12579
12580 if ((size > 0 && size <= g_switch_value)
12581 || (name
5f59ecb7 12582 && ((len == sizeof (".sdata") - 1
3cb999d8 12583 && strcmp (name, ".sdata") == 0)
5f59ecb7 12584 || (len == sizeof (".sdata2") - 1
3cb999d8 12585 && strcmp (name, ".sdata2") == 0)
5f59ecb7 12586 || (len == sizeof (".sbss") - 1
3cb999d8 12587 && strcmp (name, ".sbss") == 0)
5f59ecb7 12588 || (len == sizeof (".sbss2") - 1
3cb999d8 12589 && strcmp (name, ".sbss2") == 0)
5f59ecb7 12590 || (len == sizeof (".PPC.EMB.sdata0") - 1
3cb999d8 12591 && strcmp (name, ".PPC.EMB.sdata0") == 0)
5f59ecb7 12592 || (len == sizeof (".PPC.EMB.sbss0") - 1
3cb999d8 12593 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d9407988
MM
12594 {
12595 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
ff669a6c 12596 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 12597 char *str = alloca (len + 2);
ff669a6c 12598
ff669a6c
RH
12599 str[0] = '@';
12600 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 12601 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
12602 }
12603 }
12604}
12605
772c5265
RH
12606static const char *
12607rs6000_elf_strip_name_encoding (str)
12608 const char *str;
12609{
12610 while (*str == '*' || *str == '@')
12611 str++;
12612 return str;
12613}
12614
b91da81f 12615#endif /* USING_ELFOS_H */
000034eb 12616
a6c2a102 12617\f
000034eb 12618/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
12619 ADDR can be effectively incremented by incrementing REG.
12620
12621 r0 is special and we must not select it as an address
12622 register by this routine since our caller will try to
12623 increment the returned register via an "la" instruction. */
000034eb
DE
12624
12625struct rtx_def *
12626find_addr_reg (addr)
12627 rtx addr;
12628{
12629 while (GET_CODE (addr) == PLUS)
12630 {
02441cd6
JL
12631 if (GET_CODE (XEXP (addr, 0)) == REG
12632 && REGNO (XEXP (addr, 0)) != 0)
000034eb 12633 addr = XEXP (addr, 0);
02441cd6
JL
12634 else if (GET_CODE (XEXP (addr, 1)) == REG
12635 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
12636 addr = XEXP (addr, 1);
12637 else if (CONSTANT_P (XEXP (addr, 0)))
12638 addr = XEXP (addr, 1);
12639 else if (CONSTANT_P (XEXP (addr, 1)))
12640 addr = XEXP (addr, 0);
12641 else
12642 abort ();
12643 }
02441cd6 12644 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
12645 return addr;
12646 abort ();
12647}
12648
a6c2a102
DE
12649void
12650rs6000_fatal_bad_address (op)
12651 rtx op;
12652{
12653 fatal_insn ("bad address", op);
12654}
c8023011
MM
12655
12656/* Called to register all of our global variables with the garbage
12657 collector. */
12658
12659static void
12660rs6000_add_gc_roots ()
12661{
9ebbca7d
GK
12662 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
12663 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
12664 toc_hash_mark_table);
ee890fe2
SS
12665}
12666
12667#if TARGET_MACHO
12668
12669#if 0
12670/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12671 reference and a constant. */
12672
12673int
12674symbolic_operand (op)
592696dd 12675 rtx op;
ee890fe2
SS
12676{
12677 switch (GET_CODE (op))
12678 {
12679 case SYMBOL_REF:
12680 case LABEL_REF:
12681 return 1;
12682 case CONST:
12683 op = XEXP (op, 0);
12684 return (GET_CODE (op) == SYMBOL_REF ||
12685 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12686 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12687 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12688 default:
12689 return 0;
12690 }
c8023011 12691}
ee890fe2
SS
12692#endif
12693
12694#ifdef RS6000_LONG_BRANCH
12695
12696static tree stub_list = 0;
12697
12698/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12699 procedure calls to the linked list. */
12700
12701void
12702add_compiler_stub (label_name, function_name, line_number)
12703 tree label_name;
12704 tree function_name;
12705 int line_number;
12706{
12707 tree stub = build_tree_list (function_name, label_name);
12708 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12709 TREE_CHAIN (stub) = stub_list;
12710 stub_list = stub;
12711}
12712
12713#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12714#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12715#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12716
a4f6c312
SS
12717/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12718 handling procedure calls from the linked list and initializes the
12719 linked list. */
ee890fe2 12720
a4f6c312
SS
12721void
12722output_compiler_stub ()
ee890fe2
SS
12723{
12724 char tmp_buf[256];
12725 char label_buf[256];
308c142a 12726 tree stub;
ee890fe2
SS
12727
12728 if (!flag_pic)
12729 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12730 {
12731 fprintf (asm_out_file,
12732 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12733
12734#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12735 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12736 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12737#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12738
12739 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12740 strcpy (label_buf,
12741 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12742 else
12743 {
12744 label_buf[0] = '_';
12745 strcpy (label_buf+1,
12746 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12747 }
12748
12749 strcpy (tmp_buf, "lis r12,hi16(");
12750 strcat (tmp_buf, label_buf);
12751 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12752 strcat (tmp_buf, label_buf);
12753 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12754 output_asm_insn (tmp_buf, 0);
12755
12756#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12757 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12758 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12759#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12760 }
12761
12762 stub_list = 0;
12763}
12764
12765/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12766 already there or not. */
12767
a4f6c312
SS
12768int
12769no_previous_def (function_name)
ee890fe2
SS
12770 tree function_name;
12771{
12772 tree stub;
12773 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12774 if (function_name == STUB_FUNCTION_NAME (stub))
12775 return 0;
12776 return 1;
12777}
12778
12779/* GET_PREV_LABEL gets the label name from the previous definition of
12780 the function. */
12781
a4f6c312
SS
12782tree
12783get_prev_label (function_name)
ee890fe2
SS
12784 tree function_name;
12785{
12786 tree stub;
12787 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12788 if (function_name == STUB_FUNCTION_NAME (stub))
12789 return STUB_LABEL_NAME (stub);
12790 return 0;
12791}
12792
12793/* INSN is either a function call or a millicode call. It may have an
12794 unconditional jump in its delay slot.
12795
12796 CALL_DEST is the routine we are calling. */
12797
12798char *
12799output_call (insn, call_dest, operand_number)
12800 rtx insn;
12801 rtx call_dest;
12802 int operand_number;
12803{
12804 static char buf[256];
12805 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
12806 {
12807 tree labelname;
12808 tree funname = get_identifier (XSTR (call_dest, 0));
12809
12810 if (no_previous_def (funname))
12811 {
308c142a 12812 int line_number = 0;
ee890fe2
SS
12813 rtx label_rtx = gen_label_rtx ();
12814 char *label_buf, temp_buf[256];
12815 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
12816 CODE_LABEL_NUMBER (label_rtx));
12817 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
12818 labelname = get_identifier (label_buf);
12819 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
12820 if (insn)
12821 line_number = NOTE_LINE_NUMBER (insn);
12822 add_compiler_stub (labelname, funname, line_number);
12823 }
12824 else
12825 labelname = get_prev_label (funname);
12826
12827 sprintf (buf, "jbsr %%z%d,%.246s",
12828 operand_number, IDENTIFIER_POINTER (labelname));
12829 return buf;
12830 }
12831 else
12832 {
12833 sprintf (buf, "bl %%z%d", operand_number);
12834 return buf;
12835 }
12836}
12837
12838#endif /* RS6000_LONG_BRANCH */
12839
12840#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
12841 do { \
83182544 12842 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
12843 char *buffer_ = (BUF); \
12844 if (symbol_[0] == '"') \
12845 { \
12846 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
12847 } \
12848 else if (name_needs_quotes(symbol_)) \
12849 { \
12850 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
12851 } \
12852 else \
12853 { \
12854 sprintf(buffer_, "L%d$%s", (N), symbol_); \
12855 } \
12856 } while (0)
12857
12858
12859/* Generate PIC and indirect symbol stubs. */
12860
12861void
12862machopic_output_stub (file, symb, stub)
12863 FILE *file;
12864 const char *symb, *stub;
12865{
12866 unsigned int length;
a4f6c312
SS
12867 char *symbol_name, *lazy_ptr_name;
12868 char *local_label_0;
ee890fe2
SS
12869 static int label = 0;
12870
df56a27f 12871 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 12872 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 12873
ee890fe2
SS
12874 label += 1;
12875
ee890fe2
SS
12876 length = strlen (symb);
12877 symbol_name = alloca (length + 32);
12878 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
12879
12880 lazy_ptr_name = alloca (length + 32);
12881 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
12882
12883 local_label_0 = alloca (length + 32);
12884 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
12885
ee890fe2
SS
12886 if (flag_pic == 2)
12887 machopic_picsymbol_stub_section ();
12888 else
12889 machopic_symbol_stub_section ();
12890
12891 fprintf (file, "%s:\n", stub);
12892 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12893
12894 if (flag_pic == 2)
12895 {
12896 fprintf (file, "\tmflr r0\n");
12897 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
12898 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
12899 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
12900 lazy_ptr_name, local_label_0);
12901 fprintf (file, "\tmtlr r0\n");
12902 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
12903 lazy_ptr_name, local_label_0);
12904 fprintf (file, "\tmtctr r12\n");
12905 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
12906 lazy_ptr_name, local_label_0);
12907 fprintf (file, "\tbctr\n");
12908 }
12909 else
12910 fprintf (file, "non-pure not supported\n");
12911
12912 machopic_lazy_symbol_ptr_section ();
12913 fprintf (file, "%s:\n", lazy_ptr_name);
12914 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12915 fprintf (file, "\t.long dyld_stub_binding_helper\n");
12916}
12917
12918/* Legitimize PIC addresses. If the address is already
12919 position-independent, we return ORIG. Newly generated
12920 position-independent addresses go into a reg. This is REG if non
12921 zero, otherwise we allocate register(s) as necessary. */
12922
c859cda6 12923#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
12924
12925rtx
12926rs6000_machopic_legitimize_pic_address (orig, mode, reg)
12927 rtx orig;
12928 enum machine_mode mode;
12929 rtx reg;
12930{
12931 rtx base, offset;
12932
12933 if (reg == NULL && ! reload_in_progress && ! reload_completed)
12934 reg = gen_reg_rtx (Pmode);
12935
12936 if (GET_CODE (orig) == CONST)
12937 {
12938 if (GET_CODE (XEXP (orig, 0)) == PLUS
12939 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
12940 return orig;
12941
12942 if (GET_CODE (XEXP (orig, 0)) == PLUS)
12943 {
a4f6c312
SS
12944 base =
12945 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
12946 Pmode, reg);
12947 offset =
12948 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
12949 Pmode, reg);
ee890fe2
SS
12950 }
12951 else
12952 abort ();
12953
12954 if (GET_CODE (offset) == CONST_INT)
12955 {
12956 if (SMALL_INT (offset))
ed8908e7 12957 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
12958 else if (! reload_in_progress && ! reload_completed)
12959 offset = force_reg (Pmode, offset);
12960 else
c859cda6
DJ
12961 {
12962 rtx mem = force_const_mem (Pmode, orig);
12963 return machopic_legitimize_pic_address (mem, Pmode, reg);
12964 }
ee890fe2
SS
12965 }
12966 return gen_rtx (PLUS, Pmode, base, offset);
12967 }
12968
12969 /* Fall back on generic machopic code. */
12970 return machopic_legitimize_pic_address (orig, mode, reg);
12971}
12972
12973/* This is just a placeholder to make linking work without having to
12974 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
12975 ever needed for Darwin (not too likely!) this would have to get a
12976 real definition. */
12977
12978void
12979toc_section ()
12980{
12981}
12982
12983#endif /* TARGET_MACHO */
7c262518
RH
12984
12985#if TARGET_ELF
12986static unsigned int
12987rs6000_elf_section_type_flags (decl, name, reloc)
12988 tree decl;
12989 const char *name;
12990 int reloc;
12991{
12992 unsigned int flags = default_section_type_flags (decl, name, reloc);
12993
270fc29b
RH
12994 if (TARGET_RELOCATABLE)
12995 flags |= SECTION_WRITE;
7c262518 12996
d0101753 12997 return flags;
7c262518 12998}
d9f6800d
RH
12999
13000/* Record an element in the table of global constructors. SYMBOL is
13001 a SYMBOL_REF of the function to be called; PRIORITY is a number
13002 between 0 and MAX_INIT_PRIORITY.
13003
13004 This differs from default_named_section_asm_out_constructor in
13005 that we have special handling for -mrelocatable. */
13006
13007static void
13008rs6000_elf_asm_out_constructor (symbol, priority)
13009 rtx symbol;
13010 int priority;
13011{
13012 const char *section = ".ctors";
13013 char buf[16];
13014
13015 if (priority != DEFAULT_INIT_PRIORITY)
13016 {
13017 sprintf (buf, ".ctors.%.5u",
13018 /* Invert the numbering so the linker puts us in the proper
13019 order; constructors are run from right to left, and the
13020 linker sorts in increasing order. */
13021 MAX_INIT_PRIORITY - priority);
13022 section = buf;
13023 }
13024
715bdd29
RH
13025 named_section_flags (section, SECTION_WRITE);
13026 assemble_align (POINTER_SIZE);
d9f6800d
RH
13027
13028 if (TARGET_RELOCATABLE)
13029 {
13030 fputs ("\t.long (", asm_out_file);
13031 output_addr_const (asm_out_file, symbol);
13032 fputs (")@fixup\n", asm_out_file);
13033 }
13034 else
c8af3574 13035 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
13036}
13037
13038static void
13039rs6000_elf_asm_out_destructor (symbol, priority)
13040 rtx symbol;
13041 int priority;
13042{
13043 const char *section = ".dtors";
13044 char buf[16];
13045
13046 if (priority != DEFAULT_INIT_PRIORITY)
13047 {
13048 sprintf (buf, ".dtors.%.5u",
13049 /* Invert the numbering so the linker puts us in the proper
13050 order; constructors are run from right to left, and the
13051 linker sorts in increasing order. */
13052 MAX_INIT_PRIORITY - priority);
13053 section = buf;
13054 }
13055
715bdd29
RH
13056 named_section_flags (section, SECTION_WRITE);
13057 assemble_align (POINTER_SIZE);
d9f6800d
RH
13058
13059 if (TARGET_RELOCATABLE)
13060 {
13061 fputs ("\t.long (", asm_out_file);
13062 output_addr_const (asm_out_file, symbol);
13063 fputs (")@fixup\n", asm_out_file);
13064 }
13065 else
c8af3574 13066 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 13067}
7c262518
RH
13068#endif
13069
cbaaba19 13070#if TARGET_XCOFF
7c262518 13071static void
715bdd29 13072xcoff_asm_named_section (name, flags)
7c262518
RH
13073 const char *name;
13074 unsigned int flags ATTRIBUTE_UNUSED;
7c262518
RH
13075{
13076 fprintf (asm_out_file, "\t.csect %s\n", name);
13077}
ae46c4e0
RH
13078
13079static void
13080rs6000_xcoff_select_section (exp, reloc, align)
13081 tree exp;
13082 int reloc;
13083 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13084{
13085 if ((TREE_CODE (exp) == STRING_CST
13086 && ! flag_writable_strings)
13087 || (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
13088 && TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp)
13089 && DECL_INITIAL (exp)
13090 && (DECL_INITIAL (exp) == error_mark_node
13091 || TREE_CONSTANT (DECL_INITIAL (exp)))
13092 && ! (reloc)))
13093 {
13094 if (TREE_PUBLIC (exp))
13095 read_only_data_section ();
13096 else
13097 read_only_private_data_section ();
13098 }
13099 else
13100 {
13101 if (TREE_PUBLIC (exp))
13102 data_section ();
13103 else
13104 private_data_section ();
13105 }
13106}
13107
13108static void
13109rs6000_xcoff_unique_section (decl, reloc)
13110 tree decl;
772c5265 13111 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13112{
13113 const char *name;
13114 char *string;
13115 size_t len;
13116
13117 if (TREE_CODE (decl) == FUNCTION_DECL)
13118 {
13119 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13120 len = strlen (name) + 5;
13121 string = alloca (len + 1);
13122 sprintf (string, ".%s[PR]", name);
13123 DECL_SECTION_NAME (decl) = build_string (len, string);
13124 }
13125}
b64a1b53 13126
fb49053f
RH
13127/* Select section for constant in constant pool.
13128
13129 On RS/6000, all constants are in the private read-only data area.
13130 However, if this is being placed in the TOC it must be output as a
13131 toc entry. */
13132
b64a1b53
RH
13133static void
13134rs6000_xcoff_select_rtx_section (mode, x, align)
13135 enum machine_mode mode;
13136 rtx x;
13137 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13138{
13139 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13140 toc_section ();
13141 else
13142 read_only_private_data_section ();
13143}
772c5265
RH
13144
13145/* Remove any trailing [DS] or the like from the symbol name. */
13146
13147static const char *
13148rs6000_xcoff_strip_name_encoding (name)
13149 const char *name;
13150{
13151 size_t len;
13152 if (*name == '*')
13153 name++;
13154 len = strlen (name);
13155 if (name[len - 1] == ']')
13156 return ggc_alloc_string (name, len - 4);
13157 else
13158 return name;
13159}
13160
cbaaba19 13161#endif /* TARGET_XCOFF */
fb49053f
RH
13162
13163/* Note that this is also used for ELF64. */
13164
13165static void
13166rs6000_xcoff_encode_section_info (decl, first)
13167 tree decl;
13168 int first ATTRIBUTE_UNUSED;
13169{
13170 if (TREE_CODE (decl) == FUNCTION_DECL
13171 && (TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
13172 && ! DECL_WEAK (decl))
13173 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13174}