]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
typeck.c (build_class_member_access_expr): Handle COMPOUND_EXPR and COND_EXPR special...
[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
b275d088
DE
208static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
209static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
ae46c4e0
RH
210static void rs6000_xcoff_select_section PARAMS ((tree, int,
211 unsigned HOST_WIDE_INT));
212static void rs6000_xcoff_unique_section PARAMS ((tree, int));
b64a1b53
RH
213static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
214 unsigned HOST_WIDE_INT));
772c5265 215static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
7c262518 216#endif
fb49053f
RH
217static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
218 ATTRIBUTE_UNUSED;
c237e94a
ZW
219static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
220static int rs6000_adjust_priority PARAMS ((rtx, int));
221static int rs6000_issue_rate PARAMS ((void));
222
6fa3f289 223static void rs6000_init_builtins PARAMS ((void));
92898235
AH
224static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
225static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
226static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 227static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
92898235 228static void altivec_init_builtins PARAMS ((void));
a3170dc6
AH
229static void rs6000_common_init_builtins PARAMS ((void));
230
231static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
232 int, enum rs6000_builtins,
233 enum rs6000_builtins));
234static void spe_init_builtins PARAMS ((void));
235static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
236static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
237static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
238static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
239
92898235 240static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
3a9b8c7e
AH
241static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
242static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
243static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
100c4561 244static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 245static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
6525c0e7 246static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 247static void rs6000_parse_abi_options PARAMS ((void));
08b57fb3 248static void rs6000_parse_vrsave_option PARAMS ((void));
a3170dc6 249static void rs6000_parse_isel_option PARAMS ((void));
00b960c7
AH
250static int first_altivec_reg_to_save PARAMS ((void));
251static unsigned int compute_vrsave_mask PARAMS ((void));
252static void is_altivec_return_reg PARAMS ((rtx, void *));
9aa86737
AH
253static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
254static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
69ef87e2 255static int easy_vector_constant PARAMS ((rtx));
c81bebd7
MM
256\f
257/* Default register names. */
258char rs6000_reg_names[][8] =
259{
802a0058
MM
260 "0", "1", "2", "3", "4", "5", "6", "7",
261 "8", "9", "10", "11", "12", "13", "14", "15",
262 "16", "17", "18", "19", "20", "21", "22", "23",
263 "24", "25", "26", "27", "28", "29", "30", "31",
264 "0", "1", "2", "3", "4", "5", "6", "7",
265 "8", "9", "10", "11", "12", "13", "14", "15",
266 "16", "17", "18", "19", "20", "21", "22", "23",
267 "24", "25", "26", "27", "28", "29", "30", "31",
268 "mq", "lr", "ctr","ap",
269 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
270 "xer",
271 /* AltiVec registers. */
0cd5e3a1
AH
272 "0", "1", "2", "3", "4", "5", "6", "7",
273 "8", "9", "10", "11", "12", "13", "14", "15",
274 "16", "17", "18", "19", "20", "21", "22", "23",
275 "24", "25", "26", "27", "28", "29", "30", "31",
0ac081f6 276 "vrsave"
c81bebd7
MM
277};
278
279#ifdef TARGET_REGNAMES
8b60264b 280static const char alt_reg_names[][8] =
c81bebd7 281{
802a0058
MM
282 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
283 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
284 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
285 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
286 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
287 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
288 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
289 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
290 "mq", "lr", "ctr", "ap",
291 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6
AH
292 "xer",
293 /* AltiVec registers. */
294 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
295 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
296 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
297 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
76a773f3 298 "vrsave"
c81bebd7
MM
299};
300#endif
9878760c 301\f
daf11973
MM
302#ifndef MASK_STRICT_ALIGN
303#define MASK_STRICT_ALIGN 0
304#endif
672a6f42
NB
305\f
306/* Initialize the GCC target structure. */
91d231cb
JM
307#undef TARGET_ATTRIBUTE_TABLE
308#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
309#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
310#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 311
301d03af
RS
312#undef TARGET_ASM_ALIGNED_DI_OP
313#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
314
315/* Default unaligned ops are only provided for ELF. Find the ops needed
316 for non-ELF systems. */
317#ifndef OBJECT_FORMAT_ELF
cbaaba19 318#if TARGET_XCOFF
ae6c1efd 319/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
320 64-bit targets. */
321#undef TARGET_ASM_UNALIGNED_HI_OP
322#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
323#undef TARGET_ASM_UNALIGNED_SI_OP
324#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
325#undef TARGET_ASM_UNALIGNED_DI_OP
326#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
327#else
328/* For Darwin. */
329#undef TARGET_ASM_UNALIGNED_HI_OP
330#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
331#undef TARGET_ASM_UNALIGNED_SI_OP
332#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
333#endif
334#endif
335
336/* This hook deals with fixups for relocatable code and DI-mode objects
337 in 64-bit code. */
338#undef TARGET_ASM_INTEGER
339#define TARGET_ASM_INTEGER rs6000_assemble_integer
340
08c148a8
NB
341#undef TARGET_ASM_FUNCTION_PROLOGUE
342#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
343#undef TARGET_ASM_FUNCTION_EPILOGUE
344#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
345
7c262518
RH
346#if TARGET_ELF
347#undef TARGET_SECTION_TYPE_FLAGS
348#define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags
349#endif
350
c237e94a
ZW
351#undef TARGET_SCHED_ISSUE_RATE
352#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
353#undef TARGET_SCHED_ADJUST_COST
354#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
355#undef TARGET_SCHED_ADJUST_PRIORITY
356#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
357
0ac081f6
AH
358#undef TARGET_INIT_BUILTINS
359#define TARGET_INIT_BUILTINS rs6000_init_builtins
360
361#undef TARGET_EXPAND_BUILTIN
362#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
363
00b960c7
AH
364/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
365#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
366
f6897b10 367struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 368\f
5248c961
RK
369/* Override command line options. Mostly we process the processor
370 type and sometimes adjust other TARGET_ options. */
371
372void
8e3f41e7 373rs6000_override_options (default_cpu)
d330fd93 374 const char *default_cpu;
5248c961 375{
c4d38ccb 376 size_t i, j;
8e3f41e7 377 struct rs6000_cpu_select *ptr;
5248c961 378
85638c0d
RK
379 /* Simplify the entries below by making a mask for any POWER
380 variant and any PowerPC variant. */
381
938937d8 382#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
383#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
384 | MASK_PPC_GFXOPT | MASK_POWERPC64)
385#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 386
5248c961
RK
387 static struct ptt
388 {
8b60264b
KG
389 const char *const name; /* Canonical processor name. */
390 const enum processor_type processor; /* Processor type enum value. */
391 const int target_enable; /* Target flags to enable. */
392 const int target_disable; /* Target flags to disable. */
393 } const processor_target_table[]
cf27b467
MM
394 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
395 POWER_MASKS | POWERPC_MASKS},
db7f1e43 396 {"power", PROCESSOR_POWER,
938937d8 397 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 398 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
399 {"power2", PROCESSOR_POWER,
400 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
401 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
402 {"power3", PROCESSOR_PPC630,
403 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
404 POWER_MASKS | MASK_PPC_GPOPT},
309323c2
DE
405 {"power4", PROCESSOR_POWER4,
406 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
407 POWER_MASKS | MASK_PPC_GPOPT},
db7f1e43
RK
408 {"powerpc", PROCESSOR_POWERPC,
409 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 410 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
411 {"powerpc64", PROCESSOR_POWERPC64,
412 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
413 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 414 {"rios", PROCESSOR_RIOS1,
938937d8 415 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
416 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
417 {"rios1", PROCESSOR_RIOS1,
938937d8 418 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
419 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
420 {"rsc", PROCESSOR_PPC601,
938937d8 421 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
422 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
423 {"rsc1", PROCESSOR_PPC601,
938937d8 424 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
425 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
426 {"rios2", PROCESSOR_RIOS2,
938937d8 427 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 428 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
429 {"rs64a", PROCESSOR_RS64A,
430 MASK_POWERPC | MASK_NEW_MNEMONICS,
431 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
432 {"401", PROCESSOR_PPC403,
433 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
434 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 435 {"403", PROCESSOR_PPC403,
daf11973 436 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 437 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
438 {"405", PROCESSOR_PPC405,
439 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
440 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
441 {"505", PROCESSOR_MPCCORE,
442 MASK_POWERPC | MASK_NEW_MNEMONICS,
443 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 444 {"601", PROCESSOR_PPC601,
938937d8 445 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 446 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 447 {"602", PROCESSOR_PPC603,
cf27b467
MM
448 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
449 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 450 {"603", PROCESSOR_PPC603,
68c49ffa
RK
451 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
452 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
453 {"603e", PROCESSOR_PPC603,
454 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
455 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 456 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
457 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
458 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 459 {"604", PROCESSOR_PPC604,
b6c9286a
MM
460 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
461 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 462 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
463 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
464 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 465 {"620", PROCESSOR_PPC620,
68c49ffa 466 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
a260abc9 467 POWER_MASKS | MASK_PPC_GPOPT},
3cb999d8
DE
468 {"630", PROCESSOR_PPC630,
469 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
470 POWER_MASKS | MASK_PPC_GPOPT},
bef84347
VM
471 {"740", PROCESSOR_PPC750,
472 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
473 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
474 {"750", PROCESSOR_PPC750,
475 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
476 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
477 {"7400", PROCESSOR_PPC7400,
478 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
479 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
480 {"7450", PROCESSOR_PPC7450,
481 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
482 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a3170dc6
AH
483 {"8540", PROCESSOR_PPC8540,
484 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
485 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
486 {"801", PROCESSOR_MPCCORE,
487 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
488 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
489 {"821", PROCESSOR_MPCCORE,
490 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
491 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
492 {"823", PROCESSOR_MPCCORE,
493 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
494 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
495 {"860", PROCESSOR_MPCCORE,
496 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
497 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 498
ca7558fc 499 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 500
a4f6c312
SS
501 /* Save current -mmultiple/-mno-multiple status. */
502 int multiple = TARGET_MULTIPLE;
503 /* Save current -mstring/-mno-string status. */
504 int string = TARGET_STRING;
8a61d227 505
a4f6c312 506 /* Identify the processor type. */
8e3f41e7 507 rs6000_select[0].string = default_cpu;
3cb999d8 508 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 509
b6a1cbae 510 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 511 {
8e3f41e7
MM
512 ptr = &rs6000_select[i];
513 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 514 {
8e3f41e7
MM
515 for (j = 0; j < ptt_size; j++)
516 if (! strcmp (ptr->string, processor_target_table[j].name))
517 {
518 if (ptr->set_tune_p)
519 rs6000_cpu = processor_target_table[j].processor;
520
521 if (ptr->set_arch_p)
522 {
523 target_flags |= processor_target_table[j].target_enable;
524 target_flags &= ~processor_target_table[j].target_disable;
525 }
526 break;
527 }
528
4406229e 529 if (j == ptt_size)
8e3f41e7 530 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
531 }
532 }
8a61d227 533
a3170dc6
AH
534 if (rs6000_cpu == PROCESSOR_PPC8540)
535 rs6000_isel = 1;
536
a4f6c312
SS
537 /* If we are optimizing big endian systems for space, use the store
538 multiple instructions. */
ef792183
MM
539 if (BYTES_BIG_ENDIAN && optimize_size)
540 target_flags |= MASK_MULTIPLE;
541
8a61d227
MM
542 /* If -mmultiple or -mno-multiple was explicitly used, don't
543 override with the processor default */
544 if (TARGET_MULTIPLE_SET)
545 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 546
a4f6c312
SS
547 /* If -mstring or -mno-string was explicitly used, don't override
548 with the processor default. */
938937d8 549 if (TARGET_STRING_SET)
1f5515bf 550 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 551
a4f6c312
SS
552 /* Don't allow -mmultiple or -mstring on little endian systems
553 unless the cpu is a 750, because the hardware doesn't support the
554 instructions used in little endian mode, and causes an alignment
555 trap. The 750 does not cause an alignment trap (except when the
556 target is unaligned). */
bef84347 557
bfc79d3b 558 if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
559 {
560 if (TARGET_MULTIPLE)
561 {
562 target_flags &= ~MASK_MULTIPLE;
563 if (TARGET_MULTIPLE_SET)
564 warning ("-mmultiple is not supported on little endian systems");
565 }
566
567 if (TARGET_STRING)
568 {
569 target_flags &= ~MASK_STRING;
938937d8
MM
570 if (TARGET_STRING_SET)
571 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
572 }
573 }
3933e0e1 574
ee2ca2a2 575 if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
a260abc9 576 {
ee2ca2a2
DE
577 flag_pic = 0;
578
894bdff6
AM
579 if (extra_warnings)
580 warning ("-f%s ignored (all code is position independent)",
581 (flag_pic > 1) ? "PIC" : "pic");
a260abc9
DE
582 }
583
2bfcf297 584#ifdef XCOFF_DEBUGGING_INFO
9861b0c9 585 if (flag_function_sections && (write_symbols != NO_DEBUG)
2bfcf297 586 && DEFAULT_ABI == ABI_AIX)
9861b0c9
DE
587 {
588 warning ("-ffunction-sections disabled on AIX when debugging");
589 flag_function_sections = 0;
590 }
591
592 if (flag_data_sections && (DEFAULT_ABI == ABI_AIX))
593 {
594 warning ("-fdata-sections not supported on AIX");
595 flag_data_sections = 0;
596 }
2bfcf297 597#endif
9861b0c9 598
38c1f2d7
MM
599 /* Set debug flags */
600 if (rs6000_debug_name)
601 {
bfc79d3b 602 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 603 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 604 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 605 rs6000_debug_stack = 1;
bfc79d3b 606 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
607 rs6000_debug_arg = 1;
608 else
c725bd79 609 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
610 }
611
57ac7be9
AM
612 if (rs6000_traceback_name)
613 {
614 if (! strncmp (rs6000_traceback_name, "full", 4))
615 rs6000_traceback = traceback_full;
616 else if (! strncmp (rs6000_traceback_name, "part", 4))
617 rs6000_traceback = traceback_part;
618 else if (! strncmp (rs6000_traceback_name, "no", 2))
619 rs6000_traceback = traceback_none;
620 else
621 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
622 rs6000_traceback_name);
623 }
624
6fa3f289
ZW
625 /* Set size of long double */
626 rs6000_long_double_type_size = 64;
627 if (rs6000_long_double_size_string)
628 {
629 char *tail;
630 int size = strtol (rs6000_long_double_size_string, &tail, 10);
631 if (*tail != '\0' || (size != 64 && size != 128))
632 error ("Unknown switch -mlong-double-%s",
633 rs6000_long_double_size_string);
634 else
635 rs6000_long_double_type_size = size;
636 }
637
0ac081f6
AH
638 /* Handle -mabi= options. */
639 rs6000_parse_abi_options ();
640
08b57fb3
AH
641 /* Handle -mvrsave= option. */
642 rs6000_parse_vrsave_option ();
643
a3170dc6
AH
644 /* Handle -misel= option. */
645 rs6000_parse_isel_option ();
646
a7ae18e2
AH
647#ifdef SUBTARGET_OVERRIDE_OPTIONS
648 SUBTARGET_OVERRIDE_OPTIONS;
649#endif
650#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
651 SUBSUBTARGET_OVERRIDE_OPTIONS;
652#endif
653
a5c76ee6
ZW
654 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
655 using TARGET_OPTIONS to handle a toggle switch, but we're out of
656 bits in target_flags so TARGET_SWITCHES cannot be used.
657 Assumption here is that rs6000_longcall_switch points into the
658 text of the complete option, rather than being a copy, so we can
659 scan back for the presence or absence of the no- modifier. */
660 if (rs6000_longcall_switch)
661 {
662 const char *base = rs6000_longcall_switch;
663 while (base[-1] != 'm') base--;
664
665 if (*rs6000_longcall_switch != '\0')
666 error ("invalid option `%s'", base);
667 rs6000_default_long_calls = (base[0] != 'n');
668 }
669
c81bebd7 670#ifdef TARGET_REGNAMES
a4f6c312
SS
671 /* If the user desires alternate register names, copy in the
672 alternate names now. */
c81bebd7 673 if (TARGET_REGNAMES)
4e135bdd 674 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
675#endif
676
6fa3f289
ZW
677 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
678 If -maix-struct-return or -msvr4-struct-return was explicitly
679 used, don't override with the ABI default. */
680 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
681 {
682 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
683 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
684 else
685 target_flags |= MASK_AIX_STRUCT_RET;
686 }
687
c8023011
MM
688 /* Register global variables with the garbage collector. */
689 rs6000_add_gc_roots ();
9ebbca7d
GK
690
691 /* Allocate an alias set for register saves & restores from stack. */
692 rs6000_sr_alias_set = new_alias_set ();
693
694 if (TARGET_TOC)
695 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 696
301d03af
RS
697 /* We can only guarantee the availability of DI pseudo-ops when
698 assembling for 64-bit targets. */
ae6c1efd 699 if (!TARGET_64BIT)
301d03af
RS
700 {
701 targetm.asm_out.aligned_op.di = NULL;
702 targetm.asm_out.unaligned_op.di = NULL;
703 }
704
71f123ca
FS
705 /* Arrange to save and restore machine status around nested functions. */
706 init_machine_status = rs6000_init_machine_status;
5248c961 707}
5accd822 708
a3170dc6
AH
709/* Handle -misel= option. */
710static void
711rs6000_parse_isel_option ()
712{
713 if (rs6000_isel_string == 0)
714 return;
715 else if (! strcmp (rs6000_isel_string, "yes"))
716 rs6000_isel = 1;
717 else if (! strcmp (rs6000_isel_string, "no"))
718 rs6000_isel = 0;
719 else
720 error ("unknown -misel= option specified: '%s'",
721 rs6000_isel_string);
722}
723
08b57fb3
AH
724/* Handle -mvrsave= options. */
725static void
726rs6000_parse_vrsave_option ()
727{
728 /* Generate VRSAVE instructions by default. */
729 if (rs6000_altivec_vrsave_string == 0
730 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
731 rs6000_altivec_vrsave = 1;
732 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
733 rs6000_altivec_vrsave = 0;
734 else
735 error ("unknown -mvrsave= option specified: '%s'",
736 rs6000_altivec_vrsave_string);
737}
738
0ac081f6 739/* Handle -mabi= options. */
00b960c7
AH
740static void
741rs6000_parse_abi_options ()
0ac081f6
AH
742{
743 if (rs6000_abi_string == 0)
744 return;
745 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 746 rs6000_altivec_abi = 1;
76a773f3
AH
747 else if (! strcmp (rs6000_abi_string, "no-altivec"))
748 rs6000_altivec_abi = 0;
a3170dc6
AH
749 else if (! strcmp (rs6000_abi_string, "spe"))
750 rs6000_spe_abi = 1;
751 else if (! strcmp (rs6000_abi_string, "no-spe"))
752 rs6000_spe_abi = 0;
0ac081f6 753 else
c725bd79 754 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
755}
756
5accd822
DE
757void
758optimization_options (level, size)
e2c953b6 759 int level ATTRIBUTE_UNUSED;
5accd822
DE
760 int size ATTRIBUTE_UNUSED;
761{
5accd822 762}
3cfa4909
MM
763\f
764/* Do anything needed at the start of the asm file. */
765
766void
767rs6000_file_start (file, default_cpu)
768 FILE *file;
d330fd93 769 const char *default_cpu;
3cfa4909 770{
c4d38ccb 771 size_t i;
3cfa4909 772 char buffer[80];
d330fd93 773 const char *start = buffer;
3cfa4909
MM
774 struct rs6000_cpu_select *ptr;
775
776 if (flag_verbose_asm)
777 {
778 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
779 rs6000_select[0].string = default_cpu;
780
b6a1cbae 781 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
782 {
783 ptr = &rs6000_select[i];
784 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
785 {
786 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
787 start = "";
788 }
789 }
790
b91da81f 791#ifdef USING_ELFOS_H
3cfa4909
MM
792 switch (rs6000_sdata)
793 {
794 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
795 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
796 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
797 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
798 }
799
800 if (rs6000_sdata && g_switch_value)
801 {
802 fprintf (file, "%s -G %d", start, g_switch_value);
803 start = "";
804 }
805#endif
806
807 if (*start == '\0')
949ea356 808 putc ('\n', file);
3cfa4909
MM
809 }
810}
5248c961 811\f
9878760c
RK
812/* Return non-zero if this function is known to have a null epilogue. */
813
814int
815direct_return ()
816{
4697a36c
MM
817 if (reload_completed)
818 {
819 rs6000_stack_t *info = rs6000_stack_info ();
820
821 if (info->first_gp_reg_save == 32
822 && info->first_fp_reg_save == 64
00b960c7 823 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
824 && ! info->lr_save_p
825 && ! info->cr_save_p
00b960c7 826 && info->vrsave_mask == 0
c81fc13e 827 && ! info->push_p)
4697a36c
MM
828 return 1;
829 }
830
831 return 0;
9878760c
RK
832}
833
834/* Returns 1 always. */
835
836int
837any_operand (op, mode)
592696dd 838 rtx op ATTRIBUTE_UNUSED;
296b8152 839 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
840{
841 return 1;
842}
843
a4f6c312 844/* Returns 1 if op is the count register. */
38c1f2d7 845int
a4f6c312 846count_register_operand (op, mode)
592696dd 847 rtx op;
296b8152 848 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
849{
850 if (GET_CODE (op) != REG)
851 return 0;
852
853 if (REGNO (op) == COUNT_REGISTER_REGNUM)
854 return 1;
855
856 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
857 return 1;
858
859 return 0;
860}
861
0ec4e2a8
AH
862/* Returns 1 if op is an altivec register. */
863int
864altivec_register_operand (op, mode)
865 rtx op;
866 enum machine_mode mode ATTRIBUTE_UNUSED;
867{
868
869 return (register_operand (op, mode)
870 && (GET_CODE (op) != REG
871 || REGNO (op) > FIRST_PSEUDO_REGISTER
872 || ALTIVEC_REGNO_P (REGNO (op))));
873}
874
38c1f2d7 875int
a4f6c312 876xer_operand (op, mode)
592696dd 877 rtx op;
296b8152 878 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
879{
880 if (GET_CODE (op) != REG)
881 return 0;
882
9ebbca7d 883 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
884 return 1;
885
802a0058
MM
886 return 0;
887}
888
c859cda6 889/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 890 by such constants completes more quickly. */
c859cda6
DJ
891
892int
893s8bit_cint_operand (op, mode)
894 rtx op;
895 enum machine_mode mode ATTRIBUTE_UNUSED;
896{
897 return ( GET_CODE (op) == CONST_INT
898 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
899}
900
9878760c
RK
901/* Return 1 if OP is a constant that can fit in a D field. */
902
903int
904short_cint_operand (op, mode)
592696dd 905 rtx op;
296b8152 906 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 907{
5f59ecb7
DE
908 return (GET_CODE (op) == CONST_INT
909 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
910}
911
5519a4f9 912/* Similar for an unsigned D field. */
9878760c
RK
913
914int
915u_short_cint_operand (op, mode)
592696dd 916 rtx op;
296b8152 917 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 918{
19684119 919 return (GET_CODE (op) == CONST_INT
c1f11548 920 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
921}
922
dcfedcd0
RK
923/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
924
925int
926non_short_cint_operand (op, mode)
592696dd 927 rtx op;
296b8152 928 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
929{
930 return (GET_CODE (op) == CONST_INT
a7653a2c 931 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
932}
933
2bfcf297
DB
934/* Returns 1 if OP is a CONST_INT that is a positive value
935 and an exact power of 2. */
936
937int
938exact_log2_cint_operand (op, mode)
592696dd 939 rtx op;
2bfcf297
DB
940 enum machine_mode mode ATTRIBUTE_UNUSED;
941{
942 return (GET_CODE (op) == CONST_INT
943 && INTVAL (op) > 0
944 && exact_log2 (INTVAL (op)) >= 0);
945}
946
9878760c
RK
947/* Returns 1 if OP is a register that is not special (i.e., not MQ,
948 ctr, or lr). */
949
950int
cd2b37d9 951gpc_reg_operand (op, mode)
592696dd 952 rtx op;
9878760c
RK
953 enum machine_mode mode;
954{
955 return (register_operand (op, mode)
802a0058 956 && (GET_CODE (op) != REG
9ebbca7d
GK
957 || (REGNO (op) >= ARG_POINTER_REGNUM
958 && !XER_REGNO_P (REGNO (op)))
959 || REGNO (op) < MQ_REGNO));
9878760c
RK
960}
961
962/* Returns 1 if OP is either a pseudo-register or a register denoting a
963 CR field. */
964
965int
966cc_reg_operand (op, mode)
592696dd 967 rtx op;
9878760c
RK
968 enum machine_mode mode;
969{
970 return (register_operand (op, mode)
971 && (GET_CODE (op) != REG
972 || REGNO (op) >= FIRST_PSEUDO_REGISTER
973 || CR_REGNO_P (REGNO (op))));
974}
975
815cdc52
MM
976/* Returns 1 if OP is either a pseudo-register or a register denoting a
977 CR field that isn't CR0. */
978
979int
980cc_reg_not_cr0_operand (op, mode)
592696dd 981 rtx op;
815cdc52
MM
982 enum machine_mode mode;
983{
984 return (register_operand (op, mode)
985 && (GET_CODE (op) != REG
986 || REGNO (op) >= FIRST_PSEUDO_REGISTER
987 || CR_REGNO_NOT_CR0_P (REGNO (op))));
988}
989
a4f6c312
SS
990/* Returns 1 if OP is either a constant integer valid for a D-field or
991 a non-special register. If a register, it must be in the proper
992 mode unless MODE is VOIDmode. */
9878760c
RK
993
994int
995reg_or_short_operand (op, mode)
592696dd 996 rtx op;
9878760c
RK
997 enum machine_mode mode;
998{
f5a28898 999 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1000}
1001
a4f6c312
SS
1002/* Similar, except check if the negation of the constant would be
1003 valid for a D-field. */
9878760c
RK
1004
1005int
1006reg_or_neg_short_operand (op, mode)
592696dd 1007 rtx op;
9878760c
RK
1008 enum machine_mode mode;
1009{
1010 if (GET_CODE (op) == CONST_INT)
1011 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1012
cd2b37d9 1013 return gpc_reg_operand (op, mode);
9878760c
RK
1014}
1015
768070a0
TR
1016/* Returns 1 if OP is either a constant integer valid for a DS-field or
1017 a non-special register. If a register, it must be in the proper
1018 mode unless MODE is VOIDmode. */
1019
1020int
1021reg_or_aligned_short_operand (op, mode)
1022 rtx op;
1023 enum machine_mode mode;
1024{
1025 if (gpc_reg_operand (op, mode))
1026 return 1;
1027 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1028 return 1;
1029
1030 return 0;
1031}
1032
1033
a4f6c312
SS
1034/* Return 1 if the operand is either a register or an integer whose
1035 high-order 16 bits are zero. */
9878760c
RK
1036
1037int
1038reg_or_u_short_operand (op, mode)
592696dd 1039 rtx op;
9878760c
RK
1040 enum machine_mode mode;
1041{
e675f625 1042 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1043}
1044
1045/* Return 1 is the operand is either a non-special register or ANY
1046 constant integer. */
1047
1048int
1049reg_or_cint_operand (op, mode)
592696dd 1050 rtx op;
9878760c
RK
1051 enum machine_mode mode;
1052{
a4f6c312 1053 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1054}
1055
1056/* Return 1 is the operand is either a non-special register or ANY
1057 32-bit signed constant integer. */
1058
1059int
1060reg_or_arith_cint_operand (op, mode)
592696dd 1061 rtx op;
f6bf7de2
DE
1062 enum machine_mode mode;
1063{
a4f6c312
SS
1064 return (gpc_reg_operand (op, mode)
1065 || (GET_CODE (op) == CONST_INT
f6bf7de2 1066#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1067 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1068 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1069#endif
a4f6c312 1070 ));
9878760c
RK
1071}
1072
2bfcf297
DB
1073/* Return 1 is the operand is either a non-special register or a 32-bit
1074 signed constant integer valid for 64-bit addition. */
1075
1076int
1077reg_or_add_cint64_operand (op, mode)
592696dd 1078 rtx op;
2bfcf297
DB
1079 enum machine_mode mode;
1080{
a4f6c312
SS
1081 return (gpc_reg_operand (op, mode)
1082 || (GET_CODE (op) == CONST_INT
a65c591c 1083#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1084 && INTVAL (op) < 0x7fff8000
a65c591c 1085#else
a4f6c312
SS
1086 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1087 < 0x100000000ll)
2bfcf297 1088#endif
a4f6c312 1089 ));
2bfcf297
DB
1090}
1091
1092/* Return 1 is the operand is either a non-special register or a 32-bit
1093 signed constant integer valid for 64-bit subtraction. */
1094
1095int
1096reg_or_sub_cint64_operand (op, mode)
592696dd 1097 rtx op;
2bfcf297
DB
1098 enum machine_mode mode;
1099{
a4f6c312
SS
1100 return (gpc_reg_operand (op, mode)
1101 || (GET_CODE (op) == CONST_INT
a65c591c 1102#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1103 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1104#else
a4f6c312
SS
1105 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1106 < 0x100000000ll)
2bfcf297 1107#endif
a4f6c312 1108 ));
2bfcf297
DB
1109}
1110
9ebbca7d
GK
1111/* Return 1 is the operand is either a non-special register or ANY
1112 32-bit unsigned constant integer. */
1113
1114int
1d328b19 1115reg_or_logical_cint_operand (op, mode)
592696dd 1116 rtx op;
9ebbca7d
GK
1117 enum machine_mode mode;
1118{
1d328b19
GK
1119 if (GET_CODE (op) == CONST_INT)
1120 {
1121 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1122 {
1123 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1124 abort ();
1d328b19
GK
1125
1126 if (INTVAL (op) < 0)
1127 return 0;
1128 }
1129
1130 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1131 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1132 }
1133 else if (GET_CODE (op) == CONST_DOUBLE)
1134 {
1135 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1136 || mode != DImode)
a4f6c312 1137 abort ();
1d328b19
GK
1138
1139 return CONST_DOUBLE_HIGH (op) == 0;
1140 }
1141 else
1142 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1143}
1144
51d3e7d6 1145/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1146
1147int
1148got_operand (op, mode)
592696dd 1149 rtx op;
296b8152 1150 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1151{
1152 return (GET_CODE (op) == SYMBOL_REF
1153 || GET_CODE (op) == CONST
1154 || GET_CODE (op) == LABEL_REF);
1155}
1156
38c1f2d7
MM
1157/* Return 1 if the operand is a simple references that can be loaded via
1158 the GOT (labels involving addition aren't allowed). */
1159
1160int
1161got_no_const_operand (op, mode)
592696dd 1162 rtx op;
296b8152 1163 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1164{
1165 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1166}
1167
4e74d8ec
MM
1168/* Return the number of instructions it takes to form a constant in an
1169 integer register. */
1170
1171static int
1172num_insns_constant_wide (value)
1173 HOST_WIDE_INT value;
1174{
1175 /* signed constant loadable with {cal|addi} */
5f59ecb7 1176 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1177 return 1;
1178
4e74d8ec 1179 /* constant loadable with {cau|addis} */
5f59ecb7 1180 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1181 return 1;
1182
5f59ecb7 1183#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1184 else if (TARGET_POWERPC64)
4e74d8ec 1185 {
a65c591c
DE
1186 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1187 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1188
a65c591c 1189 if (high == 0 || high == -1)
4e74d8ec
MM
1190 return 2;
1191
a65c591c 1192 high >>= 1;
4e74d8ec 1193
a65c591c 1194 if (low == 0)
4e74d8ec 1195 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1196 else
1197 return (num_insns_constant_wide (high)
e396202a 1198 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1199 }
1200#endif
1201
1202 else
1203 return 2;
1204}
1205
1206int
1207num_insns_constant (op, mode)
1208 rtx op;
1209 enum machine_mode mode;
1210{
4e74d8ec 1211 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1212 {
1213#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1214 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1215 && mask64_operand (op, mode))
0d30d435
DE
1216 return 2;
1217 else
1218#endif
1219 return num_insns_constant_wide (INTVAL (op));
1220 }
4e74d8ec 1221
6fc48950
MM
1222 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1223 {
1224 long l;
1225 REAL_VALUE_TYPE rv;
1226
1227 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1228 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1229 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1230 }
1231
47ad8c61 1232 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1233 {
47ad8c61
MM
1234 HOST_WIDE_INT low;
1235 HOST_WIDE_INT high;
1236 long l[2];
1237 REAL_VALUE_TYPE rv;
1238 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1239
47ad8c61
MM
1240 if (mode == VOIDmode || mode == DImode)
1241 {
1242 high = CONST_DOUBLE_HIGH (op);
1243 low = CONST_DOUBLE_LOW (op);
1244 }
1245 else
1246 {
1247 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1248 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1249 high = l[endian];
1250 low = l[1 - endian];
1251 }
4e74d8ec 1252
47ad8c61
MM
1253 if (TARGET_32BIT)
1254 return (num_insns_constant_wide (low)
1255 + num_insns_constant_wide (high));
4e74d8ec
MM
1256
1257 else
47ad8c61 1258 {
e72247f4 1259 if (high == 0 && low >= 0)
47ad8c61
MM
1260 return num_insns_constant_wide (low);
1261
e72247f4 1262 else if (high == -1 && low < 0)
47ad8c61
MM
1263 return num_insns_constant_wide (low);
1264
a260abc9
DE
1265 else if (mask64_operand (op, mode))
1266 return 2;
1267
47ad8c61
MM
1268 else if (low == 0)
1269 return num_insns_constant_wide (high) + 1;
1270
1271 else
1272 return (num_insns_constant_wide (high)
1273 + num_insns_constant_wide (low) + 1);
1274 }
4e74d8ec
MM
1275 }
1276
1277 else
1278 abort ();
1279}
1280
a4f6c312
SS
1281/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1282 register with one instruction per word. We only do this if we can
1283 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1284
1285int
1286easy_fp_constant (op, mode)
592696dd
SS
1287 rtx op;
1288 enum machine_mode mode;
9878760c 1289{
9878760c
RK
1290 if (GET_CODE (op) != CONST_DOUBLE
1291 || GET_MODE (op) != mode
4e74d8ec 1292 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1293 return 0;
1294
a4f6c312 1295 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1296 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1297 && mode != DImode)
b6c9286a
MM
1298 return 1;
1299
a4f6c312 1300 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1301 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1302 return 0;
1303
5ae4759c 1304#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1305 /* Similarly if we are using -mrelocatable, consider all constants
1306 to be hard. */
5ae4759c
MM
1307 if (TARGET_RELOCATABLE)
1308 return 0;
1309#endif
1310
042259f2
DE
1311 if (mode == DFmode)
1312 {
1313 long k[2];
1314 REAL_VALUE_TYPE rv;
1315
1316 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1317 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1318
a65c591c
DE
1319 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1320 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1321 }
4e74d8ec
MM
1322
1323 else if (mode == SFmode)
042259f2
DE
1324 {
1325 long l;
1326 REAL_VALUE_TYPE rv;
1327
1328 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1329 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1330
4e74d8ec 1331 return num_insns_constant_wide (l) == 1;
042259f2 1332 }
4e74d8ec 1333
a260abc9 1334 else if (mode == DImode)
c81fc13e 1335 return ((TARGET_POWERPC64
a260abc9
DE
1336 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1337 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1338
a9098fd0
GK
1339 else if (mode == SImode)
1340 return 1;
4e74d8ec
MM
1341 else
1342 abort ();
9878760c 1343}
8f75773e 1344
69ef87e2
AH
1345/* Return 1 if the operand is a CONST_INT and can be put into a
1346 register with one instruction. */
1347
1348static int
1349easy_vector_constant (op)
1350 rtx op;
1351{
1352 rtx elt;
1353 int units, i;
1354
1355 if (GET_CODE (op) != CONST_VECTOR)
1356 return 0;
1357
1358 units = CONST_VECTOR_NUNITS (op);
1359
1360 /* We can generate 0 easily. Look for that. */
1361 for (i = 0; i < units; ++i)
1362 {
1363 elt = CONST_VECTOR_ELT (op, i);
1364
1365 /* We could probably simplify this by just checking for equality
1366 with CONST0_RTX for the current mode, but let's be safe
1367 instead. */
1368
98ef3137
JJ
1369 switch (GET_CODE (elt))
1370 {
1371 case CONST_INT:
1372 if (INTVAL (elt) != 0)
1373 return 0;
1374 break;
1375 case CONST_DOUBLE:
1376 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1377 return 0;
1378 break;
1379 default:
1380 return 0;
1381 }
69ef87e2
AH
1382 }
1383
1384 /* We could probably generate a few other constants trivially, but
1385 gcc doesn't generate them yet. FIXME later. */
98ef3137 1386 return 1;
69ef87e2
AH
1387}
1388
1389/* Return 1 if the operand is the constant 0. This works for scalars
1390 as well as vectors. */
1391int
1392zero_constant (op, mode)
1393 rtx op;
1394 enum machine_mode mode;
1395{
1396 return op == CONST0_RTX (mode);
1397}
1398
50a0b056
GK
1399/* Return 1 if the operand is 0.0. */
1400int
1401zero_fp_constant (op, mode)
592696dd
SS
1402 rtx op;
1403 enum machine_mode mode;
50a0b056
GK
1404{
1405 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1406}
1407
a4f6c312
SS
1408/* Return 1 if the operand is in volatile memory. Note that during
1409 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1410 volatile memory references. So this function allows us to
1411 recognize volatile references where its safe. */
1412
1413int
1414volatile_mem_operand (op, mode)
592696dd 1415 rtx op;
b6c9286a
MM
1416 enum machine_mode mode;
1417{
1418 if (GET_CODE (op) != MEM)
1419 return 0;
1420
1421 if (!MEM_VOLATILE_P (op))
1422 return 0;
1423
1424 if (mode != GET_MODE (op))
1425 return 0;
1426
1427 if (reload_completed)
1428 return memory_operand (op, mode);
1429
1430 if (reload_in_progress)
1431 return strict_memory_address_p (mode, XEXP (op, 0));
1432
1433 return memory_address_p (mode, XEXP (op, 0));
1434}
1435
97f6e72f 1436/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1437
1438int
97f6e72f 1439offsettable_mem_operand (op, mode)
592696dd 1440 rtx op;
914c2e77
RK
1441 enum machine_mode mode;
1442{
97f6e72f 1443 return ((GET_CODE (op) == MEM)
677a9668 1444 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1445 mode, XEXP (op, 0)));
914c2e77
RK
1446}
1447
9878760c
RK
1448/* Return 1 if the operand is either an easy FP constant (see above) or
1449 memory. */
1450
1451int
1452mem_or_easy_const_operand (op, mode)
592696dd 1453 rtx op;
9878760c
RK
1454 enum machine_mode mode;
1455{
1456 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1457}
1458
1459/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1460 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1461
1462int
1463add_operand (op, mode)
592696dd 1464 rtx op;
9878760c
RK
1465 enum machine_mode mode;
1466{
2bfcf297 1467 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1468 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1469 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1470
1471 return gpc_reg_operand (op, mode);
9878760c
RK
1472}
1473
dcfedcd0
RK
1474/* Return 1 if OP is a constant but not a valid add_operand. */
1475
1476int
1477non_add_cint_operand (op, mode)
592696dd 1478 rtx op;
296b8152 1479 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1480{
1481 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1482 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1483 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1484}
1485
9878760c
RK
1486/* Return 1 if the operand is a non-special register or a constant that
1487 can be used as the operand of an OR or XOR insn on the RS/6000. */
1488
1489int
1490logical_operand (op, mode)
592696dd 1491 rtx op;
9878760c
RK
1492 enum machine_mode mode;
1493{
40501e5f 1494 HOST_WIDE_INT opl, oph;
1d328b19 1495
dfbdccdb
GK
1496 if (gpc_reg_operand (op, mode))
1497 return 1;
1d328b19 1498
dfbdccdb 1499 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1500 {
1501 opl = INTVAL (op) & GET_MODE_MASK (mode);
1502
1503#if HOST_BITS_PER_WIDE_INT <= 32
1504 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1505 return 0;
1506#endif
1507 }
dfbdccdb
GK
1508 else if (GET_CODE (op) == CONST_DOUBLE)
1509 {
1d328b19 1510 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1511 abort ();
1d328b19
GK
1512
1513 opl = CONST_DOUBLE_LOW (op);
1514 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1515 if (oph != 0)
38886f37 1516 return 0;
dfbdccdb
GK
1517 }
1518 else
1519 return 0;
1d328b19 1520
40501e5f
AM
1521 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1522 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1523}
1524
dcfedcd0 1525/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1526 above), but could be split into one. */
dcfedcd0
RK
1527
1528int
1529non_logical_cint_operand (op, mode)
592696dd 1530 rtx op;
5f59ecb7 1531 enum machine_mode mode;
dcfedcd0 1532{
dfbdccdb 1533 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1534 && ! logical_operand (op, mode)
1535 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1536}
1537
19ba8161 1538/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1539 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1540 Reject all ones and all zeros, since these should have been optimized
1541 away and confuse the making of MB and ME. */
1542
1543int
19ba8161 1544mask_operand (op, mode)
592696dd 1545 rtx op;
19ba8161 1546 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1547{
02071907 1548 HOST_WIDE_INT c, lsb;
9878760c 1549
19ba8161
DE
1550 if (GET_CODE (op) != CONST_INT)
1551 return 0;
1552
1553 c = INTVAL (op);
1554
57deb3a1
AM
1555 /* Fail in 64-bit mode if the mask wraps around because the upper
1556 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1557 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1558 return 0;
1559
c5059423
AM
1560 /* We don't change the number of transitions by inverting,
1561 so make sure we start with the LS bit zero. */
1562 if (c & 1)
1563 c = ~c;
1564
1565 /* Reject all zeros or all ones. */
1566 if (c == 0)
9878760c
RK
1567 return 0;
1568
c5059423
AM
1569 /* Find the first transition. */
1570 lsb = c & -c;
1571
1572 /* Invert to look for a second transition. */
1573 c = ~c;
9878760c 1574
c5059423
AM
1575 /* Erase first transition. */
1576 c &= -lsb;
9878760c 1577
c5059423
AM
1578 /* Find the second transition (if any). */
1579 lsb = c & -c;
1580
1581 /* Match if all the bits above are 1's (or c is zero). */
1582 return c == -lsb;
9878760c
RK
1583}
1584
0ba1b2ff
AM
1585/* Return 1 for the PowerPC64 rlwinm corner case. */
1586
1587int
1588mask_operand_wrap (op, mode)
1589 rtx op;
1590 enum machine_mode mode ATTRIBUTE_UNUSED;
1591{
1592 HOST_WIDE_INT c, lsb;
1593
1594 if (GET_CODE (op) != CONST_INT)
1595 return 0;
1596
1597 c = INTVAL (op);
1598
1599 if ((c & 0x80000001) != 0x80000001)
1600 return 0;
1601
1602 c = ~c;
1603 if (c == 0)
1604 return 0;
1605
1606 lsb = c & -c;
1607 c = ~c;
1608 c &= -lsb;
1609 lsb = c & -c;
1610 return c == -lsb;
1611}
1612
a260abc9
DE
1613/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1614 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1615 Reject all zeros, since zero should have been optimized away and
1616 confuses the making of MB and ME. */
9878760c
RK
1617
1618int
a260abc9 1619mask64_operand (op, mode)
592696dd 1620 rtx op;
0ba1b2ff 1621 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1622{
1623 if (GET_CODE (op) == CONST_INT)
1624 {
02071907 1625 HOST_WIDE_INT c, lsb;
a260abc9 1626
c5059423 1627 c = INTVAL (op);
a260abc9 1628
0ba1b2ff 1629 /* Reject all zeros. */
c5059423 1630 if (c == 0)
e2c953b6
DE
1631 return 0;
1632
0ba1b2ff
AM
1633 /* We don't change the number of transitions by inverting,
1634 so make sure we start with the LS bit zero. */
1635 if (c & 1)
1636 c = ~c;
1637
c5059423
AM
1638 /* Find the transition, and check that all bits above are 1's. */
1639 lsb = c & -c;
1640 return c == -lsb;
e2c953b6 1641 }
0ba1b2ff
AM
1642 return 0;
1643}
1644
1645/* Like mask64_operand, but allow up to three transitions. This
1646 predicate is used by insn patterns that generate two rldicl or
1647 rldicr machine insns. */
1648
1649int
1650mask64_2_operand (op, mode)
1651 rtx op;
1652 enum machine_mode mode ATTRIBUTE_UNUSED;
1653{
1654 if (GET_CODE (op) == CONST_INT)
a260abc9 1655 {
0ba1b2ff 1656 HOST_WIDE_INT c, lsb;
a260abc9 1657
0ba1b2ff 1658 c = INTVAL (op);
a260abc9 1659
0ba1b2ff
AM
1660 /* Disallow all zeros. */
1661 if (c == 0)
1662 return 0;
a260abc9 1663
0ba1b2ff
AM
1664 /* We don't change the number of transitions by inverting,
1665 so make sure we start with the LS bit zero. */
1666 if (c & 1)
1667 c = ~c;
a260abc9 1668
0ba1b2ff
AM
1669 /* Find the first transition. */
1670 lsb = c & -c;
a260abc9 1671
0ba1b2ff
AM
1672 /* Invert to look for a second transition. */
1673 c = ~c;
1674
1675 /* Erase first transition. */
1676 c &= -lsb;
1677
1678 /* Find the second transition. */
1679 lsb = c & -c;
1680
1681 /* Invert to look for a third transition. */
1682 c = ~c;
1683
1684 /* Erase second transition. */
1685 c &= -lsb;
1686
1687 /* Find the third transition (if any). */
1688 lsb = c & -c;
1689
1690 /* Match if all the bits above are 1's (or c is zero). */
1691 return c == -lsb;
1692 }
1693 return 0;
1694}
1695
1696/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1697 implement ANDing by the mask IN. */
1698void
1699build_mask64_2_operands (in, out)
1700 rtx in;
1701 rtx *out;
1702{
1703#if HOST_BITS_PER_WIDE_INT >= 64
1704 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1705 int shift;
1706
1707 if (GET_CODE (in) != CONST_INT)
1708 abort ();
1709
1710 c = INTVAL (in);
1711 if (c & 1)
1712 {
1713 /* Assume c initially something like 0x00fff000000fffff. The idea
1714 is to rotate the word so that the middle ^^^^^^ group of zeros
1715 is at the MS end and can be cleared with an rldicl mask. We then
1716 rotate back and clear off the MS ^^ group of zeros with a
1717 second rldicl. */
1718 c = ~c; /* c == 0xff000ffffff00000 */
1719 lsb = c & -c; /* lsb == 0x0000000000100000 */
1720 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1721 c = ~c; /* c == 0x00fff000000fffff */
1722 c &= -lsb; /* c == 0x00fff00000000000 */
1723 lsb = c & -c; /* lsb == 0x0000100000000000 */
1724 c = ~c; /* c == 0xff000fffffffffff */
1725 c &= -lsb; /* c == 0xff00000000000000 */
1726 shift = 0;
1727 while ((lsb >>= 1) != 0)
1728 shift++; /* shift == 44 on exit from loop */
1729 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1730 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1731 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1732 }
1733 else
0ba1b2ff
AM
1734 {
1735 /* Assume c initially something like 0xff000f0000000000. The idea
1736 is to rotate the word so that the ^^^ middle group of zeros
1737 is at the LS end and can be cleared with an rldicr mask. We then
1738 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1739 a second rldicr. */
1740 lsb = c & -c; /* lsb == 0x0000010000000000 */
1741 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1742 c = ~c; /* c == 0x00fff0ffffffffff */
1743 c &= -lsb; /* c == 0x00fff00000000000 */
1744 lsb = c & -c; /* lsb == 0x0000100000000000 */
1745 c = ~c; /* c == 0xff000fffffffffff */
1746 c &= -lsb; /* c == 0xff00000000000000 */
1747 shift = 0;
1748 while ((lsb >>= 1) != 0)
1749 shift++; /* shift == 44 on exit from loop */
1750 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1751 m1 >>= shift; /* m1 == 0x0000000000000fff */
1752 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1753 }
1754
1755 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1756 masks will be all 1's. We are guaranteed more than one transition. */
1757 out[0] = GEN_INT (64 - shift);
1758 out[1] = GEN_INT (m1);
1759 out[2] = GEN_INT (shift);
1760 out[3] = GEN_INT (m2);
1761#else
1762 abort ();
1763#endif
a260abc9
DE
1764}
1765
1766/* Return 1 if the operand is either a non-special register or a constant
1767 that can be used as the operand of a PowerPC64 logical AND insn. */
1768
1769int
1770and64_operand (op, mode)
592696dd 1771 rtx op;
9878760c
RK
1772 enum machine_mode mode;
1773{
a4f6c312 1774 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1775 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1776
1777 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1778}
1779
0ba1b2ff
AM
1780/* Like the above, but also match constants that can be implemented
1781 with two rldicl or rldicr insns. */
1782
1783int
1784and64_2_operand (op, mode)
1785 rtx op;
1786 enum machine_mode mode;
1787{
1788 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1789 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1790
1791 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1792}
1793
a260abc9
DE
1794/* Return 1 if the operand is either a non-special register or a
1795 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1796
1797int
a260abc9 1798and_operand (op, mode)
592696dd 1799 rtx op;
a260abc9 1800 enum machine_mode mode;
dcfedcd0 1801{
a4f6c312 1802 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1803 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1804
1805 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1806}
1807
9878760c
RK
1808/* Return 1 if the operand is a general register or memory operand. */
1809
1810int
1811reg_or_mem_operand (op, mode)
592696dd
SS
1812 rtx op;
1813 enum machine_mode mode;
9878760c 1814{
b6c9286a
MM
1815 return (gpc_reg_operand (op, mode)
1816 || memory_operand (op, mode)
1817 || volatile_mem_operand (op, mode));
9878760c
RK
1818}
1819
a7a813f7 1820/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1821 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1822 instruction. */
1823
1824int
1825lwa_operand (op, mode)
592696dd
SS
1826 rtx op;
1827 enum machine_mode mode;
a7a813f7
RK
1828{
1829 rtx inner = op;
1830
1831 if (reload_completed && GET_CODE (inner) == SUBREG)
1832 inner = SUBREG_REG (inner);
1833
1834 return gpc_reg_operand (inner, mode)
1835 || (memory_operand (inner, mode)
1836 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1837 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1838 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1839 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1840 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1841}
1842
cc4d5fec
JH
1843/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1844
1845int
1846symbol_ref_operand (op, mode)
1847 rtx op;
1848 enum machine_mode mode;
1849{
1850 if (mode != VOIDmode && GET_MODE (op) != mode)
1851 return 0;
1852
1853 return (GET_CODE (op) == SYMBOL_REF);
1854}
1855
9878760c 1856/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1857 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1858
1859int
1860call_operand (op, mode)
592696dd 1861 rtx op;
9878760c
RK
1862 enum machine_mode mode;
1863{
1864 if (mode != VOIDmode && GET_MODE (op) != mode)
1865 return 0;
1866
1867 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1868 || (GET_CODE (op) == REG
1869 && (REGNO (op) == LINK_REGISTER_REGNUM
1870 || REGNO (op) == COUNT_REGISTER_REGNUM
1871 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1872}
1873
2af3d377 1874/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1875 this file and the function is not weakly defined. */
2af3d377
RK
1876
1877int
1878current_file_function_operand (op, mode)
592696dd 1879 rtx op;
296b8152 1880 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1881{
1882 return (GET_CODE (op) == SYMBOL_REF
1883 && (SYMBOL_REF_FLAG (op)
8f1b829e 1884 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1885 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1886}
1887
9878760c
RK
1888/* Return 1 if this operand is a valid input for a move insn. */
1889
1890int
1891input_operand (op, mode)
592696dd 1892 rtx op;
9878760c
RK
1893 enum machine_mode mode;
1894{
eb4e8003 1895 /* Memory is always valid. */
9878760c
RK
1896 if (memory_operand (op, mode))
1897 return 1;
1898
34792e82 1899 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1900 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1901 return 1;
1902
eb4e8003
RK
1903 /* For floating-point, easy constants are valid. */
1904 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1905 && CONSTANT_P (op)
1906 && easy_fp_constant (op, mode))
1907 return 1;
1908
4e74d8ec
MM
1909 /* Allow any integer constant. */
1910 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1911 && (GET_CODE (op) == CONST_INT
e675f625 1912 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1913 return 1;
1914
eb4e8003
RK
1915 /* For floating-point or multi-word mode, the only remaining valid type
1916 is a register. */
9878760c
RK
1917 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1918 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1919 return register_operand (op, mode);
9878760c 1920
88fe15a1
RK
1921 /* The only cases left are integral modes one word or smaller (we
1922 do not get called for MODE_CC values). These can be in any
1923 register. */
1924 if (register_operand (op, mode))
a8b3aeda 1925 return 1;
88fe15a1 1926
84cf9dda 1927 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 1928 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
1929 return 1;
1930
9ebbca7d
GK
1931 /* A constant pool expression (relative to the TOC) is valid */
1932 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
1933 return 1;
1934
88228c4b
MM
1935 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1936 to be valid. */
f607bc57 1937 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
1938 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1939 && small_data_operand (op, Pmode))
1940 return 1;
1941
042259f2 1942 return 0;
9878760c 1943}
7509c759 1944
a4f6c312 1945/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
1946
1947int
1948small_data_operand (op, mode)
296b8152
KG
1949 rtx op ATTRIBUTE_UNUSED;
1950 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 1951{
38c1f2d7 1952#if TARGET_ELF
5f59ecb7 1953 rtx sym_ref;
7509c759 1954
d9407988 1955 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 1956 return 0;
a54d04b7 1957
f607bc57 1958 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
1959 return 0;
1960
88228c4b
MM
1961 if (GET_CODE (op) == SYMBOL_REF)
1962 sym_ref = op;
1963
1964 else if (GET_CODE (op) != CONST
1965 || GET_CODE (XEXP (op, 0)) != PLUS
1966 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
1967 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
1968 return 0;
1969
88228c4b 1970 else
dbf55e53
MM
1971 {
1972 rtx sum = XEXP (op, 0);
1973 HOST_WIDE_INT summand;
1974
1975 /* We have to be careful here, because it is the referenced address
1976 that must be 32k from _SDA_BASE_, not just the symbol. */
1977 summand = INTVAL (XEXP (sum, 1));
1978 if (summand < 0 || summand > g_switch_value)
1979 return 0;
1980
1981 sym_ref = XEXP (sum, 0);
1982 }
88228c4b
MM
1983
1984 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
1985 return 0;
1986
1987 return 1;
d9407988
MM
1988
1989#else
1990 return 0;
1991#endif
7509c759 1992}
9ebbca7d
GK
1993\f
1994static int
1995constant_pool_expr_1 (op, have_sym, have_toc)
1996 rtx op;
1997 int *have_sym;
1998 int *have_toc;
1999{
2000 switch (GET_CODE(op))
2001 {
2002 case SYMBOL_REF:
a4f6c312
SS
2003 if (CONSTANT_POOL_ADDRESS_P (op))
2004 {
2005 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2006 {
2007 *have_sym = 1;
2008 return 1;
2009 }
2010 else
2011 return 0;
2012 }
2013 else if (! strcmp (XSTR (op, 0), toc_label_name))
2014 {
2015 *have_toc = 1;
2016 return 1;
2017 }
2018 else
2019 return 0;
9ebbca7d
GK
2020 case PLUS:
2021 case MINUS:
c1f11548
DE
2022 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2023 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2024 case CONST:
a4f6c312 2025 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2026 case CONST_INT:
a4f6c312 2027 return 1;
9ebbca7d 2028 default:
a4f6c312 2029 return 0;
9ebbca7d
GK
2030 }
2031}
2032
2033int
2034constant_pool_expr_p (op)
2035 rtx op;
2036{
2037 int have_sym = 0;
2038 int have_toc = 0;
2039 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2040}
2041
2042int
2043toc_relative_expr_p (op)
2044 rtx op;
2045{
2046 int have_sym = 0;
2047 int have_toc = 0;
2048 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2049}
2050
2051/* Try machine-dependent ways of modifying an illegitimate address
2052 to be legitimate. If we find one, return the new, valid address.
2053 This is used from only one place: `memory_address' in explow.c.
2054
a4f6c312
SS
2055 OLDX is the address as it was before break_out_memory_refs was
2056 called. In some cases it is useful to look at this to decide what
2057 needs to be done.
9ebbca7d 2058
a4f6c312 2059 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2060
a4f6c312
SS
2061 It is always safe for this function to do nothing. It exists to
2062 recognize opportunities to optimize the output.
9ebbca7d
GK
2063
2064 On RS/6000, first check for the sum of a register with a constant
2065 integer that is out of range. If so, generate code to add the
2066 constant with the low-order 16 bits masked to the register and force
2067 this result into another register (this can be done with `cau').
2068 Then generate an address of REG+(CONST&0xffff), allowing for the
2069 possibility of bit 16 being a one.
2070
2071 Then check for the sum of a register and something not constant, try to
2072 load the other things into a register and return the sum. */
2073rtx
2074rs6000_legitimize_address (x, oldx, mode)
2075 rtx x;
2076 rtx oldx ATTRIBUTE_UNUSED;
2077 enum machine_mode mode;
0ac081f6 2078{
9ebbca7d
GK
2079 if (GET_CODE (x) == PLUS
2080 && GET_CODE (XEXP (x, 0)) == REG
2081 && GET_CODE (XEXP (x, 1)) == CONST_INT
2082 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2083 {
2084 HOST_WIDE_INT high_int, low_int;
2085 rtx sum;
a65c591c
DE
2086 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2087 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2088 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2089 GEN_INT (high_int)), 0);
2090 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2091 }
2092 else if (GET_CODE (x) == PLUS
2093 && GET_CODE (XEXP (x, 0)) == REG
2094 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2095 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2096 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2097 || TARGET_POWERPC64
2098 || mode != DFmode)
9ebbca7d
GK
2099 && (TARGET_POWERPC64 || mode != DImode)
2100 && mode != TImode)
2101 {
2102 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2103 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2104 }
0ac081f6
AH
2105 else if (ALTIVEC_VECTOR_MODE (mode))
2106 {
2107 rtx reg;
2108
2109 /* Make sure both operands are registers. */
2110 if (GET_CODE (x) == PLUS)
9f85ed45 2111 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2112 force_reg (Pmode, XEXP (x, 1)));
2113
2114 reg = force_reg (Pmode, x);
2115 return reg;
2116 }
a3170dc6
AH
2117 else if (SPE_VECTOR_MODE (mode))
2118 {
2119 /* We accept [reg + reg] and [reg + OFFSET]. */
2120
2121 if (GET_CODE (x) == PLUS)
2122 {
2123 rtx op1 = XEXP (x, 0);
2124 rtx op2 = XEXP (x, 1);
2125
2126 op1 = force_reg (Pmode, op1);
2127
2128 if (GET_CODE (op2) != REG
2129 && (GET_CODE (op2) != CONST_INT
2130 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2131 op2 = force_reg (Pmode, op2);
2132
2133 return gen_rtx_PLUS (Pmode, op1, op2);
2134 }
2135
2136 return force_reg (Pmode, x);
2137 }
9ebbca7d
GK
2138 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2139 && GET_CODE (x) != CONST_INT
2140 && GET_CODE (x) != CONST_DOUBLE
2141 && CONSTANT_P (x)
6ac7bf2c
GK
2142 && GET_MODE_NUNITS (mode) == 1
2143 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2144 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2145 {
2146 rtx reg = gen_reg_rtx (Pmode);
2147 emit_insn (gen_elf_high (reg, (x)));
2148 return gen_rtx_LO_SUM (Pmode, reg, (x));
2149 }
ee890fe2
SS
2150 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2151 && ! flag_pic
2152 && GET_CODE (x) != CONST_INT
2153 && GET_CODE (x) != CONST_DOUBLE
2154 && CONSTANT_P (x)
a3170dc6 2155 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2156 && mode != DImode
2157 && mode != TImode)
2158 {
2159 rtx reg = gen_reg_rtx (Pmode);
2160 emit_insn (gen_macho_high (reg, (x)));
2161 return gen_rtx_LO_SUM (Pmode, reg, (x));
2162 }
9ebbca7d
GK
2163 else if (TARGET_TOC
2164 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2165 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2166 {
2167 return create_TOC_reference (x);
2168 }
2169 else
2170 return NULL_RTX;
2171}
258bfae2 2172
24ea750e
DJ
2173/* The convention appears to be to define this wherever it is used.
2174 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2175 is now used here. */
2176#ifndef REG_MODE_OK_FOR_BASE_P
2177#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2178#endif
2179
2180/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2181 replace the input X, or the original X if no replacement is called for.
2182 The output parameter *WIN is 1 if the calling macro should goto WIN,
2183 0 if it should not.
2184
2185 For RS/6000, we wish to handle large displacements off a base
2186 register by splitting the addend across an addiu/addis and the mem insn.
2187 This cuts number of extra insns needed from 3 to 1.
2188
2189 On Darwin, we use this to generate code for floating point constants.
2190 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2191 The Darwin code is inside #if TARGET_MACHO because only then is
2192 machopic_function_base_name() defined. */
2193rtx
2194rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2195 rtx x;
2196 enum machine_mode mode;
2197 int opnum;
2198 int type;
2199 int ind_levels ATTRIBUTE_UNUSED;
2200 int *win;
2201{
2202 /* We must recognize output that we have already generated ourselves. */
2203 if (GET_CODE (x) == PLUS
2204 && GET_CODE (XEXP (x, 0)) == PLUS
2205 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2206 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2207 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2208 {
2209 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2210 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2211 opnum, (enum reload_type)type);
2212 *win = 1;
2213 return x;
2214 }
3deb2758 2215
24ea750e
DJ
2216#if TARGET_MACHO
2217 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2218 && GET_CODE (x) == LO_SUM
2219 && GET_CODE (XEXP (x, 0)) == PLUS
2220 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2221 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2222 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2223 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2224 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2225 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2226 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2227 {
2228 /* Result of previous invocation of this function on Darwin
6f317ef3 2229 floating point constant. */
24ea750e
DJ
2230 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2231 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2232 opnum, (enum reload_type)type);
2233 *win = 1;
2234 return x;
2235 }
2236#endif
2237 if (GET_CODE (x) == PLUS
2238 && GET_CODE (XEXP (x, 0)) == REG
2239 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2240 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2241 && GET_CODE (XEXP (x, 1)) == CONST_INT
a3170dc6 2242 && !SPE_VECTOR_MODE (mode)
78c875e8 2243 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2244 {
2245 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2246 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2247 HOST_WIDE_INT high
2248 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2249
2250 /* Check for 32-bit overflow. */
2251 if (high + low != val)
2252 {
2253 *win = 0;
2254 return x;
2255 }
2256
2257 /* Reload the high part into a base reg; leave the low part
2258 in the mem directly. */
2259
2260 x = gen_rtx_PLUS (GET_MODE (x),
2261 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2262 GEN_INT (high)),
2263 GEN_INT (low));
2264
2265 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2266 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2267 opnum, (enum reload_type)type);
2268 *win = 1;
2269 return x;
2270 }
2271#if TARGET_MACHO
2272 if (GET_CODE (x) == SYMBOL_REF
2273 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2274 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2275 && flag_pic)
2276 {
2277 /* Darwin load of floating point constant. */
2278 rtx offset = gen_rtx (CONST, Pmode,
2279 gen_rtx (MINUS, Pmode, x,
2280 gen_rtx (SYMBOL_REF, Pmode,
2281 machopic_function_base_name ())));
2282 x = gen_rtx (LO_SUM, GET_MODE (x),
2283 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2284 gen_rtx (HIGH, Pmode, offset)), offset);
2285 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2286 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2287 opnum, (enum reload_type)type);
2288 *win = 1;
2289 return x;
2290 }
2291#endif
2292 if (TARGET_TOC
c1f11548
DE
2293 && CONSTANT_POOL_EXPR_P (x)
2294 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2295 {
2296 (x) = create_TOC_reference (x);
2297 *win = 1;
2298 return x;
2299 }
2300 *win = 0;
2301 return x;
2302}
2303
258bfae2
FS
2304/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2305 that is a valid memory address for an instruction.
2306 The MODE argument is the machine mode for the MEM expression
2307 that wants to use this address.
2308
2309 On the RS/6000, there are four valid address: a SYMBOL_REF that
2310 refers to a constant pool entry of an address (or the sum of it
2311 plus a constant), a short (16-bit signed) constant plus a register,
2312 the sum of two registers, or a register indirect, possibly with an
2313 auto-increment. For DFmode and DImode with an constant plus register,
2314 we must ensure that both words are addressable or PowerPC64 with offset
2315 word aligned.
2316
2317 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2318 32-bit DImode, TImode), indexed addressing cannot be used because
2319 adjacent memory cells are accessed by adding word-sized offsets
2320 during assembly output. */
2321int
2322rs6000_legitimate_address (mode, x, reg_ok_strict)
2323 enum machine_mode mode;
2324 rtx x;
2325 int reg_ok_strict;
2326{
2327 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2328 return 1;
2329 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2330 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2331 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2332 && TARGET_UPDATE
2333 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2334 return 1;
2335 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2336 return 1;
2337 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2338 return 1;
2339 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2340 if (! reg_ok_strict
2341 && GET_CODE (x) == PLUS
2342 && GET_CODE (XEXP (x, 0)) == REG
2343 && XEXP (x, 0) == virtual_stack_vars_rtx
2344 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2345 return 1;
2346 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2347 return 1;
2348 if (mode != TImode
a3170dc6
AH
2349 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2350 || TARGET_POWERPC64
2351 || mode != DFmode)
258bfae2
FS
2352 && (TARGET_POWERPC64 || mode != DImode)
2353 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2354 return 1;
2355 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2356 return 1;
2357 return 0;
2358}
fb4d4348 2359\f
a4f6c312
SS
2360/* Try to output insns to set TARGET equal to the constant C if it can
2361 be done in less than N insns. Do all computations in MODE.
2362 Returns the place where the output has been placed if it can be
2363 done and the insns have been emitted. If it would take more than N
2364 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2365
2366rtx
2367rs6000_emit_set_const (dest, mode, source, n)
2368 rtx dest, source;
2369 enum machine_mode mode;
2370 int n ATTRIBUTE_UNUSED;
2371{
af8cb5c5 2372 rtx result, insn, set;
2bfcf297
DB
2373 HOST_WIDE_INT c0, c1;
2374
af8cb5c5 2375 if (mode == QImode || mode == HImode)
2bfcf297
DB
2376 {
2377 if (dest == NULL)
2378 dest = gen_reg_rtx (mode);
2379 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2380 return dest;
2381 }
af8cb5c5 2382 else if (mode == SImode)
2bfcf297 2383 {
af8cb5c5
DE
2384 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2385
2386 emit_insn (gen_rtx_SET (VOIDmode, result,
2387 GEN_INT (INTVAL (source)
2388 & (~ (HOST_WIDE_INT) 0xffff))));
2389 emit_insn (gen_rtx_SET (VOIDmode, dest,
2390 gen_rtx_IOR (SImode, result,
2391 GEN_INT (INTVAL (source) & 0xffff))));
2392 result = dest;
2bfcf297 2393 }
af8cb5c5 2394 else if (mode == DImode)
2bfcf297 2395 {
af8cb5c5
DE
2396 if (GET_CODE (source) == CONST_INT)
2397 {
2398 c0 = INTVAL (source);
2399 c1 = -(c0 < 0);
2400 }
2401 else if (GET_CODE (source) == CONST_DOUBLE)
2402 {
2bfcf297 2403#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
2404 c0 = CONST_DOUBLE_LOW (source);
2405 c1 = -(c0 < 0);
2bfcf297 2406#else
af8cb5c5
DE
2407 c0 = CONST_DOUBLE_LOW (source);
2408 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 2409#endif
af8cb5c5
DE
2410 }
2411 else
2412 abort ();
2413
2414 result = rs6000_emit_set_long_const (dest, c0, c1);
2bfcf297
DB
2415 }
2416 else
a4f6c312 2417 abort ();
2bfcf297 2418
af8cb5c5
DE
2419 insn = get_last_insn ();
2420 set = single_set (insn);
2421 if (! CONSTANT_P (SET_SRC (set)))
2422 set_unique_reg_note (insn, REG_EQUAL, source);
2423
2424 return result;
2bfcf297
DB
2425}
2426
2427/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2428 fall back to a straight forward decomposition. We do this to avoid
2429 exponential run times encountered when looking for longer sequences
2430 with rs6000_emit_set_const. */
2431static rtx
2432rs6000_emit_set_long_const (dest, c1, c2)
2433 rtx dest;
2434 HOST_WIDE_INT c1, c2;
2435{
2436 if (!TARGET_POWERPC64)
2437 {
2438 rtx operand1, operand2;
2439
2440 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2441 DImode);
2442 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2443 DImode);
2444 emit_move_insn (operand1, GEN_INT (c1));
2445 emit_move_insn (operand2, GEN_INT (c2));
2446 }
2447 else
2448 {
bc06712d 2449 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2450
bc06712d
TR
2451 ud1 = c1 & 0xffff;
2452 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2453#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2454 c2 = c1 >> 32;
2bfcf297 2455#endif
bc06712d
TR
2456 ud3 = c2 & 0xffff;
2457 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2458
bc06712d
TR
2459 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2460 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2461 {
bc06712d
TR
2462 if (ud1 & 0x8000)
2463 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2464 else
2465 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2466 }
2bfcf297 2467
bc06712d
TR
2468 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2469 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2470 {
bc06712d
TR
2471 if (ud2 & 0x8000)
2472 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2473 - 0x80000000));
252b88f7 2474 else
bc06712d
TR
2475 emit_move_insn (dest, GEN_INT (ud2 << 16));
2476 if (ud1 != 0)
2477 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2478 }
bc06712d
TR
2479 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2480 || (ud4 == 0 && ! (ud3 & 0x8000)))
2481 {
2482 if (ud3 & 0x8000)
2483 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2484 - 0x80000000));
2485 else
2486 emit_move_insn (dest, GEN_INT (ud3 << 16));
2487
2488 if (ud2 != 0)
2489 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2490 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2491 if (ud1 != 0)
2492 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2493 }
2494 else
2495 {
2496 if (ud4 & 0x8000)
2497 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2498 - 0x80000000));
2499 else
2500 emit_move_insn (dest, GEN_INT (ud4 << 16));
2501
2502 if (ud3 != 0)
2503 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2504
bc06712d
TR
2505 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2506 if (ud2 != 0)
2507 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2508 GEN_INT (ud2 << 16)));
2509 if (ud1 != 0)
2510 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2511 }
2512 }
2bfcf297
DB
2513 return dest;
2514}
2515
fb4d4348
GK
2516/* Emit a move from SOURCE to DEST in mode MODE. */
2517void
2518rs6000_emit_move (dest, source, mode)
2519 rtx dest;
2520 rtx source;
2521 enum machine_mode mode;
2522{
2523 rtx operands[2];
2524 operands[0] = dest;
2525 operands[1] = source;
2526
2527 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2528 if (GET_CODE (operands[1]) == CONST_DOUBLE
2529 && ! FLOAT_MODE_P (mode)
2530 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2531 {
2532 /* FIXME. This should never happen. */
2533 /* Since it seems that it does, do the safe thing and convert
2534 to a CONST_INT. */
2496c7bd 2535 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2536 }
2537 if (GET_CODE (operands[1]) == CONST_DOUBLE
2538 && ! FLOAT_MODE_P (mode)
2539 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2540 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2541 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2542 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2543 abort ();
c9e8cb32
DD
2544
2545 /* Check if GCC is setting up a block move that will end up using FP
2546 registers as temporaries. We must make sure this is acceptable. */
2547 if (GET_CODE (operands[0]) == MEM
2548 && GET_CODE (operands[1]) == MEM
2549 && mode == DImode
41543739
GK
2550 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2551 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2552 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2553 ? 32 : MEM_ALIGN (operands[0])))
2554 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2555 ? 32
2556 : MEM_ALIGN (operands[1]))))
2557 && ! MEM_VOLATILE_P (operands [0])
2558 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2559 {
41543739
GK
2560 emit_move_insn (adjust_address (operands[0], SImode, 0),
2561 adjust_address (operands[1], SImode, 0));
2562 emit_move_insn (adjust_address (operands[0], SImode, 4),
2563 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2564 return;
2565 }
fb4d4348
GK
2566
2567 if (! no_new_pseudos && GET_CODE (operands[0]) != REG)
2568 operands[1] = force_reg (mode, operands[1]);
a9098fd0 2569
a3170dc6
AH
2570 if (mode == SFmode && ! TARGET_POWERPC
2571 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2572 && GET_CODE (operands[0]) == MEM)
fb4d4348 2573 {
ffc14f31
GK
2574 int regnum;
2575
2576 if (reload_in_progress || reload_completed)
2577 regnum = true_regnum (operands[1]);
2578 else if (GET_CODE (operands[1]) == REG)
2579 regnum = REGNO (operands[1]);
2580 else
2581 regnum = -1;
fb4d4348
GK
2582
2583 /* If operands[1] is a register, on POWER it may have
2584 double-precision data in it, so truncate it to single
2585 precision. */
2586 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2587 {
2588 rtx newreg;
2589 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2590 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2591 operands[1] = newreg;
2592 }
2593 }
2594
a9098fd0
GK
2595 /* Handle the case where reload calls us with an invalid address;
2596 and the case of CONSTANT_P_RTX. */
16861f33 2597 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2598 && (! general_operand (operands[1], mode)
2599 || ! nonimmediate_operand (operands[0], mode)
2600 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2601 {
2602 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2603 return;
2604 }
a9098fd0 2605
fb4d4348
GK
2606 /* FIXME: In the long term, this switch statement should go away
2607 and be replaced by a sequence of tests based on things like
2608 mode == Pmode. */
2609 switch (mode)
2610 {
2611 case HImode:
2612 case QImode:
2613 if (CONSTANT_P (operands[1])
2614 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2615 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2616 break;
2617
06f4e019 2618 case TFmode:
fb4d4348
GK
2619 case DFmode:
2620 case SFmode:
2621 if (CONSTANT_P (operands[1])
2622 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2623 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2624 break;
2625
0ac081f6
AH
2626 case V16QImode:
2627 case V8HImode:
2628 case V4SFmode:
2629 case V4SImode:
a3170dc6
AH
2630 case V4HImode:
2631 case V2SFmode:
2632 case V2SImode:
69ef87e2
AH
2633 if (CONSTANT_P (operands[1])
2634 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2635 operands[1] = force_const_mem (mode, operands[1]);
2636 break;
2637
fb4d4348 2638 case SImode:
a9098fd0 2639 case DImode:
fb4d4348
GK
2640 /* Use default pattern for address of ELF small data */
2641 if (TARGET_ELF
a9098fd0 2642 && mode == Pmode
f607bc57 2643 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2644 && (GET_CODE (operands[1]) == SYMBOL_REF
2645 || GET_CODE (operands[1]) == CONST)
2646 && small_data_operand (operands[1], mode))
fb4d4348
GK
2647 {
2648 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2649 return;
2650 }
2651
f607bc57 2652 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2653 && mode == Pmode && mode == SImode
2654 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2655 {
2656 emit_insn (gen_movsi_got (operands[0], operands[1]));
2657 return;
2658 }
2659
ee890fe2
SS
2660 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2661 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2662 && mode == Pmode
fb4d4348
GK
2663 && CONSTANT_P (operands[1])
2664 && GET_CODE (operands[1]) != HIGH
2665 && GET_CODE (operands[1]) != CONST_INT)
2666 {
a9098fd0 2667 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2668
2669 /* If this is a function address on -mcall-aixdesc,
2670 convert it to the address of the descriptor. */
2671 if (DEFAULT_ABI == ABI_AIX
2672 && GET_CODE (operands[1]) == SYMBOL_REF
2673 && XSTR (operands[1], 0)[0] == '.')
2674 {
2675 const char *name = XSTR (operands[1], 0);
2676 rtx new_ref;
2677 while (*name == '.')
2678 name++;
2679 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2680 CONSTANT_POOL_ADDRESS_P (new_ref)
2681 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2682 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2683 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2684 operands[1] = new_ref;
2685 }
7509c759 2686
ee890fe2
SS
2687 if (DEFAULT_ABI == ABI_DARWIN)
2688 {
2689 emit_insn (gen_macho_high (target, operands[1]));
2690 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2691 return;
2692 }
2693
fb4d4348
GK
2694 emit_insn (gen_elf_high (target, operands[1]));
2695 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2696 return;
2697 }
2698
a9098fd0
GK
2699 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2700 and we have put it in the TOC, we just need to make a TOC-relative
2701 reference to it. */
2702 if (TARGET_TOC
2703 && GET_CODE (operands[1]) == SYMBOL_REF
2704 && CONSTANT_POOL_EXPR_P (operands[1])
2705 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2706 get_pool_mode (operands[1])))
fb4d4348 2707 {
a9098fd0 2708 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2709 }
a9098fd0
GK
2710 else if (mode == Pmode
2711 && CONSTANT_P (operands[1])
38886f37
AO
2712 && ((GET_CODE (operands[1]) != CONST_INT
2713 && ! easy_fp_constant (operands[1], mode))
2714 || (GET_CODE (operands[1]) == CONST_INT
2715 && num_insns_constant (operands[1], mode) > 2)
2716 || (GET_CODE (operands[0]) == REG
2717 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2718 && GET_CODE (operands[1]) != HIGH
2719 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2720 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2721 {
2722 /* Emit a USE operation so that the constant isn't deleted if
2723 expensive optimizations are turned on because nobody
2724 references it. This should only be done for operands that
2725 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2726 This should not be done for operands that contain LABEL_REFs.
2727 For now, we just handle the obvious case. */
2728 if (GET_CODE (operands[1]) != LABEL_REF)
2729 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2730
c859cda6 2731#if TARGET_MACHO
ee890fe2
SS
2732 /* Darwin uses a special PIC legitimizer. */
2733 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2734 {
ee890fe2
SS
2735 operands[1] =
2736 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2737 operands[0]);
2738 if (operands[0] != operands[1])
2739 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2740 return;
2741 }
c859cda6 2742#endif
ee890fe2 2743
fb4d4348
GK
2744 /* If we are to limit the number of things we put in the TOC and
2745 this is a symbol plus a constant we can add in one insn,
2746 just put the symbol in the TOC and add the constant. Don't do
2747 this if reload is in progress. */
2748 if (GET_CODE (operands[1]) == CONST
2749 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2750 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2751 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2752 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2753 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2754 && ! side_effects_p (operands[0]))
2755 {
a4f6c312
SS
2756 rtx sym =
2757 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2758 rtx other = XEXP (XEXP (operands[1], 0), 1);
2759
a9098fd0
GK
2760 sym = force_reg (mode, sym);
2761 if (mode == SImode)
2762 emit_insn (gen_addsi3 (operands[0], sym, other));
2763 else
2764 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2765 return;
2766 }
2767
a9098fd0 2768 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2769
2770 if (TARGET_TOC
d34c5b80
DE
2771 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2772 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2773 get_pool_constant (XEXP (operands[1], 0)),
2774 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2775 {
ba4828e0
RK
2776 operands[1]
2777 = gen_rtx_MEM (mode,
2778 create_TOC_reference (XEXP (operands[1], 0)));
2779 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2780 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2781 }
fb4d4348
GK
2782 }
2783 break;
a9098fd0 2784
fb4d4348
GK
2785 case TImode:
2786 if (GET_CODE (operands[0]) == MEM
2787 && GET_CODE (XEXP (operands[0], 0)) != REG
2788 && ! reload_in_progress)
792760b9
RK
2789 operands[0]
2790 = replace_equiv_address (operands[0],
2791 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2792
2793 if (GET_CODE (operands[1]) == MEM
2794 && GET_CODE (XEXP (operands[1], 0)) != REG
2795 && ! reload_in_progress)
792760b9
RK
2796 operands[1]
2797 = replace_equiv_address (operands[1],
2798 copy_addr_to_reg (XEXP (operands[1], 0)));
fb4d4348
GK
2799 break;
2800
2801 default:
2802 abort ();
2803 }
2804
a9098fd0
GK
2805 /* Above, we may have called force_const_mem which may have returned
2806 an invalid address. If we can, fix this up; otherwise, reload will
2807 have to deal with it. */
2808 if (GET_CODE (operands[1]) == MEM
2809 && ! memory_address_p (mode, XEXP (operands[1], 0))
2810 && ! reload_in_progress)
f4ef873c 2811 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2812
fb4d4348 2813 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2814 return;
fb4d4348 2815}
4697a36c
MM
2816\f
2817/* Initialize a variable CUM of type CUMULATIVE_ARGS
2818 for a call to a function whose data type is FNTYPE.
2819 For a library call, FNTYPE is 0.
2820
2821 For incoming args we set the number of arguments in the prototype large
1c20ae99 2822 so we never return a PARALLEL. */
4697a36c
MM
2823
2824void
2825init_cumulative_args (cum, fntype, libname, incoming)
2826 CUMULATIVE_ARGS *cum;
2827 tree fntype;
296b8152 2828 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2829 int incoming;
2830{
2831 static CUMULATIVE_ARGS zero_cumulative;
2832
2833 *cum = zero_cumulative;
2834 cum->words = 0;
2835 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2836 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2837 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2838 cum->call_cookie = CALL_NORMAL;
4cc833b7 2839 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2840
2841 if (incoming)
bd227acc 2842 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2843
2844 else if (cum->prototype)
2845 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2846 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2847 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2848
2849 else
2850 cum->nargs_prototype = 0;
2851
2852 cum->orig_nargs = cum->nargs_prototype;
7509c759 2853
a5c76ee6
ZW
2854 /* Check for a longcall attribute. */
2855 if (fntype
2856 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2857 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2858 cum->call_cookie = CALL_LONG;
2859
4697a36c
MM
2860 if (TARGET_DEBUG_ARG)
2861 {
2862 fprintf (stderr, "\ninit_cumulative_args:");
2863 if (fntype)
2864 {
2865 tree ret_type = TREE_TYPE (fntype);
2866 fprintf (stderr, " ret code = %s,",
2867 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2868 }
2869
6a4cee5f
MM
2870 if (cum->call_cookie & CALL_LONG)
2871 fprintf (stderr, " longcall,");
2872
4697a36c
MM
2873 fprintf (stderr, " proto = %d, nargs = %d\n",
2874 cum->prototype, cum->nargs_prototype);
2875 }
2876}
2877\f
c229cba9
DE
2878/* If defined, a C expression which determines whether, and in which
2879 direction, to pad out an argument with extra space. The value
2880 should be of type `enum direction': either `upward' to pad above
2881 the argument, `downward' to pad below, or `none' to inhibit
2882 padding.
2883
2884 For the AIX ABI structs are always stored left shifted in their
2885 argument slot. */
2886
9ebbca7d 2887enum direction
c229cba9
DE
2888function_arg_padding (mode, type)
2889 enum machine_mode mode;
2890 tree type;
2891{
c85f7c16 2892 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 2893 return upward;
c229cba9
DE
2894
2895 /* This is the default definition. */
2896 return (! BYTES_BIG_ENDIAN
9ebbca7d 2897 ? upward
c229cba9
DE
2898 : ((mode == BLKmode
2899 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2900 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2901 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 2902 ? downward : upward));
c229cba9
DE
2903}
2904
b6c9286a
MM
2905/* If defined, a C expression that gives the alignment boundary, in bits,
2906 of an argument with the specified mode and type. If it is not defined,
2907 PARM_BOUNDARY is used for all arguments.
2908
2310f99a 2909 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
2910
2911int
2912function_arg_boundary (mode, type)
2913 enum machine_mode mode;
9ebbca7d 2914 tree type ATTRIBUTE_UNUSED;
b6c9286a 2915{
f607bc57 2916 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 2917 return 64;
a3170dc6
AH
2918 else if (SPE_VECTOR_MODE (mode))
2919 return 64;
0ac081f6
AH
2920 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2921 return 128;
9ebbca7d 2922 else
b6c9286a 2923 return PARM_BOUNDARY;
b6c9286a
MM
2924}
2925\f
4697a36c
MM
2926/* Update the data in CUM to advance over an argument
2927 of mode MODE and data type TYPE.
2928 (TYPE is null for libcalls where that information may not be available.) */
2929
2930void
2931function_arg_advance (cum, mode, type, named)
2932 CUMULATIVE_ARGS *cum;
2933 enum machine_mode mode;
2934 tree type;
2935 int named;
2936{
2937 cum->nargs_prototype--;
2938
0ac081f6
AH
2939 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2940 {
2941 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2942 cum->vregno++;
2943 else
2944 cum->words += RS6000_ARG_SIZE (mode, type);
2945 }
a4b0320c
AH
2946 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
2947 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
2948 cum->sysv_gregno++;
f607bc57 2949 else if (DEFAULT_ABI == ABI_V4)
4697a36c 2950 {
a3170dc6 2951 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 2952 && (mode == SFmode || mode == DFmode))
4697a36c 2953 {
4cc833b7
RH
2954 if (cum->fregno <= FP_ARG_V4_MAX_REG)
2955 cum->fregno++;
2956 else
2957 {
2958 if (mode == DFmode)
2959 cum->words += cum->words & 1;
d34c5b80 2960 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 2961 }
4697a36c 2962 }
4cc833b7
RH
2963 else
2964 {
2965 int n_words;
2966 int gregno = cum->sysv_gregno;
2967
2968 /* Aggregates and IEEE quad get passed by reference. */
2969 if ((type && AGGREGATE_TYPE_P (type))
2970 || mode == TFmode)
2971 n_words = 1;
2972 else
d34c5b80 2973 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 2974
a4b0320c 2975 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
2976 if (n_words == 2 && (gregno & 1) == 0)
2977 gregno += 1;
2978
a4b0320c
AH
2979 /* Long long and SPE vectors are not split between registers
2980 and stack. */
4cc833b7
RH
2981 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
2982 {
2983 /* Long long is aligned on the stack. */
2984 if (n_words == 2)
2985 cum->words += cum->words & 1;
2986 cum->words += n_words;
2987 }
4697a36c 2988
4cc833b7
RH
2989 /* Note: continuing to accumulate gregno past when we've started
2990 spilling to the stack indicates the fact that we've started
2991 spilling to the stack to expand_builtin_saveregs. */
2992 cum->sysv_gregno = gregno + n_words;
2993 }
4697a36c 2994
4cc833b7
RH
2995 if (TARGET_DEBUG_ARG)
2996 {
2997 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
2998 cum->words, cum->fregno);
2999 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3000 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3001 fprintf (stderr, "mode = %4s, named = %d\n",
3002 GET_MODE_NAME (mode), named);
3003 }
4697a36c
MM
3004 }
3005 else
4cc833b7
RH
3006 {
3007 int align = (TARGET_32BIT && (cum->words & 1) != 0
3008 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 3009
d34c5b80 3010 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 3011
a3170dc6
AH
3012 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3013 && TARGET_HARD_FLOAT && TARGET_FPRS)
d34c5b80 3014 cum->fregno++;
4cc833b7
RH
3015
3016 if (TARGET_DEBUG_ARG)
3017 {
3018 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3019 cum->words, cum->fregno);
3020 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3021 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3022 fprintf (stderr, "named = %d, align = %d\n", named, align);
3023 }
3024 }
4697a36c
MM
3025}
3026\f
3027/* Determine where to put an argument to a function.
3028 Value is zero to push the argument on the stack,
3029 or a hard register in which to store the argument.
3030
3031 MODE is the argument's machine mode.
3032 TYPE is the data type of the argument (as a tree).
3033 This is null for libcalls where that information may
3034 not be available.
3035 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3036 the preceding args and about the function being called.
3037 NAMED is nonzero if this argument is a named parameter
3038 (otherwise it is an extra parameter matching an ellipsis).
3039
3040 On RS/6000 the first eight words of non-FP are normally in registers
3041 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3042 Under V.4, the first 8 FP args are in registers.
3043
3044 If this is floating-point and no prototype is specified, we use
3045 both an FP and integer register (or possibly FP reg and stack). Library
3046 functions (when TYPE is zero) always have the proper types for args,
3047 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3048 doesn't support PARALLEL anyway. */
4697a36c
MM
3049
3050struct rtx_def *
3051function_arg (cum, mode, type, named)
3052 CUMULATIVE_ARGS *cum;
3053 enum machine_mode mode;
3054 tree type;
20c29ebe 3055 int named;
4697a36c 3056{
4cc833b7 3057 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3058
a4f6c312
SS
3059 /* Return a marker to indicate whether CR1 needs to set or clear the
3060 bit that V.4 uses to say fp args were passed in registers.
3061 Assume that we don't need the marker for software floating point,
3062 or compiler generated library calls. */
4697a36c
MM
3063 if (mode == VOIDmode)
3064 {
f607bc57 3065 if (abi == ABI_V4
7509c759 3066 && cum->nargs_prototype < 0
4697a36c 3067 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3068 {
a3170dc6
AH
3069 /* For the SPE, we need to crxor CR6 always. */
3070 if (TARGET_SPE_ABI)
3071 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3072 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3073 return GEN_INT (cum->call_cookie
3074 | ((cum->fregno == FP_ARG_MIN_REG)
3075 ? CALL_V4_SET_FP_ARGS
3076 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3077 }
4697a36c 3078
7509c759 3079 return GEN_INT (cum->call_cookie);
4697a36c
MM
3080 }
3081
0ac081f6
AH
3082 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3083 {
20c29ebe 3084 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3085 return gen_rtx_REG (mode, cum->vregno);
3086 else
3087 return NULL;
3088 }
a4b0320c 3089 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3090 {
a4b0320c 3091 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3092 return gen_rtx_REG (mode, cum->sysv_gregno);
3093 else
3094 return NULL;
3095 }
f607bc57 3096 else if (abi == ABI_V4)
4697a36c 3097 {
a3170dc6 3098 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3099 && (mode == SFmode || mode == DFmode))
3100 {
3101 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3102 return gen_rtx_REG (mode, cum->fregno);
3103 else
3104 return NULL;
3105 }
3106 else
3107 {
3108 int n_words;
3109 int gregno = cum->sysv_gregno;
3110
3111 /* Aggregates and IEEE quad get passed by reference. */
3112 if ((type && AGGREGATE_TYPE_P (type))
3113 || mode == TFmode)
3114 n_words = 1;
3115 else
d34c5b80 3116 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3117
a4b0320c 3118 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3119 if (n_words == 2 && (gregno & 1) == 0)
3120 gregno += 1;
3121
a4b0320c
AH
3122 /* Long long and SPE vectors are not split between registers
3123 and stack. */
4cc833b7 3124 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3125 {
3126 /* SPE vectors in ... get split into 2 registers. */
3127 if (TARGET_SPE && TARGET_SPE_ABI
3128 && SPE_VECTOR_MODE (mode) && !named)
3129 {
3130 rtx r1, r2;
3131 enum machine_mode m = GET_MODE_INNER (mode);
3132
3133 r1 = gen_rtx_REG (m, gregno);
3134 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3135 r2 = gen_rtx_REG (m, gregno + 1);
3136 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3137 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3138 }
3139 return gen_rtx_REG (mode, gregno);
3140 }
4cc833b7
RH
3141 else
3142 return NULL;
3143 }
4697a36c 3144 }
4cc833b7
RH
3145 else
3146 {
3147 int align = (TARGET_32BIT && (cum->words & 1) != 0
3148 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3149 int align_words = cum->words + align;
4697a36c 3150
4cc833b7
RH
3151 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3152 return NULL_RTX;
3153
3154 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3155 {
3156 if (! type
3157 || ((cum->nargs_prototype > 0)
3158 /* IBM AIX extended its linkage convention definition always
3159 to require FP args after register save area hole on the
3160 stack. */
3161 && (DEFAULT_ABI != ABI_AIX
3162 || ! TARGET_XL_CALL
3163 || (align_words < GP_ARG_NUM_REG))))
3164 return gen_rtx_REG (mode, cum->fregno);
3165
3166 return gen_rtx_PARALLEL (mode,
3167 gen_rtvec (2,
39403d82 3168 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3169 ((align_words >= GP_ARG_NUM_REG)
3170 ? NULL_RTX
3171 : (align_words
d34c5b80 3172 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3173 > GP_ARG_NUM_REG
3174 /* If this is partially on the stack, then
3175 we only include the portion actually
3176 in registers here. */
39403d82 3177 ? gen_rtx_REG (SImode,
1c20ae99 3178 GP_ARG_MIN_REG + align_words)
39403d82 3179 : gen_rtx_REG (mode,
1c20ae99
JW
3180 GP_ARG_MIN_REG + align_words))),
3181 const0_rtx),
39403d82
DE
3182 gen_rtx_EXPR_LIST (VOIDmode,
3183 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3184 const0_rtx)));
4cc833b7
RH
3185 }
3186 else if (align_words < GP_ARG_NUM_REG)
3187 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3188 else
3189 return NULL_RTX;
4697a36c 3190 }
4697a36c
MM
3191}
3192\f
3193/* For an arg passed partly in registers and partly in memory,
3194 this is the number of registers used.
3195 For args passed entirely in registers or entirely in memory, zero. */
3196
3197int
3198function_arg_partial_nregs (cum, mode, type, named)
3199 CUMULATIVE_ARGS *cum;
3200 enum machine_mode mode;
3201 tree type;
d34c5b80 3202 int named ATTRIBUTE_UNUSED;
4697a36c 3203{
f607bc57 3204 if (DEFAULT_ABI == ABI_V4)
4697a36c 3205 return 0;
4697a36c 3206
0ac081f6
AH
3207 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3208 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3209 {
3210 if (cum->nargs_prototype >= 0)
3211 return 0;
3212 }
3213
3214 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3215 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3216 {
3217 int ret = GP_ARG_NUM_REG - cum->words;
3218 if (ret && TARGET_DEBUG_ARG)
3219 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3220
3221 return ret;
3222 }
3223
3224 return 0;
3225}
3226\f
3227/* A C expression that indicates when an argument must be passed by
3228 reference. If nonzero for an argument, a copy of that argument is
3229 made in memory and a pointer to the argument is passed instead of
3230 the argument itself. The pointer is passed in whatever way is
3231 appropriate for passing a pointer to that type.
3232
3233 Under V.4, structures and unions are passed by reference. */
3234
3235int
3236function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3237 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3238 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3239 tree type;
296b8152 3240 int named ATTRIBUTE_UNUSED;
4697a36c 3241{
f607bc57 3242 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3243 && ((type && AGGREGATE_TYPE_P (type))
3244 || mode == TFmode))
4697a36c
MM
3245 {
3246 if (TARGET_DEBUG_ARG)
3247 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3248
3249 return 1;
3250 }
4697a36c
MM
3251
3252 return 0;
3253}
4697a36c
MM
3254\f
3255/* Perform any needed actions needed for a function that is receiving a
3256 variable number of arguments.
3257
3258 CUM is as above.
3259
3260 MODE and TYPE are the mode and type of the current parameter.
3261
3262 PRETEND_SIZE is a variable that should be set to the amount of stack
3263 that must be pushed by the prolog to pretend that our caller pushed
3264 it.
3265
3266 Normally, this macro will push all remaining incoming registers on the
3267 stack and set PRETEND_SIZE to the length of the registers pushed. */
3268
3269void
3270setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3271 CUMULATIVE_ARGS *cum;
3272 enum machine_mode mode;
3273 tree type;
3274 int *pretend_size;
3275 int no_rtl;
3276
3277{
4cc833b7
RH
3278 CUMULATIVE_ARGS next_cum;
3279 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3280 rtx save_area = NULL_RTX, mem;
dfafc897 3281 int first_reg_offset, set;
d34c5b80
DE
3282 tree fntype;
3283 int stdarg_p;
4697a36c 3284
d34c5b80
DE
3285 fntype = TREE_TYPE (current_function_decl);
3286 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3287 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3288 != void_type_node));
4cc833b7 3289
d34c5b80
DE
3290 /* For varargs, we do not want to skip the dummy va_dcl argument.
3291 For stdargs, we do want to skip the last named argument. */
3292 next_cum = *cum;
3293 if (stdarg_p)
3294 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3295
f607bc57 3296 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3297 {
4cc833b7 3298 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3299 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3300 if (! no_rtl)
2c4974b7 3301 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3302 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3303
3304 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3305 }
60e2d0ca 3306 else
4697a36c 3307 {
d34c5b80 3308 first_reg_offset = next_cum.words;
4cc833b7 3309 save_area = virtual_incoming_args_rtx;
00dba523 3310 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3311
3312 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3313 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3314 }
4697a36c 3315
dfafc897 3316 set = get_varargs_alias_set ();
c81fc13e 3317 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3318 {
dfafc897
FS
3319 mem = gen_rtx_MEM (BLKmode,
3320 plus_constant (save_area,
3321 first_reg_offset * reg_size)),
ba4828e0 3322 set_mem_alias_set (mem, set);
8ac61af7 3323 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3324
4cc833b7 3325 move_block_from_reg
dfafc897 3326 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3327 GP_ARG_NUM_REG - first_reg_offset,
3328 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
3329
3330 /* ??? Does ABI_V4 need this at all? */
4697a36c
MM
3331 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
3332 }
3333
4697a36c 3334 /* Save FP registers if needed. */
f607bc57 3335 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3336 && TARGET_HARD_FLOAT && TARGET_FPRS
3337 && ! no_rtl
4cc833b7 3338 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3339 {
4cc833b7 3340 int fregno = next_cum.fregno;
9ebbca7d 3341 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3342 rtx lab = gen_label_rtx ();
3343 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3344
4cc833b7 3345 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3346 pc_rtx,
39403d82 3347 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3348 gen_rtx_NE (VOIDmode, cr1,
3349 const0_rtx),
39403d82 3350 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3351 pc_rtx)));
3352
4cc833b7
RH
3353 while (fregno <= FP_ARG_V4_MAX_REG)
3354 {
dfafc897 3355 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3356 set_mem_alias_set (mem, set);
dfafc897 3357 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3358 fregno++;
3359 off += 8;
4697a36c 3360 }
4cc833b7
RH
3361
3362 emit_label (lab);
4697a36c 3363 }
4697a36c 3364}
4697a36c 3365
dfafc897 3366/* Create the va_list data type. */
2c4974b7 3367
dfafc897
FS
3368tree
3369rs6000_build_va_list ()
3370{
bab45a51 3371 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3372
9ebbca7d
GK
3373 /* For AIX, prefer 'char *' because that's what the system
3374 header files like. */
f607bc57 3375 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3376 return build_pointer_type (char_type_node);
dfafc897 3377
f1e639b1 3378 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3379 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3380
9ebbca7d
GK
3381 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3382 unsigned_char_type_node);
3383 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3384 unsigned_char_type_node);
dfafc897
FS
3385 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3386 ptr_type_node);
3387 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3388 ptr_type_node);
3389
3390 DECL_FIELD_CONTEXT (f_gpr) = record;
3391 DECL_FIELD_CONTEXT (f_fpr) = record;
3392 DECL_FIELD_CONTEXT (f_ovf) = record;
3393 DECL_FIELD_CONTEXT (f_sav) = record;
3394
bab45a51
FS
3395 TREE_CHAIN (record) = type_decl;
3396 TYPE_NAME (record) = type_decl;
dfafc897
FS
3397 TYPE_FIELDS (record) = f_gpr;
3398 TREE_CHAIN (f_gpr) = f_fpr;
3399 TREE_CHAIN (f_fpr) = f_ovf;
3400 TREE_CHAIN (f_ovf) = f_sav;
3401
3402 layout_type (record);
3403
3404 /* The correct type is an array type of one element. */
3405 return build_array_type (record, build_index_type (size_zero_node));
3406}
3407
3408/* Implement va_start. */
3409
3410void
e5faf155 3411rs6000_va_start (valist, nextarg)
dfafc897
FS
3412 tree valist;
3413 rtx nextarg;
4697a36c 3414{
dfafc897
FS
3415 HOST_WIDE_INT words, n_gpr, n_fpr;
3416 tree f_gpr, f_fpr, f_ovf, f_sav;
3417 tree gpr, fpr, ovf, sav, t;
2c4974b7 3418
dfafc897 3419 /* Only SVR4 needs something special. */
f607bc57 3420 if (DEFAULT_ABI != ABI_V4)
dfafc897 3421 {
e5faf155 3422 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3423 return;
3424 }
3425
973a648b 3426 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3427 f_fpr = TREE_CHAIN (f_gpr);
3428 f_ovf = TREE_CHAIN (f_fpr);
3429 f_sav = TREE_CHAIN (f_ovf);
3430
8ebecc3b 3431 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3432 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3433 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3434 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3435 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3436
3437 /* Count number of gp and fp argument registers used. */
4cc833b7 3438 words = current_function_args_info.words;
dfafc897
FS
3439 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3440 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3441
3442 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3443 {
3444 fputs ("va_start: words = ", stderr);
3445 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3446 fputs (", n_gpr = ", stderr);
3447 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3448 fputs (", n_fpr = ", stderr);
3449 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3450 putc ('\n', stderr);
3451 }
dfafc897
FS
3452
3453 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3454 TREE_SIDE_EFFECTS (t) = 1;
3455 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3456
3457 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3458 TREE_SIDE_EFFECTS (t) = 1;
3459 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3460
3461 /* Find the overflow area. */
3462 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3463 if (words != 0)
3464 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3465 build_int_2 (words * UNITS_PER_WORD, 0));
3466 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3467 TREE_SIDE_EFFECTS (t) = 1;
3468 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3469
3470 /* Find the register save area. */
3471 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3472 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3473 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3474 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3475 TREE_SIDE_EFFECTS (t) = 1;
3476 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3477}
3478
3479/* Implement va_arg. */
3480
3481rtx
3482rs6000_va_arg (valist, type)
3483 tree valist, type;
3484{
3485 tree f_gpr, f_fpr, f_ovf, f_sav;
3486 tree gpr, fpr, ovf, sav, reg, t, u;
3487 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3488 rtx lab_false, lab_over, addr_rtx, r;
3489
f607bc57 3490 if (DEFAULT_ABI != ABI_V4)
2a55fd42 3491 return std_expand_builtin_va_arg (valist, type);
dfafc897 3492
973a648b 3493 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3494 f_fpr = TREE_CHAIN (f_gpr);
3495 f_ovf = TREE_CHAIN (f_fpr);
3496 f_sav = TREE_CHAIN (f_ovf);
3497
8ebecc3b 3498 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3499 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3500 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3501 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3502 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3503
3504 size = int_size_in_bytes (type);
3505 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3506
dfafc897 3507 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3508 {
dfafc897
FS
3509 /* Aggregates and long doubles are passed by reference. */
3510 indirect_p = 1;
3511 reg = gpr;
3512 n_reg = 1;
3513 sav_ofs = 0;
3514 sav_scale = 4;
d3294cd9
FS
3515 size = UNITS_PER_WORD;
3516 rsize = 1;
dfafc897 3517 }
a3170dc6 3518 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3519 {
3520 /* FP args go in FP registers, if present. */
3521 indirect_p = 0;
3522 reg = fpr;
3523 n_reg = 1;
3524 sav_ofs = 8*4;
3525 sav_scale = 8;
4cc833b7 3526 }
dfafc897
FS
3527 else
3528 {
3529 /* Otherwise into GP registers. */
3530 indirect_p = 0;
3531 reg = gpr;
3532 n_reg = rsize;
3533 sav_ofs = 0;
3534 sav_scale = 4;
3535 }
3536
a4f6c312 3537 /* Pull the value out of the saved registers ... */
dfafc897
FS
3538
3539 lab_false = gen_label_rtx ();
3540 lab_over = gen_label_rtx ();
3541 addr_rtx = gen_reg_rtx (Pmode);
3542
16861f33
AH
3543 /* AltiVec vectors never go in registers. */
3544 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3545 {
41daaf0e
AH
3546 TREE_THIS_VOLATILE (reg) = 1;
3547 emit_cmp_and_jump_insns
3548 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3549 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3550 lab_false);
dfafc897 3551
41daaf0e
AH
3552 /* Long long is aligned in the registers. */
3553 if (n_reg > 1)
3554 {
3555 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3556 build_int_2 (n_reg - 1, 0));
3557 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3558 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3559 TREE_SIDE_EFFECTS (u) = 1;
3560 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3561 }
2c4974b7 3562
41daaf0e
AH
3563 if (sav_ofs)
3564 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3565 else
3566 t = sav;
2c4974b7 3567
41daaf0e
AH
3568 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3569 build_int_2 (n_reg, 0));
3570 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3571
41daaf0e
AH
3572 u = build1 (CONVERT_EXPR, integer_type_node, u);
3573 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3574
41daaf0e
AH
3575 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3576 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3577
41daaf0e
AH
3578 t = build (PLUS_EXPR, ptr_type_node, t, u);
3579 TREE_SIDE_EFFECTS (t) = 1;
3580
3581 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3582 if (r != addr_rtx)
3583 emit_move_insn (addr_rtx, r);
3584
3585 emit_jump_insn (gen_jump (lab_over));
3586 emit_barrier ();
3587 }
dfafc897 3588
dfafc897
FS
3589 emit_label (lab_false);
3590
a4f6c312 3591 /* ... otherwise out of the overflow area. */
dfafc897 3592
41daaf0e
AH
3593 /* Make sure we don't find reg 7 for the next int arg.
3594
3595 All AltiVec vectors go in the overflow area. So in the AltiVec
3596 case we need to get the vectors from the overflow area, but
3597 remember where the GPRs and FPRs are. */
16861f33
AH
3598 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3599 || !TARGET_ALTIVEC))
dfafc897
FS
3600 {
3601 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3602 TREE_SIDE_EFFECTS (t) = 1;
3603 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3604 }
3605
3606 /* Care for on-stack alignment if needed. */
3607 if (rsize <= 1)
3608 t = ovf;
3609 else
3610 {
41daaf0e
AH
3611 int align;
3612
16861f33
AH
3613 /* AltiVec vectors are 16 byte aligned. */
3614 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3615 align = 15;
3616 else
3617 align = 7;
3618
3619 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3620 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3621 }
3622 t = save_expr (t);
3623
3624 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3625 if (r != addr_rtx)
3626 emit_move_insn (addr_rtx, r);
3627
3628 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3629 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3630 TREE_SIDE_EFFECTS (t) = 1;
3631 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3632
3633 emit_label (lab_over);
3634
3635 if (indirect_p)
3636 {
3637 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3638 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3639 emit_move_insn (addr_rtx, r);
3640 }
3641
3642 return addr_rtx;
4697a36c 3643}
0ac081f6
AH
3644
3645/* Builtins. */
3646
6a2dd09a
RS
3647#define def_builtin(MASK, NAME, TYPE, CODE) \
3648do { \
3649 if ((MASK) & target_flags) \
3650 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3651 NULL, NULL_TREE); \
0ac081f6
AH
3652} while (0)
3653
24408032
AH
3654/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3655
2212663f 3656static const struct builtin_description bdesc_3arg[] =
24408032
AH
3657{
3658 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3659 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3660 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3661 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3662 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3663 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3664 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3665 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3666 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3667 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3668 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3669 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3670 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3671 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3672 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3673 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3674 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3675 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3676 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3677 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3678 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3679 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3680 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3681};
2212663f 3682
95385cbb
AH
3683/* DST operations: void foo (void *, const int, const char). */
3684
3685static const struct builtin_description bdesc_dst[] =
3686{
3687 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3688 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3689 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3690 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3691};
3692
2212663f 3693/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3694
a3170dc6 3695static struct builtin_description bdesc_2arg[] =
0ac081f6 3696{
f18c054f
DB
3697 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3698 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3699 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3700 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3701 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3702 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3703 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3704 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3705 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3706 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3707 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3708 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3709 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3710 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3711 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3712 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3713 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3714 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3715 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3716 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3717 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3718 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3719 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3720 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3721 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3722 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3723 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3724 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3725 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3726 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3727 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3728 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3729 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3730 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3731 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3732 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3733 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3734 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
3735 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3736 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3737 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3738 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3739 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3740 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3741 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3742 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3743 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3744 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3745 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3746 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3747 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3748 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3749 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3750 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3751 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3752 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3753 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3754 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3755 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3756 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3757 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3758 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3759 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3760 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3761 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3762 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3763 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3764 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3765 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3766 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3767 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3768 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3769 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3770 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3771 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3772 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3773 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3774 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3775 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3776 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3777 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3778 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3779 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3780 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3781 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3782 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3783 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3784 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3785 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3786 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3787 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3788 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3789 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3790 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3791 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3792 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3793 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3794 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3795 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3796 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3797 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3798 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3799 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3800 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3801 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3802 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3803 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3804 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3805 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3806 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3807 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3808 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3809 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
3810
3811 /* Place holder, leave as first spe builtin. */
3812 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3813 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3814 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3815 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3816 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3817 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3818 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3819 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3820 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3821 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3822 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3823 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3824 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3825 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3826 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3827 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3828 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3829 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3830 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3831 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3832 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3833 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3834 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3835 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3836 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3837 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3838 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3839 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3840 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3841 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3842 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3843 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3844 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3845 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3846 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3847 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3848 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3849 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3850 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
3851 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
3852 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
3853 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
3854 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
3855 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
3856 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
3857 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
3858 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
3859 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
3860 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
3861 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
3862 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
3863 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
3864 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
3865 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
3866 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
3867 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
3868 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
3869 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
3870 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
3871 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
3872 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
3873 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
3874 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
3875 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
3876 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
3877 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
3878 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
3879 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
3880 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
3881 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
3882 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
3883 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
3884 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
3885 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
3886 { 0, CODE_FOR_spe_evmwlsmf, "__builtin_spe_evmwlsmf", SPE_BUILTIN_EVMWLSMF },
3887 { 0, CODE_FOR_spe_evmwlsmfa, "__builtin_spe_evmwlsmfa", SPE_BUILTIN_EVMWLSMFA },
3888 { 0, CODE_FOR_spe_evmwlsmfaaw, "__builtin_spe_evmwlsmfaaw", SPE_BUILTIN_EVMWLSMFAAW },
3889 { 0, CODE_FOR_spe_evmwlsmfanw, "__builtin_spe_evmwlsmfanw", SPE_BUILTIN_EVMWLSMFANW },
3890 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
3891 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
3892 { 0, CODE_FOR_spe_evmwlssf, "__builtin_spe_evmwlssf", SPE_BUILTIN_EVMWLSSF },
3893 { 0, CODE_FOR_spe_evmwlssfa, "__builtin_spe_evmwlssfa", SPE_BUILTIN_EVMWLSSFA },
3894 { 0, CODE_FOR_spe_evmwlssfaaw, "__builtin_spe_evmwlssfaaw", SPE_BUILTIN_EVMWLSSFAAW },
3895 { 0, CODE_FOR_spe_evmwlssfanw, "__builtin_spe_evmwlssfanw", SPE_BUILTIN_EVMWLSSFANW },
3896 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
3897 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
3898 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
3899 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
3900 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
3901 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
3902 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
3903 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
3904 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
3905 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
3906 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
3907 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
3908 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
3909 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
3910 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
3911 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
3912 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
3913 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
3914 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
3915 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
3916 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
3917 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
3918 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
3919 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
3920 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
3921 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
3922 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
3923 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
3924 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
3925 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
3926 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
3927 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
3928 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
3929
3930 /* SPE binary operations expecting a 5-bit unsigned literal. */
3931 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
3932
3933 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
3934 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
3935 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
3936 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
3937 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
3938 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
3939 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
3940 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
3941 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
3942 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
3943 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
3944 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
3945 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
3946 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
3947 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
3948 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
3949 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
3950 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
3951 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
3952 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
3953 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
3954 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
3955 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
3956 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
3957 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
3958 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
3959
3960 /* Place-holder. Leave as last binary SPE builtin. */
3961 { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
3962};
3963
3964/* AltiVec predicates. */
3965
3966struct builtin_description_predicates
3967{
3968 const unsigned int mask;
3969 const enum insn_code icode;
3970 const char *opcode;
3971 const char *const name;
3972 const enum rs6000_builtins code;
3973};
3974
3975static const struct builtin_description_predicates bdesc_altivec_preds[] =
3976{
3977 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
3978 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
3979 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
3980 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
3981 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
3982 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
3983 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
3984 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
3985 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
3986 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
3987 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
3988 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
3989 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 3990};
24408032 3991
a3170dc6
AH
3992/* SPE predicates. */
3993static struct builtin_description bdesc_spe_predicates[] =
3994{
3995 /* Place-holder. Leave as first. */
3996 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
3997 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
3998 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
3999 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4000 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4001 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4002 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4003 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4004 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4005 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4006 /* Place-holder. Leave as last. */
4007 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4008};
4009
4010/* SPE evsel predicates. */
4011static struct builtin_description bdesc_spe_evsel[] =
4012{
4013 /* Place-holder. Leave as first. */
4014 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4015 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4016 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4017 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4018 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4019 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4020 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4021 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4022 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4023 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4024 /* Place-holder. Leave as last. */
4025 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4026};
4027
100c4561
AH
4028/* ABS* opreations. */
4029
4030static const struct builtin_description bdesc_abs[] =
4031{
4032 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4033 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4034 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4035 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4036 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4037 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4038 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4039};
4040
617e0e1d
DB
4041/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4042 foo (VECa). */
24408032 4043
a3170dc6 4044static struct builtin_description bdesc_1arg[] =
2212663f 4045{
617e0e1d
DB
4046 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4047 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4048 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4049 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4050 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4051 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4052 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4053 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4054 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4055 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4056 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4057 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4058 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4059 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4060 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4061 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4062 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4063
4064 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4065 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4066 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4067 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4068 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4069 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4070 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4071 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4072 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4073 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4074 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4075 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4076 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4077 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4078 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4079 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4080 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4081 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4082 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4083 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4084 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4085 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4086 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4087 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4088 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4089 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4090 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4091 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4092 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4093 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4094 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4095 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4096
4097 /* Place-holder. Leave as last unary SPE builtin. */
4098 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4099};
4100
4101static rtx
92898235 4102rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4103 enum insn_code icode;
4104 tree arglist;
4105 rtx target;
4106{
4107 rtx pat;
4108 tree arg0 = TREE_VALUE (arglist);
4109 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4110 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4111 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4112
0559cc77
DE
4113 if (icode == CODE_FOR_nothing)
4114 /* Builtin not supported on this processor. */
4115 return 0;
4116
20e26713
AH
4117 /* If we got invalid arguments bail out before generating bad rtl. */
4118 if (arg0 == error_mark_node)
9a171fcd 4119 return const0_rtx;
20e26713 4120
0559cc77
DE
4121 if (icode == CODE_FOR_altivec_vspltisb
4122 || icode == CODE_FOR_altivec_vspltish
4123 || icode == CODE_FOR_altivec_vspltisw
4124 || icode == CODE_FOR_spe_evsplatfi
4125 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4126 {
4127 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4128 if (GET_CODE (op0) != CONST_INT
4129 || INTVAL (op0) > 0x1f
4130 || INTVAL (op0) < -0x1f)
4131 {
4132 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4133 return const0_rtx;
b44140e7 4134 }
b44140e7
AH
4135 }
4136
c62f2db5 4137 if (target == 0
2212663f
DB
4138 || GET_MODE (target) != tmode
4139 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4140 target = gen_reg_rtx (tmode);
4141
4142 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4143 op0 = copy_to_mode_reg (mode0, op0);
4144
4145 pat = GEN_FCN (icode) (target, op0);
4146 if (! pat)
4147 return 0;
4148 emit_insn (pat);
0ac081f6 4149
2212663f
DB
4150 return target;
4151}
ae4b4a02 4152
100c4561
AH
4153static rtx
4154altivec_expand_abs_builtin (icode, arglist, target)
4155 enum insn_code icode;
4156 tree arglist;
4157 rtx target;
4158{
4159 rtx pat, scratch1, scratch2;
4160 tree arg0 = TREE_VALUE (arglist);
4161 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4162 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4163 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4164
4165 /* If we have invalid arguments, bail out before generating bad rtl. */
4166 if (arg0 == error_mark_node)
9a171fcd 4167 return const0_rtx;
100c4561
AH
4168
4169 if (target == 0
4170 || GET_MODE (target) != tmode
4171 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4172 target = gen_reg_rtx (tmode);
4173
4174 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4175 op0 = copy_to_mode_reg (mode0, op0);
4176
4177 scratch1 = gen_reg_rtx (mode0);
4178 scratch2 = gen_reg_rtx (mode0);
4179
4180 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4181 if (! pat)
4182 return 0;
4183 emit_insn (pat);
4184
4185 return target;
4186}
4187
0ac081f6 4188static rtx
92898235 4189rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4190 enum insn_code icode;
4191 tree arglist;
4192 rtx target;
4193{
4194 rtx pat;
4195 tree arg0 = TREE_VALUE (arglist);
4196 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4197 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4198 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4199 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4200 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4201 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4202
0559cc77
DE
4203 if (icode == CODE_FOR_nothing)
4204 /* Builtin not supported on this processor. */
4205 return 0;
4206
20e26713
AH
4207 /* If we got invalid arguments bail out before generating bad rtl. */
4208 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4209 return const0_rtx;
20e26713 4210
0559cc77
DE
4211 if (icode == CODE_FOR_altivec_vcfux
4212 || icode == CODE_FOR_altivec_vcfsx
4213 || icode == CODE_FOR_altivec_vctsxs
4214 || icode == CODE_FOR_altivec_vctuxs
4215 || icode == CODE_FOR_altivec_vspltb
4216 || icode == CODE_FOR_altivec_vsplth
4217 || icode == CODE_FOR_altivec_vspltw
4218 || icode == CODE_FOR_spe_evaddiw
4219 || icode == CODE_FOR_spe_evldd
4220 || icode == CODE_FOR_spe_evldh
4221 || icode == CODE_FOR_spe_evldw
4222 || icode == CODE_FOR_spe_evlhhesplat
4223 || icode == CODE_FOR_spe_evlhhossplat
4224 || icode == CODE_FOR_spe_evlhhousplat
4225 || icode == CODE_FOR_spe_evlwhe
4226 || icode == CODE_FOR_spe_evlwhos
4227 || icode == CODE_FOR_spe_evlwhou
4228 || icode == CODE_FOR_spe_evlwhsplat
4229 || icode == CODE_FOR_spe_evlwwsplat
4230 || icode == CODE_FOR_spe_evrlwi
4231 || icode == CODE_FOR_spe_evslwi
4232 || icode == CODE_FOR_spe_evsrwis
4233 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4234 {
4235 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4236 if (TREE_CODE (arg1) != INTEGER_CST
4237 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4238 {
4239 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4240 return const0_rtx;
b44140e7 4241 }
b44140e7
AH
4242 }
4243
c62f2db5 4244 if (target == 0
0ac081f6
AH
4245 || GET_MODE (target) != tmode
4246 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4247 target = gen_reg_rtx (tmode);
4248
4249 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4250 op0 = copy_to_mode_reg (mode0, op0);
4251 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4252 op1 = copy_to_mode_reg (mode1, op1);
4253
4254 pat = GEN_FCN (icode) (target, op0, op1);
4255 if (! pat)
4256 return 0;
4257 emit_insn (pat);
4258
4259 return target;
4260}
6525c0e7 4261
ae4b4a02
AH
4262static rtx
4263altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4264 enum insn_code icode;
4265 const char *opcode;
4266 tree arglist;
4267 rtx target;
4268{
4269 rtx pat, scratch;
4270 tree cr6_form = TREE_VALUE (arglist);
4271 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4272 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4273 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4274 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4275 enum machine_mode tmode = SImode;
4276 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4277 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4278 int cr6_form_int;
4279
4280 if (TREE_CODE (cr6_form) != INTEGER_CST)
4281 {
4282 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4283 return const0_rtx;
ae4b4a02
AH
4284 }
4285 else
4286 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4287
4288 if (mode0 != mode1)
4289 abort ();
4290
4291 /* If we have invalid arguments, bail out before generating bad rtl. */
4292 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4293 return const0_rtx;
ae4b4a02
AH
4294
4295 if (target == 0
4296 || GET_MODE (target) != tmode
4297 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4298 target = gen_reg_rtx (tmode);
4299
4300 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4301 op0 = copy_to_mode_reg (mode0, op0);
4302 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4303 op1 = copy_to_mode_reg (mode1, op1);
4304
4305 scratch = gen_reg_rtx (mode0);
4306
4307 pat = GEN_FCN (icode) (scratch, op0, op1,
4308 gen_rtx (SYMBOL_REF, Pmode, opcode));
4309 if (! pat)
4310 return 0;
4311 emit_insn (pat);
4312
4313 /* The vec_any* and vec_all* predicates use the same opcodes for two
4314 different operations, but the bits in CR6 will be different
4315 depending on what information we want. So we have to play tricks
4316 with CR6 to get the right bits out.
4317
4318 If you think this is disgusting, look at the specs for the
4319 AltiVec predicates. */
4320
4321 switch (cr6_form_int)
4322 {
4323 case 0:
4324 emit_insn (gen_cr6_test_for_zero (target));
4325 break;
4326 case 1:
4327 emit_insn (gen_cr6_test_for_zero_reverse (target));
4328 break;
4329 case 2:
4330 emit_insn (gen_cr6_test_for_lt (target));
4331 break;
4332 case 3:
4333 emit_insn (gen_cr6_test_for_lt_reverse (target));
4334 break;
4335 default:
4336 error ("argument 1 of __builtin_altivec_predicate is out of range");
4337 break;
4338 }
4339
4340 return target;
4341}
4342
6525c0e7
AH
4343static rtx
4344altivec_expand_stv_builtin (icode, arglist)
4345 enum insn_code icode;
4346 tree arglist;
4347{
4348 tree arg0 = TREE_VALUE (arglist);
4349 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4350 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4351 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4352 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4353 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4354 rtx pat;
4355 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4356 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4357 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4358
4359 /* Invalid arguments. Bail before doing anything stoopid! */
4360 if (arg0 == error_mark_node
4361 || arg1 == error_mark_node
4362 || arg2 == error_mark_node)
9a171fcd 4363 return const0_rtx;
6525c0e7
AH
4364
4365 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4366 op0 = copy_to_mode_reg (mode2, op0);
4367 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4368 op1 = copy_to_mode_reg (mode0, op1);
4369 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4370 op2 = copy_to_mode_reg (mode1, op2);
4371
4372 pat = GEN_FCN (icode) (op1, op2, op0);
4373 if (pat)
4374 emit_insn (pat);
4375 return NULL_RTX;
4376}
4377
2212663f 4378static rtx
92898235 4379rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4380 enum insn_code icode;
4381 tree arglist;
4382 rtx target;
4383{
4384 rtx pat;
4385 tree arg0 = TREE_VALUE (arglist);
4386 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4387 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4388 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4389 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4390 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4391 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4392 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4393 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4394 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4395
774b5662
DE
4396 if (icode == CODE_FOR_nothing)
4397 /* Builtin not supported on this processor. */
4398 return 0;
4399
20e26713
AH
4400 /* If we got invalid arguments bail out before generating bad rtl. */
4401 if (arg0 == error_mark_node
4402 || arg1 == error_mark_node
4403 || arg2 == error_mark_node)
9a171fcd 4404 return const0_rtx;
20e26713 4405
774b5662
DE
4406 if (icode == CODE_FOR_altivec_vsldoi_4sf
4407 || icode == CODE_FOR_altivec_vsldoi_4si
4408 || icode == CODE_FOR_altivec_vsldoi_8hi
4409 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4410 {
4411 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4412 if (TREE_CODE (arg2) != INTEGER_CST
4413 || TREE_INT_CST_LOW (arg2) & ~0xf)
4414 {
4415 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4416 return const0_rtx;
b44140e7 4417 }
b44140e7
AH
4418 }
4419
c62f2db5 4420 if (target == 0
2212663f
DB
4421 || GET_MODE (target) != tmode
4422 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4423 target = gen_reg_rtx (tmode);
4424
4425 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4426 op0 = copy_to_mode_reg (mode0, op0);
4427 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4428 op1 = copy_to_mode_reg (mode1, op1);
4429 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4430 op2 = copy_to_mode_reg (mode2, op2);
4431
4432 pat = GEN_FCN (icode) (target, op0, op1, op2);
4433 if (! pat)
4434 return 0;
4435 emit_insn (pat);
4436
4437 return target;
4438}
92898235 4439
3a9b8c7e 4440/* Expand the lvx builtins. */
0ac081f6 4441static rtx
3a9b8c7e 4442altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4443 tree exp;
4444 rtx target;
92898235 4445 bool *expandedp;
0ac081f6 4446{
0ac081f6
AH
4447 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4448 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4449 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4450 tree arg0;
4451 enum machine_mode tmode, mode0;
7c3abc73 4452 rtx pat, op0;
3a9b8c7e 4453 enum insn_code icode;
92898235 4454
0ac081f6
AH
4455 switch (fcode)
4456 {
f18c054f
DB
4457 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4458 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4459 break;
f18c054f
DB
4460 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4461 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4462 break;
4463 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4464 icode = CODE_FOR_altivec_lvx_4si;
4465 break;
4466 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4467 icode = CODE_FOR_altivec_lvx_4sf;
4468 break;
4469 default:
4470 *expandedp = false;
4471 return NULL_RTX;
4472 }
0ac081f6 4473
3a9b8c7e 4474 *expandedp = true;
f18c054f 4475
3a9b8c7e
AH
4476 arg0 = TREE_VALUE (arglist);
4477 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4478 tmode = insn_data[icode].operand[0].mode;
4479 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4480
3a9b8c7e
AH
4481 if (target == 0
4482 || GET_MODE (target) != tmode
4483 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4484 target = gen_reg_rtx (tmode);
24408032 4485
3a9b8c7e
AH
4486 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4487 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4488
3a9b8c7e
AH
4489 pat = GEN_FCN (icode) (target, op0);
4490 if (! pat)
4491 return 0;
4492 emit_insn (pat);
4493 return target;
4494}
f18c054f 4495
3a9b8c7e
AH
4496/* Expand the stvx builtins. */
4497static rtx
4498altivec_expand_st_builtin (exp, target, expandedp)
4499 tree exp;
7c3abc73 4500 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4501 bool *expandedp;
4502{
4503 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4504 tree arglist = TREE_OPERAND (exp, 1);
4505 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4506 tree arg0, arg1;
4507 enum machine_mode mode0, mode1;
7c3abc73 4508 rtx pat, op0, op1;
3a9b8c7e 4509 enum insn_code icode;
f18c054f 4510
3a9b8c7e
AH
4511 switch (fcode)
4512 {
4513 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4514 icode = CODE_FOR_altivec_stvx_16qi;
4515 break;
4516 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4517 icode = CODE_FOR_altivec_stvx_8hi;
4518 break;
4519 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4520 icode = CODE_FOR_altivec_stvx_4si;
4521 break;
4522 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4523 icode = CODE_FOR_altivec_stvx_4sf;
4524 break;
4525 default:
4526 *expandedp = false;
4527 return NULL_RTX;
4528 }
24408032 4529
3a9b8c7e
AH
4530 arg0 = TREE_VALUE (arglist);
4531 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4532 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4533 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4534 mode0 = insn_data[icode].operand[0].mode;
4535 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4536
3a9b8c7e
AH
4537 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4538 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4539 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4540 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4541
3a9b8c7e
AH
4542 pat = GEN_FCN (icode) (op0, op1);
4543 if (pat)
4544 emit_insn (pat);
f18c054f 4545
3a9b8c7e
AH
4546 *expandedp = true;
4547 return NULL_RTX;
4548}
f18c054f 4549
3a9b8c7e
AH
4550/* Expand the dst builtins. */
4551static rtx
4552altivec_expand_dst_builtin (exp, target, expandedp)
4553 tree exp;
7c3abc73 4554 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4555 bool *expandedp;
4556{
4557 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4558 tree arglist = TREE_OPERAND (exp, 1);
4559 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4560 tree arg0, arg1, arg2;
4561 enum machine_mode mode0, mode1, mode2;
7c3abc73 4562 rtx pat, op0, op1, op2;
3a9b8c7e 4563 struct builtin_description *d;
a3170dc6 4564 size_t i;
f18c054f 4565
3a9b8c7e 4566 *expandedp = false;
f18c054f 4567
3a9b8c7e
AH
4568 /* Handle DST variants. */
4569 d = (struct builtin_description *) bdesc_dst;
4570 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4571 if (d->code == fcode)
4572 {
4573 arg0 = TREE_VALUE (arglist);
4574 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4575 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4576 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4577 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4578 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4579 mode0 = insn_data[d->icode].operand[0].mode;
4580 mode1 = insn_data[d->icode].operand[1].mode;
4581 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4582
3a9b8c7e
AH
4583 /* Invalid arguments, bail out before generating bad rtl. */
4584 if (arg0 == error_mark_node
4585 || arg1 == error_mark_node
4586 || arg2 == error_mark_node)
4587 return const0_rtx;
f18c054f 4588
3a9b8c7e
AH
4589 if (TREE_CODE (arg2) != INTEGER_CST
4590 || TREE_INT_CST_LOW (arg2) & ~0x3)
4591 {
4592 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4593 return const0_rtx;
4594 }
f18c054f 4595
3a9b8c7e
AH
4596 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4597 op0 = copy_to_mode_reg (mode0, op0);
4598 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4599 op1 = copy_to_mode_reg (mode1, op1);
24408032 4600
3a9b8c7e
AH
4601 pat = GEN_FCN (d->icode) (op0, op1, op2);
4602 if (pat != 0)
4603 emit_insn (pat);
f18c054f 4604
3a9b8c7e
AH
4605 *expandedp = true;
4606 return NULL_RTX;
4607 }
f18c054f 4608
3a9b8c7e
AH
4609 return NULL_RTX;
4610}
24408032 4611
3a9b8c7e
AH
4612/* Expand the builtin in EXP and store the result in TARGET. Store
4613 true in *EXPANDEDP if we found a builtin to expand. */
4614static rtx
4615altivec_expand_builtin (exp, target, expandedp)
4616 tree exp;
4617 rtx target;
4618 bool *expandedp;
4619{
4620 struct builtin_description *d;
4621 struct builtin_description_predicates *dp;
4622 size_t i;
4623 enum insn_code icode;
4624 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4625 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4626 tree arg0;
4627 rtx op0, pat;
4628 enum machine_mode tmode, mode0;
3a9b8c7e 4629 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4630
3a9b8c7e
AH
4631 target = altivec_expand_ld_builtin (exp, target, expandedp);
4632 if (*expandedp)
4633 return target;
0ac081f6 4634
3a9b8c7e
AH
4635 target = altivec_expand_st_builtin (exp, target, expandedp);
4636 if (*expandedp)
4637 return target;
4638
4639 target = altivec_expand_dst_builtin (exp, target, expandedp);
4640 if (*expandedp)
4641 return target;
4642
4643 *expandedp = true;
95385cbb 4644
3a9b8c7e
AH
4645 switch (fcode)
4646 {
6525c0e7
AH
4647 case ALTIVEC_BUILTIN_STVX:
4648 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4649 case ALTIVEC_BUILTIN_STVEBX:
4650 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4651 case ALTIVEC_BUILTIN_STVEHX:
4652 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4653 case ALTIVEC_BUILTIN_STVEWX:
4654 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4655 case ALTIVEC_BUILTIN_STVXL:
4656 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4657
95385cbb
AH
4658 case ALTIVEC_BUILTIN_MFVSCR:
4659 icode = CODE_FOR_altivec_mfvscr;
4660 tmode = insn_data[icode].operand[0].mode;
4661
4662 if (target == 0
4663 || GET_MODE (target) != tmode
4664 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4665 target = gen_reg_rtx (tmode);
4666
4667 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4668 if (! pat)
4669 return 0;
4670 emit_insn (pat);
95385cbb
AH
4671 return target;
4672
4673 case ALTIVEC_BUILTIN_MTVSCR:
4674 icode = CODE_FOR_altivec_mtvscr;
4675 arg0 = TREE_VALUE (arglist);
4676 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4677 mode0 = insn_data[icode].operand[0].mode;
4678
4679 /* If we got invalid arguments bail out before generating bad rtl. */
4680 if (arg0 == error_mark_node)
9a171fcd 4681 return const0_rtx;
95385cbb
AH
4682
4683 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4684 op0 = copy_to_mode_reg (mode0, op0);
4685
4686 pat = GEN_FCN (icode) (op0);
4687 if (pat)
4688 emit_insn (pat);
4689 return NULL_RTX;
3a9b8c7e 4690
95385cbb
AH
4691 case ALTIVEC_BUILTIN_DSSALL:
4692 emit_insn (gen_altivec_dssall ());
4693 return NULL_RTX;
4694
4695 case ALTIVEC_BUILTIN_DSS:
4696 icode = CODE_FOR_altivec_dss;
4697 arg0 = TREE_VALUE (arglist);
4698 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4699 mode0 = insn_data[icode].operand[0].mode;
4700
4701 /* If we got invalid arguments bail out before generating bad rtl. */
4702 if (arg0 == error_mark_node)
9a171fcd 4703 return const0_rtx;
95385cbb 4704
b44140e7
AH
4705 if (TREE_CODE (arg0) != INTEGER_CST
4706 || TREE_INT_CST_LOW (arg0) & ~0x3)
4707 {
4708 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4709 return const0_rtx;
b44140e7
AH
4710 }
4711
95385cbb
AH
4712 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4713 op0 = copy_to_mode_reg (mode0, op0);
4714
4715 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4716 return NULL_RTX;
4717 }
24408032 4718
100c4561
AH
4719 /* Expand abs* operations. */
4720 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4721 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4722 if (d->code == fcode)
4723 return altivec_expand_abs_builtin (d->icode, arglist, target);
4724
ae4b4a02
AH
4725 /* Expand the AltiVec predicates. */
4726 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4727 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4728 if (dp->code == fcode)
4729 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4730
6525c0e7
AH
4731 /* LV* are funky. We initialized them differently. */
4732 switch (fcode)
4733 {
4734 case ALTIVEC_BUILTIN_LVSL:
92898235 4735 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
4736 arglist, target);
4737 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
4738 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4739 arglist, target);
6525c0e7 4740 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
4741 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4742 arglist, target);
6525c0e7 4743 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
4744 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4745 arglist, target);
6525c0e7 4746 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
4747 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4748 arglist, target);
6525c0e7 4749 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
4750 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4751 arglist, target);
6525c0e7 4752 case ALTIVEC_BUILTIN_LVX:
92898235
AH
4753 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4754 arglist, target);
6525c0e7
AH
4755 default:
4756 break;
4757 /* Fall through. */
4758 }
95385cbb 4759
92898235 4760 *expandedp = false;
0ac081f6
AH
4761 return NULL_RTX;
4762}
4763
a3170dc6
AH
4764/* Binops that need to be initialized manually, but can be expanded
4765 automagically by rs6000_expand_binop_builtin. */
4766static struct builtin_description bdesc_2arg_spe[] =
4767{
4768 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4769 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4770 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4771 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4772 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4773 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4774 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4775 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4776 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4777 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4778 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4779 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4780 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4781 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4782 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4783 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4784 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4785 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4786 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4787 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4788 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4789 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4790};
4791
4792/* Expand the builtin in EXP and store the result in TARGET. Store
4793 true in *EXPANDEDP if we found a builtin to expand.
4794
4795 This expands the SPE builtins that are not simple unary and binary
4796 operations. */
4797static rtx
4798spe_expand_builtin (exp, target, expandedp)
4799 tree exp;
4800 rtx target;
4801 bool *expandedp;
4802{
4803 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4804 tree arglist = TREE_OPERAND (exp, 1);
4805 tree arg1, arg0;
4806 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4807 enum insn_code icode;
4808 enum machine_mode tmode, mode0;
4809 rtx pat, op0;
4810 struct builtin_description *d;
4811 size_t i;
4812
4813 *expandedp = true;
4814
4815 /* Syntax check for a 5-bit unsigned immediate. */
4816 switch (fcode)
4817 {
4818 case SPE_BUILTIN_EVSTDD:
4819 case SPE_BUILTIN_EVSTDH:
4820 case SPE_BUILTIN_EVSTDW:
4821 case SPE_BUILTIN_EVSTWHE:
4822 case SPE_BUILTIN_EVSTWHO:
4823 case SPE_BUILTIN_EVSTWWE:
4824 case SPE_BUILTIN_EVSTWWO:
4825 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4826 if (TREE_CODE (arg1) != INTEGER_CST
4827 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4828 {
4829 error ("argument 2 must be a 5-bit unsigned literal");
4830 return const0_rtx;
4831 }
4832 break;
4833 default:
4834 break;
4835 }
4836
4837 d = (struct builtin_description *) bdesc_2arg_spe;
4838 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4839 if (d->code == fcode)
4840 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4841
4842 d = (struct builtin_description *) bdesc_spe_predicates;
4843 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4844 if (d->code == fcode)
4845 return spe_expand_predicate_builtin (d->icode, arglist, target);
4846
4847 d = (struct builtin_description *) bdesc_spe_evsel;
4848 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4849 if (d->code == fcode)
4850 return spe_expand_evsel_builtin (d->icode, arglist, target);
4851
4852 switch (fcode)
4853 {
4854 case SPE_BUILTIN_EVSTDDX:
4855 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4856 case SPE_BUILTIN_EVSTDHX:
4857 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4858 case SPE_BUILTIN_EVSTDWX:
4859 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
4860 case SPE_BUILTIN_EVSTWHEX:
4861 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
4862 case SPE_BUILTIN_EVSTWHOX:
4863 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
4864 case SPE_BUILTIN_EVSTWWEX:
4865 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
4866 case SPE_BUILTIN_EVSTWWOX:
4867 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
4868 case SPE_BUILTIN_EVSTDD:
4869 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
4870 case SPE_BUILTIN_EVSTDH:
4871 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
4872 case SPE_BUILTIN_EVSTDW:
4873 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
4874 case SPE_BUILTIN_EVSTWHE:
4875 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
4876 case SPE_BUILTIN_EVSTWHO:
4877 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
4878 case SPE_BUILTIN_EVSTWWE:
4879 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
4880 case SPE_BUILTIN_EVSTWWO:
4881 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
4882 case SPE_BUILTIN_MFSPEFSCR:
4883 icode = CODE_FOR_spe_mfspefscr;
4884 tmode = insn_data[icode].operand[0].mode;
4885
4886 if (target == 0
4887 || GET_MODE (target) != tmode
4888 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4889 target = gen_reg_rtx (tmode);
4890
4891 pat = GEN_FCN (icode) (target);
4892 if (! pat)
4893 return 0;
4894 emit_insn (pat);
4895 return target;
4896 case SPE_BUILTIN_MTSPEFSCR:
4897 icode = CODE_FOR_spe_mtspefscr;
4898 arg0 = TREE_VALUE (arglist);
4899 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4900 mode0 = insn_data[icode].operand[0].mode;
4901
4902 if (arg0 == error_mark_node)
4903 return const0_rtx;
4904
4905 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4906 op0 = copy_to_mode_reg (mode0, op0);
4907
4908 pat = GEN_FCN (icode) (op0);
4909 if (pat)
4910 emit_insn (pat);
4911 return NULL_RTX;
4912 default:
4913 break;
4914 }
4915
4916 *expandedp = false;
4917 return NULL_RTX;
4918}
4919
4920static rtx
4921spe_expand_predicate_builtin (icode, arglist, target)
4922 enum insn_code icode;
4923 tree arglist;
4924 rtx target;
4925{
4926 rtx pat, scratch, tmp;
4927 tree form = TREE_VALUE (arglist);
4928 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4929 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4930 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4931 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4932 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4933 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4934 int form_int;
4935 enum rtx_code code;
4936
4937 if (TREE_CODE (form) != INTEGER_CST)
4938 {
4939 error ("argument 1 of __builtin_spe_predicate must be a constant");
4940 return const0_rtx;
4941 }
4942 else
4943 form_int = TREE_INT_CST_LOW (form);
4944
4945 if (mode0 != mode1)
4946 abort ();
4947
4948 if (arg0 == error_mark_node || arg1 == error_mark_node)
4949 return const0_rtx;
4950
4951 if (target == 0
4952 || GET_MODE (target) != SImode
4953 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
4954 target = gen_reg_rtx (SImode);
4955
4956 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4957 op0 = copy_to_mode_reg (mode0, op0);
4958 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4959 op1 = copy_to_mode_reg (mode1, op1);
4960
4961 scratch = gen_reg_rtx (CCmode);
4962
4963 pat = GEN_FCN (icode) (scratch, op0, op1);
4964 if (! pat)
4965 return const0_rtx;
4966 emit_insn (pat);
4967
4968 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
4969 _lower_. We use one compare, but look in different bits of the
4970 CR for each variant.
4971
4972 There are 2 elements in each SPE simd type (upper/lower). The CR
4973 bits are set as follows:
4974
4975 BIT0 | BIT 1 | BIT 2 | BIT 3
4976 U | L | (U | L) | (U & L)
4977
4978 So, for an "all" relationship, BIT 3 would be set.
4979 For an "any" relationship, BIT 2 would be set. Etc.
4980
4981 Following traditional nomenclature, these bits map to:
4982
4983 BIT0 | BIT 1 | BIT 2 | BIT 3
4984 LT | GT | EQ | OV
4985
4986 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
4987 */
4988
4989 switch (form_int)
4990 {
4991 /* All variant. OV bit. */
4992 case 0:
4993 /* We need to get to the OV bit, which is the ORDERED bit. We
4994 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
4995 that's ugly and will trigger a validate_condition_mode abort.
4996 So let's just use another pattern. */
4997 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
4998 return target;
4999 /* Any variant. EQ bit. */
5000 case 1:
5001 code = EQ;
5002 break;
5003 /* Upper variant. LT bit. */
5004 case 2:
5005 code = LT;
5006 break;
5007 /* Lower variant. GT bit. */
5008 case 3:
5009 code = GT;
5010 break;
5011 default:
5012 error ("argument 1 of __builtin_spe_predicate is out of range");
5013 return const0_rtx;
5014 }
5015
5016 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5017 emit_move_insn (target, tmp);
5018
5019 return target;
5020}
5021
5022/* The evsel builtins look like this:
5023
5024 e = __builtin_spe_evsel_OP (a, b, c, d);
5025
5026 and work like this:
5027
5028 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5029 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5030*/
5031
5032static rtx
5033spe_expand_evsel_builtin (icode, arglist, target)
5034 enum insn_code icode;
5035 tree arglist;
5036 rtx target;
5037{
5038 rtx pat, scratch;
5039 tree arg0 = TREE_VALUE (arglist);
5040 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5041 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5042 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5043 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5044 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5045 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5046 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5047 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5048 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5049
5050 if (mode0 != mode1)
5051 abort ();
5052
5053 if (arg0 == error_mark_node || arg1 == error_mark_node
5054 || arg2 == error_mark_node || arg3 == error_mark_node)
5055 return const0_rtx;
5056
5057 if (target == 0
5058 || GET_MODE (target) != mode0
5059 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5060 target = gen_reg_rtx (mode0);
5061
5062 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5063 op0 = copy_to_mode_reg (mode0, op0);
5064 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5065 op1 = copy_to_mode_reg (mode0, op1);
5066 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5067 op2 = copy_to_mode_reg (mode0, op2);
5068 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5069 op3 = copy_to_mode_reg (mode0, op3);
5070
5071 /* Generate the compare. */
5072 scratch = gen_reg_rtx (CCmode);
5073 pat = GEN_FCN (icode) (scratch, op0, op1);
5074 if (! pat)
5075 return const0_rtx;
5076 emit_insn (pat);
5077
5078 if (mode0 == V2SImode)
5079 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5080 else
5081 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5082
5083 return target;
5084}
5085
0ac081f6
AH
5086/* Expand an expression EXP that calls a built-in function,
5087 with result going to TARGET if that's convenient
5088 (and in mode MODE if that's convenient).
5089 SUBTARGET may be used as the target for computing one of EXP's operands.
5090 IGNORE is nonzero if the value is to be ignored. */
5091
5092static rtx
5093rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5094 tree exp;
5095 rtx target;
00b960c7
AH
5096 rtx subtarget ATTRIBUTE_UNUSED;
5097 enum machine_mode mode ATTRIBUTE_UNUSED;
5098 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5099{
92898235
AH
5100 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5101 tree arglist = TREE_OPERAND (exp, 1);
5102 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5103 struct builtin_description *d;
5104 size_t i;
5105 rtx ret;
5106 bool success;
5107
0ac081f6 5108 if (TARGET_ALTIVEC)
92898235
AH
5109 {
5110 ret = altivec_expand_builtin (exp, target, &success);
5111
a3170dc6
AH
5112 if (success)
5113 return ret;
5114 }
5115 if (TARGET_SPE)
5116 {
5117 ret = spe_expand_builtin (exp, target, &success);
5118
92898235
AH
5119 if (success)
5120 return ret;
5121 }
5122
0559cc77
DE
5123 if (TARGET_ALTIVEC || TARGET_SPE)
5124 {
5125 /* Handle simple unary operations. */
5126 d = (struct builtin_description *) bdesc_1arg;
5127 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5128 if (d->code == fcode)
5129 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5130
5131 /* Handle simple binary operations. */
5132 d = (struct builtin_description *) bdesc_2arg;
5133 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5134 if (d->code == fcode)
5135 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5136
5137 /* Handle simple ternary operations. */
5138 d = (struct builtin_description *) bdesc_3arg;
5139 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5140 if (d->code == fcode)
5141 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5142 }
0ac081f6
AH
5143
5144 abort ();
92898235 5145 return NULL_RTX;
0ac081f6
AH
5146}
5147
5148static void
6fa3f289 5149rs6000_init_builtins ()
0ac081f6 5150{
a3170dc6
AH
5151 if (TARGET_SPE)
5152 spe_init_builtins ();
0ac081f6
AH
5153 if (TARGET_ALTIVEC)
5154 altivec_init_builtins ();
0559cc77
DE
5155 if (TARGET_ALTIVEC || TARGET_SPE)
5156 rs6000_common_init_builtins ();
0ac081f6
AH
5157}
5158
a3170dc6
AH
5159/* Search through a set of builtins and enable the mask bits.
5160 DESC is an array of builtins.
5161 SIZE is the totaly number of builtins.
5162 START is the builtin enum at which to start.
5163 END is the builtin enum at which to end. */
0ac081f6 5164static void
a3170dc6
AH
5165enable_mask_for_builtins (desc, size, start, end)
5166 struct builtin_description *desc;
5167 int size;
5168 enum rs6000_builtins start, end;
5169{
5170 int i;
5171
5172 for (i = 0; i < size; ++i)
5173 if (desc[i].code == start)
5174 break;
5175
5176 if (i == size)
5177 return;
5178
5179 for (; i < size; ++i)
5180 {
5181 /* Flip all the bits on. */
5182 desc[i].mask = target_flags;
5183 if (desc[i].code == end)
5184 break;
5185 }
5186}
5187
5188static void
b24c9d35 5189spe_init_builtins ()
0ac081f6 5190{
a3170dc6
AH
5191 tree endlink = void_list_node;
5192 tree puint_type_node = build_pointer_type (unsigned_type_node);
5193 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5194 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5195 struct builtin_description *d;
0ac081f6
AH
5196 size_t i;
5197
a3170dc6
AH
5198 tree v2si_ftype_4_v2si
5199 = build_function_type
5200 (V2SI_type_node,
5201 tree_cons (NULL_TREE, V2SI_type_node,
5202 tree_cons (NULL_TREE, V2SI_type_node,
5203 tree_cons (NULL_TREE, V2SI_type_node,
5204 tree_cons (NULL_TREE, V2SI_type_node,
5205 endlink)))));
5206
5207 tree v2sf_ftype_4_v2sf
5208 = build_function_type
5209 (V2SF_type_node,
5210 tree_cons (NULL_TREE, V2SF_type_node,
5211 tree_cons (NULL_TREE, V2SF_type_node,
5212 tree_cons (NULL_TREE, V2SF_type_node,
5213 tree_cons (NULL_TREE, V2SF_type_node,
5214 endlink)))));
5215
5216 tree int_ftype_int_v2si_v2si
5217 = build_function_type
5218 (integer_type_node,
5219 tree_cons (NULL_TREE, integer_type_node,
5220 tree_cons (NULL_TREE, V2SI_type_node,
5221 tree_cons (NULL_TREE, V2SI_type_node,
5222 endlink))));
5223
5224 tree int_ftype_int_v2sf_v2sf
5225 = build_function_type
5226 (integer_type_node,
5227 tree_cons (NULL_TREE, integer_type_node,
5228 tree_cons (NULL_TREE, V2SF_type_node,
5229 tree_cons (NULL_TREE, V2SF_type_node,
5230 endlink))));
5231
5232 tree void_ftype_v2si_puint_int
5233 = build_function_type (void_type_node,
5234 tree_cons (NULL_TREE, V2SI_type_node,
5235 tree_cons (NULL_TREE, puint_type_node,
5236 tree_cons (NULL_TREE,
5237 integer_type_node,
5238 endlink))));
5239
5240 tree void_ftype_v2si_puint_char
5241 = build_function_type (void_type_node,
5242 tree_cons (NULL_TREE, V2SI_type_node,
5243 tree_cons (NULL_TREE, puint_type_node,
5244 tree_cons (NULL_TREE,
5245 char_type_node,
5246 endlink))));
5247
5248 tree void_ftype_v2si_pv2si_int
5249 = build_function_type (void_type_node,
5250 tree_cons (NULL_TREE, V2SI_type_node,
5251 tree_cons (NULL_TREE, pv2si_type_node,
5252 tree_cons (NULL_TREE,
5253 integer_type_node,
5254 endlink))));
5255
5256 tree void_ftype_v2si_pv2si_char
5257 = build_function_type (void_type_node,
5258 tree_cons (NULL_TREE, V2SI_type_node,
5259 tree_cons (NULL_TREE, pv2si_type_node,
5260 tree_cons (NULL_TREE,
5261 char_type_node,
5262 endlink))));
5263
5264 tree void_ftype_int
5265 = build_function_type (void_type_node,
5266 tree_cons (NULL_TREE, integer_type_node, endlink));
5267
5268 tree int_ftype_void
5269 = build_function_type (integer_type_node,
5270 tree_cons (NULL_TREE, void_type_node, endlink));
5271
5272 tree v2si_ftype_pv2si_int
5273 = build_function_type (V2SI_type_node,
5274 tree_cons (NULL_TREE, pv2si_type_node,
5275 tree_cons (NULL_TREE, integer_type_node,
5276 endlink)));
5277
5278 tree v2si_ftype_puint_int
5279 = build_function_type (V2SI_type_node,
5280 tree_cons (NULL_TREE, puint_type_node,
5281 tree_cons (NULL_TREE, integer_type_node,
5282 endlink)));
5283
5284 tree v2si_ftype_pushort_int
5285 = build_function_type (V2SI_type_node,
5286 tree_cons (NULL_TREE, pushort_type_node,
5287 tree_cons (NULL_TREE, integer_type_node,
5288 endlink)));
5289
5290 /* The initialization of the simple binary and unary builtins is
5291 done in rs6000_common_init_builtins, but we have to enable the
5292 mask bits here manually because we have run out of `target_flags'
5293 bits. We really need to redesign this mask business. */
5294
5295 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5296 ARRAY_SIZE (bdesc_2arg),
5297 SPE_BUILTIN_EVADDW,
5298 SPE_BUILTIN_EVXOR);
5299 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5300 ARRAY_SIZE (bdesc_1arg),
5301 SPE_BUILTIN_EVABS,
5302 SPE_BUILTIN_EVSUBFUSIAAW);
5303 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5304 ARRAY_SIZE (bdesc_spe_predicates),
5305 SPE_BUILTIN_EVCMPEQ,
5306 SPE_BUILTIN_EVFSTSTLT);
5307 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5308 ARRAY_SIZE (bdesc_spe_evsel),
5309 SPE_BUILTIN_EVSEL_CMPGTS,
5310 SPE_BUILTIN_EVSEL_FSTSTEQ);
5311
5312 /* Initialize irregular SPE builtins. */
5313
5314 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5315 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5316 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5317 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5318 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5319 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5320 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5321 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5322 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5323 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5324 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5325 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5326 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5327 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5328 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5329 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5330
5331 /* Loads. */
5332 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5333 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5334 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5335 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5336 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5337 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5338 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5339 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5340 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5341 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5342 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5343 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5344 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5345 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5346 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5347 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5348 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5349 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5350 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5351 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5352 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5353 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5354
5355 /* Predicates. */
5356 d = (struct builtin_description *) bdesc_spe_predicates;
5357 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5358 {
5359 tree type;
5360
5361 switch (insn_data[d->icode].operand[1].mode)
5362 {
5363 case V2SImode:
5364 type = int_ftype_int_v2si_v2si;
5365 break;
5366 case V2SFmode:
5367 type = int_ftype_int_v2sf_v2sf;
5368 break;
5369 default:
5370 abort ();
5371 }
5372
5373 def_builtin (d->mask, d->name, type, d->code);
5374 }
5375
5376 /* Evsel predicates. */
5377 d = (struct builtin_description *) bdesc_spe_evsel;
5378 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5379 {
5380 tree type;
5381
5382 switch (insn_data[d->icode].operand[1].mode)
5383 {
5384 case V2SImode:
5385 type = v2si_ftype_4_v2si;
5386 break;
5387 case V2SFmode:
5388 type = v2sf_ftype_4_v2sf;
5389 break;
5390 default:
5391 abort ();
5392 }
5393
5394 def_builtin (d->mask, d->name, type, d->code);
5395 }
5396}
5397
5398static void
b24c9d35 5399altivec_init_builtins ()
a3170dc6
AH
5400{
5401 struct builtin_description *d;
5402 struct builtin_description_predicates *dp;
5403 size_t i;
5404 tree pfloat_type_node = build_pointer_type (float_type_node);
5405 tree pint_type_node = build_pointer_type (integer_type_node);
5406 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5407 tree pchar_type_node = build_pointer_type (char_type_node);
5408
5409 tree pvoid_type_node = build_pointer_type (void_type_node);
5410
5411 tree int_ftype_int_v4si_v4si
5412 = build_function_type_list (integer_type_node,
5413 integer_type_node, V4SI_type_node,
5414 V4SI_type_node, NULL_TREE);
f18c054f 5415 tree v4sf_ftype_pfloat
b4de2f7d 5416 = build_function_type_list (V4SF_type_node, pfloat_type_node, NULL_TREE);
a3170dc6 5417 tree void_ftype_pfloat_v4sf
b4de2f7d 5418 = build_function_type_list (void_type_node,
a3170dc6
AH
5419 pfloat_type_node, V4SF_type_node, NULL_TREE);
5420 tree v4si_ftype_pint
5421 = build_function_type_list (V4SI_type_node, pint_type_node, NULL_TREE); tree void_ftype_pint_v4si
b4de2f7d
AH
5422 = build_function_type_list (void_type_node,
5423 pint_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5424 tree v8hi_ftype_pshort
5425 = build_function_type_list (V8HI_type_node, pshort_type_node, NULL_TREE);
f18c054f 5426 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5427 = build_function_type_list (void_type_node,
5428 pshort_type_node, V8HI_type_node, NULL_TREE);
a3170dc6
AH
5429 tree v16qi_ftype_pchar
5430 = build_function_type_list (V16QI_type_node, pchar_type_node, NULL_TREE);
f18c054f 5431 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5432 = build_function_type_list (void_type_node,
5433 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5434 tree void_ftype_v4si
b4de2f7d 5435 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5436 tree v8hi_ftype_void
5437 = build_function_type (V8HI_type_node, void_list_node);
5438 tree void_ftype_void
5439 = build_function_type (void_type_node, void_list_node);
5440 tree void_ftype_qi
5441 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
5442 tree v16qi_ftype_int_pvoid
5443 = build_function_type_list (V16QI_type_node,
5444 integer_type_node, pvoid_type_node, NULL_TREE);
5445 tree v8hi_ftype_int_pvoid
5446 = build_function_type_list (V8HI_type_node,
5447 integer_type_node, pvoid_type_node, NULL_TREE);
5448 tree v4si_ftype_int_pvoid
5449 = build_function_type_list (V4SI_type_node,
5450 integer_type_node, pvoid_type_node, NULL_TREE);
14b32f4e 5451 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5452 = build_function_type_list (void_type_node,
5453 V4SI_type_node, integer_type_node,
5454 pvoid_type_node, NULL_TREE);
6525c0e7 5455 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5456 = build_function_type_list (void_type_node,
5457 V16QI_type_node, integer_type_node,
5458 pvoid_type_node, NULL_TREE);
6525c0e7 5459 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5460 = build_function_type_list (void_type_node,
5461 V8HI_type_node, integer_type_node,
5462 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5463 tree int_ftype_int_v8hi_v8hi
5464 = build_function_type_list (integer_type_node,
5465 integer_type_node, V8HI_type_node,
5466 V8HI_type_node, NULL_TREE);
5467 tree int_ftype_int_v16qi_v16qi
5468 = build_function_type_list (integer_type_node,
5469 integer_type_node, V16QI_type_node,
5470 V16QI_type_node, NULL_TREE);
5471 tree int_ftype_int_v4sf_v4sf
5472 = build_function_type_list (integer_type_node,
5473 integer_type_node, V4SF_type_node,
5474 V4SF_type_node, NULL_TREE);
5475 tree v4si_ftype_v4si
5476 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5477 tree v8hi_ftype_v8hi
5478 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5479 tree v16qi_ftype_v16qi
5480 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5481 tree v4sf_ftype_v4sf
5482 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5483 tree void_ftype_pvoid_int_char
5484 = build_function_type_list (void_type_node,
5485 pvoid_type_node, integer_type_node,
5486 char_type_node, NULL_TREE);
5487
5488 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pfloat, ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5489 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf, ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5490 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5491 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5492 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pshort, ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5493 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi, ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5494 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pchar, ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5495 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi, ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
5496 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5497 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5498 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5499 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
5500 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
5501 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
5502 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEBX);
5503 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEHX);
5504 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEWX);
5505 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVXL);
5506 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVX);
5507 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5508 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5509 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5510 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5511 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5512
5513 /* Add the DST variants. */
5514 d = (struct builtin_description *) bdesc_dst;
5515 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
5516 def_builtin (d->mask, d->name, void_ftype_pvoid_int_char, d->code);
5517
5518 /* Initialize the predicates. */
5519 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5520 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5521 {
5522 enum machine_mode mode1;
5523 tree type;
5524
5525 mode1 = insn_data[dp->icode].operand[1].mode;
5526
5527 switch (mode1)
5528 {
5529 case V4SImode:
5530 type = int_ftype_int_v4si_v4si;
5531 break;
5532 case V8HImode:
5533 type = int_ftype_int_v8hi_v8hi;
5534 break;
5535 case V16QImode:
5536 type = int_ftype_int_v16qi_v16qi;
5537 break;
5538 case V4SFmode:
5539 type = int_ftype_int_v4sf_v4sf;
5540 break;
5541 default:
5542 abort ();
5543 }
5544
5545 def_builtin (dp->mask, dp->name, type, dp->code);
5546 }
5547
5548 /* Initialize the abs* operators. */
5549 d = (struct builtin_description *) bdesc_abs;
5550 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5551 {
5552 enum machine_mode mode0;
5553 tree type;
5554
5555 mode0 = insn_data[d->icode].operand[0].mode;
5556
5557 switch (mode0)
5558 {
5559 case V4SImode:
5560 type = v4si_ftype_v4si;
5561 break;
5562 case V8HImode:
5563 type = v8hi_ftype_v8hi;
5564 break;
5565 case V16QImode:
5566 type = v16qi_ftype_v16qi;
5567 break;
5568 case V4SFmode:
5569 type = v4sf_ftype_v4sf;
5570 break;
5571 default:
5572 abort ();
5573 }
5574
5575 def_builtin (d->mask, d->name, type, d->code);
5576 }
5577}
5578
5579static void
b24c9d35 5580rs6000_common_init_builtins ()
a3170dc6
AH
5581{
5582 struct builtin_description *d;
5583 size_t i;
5584
5585 tree v4sf_ftype_v4sf_v4sf_v16qi
5586 = build_function_type_list (V4SF_type_node,
5587 V4SF_type_node, V4SF_type_node,
5588 V16QI_type_node, NULL_TREE);
5589 tree v4si_ftype_v4si_v4si_v16qi
5590 = build_function_type_list (V4SI_type_node,
5591 V4SI_type_node, V4SI_type_node,
5592 V16QI_type_node, NULL_TREE);
5593 tree v8hi_ftype_v8hi_v8hi_v16qi
5594 = build_function_type_list (V8HI_type_node,
5595 V8HI_type_node, V8HI_type_node,
5596 V16QI_type_node, NULL_TREE);
5597 tree v16qi_ftype_v16qi_v16qi_v16qi
5598 = build_function_type_list (V16QI_type_node,
5599 V16QI_type_node, V16QI_type_node,
5600 V16QI_type_node, NULL_TREE);
5601 tree v4si_ftype_char
5602 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5603 tree v8hi_ftype_char
5604 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5605 tree v16qi_ftype_char
5606 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5607 tree v8hi_ftype_v16qi
5608 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5609 tree v4sf_ftype_v4sf
5610 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5611
5612 tree v2si_ftype_v2si_v2si
5613 = build_function_type_list (V2SI_type_node,
5614 V2SI_type_node, V2SI_type_node, NULL_TREE);
5615
5616 tree v2sf_ftype_v2sf_v2sf
5617 = build_function_type_list (V2SF_type_node,
5618 V2SF_type_node, V2SF_type_node, NULL_TREE);
5619
5620 tree v2si_ftype_int_int
5621 = build_function_type_list (V2SI_type_node,
5622 integer_type_node, integer_type_node,
5623 NULL_TREE);
5624
5625 tree v2si_ftype_v2si
5626 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5627
5628 tree v2sf_ftype_v2sf
5629 = build_function_type_list (V2SF_type_node,
5630 V2SF_type_node, NULL_TREE);
5631
5632 tree v2sf_ftype_v2si
5633 = build_function_type_list (V2SF_type_node,
5634 V2SI_type_node, NULL_TREE);
5635
5636 tree v2si_ftype_v2sf
5637 = build_function_type_list (V2SI_type_node,
5638 V2SF_type_node, NULL_TREE);
5639
5640 tree v2si_ftype_v2si_char
5641 = build_function_type_list (V2SI_type_node,
5642 V2SI_type_node, char_type_node, NULL_TREE);
5643
5644 tree v2si_ftype_int_char
5645 = build_function_type_list (V2SI_type_node,
5646 integer_type_node, char_type_node, NULL_TREE);
5647
5648 tree v2si_ftype_char
5649 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5650
5651 tree int_ftype_int_int
5652 = build_function_type_list (integer_type_node,
5653 integer_type_node, integer_type_node,
5654 NULL_TREE);
95385cbb 5655
0ac081f6 5656 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5657 = build_function_type_list (V4SI_type_node,
5658 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5659 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5660 = build_function_type_list (V4SF_type_node,
5661 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5662 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5663 = build_function_type_list (V4SI_type_node,
5664 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5665 tree v4si_ftype_v4si_char
b4de2f7d
AH
5666 = build_function_type_list (V4SI_type_node,
5667 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5668 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5669 = build_function_type_list (V8HI_type_node,
5670 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5671 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5672 = build_function_type_list (V16QI_type_node,
5673 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5674 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5675 = build_function_type_list (V16QI_type_node,
5676 V16QI_type_node, V16QI_type_node,
5677 char_type_node, NULL_TREE);
24408032 5678 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5679 = build_function_type_list (V8HI_type_node,
5680 V8HI_type_node, V8HI_type_node,
5681 char_type_node, NULL_TREE);
24408032 5682 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5683 = build_function_type_list (V4SI_type_node,
5684 V4SI_type_node, V4SI_type_node,
5685 char_type_node, NULL_TREE);
24408032 5686 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5687 = build_function_type_list (V4SF_type_node,
5688 V4SF_type_node, V4SF_type_node,
5689 char_type_node, NULL_TREE);
0ac081f6 5690 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5691 = build_function_type_list (V4SF_type_node,
5692 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5693 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5694 = build_function_type_list (V4SF_type_node,
5695 V4SF_type_node, V4SF_type_node,
5696 V4SI_type_node, NULL_TREE);
2212663f 5697 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5698 = build_function_type_list (V4SF_type_node,
5699 V4SF_type_node, V4SF_type_node,
5700 V4SF_type_node, NULL_TREE);
617e0e1d 5701 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
5702 = build_function_type_list (V4SI_type_node,
5703 V4SI_type_node, V4SI_type_node,
5704 V4SI_type_node, NULL_TREE);
0ac081f6 5705 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
5706 = build_function_type_list (V8HI_type_node,
5707 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 5708 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
5709 = build_function_type_list (V8HI_type_node,
5710 V8HI_type_node, V8HI_type_node,
5711 V8HI_type_node, NULL_TREE);
2212663f 5712 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
5713 = build_function_type_list (V4SI_type_node,
5714 V8HI_type_node, V8HI_type_node,
5715 V4SI_type_node, NULL_TREE);
2212663f 5716 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
5717 = build_function_type_list (V4SI_type_node,
5718 V16QI_type_node, V16QI_type_node,
5719 V4SI_type_node, NULL_TREE);
0ac081f6 5720 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
5721 = build_function_type_list (V16QI_type_node,
5722 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5723 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
5724 = build_function_type_list (V4SI_type_node,
5725 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 5726 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
5727 = build_function_type_list (V8HI_type_node,
5728 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5729 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
5730 = build_function_type_list (V4SI_type_node,
5731 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5732 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
5733 = build_function_type_list (V8HI_type_node,
5734 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 5735 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
5736 = build_function_type_list (V16QI_type_node,
5737 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5738 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
5739 = build_function_type_list (V4SI_type_node,
5740 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 5741 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
5742 = build_function_type_list (V4SI_type_node,
5743 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5744 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
5745 = build_function_type_list (V4SI_type_node,
5746 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5747 tree v4si_ftype_v8hi
5748 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5749 tree int_ftype_v4si_v4si
5750 = build_function_type_list (integer_type_node,
5751 V4SI_type_node, V4SI_type_node, NULL_TREE);
5752 tree int_ftype_v4sf_v4sf
5753 = build_function_type_list (integer_type_node,
5754 V4SF_type_node, V4SF_type_node, NULL_TREE);
5755 tree int_ftype_v16qi_v16qi
5756 = build_function_type_list (integer_type_node,
5757 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5758 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
5759 = build_function_type_list (integer_type_node,
5760 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5761
6f317ef3 5762 /* Add the simple ternary operators. */
2212663f 5763 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 5764 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
5765 {
5766
5767 enum machine_mode mode0, mode1, mode2, mode3;
5768 tree type;
5769
0559cc77 5770 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5771 continue;
5772
5773 mode0 = insn_data[d->icode].operand[0].mode;
5774 mode1 = insn_data[d->icode].operand[1].mode;
5775 mode2 = insn_data[d->icode].operand[2].mode;
5776 mode3 = insn_data[d->icode].operand[3].mode;
5777
5778 /* When all four are of the same mode. */
5779 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5780 {
5781 switch (mode0)
5782 {
617e0e1d
DB
5783 case V4SImode:
5784 type = v4si_ftype_v4si_v4si_v4si;
5785 break;
2212663f
DB
5786 case V4SFmode:
5787 type = v4sf_ftype_v4sf_v4sf_v4sf;
5788 break;
5789 case V8HImode:
5790 type = v8hi_ftype_v8hi_v8hi_v8hi;
5791 break;
5792 case V16QImode:
5793 type = v16qi_ftype_v16qi_v16qi_v16qi;
5794 break;
5795 default:
5796 abort();
5797 }
5798 }
5799 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5800 {
5801 switch (mode0)
5802 {
5803 case V4SImode:
5804 type = v4si_ftype_v4si_v4si_v16qi;
5805 break;
5806 case V4SFmode:
5807 type = v4sf_ftype_v4sf_v4sf_v16qi;
5808 break;
5809 case V8HImode:
5810 type = v8hi_ftype_v8hi_v8hi_v16qi;
5811 break;
5812 case V16QImode:
5813 type = v16qi_ftype_v16qi_v16qi_v16qi;
5814 break;
5815 default:
5816 abort();
5817 }
5818 }
5819 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5820 && mode3 == V4SImode)
24408032 5821 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
5822 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5823 && mode3 == V4SImode)
24408032 5824 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
5825 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5826 && mode3 == V4SImode)
24408032
AH
5827 type = v4sf_ftype_v4sf_v4sf_v4si;
5828
5829 /* vchar, vchar, vchar, 4 bit literal. */
5830 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5831 && mode3 == QImode)
5832 type = v16qi_ftype_v16qi_v16qi_char;
5833
5834 /* vshort, vshort, vshort, 4 bit literal. */
5835 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5836 && mode3 == QImode)
5837 type = v8hi_ftype_v8hi_v8hi_char;
5838
5839 /* vint, vint, vint, 4 bit literal. */
5840 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
5841 && mode3 == QImode)
5842 type = v4si_ftype_v4si_v4si_char;
5843
5844 /* vfloat, vfloat, vfloat, 4 bit literal. */
5845 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
5846 && mode3 == QImode)
5847 type = v4sf_ftype_v4sf_v4sf_char;
5848
2212663f
DB
5849 else
5850 abort ();
5851
5852 def_builtin (d->mask, d->name, type, d->code);
5853 }
5854
0ac081f6 5855 /* Add the simple binary operators. */
00b960c7 5856 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 5857 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
5858 {
5859 enum machine_mode mode0, mode1, mode2;
5860 tree type;
5861
0559cc77 5862 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
5863 continue;
5864
5865 mode0 = insn_data[d->icode].operand[0].mode;
5866 mode1 = insn_data[d->icode].operand[1].mode;
5867 mode2 = insn_data[d->icode].operand[2].mode;
5868
5869 /* When all three operands are of the same mode. */
5870 if (mode0 == mode1 && mode1 == mode2)
5871 {
5872 switch (mode0)
5873 {
5874 case V4SFmode:
5875 type = v4sf_ftype_v4sf_v4sf;
5876 break;
5877 case V4SImode:
5878 type = v4si_ftype_v4si_v4si;
5879 break;
5880 case V16QImode:
5881 type = v16qi_ftype_v16qi_v16qi;
5882 break;
5883 case V8HImode:
5884 type = v8hi_ftype_v8hi_v8hi;
5885 break;
a3170dc6
AH
5886 case V2SImode:
5887 type = v2si_ftype_v2si_v2si;
5888 break;
5889 case V2SFmode:
5890 type = v2sf_ftype_v2sf_v2sf;
5891 break;
5892 case SImode:
5893 type = int_ftype_int_int;
5894 break;
0ac081f6
AH
5895 default:
5896 abort ();
5897 }
5898 }
5899
5900 /* A few other combos we really don't want to do manually. */
5901
5902 /* vint, vfloat, vfloat. */
5903 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
5904 type = v4si_ftype_v4sf_v4sf;
5905
5906 /* vshort, vchar, vchar. */
5907 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
5908 type = v8hi_ftype_v16qi_v16qi;
5909
5910 /* vint, vshort, vshort. */
5911 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
5912 type = v4si_ftype_v8hi_v8hi;
5913
5914 /* vshort, vint, vint. */
5915 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
5916 type = v8hi_ftype_v4si_v4si;
5917
5918 /* vchar, vshort, vshort. */
5919 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
5920 type = v16qi_ftype_v8hi_v8hi;
5921
5922 /* vint, vchar, vint. */
5923 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
5924 type = v4si_ftype_v16qi_v4si;
5925
fa066a23
AH
5926 /* vint, vchar, vchar. */
5927 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
5928 type = v4si_ftype_v16qi_v16qi;
5929
0ac081f6
AH
5930 /* vint, vshort, vint. */
5931 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
5932 type = v4si_ftype_v8hi_v4si;
2212663f
DB
5933
5934 /* vint, vint, 5 bit literal. */
5935 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
5936 type = v4si_ftype_v4si_char;
5937
5938 /* vshort, vshort, 5 bit literal. */
5939 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
5940 type = v8hi_ftype_v8hi_char;
5941
5942 /* vchar, vchar, 5 bit literal. */
5943 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
5944 type = v16qi_ftype_v16qi_char;
0ac081f6 5945
617e0e1d
DB
5946 /* vfloat, vint, 5 bit literal. */
5947 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
5948 type = v4sf_ftype_v4si_char;
5949
5950 /* vint, vfloat, 5 bit literal. */
5951 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
5952 type = v4si_ftype_v4sf_char;
5953
a3170dc6
AH
5954 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
5955 type = v2si_ftype_int_int;
5956
5957 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
5958 type = v2si_ftype_v2si_char;
5959
5960 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
5961 type = v2si_ftype_int_char;
5962
0ac081f6
AH
5963 /* int, x, x. */
5964 else if (mode0 == SImode)
5965 {
5966 switch (mode1)
5967 {
5968 case V4SImode:
5969 type = int_ftype_v4si_v4si;
5970 break;
5971 case V4SFmode:
5972 type = int_ftype_v4sf_v4sf;
5973 break;
5974 case V16QImode:
5975 type = int_ftype_v16qi_v16qi;
5976 break;
5977 case V8HImode:
5978 type = int_ftype_v8hi_v8hi;
5979 break;
5980 default:
5981 abort ();
5982 }
5983 }
5984
5985 else
5986 abort ();
5987
2212663f
DB
5988 def_builtin (d->mask, d->name, type, d->code);
5989 }
24408032 5990
2212663f
DB
5991 /* Add the simple unary operators. */
5992 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 5993 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
5994 {
5995 enum machine_mode mode0, mode1;
5996 tree type;
5997
0559cc77 5998 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5999 continue;
6000
6001 mode0 = insn_data[d->icode].operand[0].mode;
6002 mode1 = insn_data[d->icode].operand[1].mode;
6003
6004 if (mode0 == V4SImode && mode1 == QImode)
6005 type = v4si_ftype_char;
6006 else if (mode0 == V8HImode && mode1 == QImode)
6007 type = v8hi_ftype_char;
6008 else if (mode0 == V16QImode && mode1 == QImode)
6009 type = v16qi_ftype_char;
617e0e1d
DB
6010 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6011 type = v4sf_ftype_v4sf;
20e26713
AH
6012 else if (mode0 == V8HImode && mode1 == V16QImode)
6013 type = v8hi_ftype_v16qi;
6014 else if (mode0 == V4SImode && mode1 == V8HImode)
6015 type = v4si_ftype_v8hi;
a3170dc6
AH
6016 else if (mode0 == V2SImode && mode1 == V2SImode)
6017 type = v2si_ftype_v2si;
6018 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6019 type = v2sf_ftype_v2sf;
6020 else if (mode0 == V2SFmode && mode1 == V2SImode)
6021 type = v2sf_ftype_v2si;
6022 else if (mode0 == V2SImode && mode1 == V2SFmode)
6023 type = v2si_ftype_v2sf;
6024 else if (mode0 == V2SImode && mode1 == QImode)
6025 type = v2si_ftype_char;
2212663f
DB
6026 else
6027 abort ();
6028
0ac081f6
AH
6029 def_builtin (d->mask, d->name, type, d->code);
6030 }
6031}
6032
5b5040b9
RK
6033/* Generate a memory reference for expand_block_move, copying volatile,
6034 and other bits from an original memory reference. */
6035
6036static rtx
6037expand_block_move_mem (mode, addr, orig_mem)
6038 enum machine_mode mode;
6039 rtx addr;
6040 rtx orig_mem;
6041{
39403d82 6042 rtx mem = gen_rtx_MEM (mode, addr);
b6c9286a 6043
c6df88cb 6044 MEM_COPY_ATTRIBUTES (mem, orig_mem);
5b5040b9
RK
6045 return mem;
6046}
6047
7e69e155
MM
6048/* Expand a block move operation, and return 1 if successful. Return 0
6049 if we should let the compiler generate normal code.
6050
6051 operands[0] is the destination
6052 operands[1] is the source
6053 operands[2] is the length
6054 operands[3] is the alignment */
6055
3933e0e1
MM
6056#define MAX_MOVE_REG 4
6057
7e69e155
MM
6058int
6059expand_block_move (operands)
6060 rtx operands[];
6061{
b6c9286a
MM
6062 rtx orig_dest = operands[0];
6063 rtx orig_src = operands[1];
7e69e155 6064 rtx bytes_rtx = operands[2];
7e69e155 6065 rtx align_rtx = operands[3];
3933e0e1 6066 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6067 int align;
3933e0e1
MM
6068 int bytes;
6069 int offset;
6070 int num_reg;
6071 int i;
7e69e155
MM
6072 rtx src_reg;
6073 rtx dest_reg;
3933e0e1
MM
6074 rtx src_addr;
6075 rtx dest_addr;
7e69e155 6076 rtx tmp_reg;
3933e0e1 6077 rtx stores[MAX_MOVE_REG];
7e69e155
MM
6078 int move_bytes;
6079
3933e0e1 6080 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6081 if (! constp)
3933e0e1
MM
6082 return 0;
6083
5ee95df6
FS
6084 /* If this is not a fixed size alignment, abort */
6085 if (GET_CODE (align_rtx) != CONST_INT)
6086 abort ();
6087 align = INTVAL (align_rtx);
6088
7e69e155 6089 /* Anything to move? */
3933e0e1
MM
6090 bytes = INTVAL (bytes_rtx);
6091 if (bytes <= 0)
7e69e155
MM
6092 return 1;
6093
ea9982a8 6094 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6095 reg_parm_stack_space. */
ea9982a8 6096 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6097 return 0;
6098
6099 /* Move the address into scratch registers. */
b6c9286a
MM
6100 dest_reg = copy_addr_to_reg (XEXP (orig_dest, 0));
6101 src_reg = copy_addr_to_reg (XEXP (orig_src, 0));
7e69e155 6102
3933e0e1 6103 if (TARGET_STRING) /* string instructions are available */
7e69e155 6104 {
3933e0e1 6105 for ( ; bytes > 0; bytes -= move_bytes)
7e69e155 6106 {
3933e0e1 6107 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6108 && ! fixed_regs[5]
6109 && ! fixed_regs[6]
6110 && ! fixed_regs[7]
6111 && ! fixed_regs[8]
6112 && ! fixed_regs[9]
6113 && ! fixed_regs[10]
6114 && ! fixed_regs[11]
6115 && ! fixed_regs[12])
3933e0e1
MM
6116 {
6117 move_bytes = (bytes > 32) ? 32 : bytes;
cc0d9ba8
DE
6118 emit_insn (gen_movstrsi_8reg (expand_block_move_mem (BLKmode,
6119 dest_reg,
6120 orig_dest),
6121 expand_block_move_mem (BLKmode,
6122 src_reg,
6123 orig_src),
6124 GEN_INT ((move_bytes == 32)
6125 ? 0 : move_bytes),
4c64a852 6126 align_rtx));
3933e0e1
MM
6127 }
6128 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6129 && ! fixed_regs[5]
6130 && ! fixed_regs[6]
cc0d9ba8
DE
6131 && ! fixed_regs[7]
6132 && ! fixed_regs[8]
6133 && ! fixed_regs[9]
f9562f27 6134 && ! fixed_regs[10])
3933e0e1
MM
6135 {
6136 move_bytes = (bytes > 24) ? 24 : bytes;
cc0d9ba8
DE
6137 emit_insn (gen_movstrsi_6reg (expand_block_move_mem (BLKmode,
6138 dest_reg,
6139 orig_dest),
6140 expand_block_move_mem (BLKmode,
6141 src_reg,
6142 orig_src),
3933e0e1 6143 GEN_INT (move_bytes),
4c64a852 6144 align_rtx));
3933e0e1
MM
6145 }
6146 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6147 && ! fixed_regs[5]
6148 && ! fixed_regs[6]
6149 && ! fixed_regs[7]
6150 && ! fixed_regs[8])
3933e0e1
MM
6151 {
6152 move_bytes = (bytes > 16) ? 16 : bytes;
cc0d9ba8
DE
6153 emit_insn (gen_movstrsi_4reg (expand_block_move_mem (BLKmode,
6154 dest_reg,
6155 orig_dest),
6156 expand_block_move_mem (BLKmode,
6157 src_reg,
6158 orig_src),
3933e0e1 6159 GEN_INT (move_bytes),
4c64a852 6160 align_rtx));
3933e0e1 6161 }
acad7ed3 6162 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6163 /* 64-bit loads and stores require word-aligned
82e41834 6164 displacements. */
a4f6c312 6165 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6166 {
6167 move_bytes = 8;
6168 tmp_reg = gen_reg_rtx (DImode);
6169 emit_move_insn (tmp_reg,
6170 expand_block_move_mem (DImode,
2eba1afa 6171 src_reg, orig_src));
acad7ed3 6172 emit_move_insn (expand_block_move_mem (DImode,
2eba1afa 6173 dest_reg, orig_dest),
acad7ed3
DE
6174 tmp_reg);
6175 }
09a625f7 6176 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6177 { /* move up to 8 bytes at a time */
6178 move_bytes = (bytes > 8) ? 8 : bytes;
cc0d9ba8
DE
6179 emit_insn (gen_movstrsi_2reg (expand_block_move_mem (BLKmode,
6180 dest_reg,
6181 orig_dest),
6182 expand_block_move_mem (BLKmode,
6183 src_reg,
6184 orig_src),
3933e0e1 6185 GEN_INT (move_bytes),
4c64a852 6186 align_rtx));
3933e0e1 6187 }
cc0d9ba8 6188 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6189 { /* move 4 bytes */
6190 move_bytes = 4;
6191 tmp_reg = gen_reg_rtx (SImode);
cc0d9ba8
DE
6192 emit_move_insn (tmp_reg,
6193 expand_block_move_mem (SImode,
6194 src_reg, orig_src));
6195 emit_move_insn (expand_block_move_mem (SImode,
6196 dest_reg, orig_dest),
6197 tmp_reg);
3933e0e1 6198 }
cc0d9ba8 6199 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6200 { /* move 2 bytes */
6201 move_bytes = 2;
6202 tmp_reg = gen_reg_rtx (HImode);
cc0d9ba8
DE
6203 emit_move_insn (tmp_reg,
6204 expand_block_move_mem (HImode,
6205 src_reg, orig_src));
6206 emit_move_insn (expand_block_move_mem (HImode,
6207 dest_reg, orig_dest),
6208 tmp_reg);
3933e0e1
MM
6209 }
6210 else if (bytes == 1) /* move 1 byte */
6211 {
6212 move_bytes = 1;
6213 tmp_reg = gen_reg_rtx (QImode);
cc0d9ba8
DE
6214 emit_move_insn (tmp_reg,
6215 expand_block_move_mem (QImode,
6216 src_reg, orig_src));
6217 emit_move_insn (expand_block_move_mem (QImode,
6218 dest_reg, orig_dest),
6219 tmp_reg);
3933e0e1
MM
6220 }
6221 else
6222 { /* move up to 4 bytes at a time */
6223 move_bytes = (bytes > 4) ? 4 : bytes;
cc0d9ba8
DE
6224 emit_insn (gen_movstrsi_1reg (expand_block_move_mem (BLKmode,
6225 dest_reg,
6226 orig_dest),
6227 expand_block_move_mem (BLKmode,
6228 src_reg,
6229 orig_src),
3933e0e1 6230 GEN_INT (move_bytes),
4c64a852 6231 align_rtx));
3933e0e1 6232 }
4c64a852 6233
015892ee
RK
6234 if (bytes > move_bytes)
6235 {
cc0d9ba8
DE
6236 if (! TARGET_POWERPC64)
6237 {
6238 emit_insn (gen_addsi3 (src_reg, src_reg,
6239 GEN_INT (move_bytes)));
6240 emit_insn (gen_addsi3 (dest_reg, dest_reg,
6241 GEN_INT (move_bytes)));
6242 }
6243 else
6244 {
6245 emit_insn (gen_adddi3 (src_reg, src_reg,
6246 GEN_INT (move_bytes)));
6247 emit_insn (gen_adddi3 (dest_reg, dest_reg,
6248 GEN_INT (move_bytes)));
6249 }
015892ee 6250 }
4c64a852 6251 }
3933e0e1
MM
6252 }
6253
6254 else /* string instructions not available */
6255 {
6256 num_reg = offset = 0;
6257 for ( ; bytes > 0; (bytes -= move_bytes), (offset += move_bytes))
7e69e155 6258 {
3933e0e1
MM
6259 /* Calculate the correct offset for src/dest */
6260 if (offset == 0)
7e69e155 6261 {
3933e0e1
MM
6262 src_addr = src_reg;
6263 dest_addr = dest_reg;
6264 }
6265 else
6266 {
c5c76735
JL
6267 src_addr = plus_constant (src_reg, offset);
6268 dest_addr = plus_constant (dest_reg, offset);
3933e0e1
MM
6269 }
6270
cc0d9ba8
DE
6271 /* Generate the appropriate load and store, saving the stores
6272 for later. */
6273 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6274 /* 64-bit loads and stores require word-aligned
6275 displacements. */
cc0d9ba8 6276 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6277 {
6278 move_bytes = 8;
6279 tmp_reg = gen_reg_rtx (DImode);
cc0d9ba8
DE
6280 emit_insn (gen_movdi (tmp_reg,
6281 expand_block_move_mem (DImode,
6282 src_addr,
6283 orig_src)));
6284 stores[num_reg++] = gen_movdi (expand_block_move_mem (DImode,
6285 dest_addr,
6286 orig_dest),
6287 tmp_reg);
b6c9286a 6288 }
cc0d9ba8 6289 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6290 {
6291 move_bytes = 4;
6292 tmp_reg = gen_reg_rtx (SImode);
cc0d9ba8
DE
6293 emit_insn (gen_movsi (tmp_reg,
6294 expand_block_move_mem (SImode,
6295 src_addr,
6296 orig_src)));
6297 stores[num_reg++] = gen_movsi (expand_block_move_mem (SImode,
6298 dest_addr,
6299 orig_dest),
6300 tmp_reg);
3933e0e1 6301 }
cc0d9ba8 6302 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6303 {
6304 move_bytes = 2;
6305 tmp_reg = gen_reg_rtx (HImode);
c81fc13e 6306 emit_insn (gen_movhi (tmp_reg,
cc0d9ba8
DE
6307 expand_block_move_mem (HImode,
6308 src_addr,
6309 orig_src)));
6310 stores[num_reg++] = gen_movhi (expand_block_move_mem (HImode,
6311 dest_addr,
6312 orig_dest),
6313 tmp_reg);
3933e0e1
MM
6314 }
6315 else
6316 {
6317 move_bytes = 1;
6318 tmp_reg = gen_reg_rtx (QImode);
c81fc13e 6319 emit_insn (gen_movqi (tmp_reg,
cc0d9ba8
DE
6320 expand_block_move_mem (QImode,
6321 src_addr,
6322 orig_src)));
6323 stores[num_reg++] = gen_movqi (expand_block_move_mem (QImode,
6324 dest_addr,
6325 orig_dest),
a4f6c312 6326 tmp_reg);
3933e0e1
MM
6327 }
6328
6329 if (num_reg >= MAX_MOVE_REG)
6330 {
6331 for (i = 0; i < num_reg; i++)
6332 emit_insn (stores[i]);
6333 num_reg = 0;
7e69e155
MM
6334 }
6335 }
3933e0e1 6336
b6c9286a
MM
6337 for (i = 0; i < num_reg; i++)
6338 emit_insn (stores[i]);
7e69e155
MM
6339 }
6340
6341 return 1;
6342}
6343
9878760c
RK
6344\f
6345/* Return 1 if OP is a load multiple operation. It is known to be a
6346 PARALLEL and the first section will be tested. */
6347
6348int
6349load_multiple_operation (op, mode)
6350 rtx op;
296b8152 6351 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6352{
6353 int count = XVECLEN (op, 0);
e2c953b6 6354 unsigned int dest_regno;
9878760c
RK
6355 rtx src_addr;
6356 int i;
6357
6358 /* Perform a quick check so we don't blow up below. */
6359 if (count <= 1
6360 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6361 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6362 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6363 return 0;
6364
6365 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6366 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6367
6368 for (i = 1; i < count; i++)
6369 {
6370 rtx elt = XVECEXP (op, 0, i);
6371
6372 if (GET_CODE (elt) != SET
6373 || GET_CODE (SET_DEST (elt)) != REG
6374 || GET_MODE (SET_DEST (elt)) != SImode
6375 || REGNO (SET_DEST (elt)) != dest_regno + i
6376 || GET_CODE (SET_SRC (elt)) != MEM
6377 || GET_MODE (SET_SRC (elt)) != SImode
6378 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6379 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6380 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6381 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6382 return 0;
6383 }
6384
6385 return 1;
6386}
6387
6388/* Similar, but tests for store multiple. Here, the second vector element
6389 is a CLOBBER. It will be tested later. */
6390
6391int
6392store_multiple_operation (op, mode)
6393 rtx op;
296b8152 6394 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6395{
6396 int count = XVECLEN (op, 0) - 1;
e2c953b6 6397 unsigned int src_regno;
9878760c
RK
6398 rtx dest_addr;
6399 int i;
6400
6401 /* Perform a quick check so we don't blow up below. */
6402 if (count <= 1
6403 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6404 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6405 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6406 return 0;
6407
6408 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6409 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6410
6411 for (i = 1; i < count; i++)
6412 {
6413 rtx elt = XVECEXP (op, 0, i + 1);
6414
6415 if (GET_CODE (elt) != SET
6416 || GET_CODE (SET_SRC (elt)) != REG
6417 || GET_MODE (SET_SRC (elt)) != SImode
6418 || REGNO (SET_SRC (elt)) != src_regno + i
6419 || GET_CODE (SET_DEST (elt)) != MEM
6420 || GET_MODE (SET_DEST (elt)) != SImode
6421 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6422 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6423 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6424 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6425 return 0;
6426 }
6427
6428 return 1;
6429}
9ebbca7d 6430
00b960c7
AH
6431/* Return 1 for a parallel vrsave operation. */
6432
6433int
6434vrsave_operation (op, mode)
6435 rtx op;
6436 enum machine_mode mode ATTRIBUTE_UNUSED;
6437{
6438 int count = XVECLEN (op, 0);
6439 unsigned int dest_regno, src_regno;
6440 int i;
6441
6442 if (count <= 1
6443 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6444 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6445 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6446 return 0;
6447
6448 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6449 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6450
6451 if (dest_regno != VRSAVE_REGNO
6452 && src_regno != VRSAVE_REGNO)
6453 return 0;
6454
6455 for (i = 1; i < count; i++)
6456 {
6457 rtx elt = XVECEXP (op, 0, i);
6458
9aa86737
AH
6459 if (GET_CODE (elt) != CLOBBER
6460 && GET_CODE (elt) != SET)
00b960c7
AH
6461 return 0;
6462 }
6463
6464 return 1;
6465}
6466
a4f6c312 6467/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6468
6469int
6470mtcrf_operation (op, mode)
6471 rtx op;
6472 enum machine_mode mode ATTRIBUTE_UNUSED;
6473{
6474 int count = XVECLEN (op, 0);
6475 int i;
9ebbca7d
GK
6476 rtx src_reg;
6477
6478 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6479 if (count < 1
6480 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6481 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6482 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6483 return 0;
e35b9579 6484 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6485
6486 if (GET_CODE (src_reg) != REG
6487 || GET_MODE (src_reg) != SImode
6488 || ! INT_REGNO_P (REGNO (src_reg)))
6489 return 0;
6490
e35b9579 6491 for (i = 0; i < count; i++)
9ebbca7d
GK
6492 {
6493 rtx exp = XVECEXP (op, 0, i);
6494 rtx unspec;
6495 int maskval;
6496
6497 if (GET_CODE (exp) != SET
6498 || GET_CODE (SET_DEST (exp)) != REG
6499 || GET_MODE (SET_DEST (exp)) != CCmode
6500 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6501 return 0;
6502 unspec = SET_SRC (exp);
6503 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6504
6505 if (GET_CODE (unspec) != UNSPEC
6506 || XINT (unspec, 1) != 20
6507 || XVECLEN (unspec, 0) != 2
6508 || XVECEXP (unspec, 0, 0) != src_reg
6509 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6510 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6511 return 0;
6512 }
e35b9579 6513 return 1;
9ebbca7d
GK
6514}
6515
a4f6c312 6516/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6517
6518int
6519lmw_operation (op, mode)
6520 rtx op;
6521 enum machine_mode mode ATTRIBUTE_UNUSED;
6522{
6523 int count = XVECLEN (op, 0);
e2c953b6 6524 unsigned int dest_regno;
9ebbca7d 6525 rtx src_addr;
e2c953b6 6526 unsigned int base_regno;
9ebbca7d
GK
6527 HOST_WIDE_INT offset;
6528 int i;
6529
6530 /* Perform a quick check so we don't blow up below. */
6531 if (count <= 1
6532 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6533 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6534 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6535 return 0;
6536
6537 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6538 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6539
6540 if (dest_regno > 31
e2c953b6 6541 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6542 return 0;
6543
258bfae2 6544 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6545 {
6546 offset = 0;
6547 base_regno = REGNO (src_addr);
6548 if (base_regno == 0)
6549 return 0;
6550 }
258bfae2 6551 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6552 {
6553 offset = INTVAL (XEXP (src_addr, 1));
6554 base_regno = REGNO (XEXP (src_addr, 0));
6555 }
6556 else
6557 return 0;
6558
6559 for (i = 0; i < count; i++)
6560 {
6561 rtx elt = XVECEXP (op, 0, i);
6562 rtx newaddr;
6563 rtx addr_reg;
6564 HOST_WIDE_INT newoffset;
6565
6566 if (GET_CODE (elt) != SET
6567 || GET_CODE (SET_DEST (elt)) != REG
6568 || GET_MODE (SET_DEST (elt)) != SImode
6569 || REGNO (SET_DEST (elt)) != dest_regno + i
6570 || GET_CODE (SET_SRC (elt)) != MEM
6571 || GET_MODE (SET_SRC (elt)) != SImode)
6572 return 0;
6573 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6574 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6575 {
6576 newoffset = 0;
6577 addr_reg = newaddr;
6578 }
258bfae2 6579 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6580 {
6581 addr_reg = XEXP (newaddr, 0);
6582 newoffset = INTVAL (XEXP (newaddr, 1));
6583 }
6584 else
6585 return 0;
6586 if (REGNO (addr_reg) != base_regno
6587 || newoffset != offset + 4 * i)
6588 return 0;
6589 }
6590
6591 return 1;
6592}
6593
a4f6c312 6594/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6595
6596int
6597stmw_operation (op, mode)
6598 rtx op;
6599 enum machine_mode mode ATTRIBUTE_UNUSED;
6600{
6601 int count = XVECLEN (op, 0);
e2c953b6 6602 unsigned int src_regno;
9ebbca7d 6603 rtx dest_addr;
e2c953b6 6604 unsigned int base_regno;
9ebbca7d
GK
6605 HOST_WIDE_INT offset;
6606 int i;
6607
6608 /* Perform a quick check so we don't blow up below. */
6609 if (count <= 1
6610 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6611 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6612 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6613 return 0;
6614
6615 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6616 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6617
6618 if (src_regno > 31
e2c953b6 6619 || count != 32 - (int) src_regno)
9ebbca7d
GK
6620 return 0;
6621
258bfae2 6622 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6623 {
6624 offset = 0;
6625 base_regno = REGNO (dest_addr);
6626 if (base_regno == 0)
6627 return 0;
6628 }
258bfae2 6629 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6630 {
6631 offset = INTVAL (XEXP (dest_addr, 1));
6632 base_regno = REGNO (XEXP (dest_addr, 0));
6633 }
6634 else
6635 return 0;
6636
6637 for (i = 0; i < count; i++)
6638 {
6639 rtx elt = XVECEXP (op, 0, i);
6640 rtx newaddr;
6641 rtx addr_reg;
6642 HOST_WIDE_INT newoffset;
6643
6644 if (GET_CODE (elt) != SET
6645 || GET_CODE (SET_SRC (elt)) != REG
6646 || GET_MODE (SET_SRC (elt)) != SImode
6647 || REGNO (SET_SRC (elt)) != src_regno + i
6648 || GET_CODE (SET_DEST (elt)) != MEM
6649 || GET_MODE (SET_DEST (elt)) != SImode)
6650 return 0;
6651 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6652 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6653 {
6654 newoffset = 0;
6655 addr_reg = newaddr;
6656 }
258bfae2 6657 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6658 {
6659 addr_reg = XEXP (newaddr, 0);
6660 newoffset = INTVAL (XEXP (newaddr, 1));
6661 }
6662 else
6663 return 0;
6664 if (REGNO (addr_reg) != base_regno
6665 || newoffset != offset + 4 * i)
6666 return 0;
6667 }
6668
6669 return 1;
6670}
9878760c 6671\f
a4f6c312
SS
6672/* A validation routine: say whether CODE, a condition code, and MODE
6673 match. The other alternatives either don't make sense or should
6674 never be generated. */
39a10a29 6675
39a10a29
GK
6676static void
6677validate_condition_mode (code, mode)
6678 enum rtx_code code;
6679 enum machine_mode mode;
6680{
6681 if (GET_RTX_CLASS (code) != '<'
6682 || GET_MODE_CLASS (mode) != MODE_CC)
6683 abort ();
6684
6685 /* These don't make sense. */
6686 if ((code == GT || code == LT || code == GE || code == LE)
6687 && mode == CCUNSmode)
6688 abort ();
6689
6690 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6691 && mode != CCUNSmode)
6692 abort ();
6693
6694 if (mode != CCFPmode
6695 && (code == ORDERED || code == UNORDERED
6696 || code == UNEQ || code == LTGT
6697 || code == UNGT || code == UNLT
6698 || code == UNGE || code == UNLE))
a4f6c312 6699 abort ();
39a10a29 6700
de6c5979 6701 /* These should never be generated except for
ad72b533 6702 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6703 if (mode == CCFPmode
de6c5979 6704 && ! flag_unsafe_math_optimizations
ad72b533 6705 && ! flag_finite_math_only
39a10a29
GK
6706 && (code == LE || code == GE
6707 || code == UNEQ || code == LTGT
6708 || code == UNGT || code == UNLT))
6709 abort ();
6710
6711 /* These are invalid; the information is not there. */
6712 if (mode == CCEQmode
6713 && code != EQ && code != NE)
6714 abort ();
6715}
6716
9878760c
RK
6717/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6718 We only check the opcode against the mode of the CC value here. */
6719
6720int
6721branch_comparison_operator (op, mode)
592696dd 6722 rtx op;
296b8152 6723 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6724{
6725 enum rtx_code code = GET_CODE (op);
6726 enum machine_mode cc_mode;
6727
6728 if (GET_RTX_CLASS (code) != '<')
6729 return 0;
6730
6731 cc_mode = GET_MODE (XEXP (op, 0));
6732 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6733 return 0;
6734
39a10a29 6735 validate_condition_mode (code, cc_mode);
9878760c 6736
39a10a29
GK
6737 return 1;
6738}
6739
6740/* Return 1 if OP is a comparison operation that is valid for a branch
6741 insn and which is true if the corresponding bit in the CC register
6742 is set. */
6743
6744int
6745branch_positive_comparison_operator (op, mode)
592696dd 6746 rtx op;
39a10a29
GK
6747 enum machine_mode mode;
6748{
6749 enum rtx_code code;
6750
6751 if (! branch_comparison_operator (op, mode))
9878760c
RK
6752 return 0;
6753
39a10a29
GK
6754 code = GET_CODE (op);
6755 return (code == EQ || code == LT || code == GT
a3170dc6 6756 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
6757 || code == LTU || code == GTU
6758 || code == UNORDERED);
9878760c
RK
6759}
6760
6761/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6762 We check the opcode against the mode of the CC value and disallow EQ or
6763 NE comparisons for integers. */
6764
6765int
6766scc_comparison_operator (op, mode)
592696dd 6767 rtx op;
9878760c
RK
6768 enum machine_mode mode;
6769{
6770 enum rtx_code code = GET_CODE (op);
6771 enum machine_mode cc_mode;
6772
6773 if (GET_MODE (op) != mode && mode != VOIDmode)
6774 return 0;
6775
6776 if (GET_RTX_CLASS (code) != '<')
6777 return 0;
6778
6779 cc_mode = GET_MODE (XEXP (op, 0));
6780 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6781 return 0;
6782
39a10a29 6783 validate_condition_mode (code, cc_mode);
9878760c 6784
39a10a29 6785 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
6786 return 0;
6787
9878760c
RK
6788 return 1;
6789}
e0cd0770
JC
6790
6791int
6792trap_comparison_operator (op, mode)
6793 rtx op;
6794 enum machine_mode mode;
6795{
6796 if (mode != VOIDmode && mode != GET_MODE (op))
6797 return 0;
39a10a29 6798 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 6799}
dfbdccdb
GK
6800
6801int
6802boolean_operator (op, mode)
6803 rtx op;
6804 enum machine_mode mode ATTRIBUTE_UNUSED;
6805{
6806 enum rtx_code code = GET_CODE (op);
6807 return (code == AND || code == IOR || code == XOR);
6808}
1d328b19
GK
6809
6810int
6811boolean_or_operator (op, mode)
6812 rtx op;
6813 enum machine_mode mode ATTRIBUTE_UNUSED;
6814{
6815 enum rtx_code code = GET_CODE (op);
6816 return (code == IOR || code == XOR);
6817}
50a0b056
GK
6818
6819int
6820min_max_operator (op, mode)
6821 rtx op;
6822 enum machine_mode mode ATTRIBUTE_UNUSED;
6823{
6824 enum rtx_code code = GET_CODE (op);
6825 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6826}
9878760c
RK
6827\f
6828/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6829 mask required to convert the result of a rotate insn into a shift
b1765bde 6830 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
6831
6832int
6833includes_lshift_p (shiftop, andop)
592696dd
SS
6834 rtx shiftop;
6835 rtx andop;
9878760c 6836{
e2c953b6
DE
6837 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6838
6839 shift_mask <<= INTVAL (shiftop);
9878760c 6840
b1765bde 6841 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
6842}
6843
6844/* Similar, but for right shift. */
6845
6846int
6847includes_rshift_p (shiftop, andop)
592696dd
SS
6848 rtx shiftop;
6849 rtx andop;
9878760c 6850{
a7653a2c 6851 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
6852
6853 shift_mask >>= INTVAL (shiftop);
6854
b1765bde 6855 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
6856}
6857
c5059423
AM
6858/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6859 to perform a left shift. It must have exactly SHIFTOP least
6860 signifigant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
6861
6862int
c5059423 6863includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
6864 rtx shiftop;
6865 rtx andop;
e2c953b6 6866{
c5059423
AM
6867 if (GET_CODE (andop) == CONST_INT)
6868 {
02071907 6869 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 6870
c5059423 6871 c = INTVAL (andop);
02071907 6872 if (c == 0 || c == ~0)
c5059423 6873 return 0;
e2c953b6 6874
02071907 6875 shift_mask = ~0;
c5059423
AM
6876 shift_mask <<= INTVAL (shiftop);
6877
6878 /* Find the least signifigant one bit. */
6879 lsb = c & -c;
6880
6881 /* It must coincide with the LSB of the shift mask. */
6882 if (-lsb != shift_mask)
6883 return 0;
e2c953b6 6884
c5059423
AM
6885 /* Invert to look for the next transition (if any). */
6886 c = ~c;
6887
6888 /* Remove the low group of ones (originally low group of zeros). */
6889 c &= -lsb;
6890
6891 /* Again find the lsb, and check we have all 1's above. */
6892 lsb = c & -c;
6893 return c == -lsb;
6894 }
6895 else if (GET_CODE (andop) == CONST_DOUBLE
6896 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6897 {
02071907
AM
6898 HOST_WIDE_INT low, high, lsb;
6899 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
6900
6901 low = CONST_DOUBLE_LOW (andop);
6902 if (HOST_BITS_PER_WIDE_INT < 64)
6903 high = CONST_DOUBLE_HIGH (andop);
6904
6905 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 6906 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
6907 return 0;
6908
6909 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6910 {
02071907 6911 shift_mask_high = ~0;
c5059423
AM
6912 if (INTVAL (shiftop) > 32)
6913 shift_mask_high <<= INTVAL (shiftop) - 32;
6914
6915 lsb = high & -high;
6916
6917 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
6918 return 0;
6919
6920 high = ~high;
6921 high &= -lsb;
6922
6923 lsb = high & -high;
6924 return high == -lsb;
6925 }
6926
02071907 6927 shift_mask_low = ~0;
c5059423
AM
6928 shift_mask_low <<= INTVAL (shiftop);
6929
6930 lsb = low & -low;
6931
6932 if (-lsb != shift_mask_low)
6933 return 0;
6934
6935 if (HOST_BITS_PER_WIDE_INT < 64)
6936 high = ~high;
6937 low = ~low;
6938 low &= -lsb;
6939
6940 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6941 {
6942 lsb = high & -high;
6943 return high == -lsb;
6944 }
6945
6946 lsb = low & -low;
6947 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
6948 }
6949 else
6950 return 0;
6951}
e2c953b6 6952
c5059423
AM
6953/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
6954 to perform a left shift. It must have SHIFTOP or more least
6955 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 6956
c5059423
AM
6957int
6958includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
6959 rtx shiftop;
6960 rtx andop;
c5059423 6961{
e2c953b6 6962 if (GET_CODE (andop) == CONST_INT)
c5059423 6963 {
02071907 6964 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 6965
02071907 6966 shift_mask = ~0;
c5059423
AM
6967 shift_mask <<= INTVAL (shiftop);
6968 c = INTVAL (andop);
6969
6970 /* Find the least signifigant one bit. */
6971 lsb = c & -c;
6972
6973 /* It must be covered by the shift mask.
a4f6c312 6974 This test also rejects c == 0. */
c5059423
AM
6975 if ((lsb & shift_mask) == 0)
6976 return 0;
6977
6978 /* Check we have all 1's above the transition, and reject all 1's. */
6979 return c == -lsb && lsb != 1;
6980 }
6981 else if (GET_CODE (andop) == CONST_DOUBLE
6982 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6983 {
02071907 6984 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
6985
6986 low = CONST_DOUBLE_LOW (andop);
6987
6988 if (HOST_BITS_PER_WIDE_INT < 64)
6989 {
02071907 6990 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
6991
6992 high = CONST_DOUBLE_HIGH (andop);
6993
6994 if (low == 0)
6995 {
02071907 6996 shift_mask_high = ~0;
c5059423
AM
6997 if (INTVAL (shiftop) > 32)
6998 shift_mask_high <<= INTVAL (shiftop) - 32;
6999
7000 lsb = high & -high;
7001
7002 if ((lsb & shift_mask_high) == 0)
7003 return 0;
7004
7005 return high == -lsb;
7006 }
7007 if (high != ~0)
7008 return 0;
7009 }
7010
02071907 7011 shift_mask_low = ~0;
c5059423
AM
7012 shift_mask_low <<= INTVAL (shiftop);
7013
7014 lsb = low & -low;
7015
7016 if ((lsb & shift_mask_low) == 0)
7017 return 0;
7018
7019 return low == -lsb && lsb != 1;
7020 }
e2c953b6 7021 else
c5059423 7022 return 0;
9878760c 7023}
35068b43
RK
7024
7025/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
7026 for lfq and stfq insns.
7027
7028 Note reg1 and reg2 *must* be hard registers. To be sure we will
7029 abort if we are passed pseudo registers. */
7030
7031int
7032registers_ok_for_quad_peep (reg1, reg2)
7033 rtx reg1, reg2;
7034{
7035 /* We might have been passed a SUBREG. */
7036 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
7037 return 0;
7038
7039 return (REGNO (reg1) == REGNO (reg2) - 1);
7040}
7041
a4f6c312
SS
7042/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
7043 addr1 and addr2 must be in consecutive memory locations
7044 (addr2 == addr1 + 8). */
35068b43
RK
7045
7046int
7047addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
7048 rtx addr1;
7049 rtx addr2;
35068b43 7050{
e2c953b6 7051 unsigned int reg1;
35068b43
RK
7052 int offset1;
7053
7054 /* Extract an offset (if used) from the first addr. */
7055 if (GET_CODE (addr1) == PLUS)
7056 {
7057 /* If not a REG, return zero. */
7058 if (GET_CODE (XEXP (addr1, 0)) != REG)
7059 return 0;
7060 else
7061 {
7062 reg1 = REGNO (XEXP (addr1, 0));
7063 /* The offset must be constant! */
7064 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7065 return 0;
7066 offset1 = INTVAL (XEXP (addr1, 1));
7067 }
7068 }
7069 else if (GET_CODE (addr1) != REG)
7070 return 0;
7071 else
7072 {
7073 reg1 = REGNO (addr1);
7074 /* This was a simple (mem (reg)) expression. Offset is 0. */
7075 offset1 = 0;
7076 }
7077
acad7ed3 7078 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
7079 if (GET_CODE (addr2) != PLUS)
7080 return 0;
7081
7082 if (GET_CODE (XEXP (addr2, 0)) != REG
7083 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7084 return 0;
7085
7086 if (reg1 != REGNO (XEXP (addr2, 0)))
7087 return 0;
7088
7089 /* The offset for the second addr must be 8 more than the first addr. */
7090 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7091 return 0;
7092
7093 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7094 instructions. */
7095 return 1;
7096}
9878760c
RK
7097\f
7098/* Return the register class of a scratch register needed to copy IN into
7099 or out of a register in CLASS in MODE. If it can be done directly,
7100 NO_REGS is returned. */
7101
7102enum reg_class
7103secondary_reload_class (class, mode, in)
7104 enum reg_class class;
296b8152 7105 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7106 rtx in;
7107{
5accd822 7108 int regno;
9878760c 7109
46fad5b7
DJ
7110 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
7111 {
7112 /* We cannot copy a symbolic operand directly into anything
7113 other than BASE_REGS for TARGET_ELF. So indicate that a
7114 register from BASE_REGS is needed as an intermediate
7115 register.
7116
7117 On Darwin, pic addresses require a load from memory, which
7118 needs a base register. */
7119 if (class != BASE_REGS
7120 && (GET_CODE (in) == SYMBOL_REF
7121 || GET_CODE (in) == HIGH
7122 || GET_CODE (in) == LABEL_REF
7123 || GET_CODE (in) == CONST))
7124 return BASE_REGS;
7125 }
e7b7998a 7126
5accd822
DE
7127 if (GET_CODE (in) == REG)
7128 {
7129 regno = REGNO (in);
7130 if (regno >= FIRST_PSEUDO_REGISTER)
7131 {
7132 regno = true_regnum (in);
7133 if (regno >= FIRST_PSEUDO_REGISTER)
7134 regno = -1;
7135 }
7136 }
7137 else if (GET_CODE (in) == SUBREG)
7138 {
7139 regno = true_regnum (in);
7140 if (regno >= FIRST_PSEUDO_REGISTER)
7141 regno = -1;
7142 }
7143 else
7144 regno = -1;
7145
9878760c
RK
7146 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7147 into anything. */
7148 if (class == GENERAL_REGS || class == BASE_REGS
7149 || (regno >= 0 && INT_REGNO_P (regno)))
7150 return NO_REGS;
7151
7152 /* Constants, memory, and FP registers can go into FP registers. */
7153 if ((regno == -1 || FP_REGNO_P (regno))
7154 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7155 return NO_REGS;
7156
0ac081f6
AH
7157 /* Memory, and AltiVec registers can go into AltiVec registers. */
7158 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7159 && class == ALTIVEC_REGS)
7160 return NO_REGS;
7161
9878760c
RK
7162 /* We can copy among the CR registers. */
7163 if ((class == CR_REGS || class == CR0_REGS)
7164 && regno >= 0 && CR_REGNO_P (regno))
7165 return NO_REGS;
7166
7167 /* Otherwise, we need GENERAL_REGS. */
7168 return GENERAL_REGS;
7169}
7170\f
7171/* Given a comparison operation, return the bit number in CCR to test. We
7172 know this is a valid comparison.
7173
7174 SCC_P is 1 if this is for an scc. That means that %D will have been
7175 used instead of %C, so the bits will be in different places.
7176
b4ac57ab 7177 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7178
7179int
7180ccr_bit (op, scc_p)
592696dd 7181 rtx op;
9878760c
RK
7182 int scc_p;
7183{
7184 enum rtx_code code = GET_CODE (op);
7185 enum machine_mode cc_mode;
7186 int cc_regnum;
7187 int base_bit;
9ebbca7d 7188 rtx reg;
9878760c
RK
7189
7190 if (GET_RTX_CLASS (code) != '<')
7191 return -1;
7192
9ebbca7d
GK
7193 reg = XEXP (op, 0);
7194
7195 if (GET_CODE (reg) != REG
7196 || ! CR_REGNO_P (REGNO (reg)))
7197 abort ();
7198
7199 cc_mode = GET_MODE (reg);
7200 cc_regnum = REGNO (reg);
7201 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7202
39a10a29 7203 validate_condition_mode (code, cc_mode);
c5defebb 7204
9878760c
RK
7205 switch (code)
7206 {
7207 case NE:
a3170dc6
AH
7208 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7209 return base_bit + 1;
9878760c
RK
7210 return scc_p ? base_bit + 3 : base_bit + 2;
7211 case EQ:
a3170dc6
AH
7212 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7213 return base_bit + 1;
9878760c 7214 return base_bit + 2;
1c882ea4 7215 case GT: case GTU: case UNLE:
9878760c 7216 return base_bit + 1;
1c882ea4 7217 case LT: case LTU: case UNGE:
9878760c 7218 return base_bit;
1c882ea4
GK
7219 case ORDERED: case UNORDERED:
7220 return base_bit + 3;
9878760c
RK
7221
7222 case GE: case GEU:
39a10a29 7223 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7224 unordered position. So test that bit. For integer, this is ! LT
7225 unless this is an scc insn. */
39a10a29 7226 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7227
7228 case LE: case LEU:
39a10a29 7229 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7230
9878760c
RK
7231 default:
7232 abort ();
7233 }
7234}
1ff7789b 7235\f
8d30c4ee 7236/* Return the GOT register. */
1ff7789b
MM
7237
7238struct rtx_def *
7239rs6000_got_register (value)
5f59ecb7 7240 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7241{
a4f6c312
SS
7242 /* The second flow pass currently (June 1999) can't update
7243 regs_ever_live without disturbing other parts of the compiler, so
7244 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7245 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7246 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7247
8d30c4ee 7248 current_function_uses_pic_offset_table = 1;
3cb999d8 7249
1ff7789b
MM
7250 return pic_offset_table_rtx;
7251}
a7df97e6 7252\f
e2500fed
GK
7253/* Function to init struct machine_function.
7254 This will be called, via a pointer variable,
7255 from push_function_context. */
a7df97e6 7256
e2500fed
GK
7257static struct machine_function *
7258rs6000_init_machine_status ()
a7df97e6 7259{
e2500fed 7260 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7261}
9878760c 7262\f
0ba1b2ff
AM
7263/* These macros test for integers and extract the low-order bits. */
7264#define INT_P(X) \
7265((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7266 && GET_MODE (X) == VOIDmode)
7267
7268#define INT_LOWPART(X) \
7269 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7270
7271int
7272extract_MB (op)
7273 rtx op;
7274{
7275 int i;
7276 unsigned long val = INT_LOWPART (op);
7277
7278 /* If the high bit is zero, the value is the first 1 bit we find
7279 from the left. */
7280 if ((val & 0x80000000) == 0)
7281 {
7282 if ((val & 0xffffffff) == 0)
7283 abort ();
7284
7285 i = 1;
7286 while (((val <<= 1) & 0x80000000) == 0)
7287 ++i;
7288 return i;
7289 }
7290
7291 /* If the high bit is set and the low bit is not, or the mask is all
7292 1's, the value is zero. */
7293 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7294 return 0;
7295
7296 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7297 from the right. */
7298 i = 31;
7299 while (((val >>= 1) & 1) != 0)
7300 --i;
7301
7302 return i;
7303}
7304
7305int
7306extract_ME (op)
7307 rtx op;
7308{
7309 int i;
7310 unsigned long val = INT_LOWPART (op);
7311
7312 /* If the low bit is zero, the value is the first 1 bit we find from
7313 the right. */
7314 if ((val & 1) == 0)
7315 {
7316 if ((val & 0xffffffff) == 0)
7317 abort ();
7318
7319 i = 30;
7320 while (((val >>= 1) & 1) == 0)
7321 --i;
7322
7323 return i;
7324 }
7325
7326 /* If the low bit is set and the high bit is not, or the mask is all
7327 1's, the value is 31. */
7328 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7329 return 31;
7330
7331 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7332 from the left. */
7333 i = 0;
7334 while (((val <<= 1) & 0x80000000) != 0)
7335 ++i;
7336
7337 return i;
7338}
7339
9878760c
RK
7340/* Print an operand. Recognize special options, documented below. */
7341
38c1f2d7 7342#if TARGET_ELF
d9407988 7343#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7344#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7345#else
7346#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7347#define SMALL_DATA_REG 0
ba5e43aa
MM
7348#endif
7349
9878760c
RK
7350void
7351print_operand (file, x, code)
7352 FILE *file;
7353 rtx x;
9ebbca7d 7354 int code;
9878760c
RK
7355{
7356 int i;
a260abc9 7357 HOST_WIDE_INT val;
0ba1b2ff 7358 unsigned HOST_WIDE_INT uval;
9878760c
RK
7359
7360 switch (code)
7361 {
a8b3aeda 7362 case '.':
a85d226b
RK
7363 /* Write out an instruction after the call which may be replaced
7364 with glue code by the loader. This depends on the AIX version. */
7365 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7366 return;
7367
81eace42
GK
7368 /* %a is output_address. */
7369
9854d9ed
RK
7370 case 'A':
7371 /* If X is a constant integer whose low-order 5 bits are zero,
7372 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7373 in the AIX assembler where "sri" with a zero shift count
20e26713 7374 writes a trash instruction. */
9854d9ed 7375 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7376 putc ('l', file);
9854d9ed 7377 else
76229ac8 7378 putc ('r', file);
9854d9ed
RK
7379 return;
7380
7381 case 'b':
e2c953b6
DE
7382 /* If constant, low-order 16 bits of constant, unsigned.
7383 Otherwise, write normally. */
7384 if (INT_P (x))
7385 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7386 else
7387 print_operand (file, x, 0);
cad12a8d
RK
7388 return;
7389
a260abc9
DE
7390 case 'B':
7391 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7392 for 64-bit mask direction. */
296b8152 7393 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7394 return;
a260abc9 7395
81eace42
GK
7396 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7397 output_operand. */
7398
9854d9ed 7399 case 'D':
39a10a29
GK
7400 /* There used to be a comment for 'C' reading "This is an
7401 optional cror needed for certain floating-point
7402 comparisons. Otherwise write nothing." */
7403
9854d9ed
RK
7404 /* Similar, except that this is for an scc, so we must be able to
7405 encode the test in a single bit that is one. We do the above
7406 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7407 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7408 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7409 {
9ebbca7d 7410 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7411
7412 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7413 base_bit + 2,
7414 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7415 }
7416
7417 else if (GET_CODE (x) == NE)
7418 {
9ebbca7d 7419 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7420
7421 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7422 base_bit + 2, base_bit + 2);
7423 }
a3170dc6
AH
7424 else if (TARGET_SPE && TARGET_HARD_FLOAT
7425 && GET_CODE (x) == EQ
7426 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7427 {
7428 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7429
7430 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7431 base_bit + 1, base_bit + 1);
7432 }
9854d9ed
RK
7433 return;
7434
7435 case 'E':
39a10a29 7436 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7437 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7438 output_operand_lossage ("invalid %%E value");
78fbdbf7 7439 else
39a10a29 7440 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7441 return;
9854d9ed
RK
7442
7443 case 'f':
7444 /* X is a CR register. Print the shift count needed to move it
7445 to the high-order four bits. */
7446 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7447 output_operand_lossage ("invalid %%f value");
7448 else
9ebbca7d 7449 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7450 return;
7451
7452 case 'F':
7453 /* Similar, but print the count for the rotate in the opposite
7454 direction. */
7455 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7456 output_operand_lossage ("invalid %%F value");
7457 else
9ebbca7d 7458 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7459 return;
7460
7461 case 'G':
7462 /* X is a constant integer. If it is negative, print "m",
7463 otherwise print "z". This is to make a aze or ame insn. */
7464 if (GET_CODE (x) != CONST_INT)
7465 output_operand_lossage ("invalid %%G value");
7466 else if (INTVAL (x) >= 0)
76229ac8 7467 putc ('z', file);
9854d9ed 7468 else
76229ac8 7469 putc ('m', file);
9854d9ed 7470 return;
e2c953b6 7471
9878760c 7472 case 'h':
a4f6c312
SS
7473 /* If constant, output low-order five bits. Otherwise, write
7474 normally. */
9878760c 7475 if (INT_P (x))
5f59ecb7 7476 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7477 else
7478 print_operand (file, x, 0);
7479 return;
7480
64305719 7481 case 'H':
a4f6c312
SS
7482 /* If constant, output low-order six bits. Otherwise, write
7483 normally. */
64305719 7484 if (INT_P (x))
5f59ecb7 7485 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7486 else
7487 print_operand (file, x, 0);
7488 return;
7489
9854d9ed
RK
7490 case 'I':
7491 /* Print `i' if this is a constant, else nothing. */
9878760c 7492 if (INT_P (x))
76229ac8 7493 putc ('i', file);
9878760c
RK
7494 return;
7495
9854d9ed
RK
7496 case 'j':
7497 /* Write the bit number in CCR for jump. */
7498 i = ccr_bit (x, 0);
7499 if (i == -1)
7500 output_operand_lossage ("invalid %%j code");
9878760c 7501 else
9854d9ed 7502 fprintf (file, "%d", i);
9878760c
RK
7503 return;
7504
9854d9ed
RK
7505 case 'J':
7506 /* Similar, but add one for shift count in rlinm for scc and pass
7507 scc flag to `ccr_bit'. */
7508 i = ccr_bit (x, 1);
7509 if (i == -1)
7510 output_operand_lossage ("invalid %%J code");
7511 else
a0466a68
RK
7512 /* If we want bit 31, write a shift count of zero, not 32. */
7513 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7514 return;
7515
9854d9ed
RK
7516 case 'k':
7517 /* X must be a constant. Write the 1's complement of the
7518 constant. */
9878760c 7519 if (! INT_P (x))
9854d9ed 7520 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7521 else
7522 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7523 return;
7524
81eace42 7525 case 'K':
9ebbca7d
GK
7526 /* X must be a symbolic constant on ELF. Write an
7527 expression suitable for an 'addi' that adds in the low 16
7528 bits of the MEM. */
7529 if (GET_CODE (x) != CONST)
7530 {
7531 print_operand_address (file, x);
7532 fputs ("@l", file);
7533 }
7534 else
7535 {
7536 if (GET_CODE (XEXP (x, 0)) != PLUS
7537 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7538 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7539 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7540 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7541 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7542 fputs ("@l", file);
ed8d2920
MM
7543 /* For GNU as, there must be a non-alphanumeric character
7544 between 'l' and the number. The '-' is added by
7545 print_operand() already. */
7546 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7547 fputs ("+", file);
9ebbca7d
GK
7548 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7549 }
81eace42
GK
7550 return;
7551
7552 /* %l is output_asm_label. */
9ebbca7d 7553
9854d9ed
RK
7554 case 'L':
7555 /* Write second word of DImode or DFmode reference. Works on register
7556 or non-indexed memory only. */
7557 if (GET_CODE (x) == REG)
5ebfb2ba 7558 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7559 else if (GET_CODE (x) == MEM)
7560 {
7561 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7562 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7563 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7564 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7565 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7566 UNITS_PER_WORD));
9854d9ed 7567 else
d7624dc0
RK
7568 output_address (XEXP (adjust_address_nv (x, SImode,
7569 UNITS_PER_WORD),
7570 0));
ed8908e7 7571
ba5e43aa 7572 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7573 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7574 reg_names[SMALL_DATA_REG]);
9854d9ed 7575 }
9878760c 7576 return;
9854d9ed 7577
9878760c
RK
7578 case 'm':
7579 /* MB value for a mask operand. */
b1765bde 7580 if (! mask_operand (x, SImode))
9878760c
RK
7581 output_operand_lossage ("invalid %%m value");
7582
0ba1b2ff 7583 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7584 return;
7585
7586 case 'M':
7587 /* ME value for a mask operand. */
b1765bde 7588 if (! mask_operand (x, SImode))
a260abc9 7589 output_operand_lossage ("invalid %%M value");
9878760c 7590
0ba1b2ff 7591 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7592 return;
7593
81eace42
GK
7594 /* %n outputs the negative of its operand. */
7595
9878760c
RK
7596 case 'N':
7597 /* Write the number of elements in the vector times 4. */
7598 if (GET_CODE (x) != PARALLEL)
7599 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7600 else
7601 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7602 return;
7603
7604 case 'O':
7605 /* Similar, but subtract 1 first. */
7606 if (GET_CODE (x) != PARALLEL)
1427100a 7607 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7608 else
7609 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7610 return;
7611
9854d9ed
RK
7612 case 'p':
7613 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7614 if (! INT_P (x)
2bfcf297 7615 || INT_LOWPART (x) < 0
9854d9ed
RK
7616 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7617 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7618 else
7619 fprintf (file, "%d", i);
9854d9ed
RK
7620 return;
7621
9878760c
RK
7622 case 'P':
7623 /* The operand must be an indirect memory reference. The result
a4f6c312 7624 is the register number. */
9878760c
RK
7625 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7626 || REGNO (XEXP (x, 0)) >= 32)
7627 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7628 else
7629 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7630 return;
7631
dfbdccdb
GK
7632 case 'q':
7633 /* This outputs the logical code corresponding to a boolean
7634 expression. The expression may have one or both operands
39a10a29
GK
7635 negated (if one, only the first one). For condition register
7636 logical operations, it will also treat the negated
7637 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7638 {
63bc1d05 7639 const char *const *t = 0;
dfbdccdb
GK
7640 const char *s;
7641 enum rtx_code code = GET_CODE (x);
7642 static const char * const tbl[3][3] = {
7643 { "and", "andc", "nor" },
7644 { "or", "orc", "nand" },
7645 { "xor", "eqv", "xor" } };
7646
7647 if (code == AND)
7648 t = tbl[0];
7649 else if (code == IOR)
7650 t = tbl[1];
7651 else if (code == XOR)
7652 t = tbl[2];
7653 else
7654 output_operand_lossage ("invalid %%q value");
7655
7656 if (GET_CODE (XEXP (x, 0)) != NOT)
7657 s = t[0];
7658 else
7659 {
7660 if (GET_CODE (XEXP (x, 1)) == NOT)
7661 s = t[2];
7662 else
7663 s = t[1];
7664 }
7665
7666 fputs (s, file);
7667 }
7668 return;
7669
9854d9ed
RK
7670 case 'R':
7671 /* X is a CR register. Print the mask for `mtcrf'. */
7672 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7673 output_operand_lossage ("invalid %%R value");
7674 else
9ebbca7d 7675 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7676 return;
9854d9ed
RK
7677
7678 case 's':
7679 /* Low 5 bits of 32 - value */
7680 if (! INT_P (x))
7681 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7682 else
7683 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7684 return;
9854d9ed 7685
a260abc9 7686 case 'S':
0ba1b2ff 7687 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7688 CONST_INT 32-bit mask is considered sign-extended so any
7689 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7690 if (! mask64_operand (x, DImode))
a260abc9
DE
7691 output_operand_lossage ("invalid %%S value");
7692
0ba1b2ff 7693 uval = INT_LOWPART (x);
a260abc9 7694
0ba1b2ff 7695 if (uval & 1) /* Clear Left */
a260abc9 7696 {
0ba1b2ff
AM
7697 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7698 i = 64;
a260abc9 7699 }
0ba1b2ff 7700 else /* Clear Right */
a260abc9 7701 {
0ba1b2ff
AM
7702 uval = ~uval;
7703 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7704 i = 63;
a260abc9 7705 }
0ba1b2ff
AM
7706 while (uval != 0)
7707 --i, uval >>= 1;
7708 if (i < 0)
7709 abort ();
7710 fprintf (file, "%d", i);
7711 return;
a260abc9 7712
a3170dc6
AH
7713 case 't':
7714 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7715 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7716 abort ();
7717
7718 /* Bit 3 is OV bit. */
7719 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7720
7721 /* If we want bit 31, write a shift count of zero, not 32. */
7722 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7723 return;
7724
cccf3bdc
DE
7725 case 'T':
7726 /* Print the symbolic name of a branch target register. */
7727 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7728 && REGNO (x) != COUNT_REGISTER_REGNUM))
7729 output_operand_lossage ("invalid %%T value");
e2c953b6 7730 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
7731 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7732 else
7733 fputs ("ctr", file);
7734 return;
7735
9854d9ed 7736 case 'u':
802a0058 7737 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
7738 if (! INT_P (x))
7739 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
7740 else
7741 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7742 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
7743 return;
7744
802a0058
MM
7745 case 'v':
7746 /* High-order 16 bits of constant for use in signed operand. */
7747 if (! INT_P (x))
7748 output_operand_lossage ("invalid %%v value");
e2c953b6 7749 else
134c32f6
DE
7750 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7751 (INT_LOWPART (x) >> 16) & 0xffff);
7752 return;
802a0058 7753
9854d9ed
RK
7754 case 'U':
7755 /* Print `u' if this has an auto-increment or auto-decrement. */
7756 if (GET_CODE (x) == MEM
7757 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7758 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 7759 putc ('u', file);
9854d9ed 7760 return;
9878760c 7761
e0cd0770
JC
7762 case 'V':
7763 /* Print the trap code for this operand. */
7764 switch (GET_CODE (x))
7765 {
7766 case EQ:
7767 fputs ("eq", file); /* 4 */
7768 break;
7769 case NE:
7770 fputs ("ne", file); /* 24 */
7771 break;
7772 case LT:
7773 fputs ("lt", file); /* 16 */
7774 break;
7775 case LE:
7776 fputs ("le", file); /* 20 */
7777 break;
7778 case GT:
7779 fputs ("gt", file); /* 8 */
7780 break;
7781 case GE:
7782 fputs ("ge", file); /* 12 */
7783 break;
7784 case LTU:
7785 fputs ("llt", file); /* 2 */
7786 break;
7787 case LEU:
7788 fputs ("lle", file); /* 6 */
7789 break;
7790 case GTU:
7791 fputs ("lgt", file); /* 1 */
7792 break;
7793 case GEU:
7794 fputs ("lge", file); /* 5 */
7795 break;
7796 default:
7797 abort ();
7798 }
7799 break;
7800
9854d9ed
RK
7801 case 'w':
7802 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7803 normally. */
7804 if (INT_P (x))
5f59ecb7
DE
7805 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7806 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
7807 else
7808 print_operand (file, x, 0);
9878760c
RK
7809 return;
7810
9854d9ed 7811 case 'W':
e2c953b6 7812 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
7813 val = (GET_CODE (x) == CONST_INT
7814 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7815
7816 if (val < 0)
7817 i = -1;
9854d9ed 7818 else
e2c953b6
DE
7819 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7820 if ((val <<= 1) < 0)
7821 break;
7822
7823#if HOST_BITS_PER_WIDE_INT == 32
7824 if (GET_CODE (x) == CONST_INT && i >= 0)
7825 i += 32; /* zero-extend high-part was all 0's */
7826 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7827 {
7828 val = CONST_DOUBLE_LOW (x);
7829
7830 if (val == 0)
a4f6c312 7831 abort ();
e2c953b6
DE
7832 else if (val < 0)
7833 --i;
7834 else
7835 for ( ; i < 64; i++)
7836 if ((val <<= 1) < 0)
7837 break;
7838 }
7839#endif
7840
7841 fprintf (file, "%d", i + 1);
9854d9ed 7842 return;
9878760c 7843
9854d9ed
RK
7844 case 'X':
7845 if (GET_CODE (x) == MEM
258bfae2 7846 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 7847 putc ('x', file);
9854d9ed 7848 return;
9878760c 7849
9854d9ed
RK
7850 case 'Y':
7851 /* Like 'L', for third word of TImode */
7852 if (GET_CODE (x) == REG)
5ebfb2ba 7853 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 7854 else if (GET_CODE (x) == MEM)
9878760c 7855 {
9854d9ed
RK
7856 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7857 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7858 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 7859 else
d7624dc0 7860 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 7861 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7862 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7863 reg_names[SMALL_DATA_REG]);
9878760c
RK
7864 }
7865 return;
9854d9ed 7866
9878760c 7867 case 'z':
b4ac57ab
RS
7868 /* X is a SYMBOL_REF. Write out the name preceded by a
7869 period and without any trailing data in brackets. Used for function
4d30c363
MM
7870 names. If we are configured for System V (or the embedded ABI) on
7871 the PowerPC, do not emit the period, since those systems do not use
7872 TOCs and the like. */
9878760c
RK
7873 if (GET_CODE (x) != SYMBOL_REF)
7874 abort ();
7875
b6c9286a
MM
7876 if (XSTR (x, 0)[0] != '.')
7877 {
7878 switch (DEFAULT_ABI)
7879 {
7880 default:
7881 abort ();
7882
7883 case ABI_AIX:
7884 putc ('.', file);
7885 break;
7886
7887 case ABI_V4:
7888 case ABI_AIX_NODESC:
ee890fe2 7889 case ABI_DARWIN:
b6c9286a 7890 break;
b6c9286a
MM
7891 }
7892 }
54ee9799
DE
7893#if TARGET_AIX
7894 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
7895#else
9ebbca7d 7896 assemble_name (file, XSTR (x, 0));
54ee9799 7897#endif
9878760c
RK
7898 return;
7899
9854d9ed
RK
7900 case 'Z':
7901 /* Like 'L', for last word of TImode. */
7902 if (GET_CODE (x) == REG)
5ebfb2ba 7903 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
7904 else if (GET_CODE (x) == MEM)
7905 {
7906 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7907 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7908 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 7909 else
d7624dc0 7910 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 7911 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7912 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7913 reg_names[SMALL_DATA_REG]);
9854d9ed 7914 }
5c23c401 7915 return;
0ac081f6 7916
a3170dc6 7917 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
7918 case 'y':
7919 {
7920 rtx tmp;
7921
7922 if (GET_CODE (x) != MEM)
7923 abort ();
7924
7925 tmp = XEXP (x, 0);
7926
a3170dc6
AH
7927 if (TARGET_SPE)
7928 {
7929 /* Handle [reg]. */
7930 if (GET_CODE (tmp) == REG)
7931 {
7932 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
7933 break;
7934 }
7935 /* Handle [reg+UIMM]. */
7936 else if (GET_CODE (tmp) == PLUS &&
7937 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
7938 {
7939 int x;
7940
7941 if (GET_CODE (XEXP (tmp, 0)) != REG)
7942 abort ();
7943
7944 x = INTVAL (XEXP (tmp, 1));
7945 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
7946 break;
7947 }
7948
7949 /* Fall through. Must be [reg+reg]. */
7950 }
0ac081f6 7951 if (GET_CODE (tmp) == REG)
c62f2db5 7952 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
7953 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
7954 {
7955 if (REGNO (XEXP (tmp, 0)) == 0)
7956 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
7957 reg_names[ REGNO (XEXP (tmp, 0)) ]);
7958 else
7959 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
7960 reg_names[ REGNO (XEXP (tmp, 1)) ]);
7961 }
7962 else
7963 abort ();
7964 break;
7965 }
9854d9ed 7966
9878760c
RK
7967 case 0:
7968 if (GET_CODE (x) == REG)
7969 fprintf (file, "%s", reg_names[REGNO (x)]);
7970 else if (GET_CODE (x) == MEM)
7971 {
7972 /* We need to handle PRE_INC and PRE_DEC here, since we need to
7973 know the width from the mode. */
7974 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
7975 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
7976 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7977 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
7978 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
7979 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7980 else
a54d04b7 7981 output_address (XEXP (x, 0));
9878760c
RK
7982 }
7983 else
a54d04b7 7984 output_addr_const (file, x);
a85d226b 7985 return;
9878760c
RK
7986
7987 default:
7988 output_operand_lossage ("invalid %%xn code");
7989 }
7990}
7991\f
7992/* Print the address of an operand. */
7993
7994void
7995print_operand_address (file, x)
7996 FILE *file;
592696dd 7997 rtx x;
9878760c
RK
7998{
7999 if (GET_CODE (x) == REG)
4697a36c 8000 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
8001 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
8002 || GET_CODE (x) == LABEL_REF)
9878760c
RK
8003 {
8004 output_addr_const (file, x);
ba5e43aa 8005 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8006 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8007 reg_names[SMALL_DATA_REG]);
9ebbca7d 8008 else if (TARGET_TOC)
a4f6c312 8009 abort ();
9878760c
RK
8010 }
8011 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
8012 {
8013 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
8014 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
8015 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 8016 else
4697a36c
MM
8017 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
8018 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
8019 }
8020 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
8021 {
8022 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
8023 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8024 }
3cb999d8
DE
8025#if TARGET_ELF
8026 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8027 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
8028 {
8029 output_addr_const (file, XEXP (x, 1));
8030 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8031 }
c859cda6
DJ
8032#endif
8033#if TARGET_MACHO
8034 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8035 && CONSTANT_P (XEXP (x, 1)))
8036 {
8037 fprintf (file, "lo16(");
8038 output_addr_const (file, XEXP (x, 1));
8039 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8040 }
3cb999d8 8041#endif
9ebbca7d
GK
8042 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
8043 {
2bfcf297 8044 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 8045 {
2bfcf297
DB
8046 rtx contains_minus = XEXP (x, 1);
8047 rtx minus, symref;
8048 const char *name;
9ebbca7d
GK
8049
8050 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 8051 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
8052 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8053 contains_minus = XEXP (contains_minus, 0);
8054
2bfcf297
DB
8055 minus = XEXP (contains_minus, 0);
8056 symref = XEXP (minus, 0);
8057 XEXP (contains_minus, 0) = symref;
8058 if (TARGET_ELF)
8059 {
8060 char *newname;
8061
8062 name = XSTR (symref, 0);
8063 newname = alloca (strlen (name) + sizeof ("@toc"));
8064 strcpy (newname, name);
8065 strcat (newname, "@toc");
8066 XSTR (symref, 0) = newname;
8067 }
8068 output_addr_const (file, XEXP (x, 1));
8069 if (TARGET_ELF)
8070 XSTR (symref, 0) = name;
9ebbca7d
GK
8071 XEXP (contains_minus, 0) = minus;
8072 }
8073 else
8074 output_addr_const (file, XEXP (x, 1));
8075
8076 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8077 }
9878760c
RK
8078 else
8079 abort ();
8080}
8081\f
301d03af
RS
8082/* Target hook for assembling integer objects. The powerpc version has
8083 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8084 is defined. It also needs to handle DI-mode objects on 64-bit
8085 targets. */
8086
8087static bool
8088rs6000_assemble_integer (x, size, aligned_p)
8089 rtx x;
8090 unsigned int size;
8091 int aligned_p;
8092{
8093#ifdef RELOCATABLE_NEEDS_FIXUP
8094 /* Special handling for SI values. */
8095 if (size == 4 && aligned_p)
8096 {
8097 extern int in_toc_section PARAMS ((void));
8098 static int recurse = 0;
8099
8100 /* For -mrelocatable, we mark all addresses that need to be fixed up
8101 in the .fixup section. */
8102 if (TARGET_RELOCATABLE
8103 && !in_toc_section ()
8104 && !in_text_section ()
8105 && !recurse
8106 && GET_CODE (x) != CONST_INT
8107 && GET_CODE (x) != CONST_DOUBLE
8108 && CONSTANT_P (x))
8109 {
8110 char buf[256];
8111
8112 recurse = 1;
8113 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8114 fixuplabelno++;
8115 ASM_OUTPUT_LABEL (asm_out_file, buf);
8116 fprintf (asm_out_file, "\t.long\t(");
8117 output_addr_const (asm_out_file, x);
8118 fprintf (asm_out_file, ")@fixup\n");
8119 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8120 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8121 fprintf (asm_out_file, "\t.long\t");
8122 assemble_name (asm_out_file, buf);
8123 fprintf (asm_out_file, "\n\t.previous\n");
8124 recurse = 0;
8125 return true;
8126 }
8127 /* Remove initial .'s to turn a -mcall-aixdesc function
8128 address into the address of the descriptor, not the function
8129 itself. */
8130 else if (GET_CODE (x) == SYMBOL_REF
8131 && XSTR (x, 0)[0] == '.'
8132 && DEFAULT_ABI == ABI_AIX)
8133 {
8134 const char *name = XSTR (x, 0);
8135 while (*name == '.')
8136 name++;
8137
8138 fprintf (asm_out_file, "\t.long\t%s\n", name);
8139 return true;
8140 }
8141 }
8142#endif /* RELOCATABLE_NEEDS_FIXUP */
8143 return default_assemble_integer (x, size, aligned_p);
8144}
8145\f
39a10a29
GK
8146enum rtx_code
8147rs6000_reverse_condition (mode, code)
8148 enum machine_mode mode;
8149 enum rtx_code code;
8150{
8151 /* Reversal of FP compares takes care -- an ordered compare
8152 becomes an unordered compare and vice versa. */
8153 if (mode == CCFPmode)
bab6226b 8154 return reverse_condition_maybe_unordered (code);
39a10a29 8155 else
bab6226b 8156 return reverse_condition (code);
39a10a29
GK
8157}
8158
39a10a29
GK
8159/* Generate a compare for CODE. Return a brand-new rtx that
8160 represents the result of the compare. */
a4f6c312 8161
39a10a29
GK
8162static rtx
8163rs6000_generate_compare (code)
8164 enum rtx_code code;
8165{
8166 enum machine_mode comp_mode;
8167 rtx compare_result;
8168
8169 if (rs6000_compare_fp_p)
8170 comp_mode = CCFPmode;
8171 else if (code == GTU || code == LTU
8172 || code == GEU || code == LEU)
8173 comp_mode = CCUNSmode;
8174 else
8175 comp_mode = CCmode;
8176
8177 /* First, the compare. */
8178 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
8179
8180 /* SPE FP compare instructions on the GPRs. Yuck! */
8181 if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
8182 {
8183 rtx cmp, or1, or2, or_result, compare_result2;
8184
8185 switch (code)
8186 {
8187 case EQ:
8188 case UNEQ:
8189 case NE:
8190 case LTGT:
8191 cmp = flag_unsafe_math_optimizations
8192 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8193 rs6000_compare_op1)
8194 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8195 rs6000_compare_op1);
8196 break;
8197 case GT:
8198 case GTU:
8199 case UNGT:
8200 case UNGE:
8201 case GE:
8202 case GEU:
8203 cmp = flag_unsafe_math_optimizations
8204 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8205 rs6000_compare_op1)
8206 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8207 rs6000_compare_op1);
8208 break;
8209 case LT:
8210 case LTU:
8211 case UNLT:
8212 case UNLE:
8213 case LE:
8214 case LEU:
8215 cmp = flag_unsafe_math_optimizations
8216 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8217 rs6000_compare_op1)
8218 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8219 rs6000_compare_op1);
8220 break;
8221 default:
8222 abort ();
8223 }
8224
8225 /* Synthesize LE and GE from LT/GT || EQ. */
8226 if (code == LE || code == GE || code == LEU || code == GEU)
8227 {
8228 /* Synthesize GE/LE frome GT/LT || EQ. */
8229
8230 emit_insn (cmp);
8231
8232 switch (code)
8233 {
8234 case LE: code = LT; break;
8235 case GE: code = GT; break;
8236 case LEU: code = LT; break;
8237 case GEU: code = GT; break;
8238 default: abort ();
8239 }
8240
8241 or1 = gen_reg_rtx (SImode);
8242 or2 = gen_reg_rtx (SImode);
8243 or_result = gen_reg_rtx (CCEQmode);
8244 compare_result2 = gen_reg_rtx (CCFPmode);
8245
8246 /* Do the EQ. */
8247 cmp = flag_unsafe_math_optimizations
8248 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8249 rs6000_compare_op1)
8250 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8251 rs6000_compare_op1);
8252 emit_insn (cmp);
8253
8254 /* The MC8540 FP compare instructions set the CR bits
8255 differently than other PPC compare instructions. For
8256 that matter, there is no generic test instruction, but a
8257 testgt, testlt, and testeq. For a true condition, bit 2
8258 is set (x1xx) in the CR. Following the traditional CR
8259 values:
8260
8261 LT GT EQ OV
8262 bit3 bit2 bit1 bit0
8263
8264 ... bit 2 would be a GT CR alias, so later on we
8265 look in the GT bits for the branch instructins.
8266 However, we must be careful to emit correct RTL in
8267 the meantime, so optimizations don't get confused. */
8268
8269 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8270 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8271
8272 /* OR them together. */
8273 cmp = gen_rtx_SET (VOIDmode, or_result,
8274 gen_rtx_COMPARE (CCEQmode,
8275 gen_rtx_IOR (SImode, or1, or2),
8276 const_true_rtx));
8277 compare_result = or_result;
8278 code = EQ;
8279 }
8280 else
8281 {
8282 /* We only care about 1 bit (x1xx), so map everything to NE to
8283 maintain rtl sanity. We'll get to the right bit (x1xx) at
8284 code output time. */
8285 if (code == NE || code == LTGT)
8286 /* Do the inverse here because we have no cmpne
8287 instruction. We use the cmpeq instruction and expect
8288 to get a 0 instead. */
8289 code = EQ;
8290 else
8291 code = NE;
8292 }
8293
8294 emit_insn (cmp);
8295 }
8296 else
8297 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8298 gen_rtx_COMPARE (comp_mode,
8299 rs6000_compare_op0,
8300 rs6000_compare_op1)));
39a10a29 8301
ca5adc63 8302 /* Some kinds of FP comparisons need an OR operation;
de6c5979 8303 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 8304 if (rs6000_compare_fp_p
de6c5979 8305 && ! flag_unsafe_math_optimizations
a3170dc6 8306 && ! (TARGET_HARD_FLOAT && TARGET_SPE)
39a10a29
GK
8307 && (code == LE || code == GE
8308 || code == UNEQ || code == LTGT
8309 || code == UNGT || code == UNLT))
8310 {
8311 enum rtx_code or1, or2;
8312 rtx or1_rtx, or2_rtx, compare2_rtx;
8313 rtx or_result = gen_reg_rtx (CCEQmode);
8314
8315 switch (code)
8316 {
8317 case LE: or1 = LT; or2 = EQ; break;
8318 case GE: or1 = GT; or2 = EQ; break;
8319 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8320 case LTGT: or1 = LT; or2 = GT; break;
8321 case UNGT: or1 = UNORDERED; or2 = GT; break;
8322 case UNLT: or1 = UNORDERED; or2 = LT; break;
8323 default: abort ();
8324 }
8325 validate_condition_mode (or1, comp_mode);
8326 validate_condition_mode (or2, comp_mode);
8327 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8328 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8329 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8330 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8331 const_true_rtx);
8332 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8333
8334 compare_result = or_result;
8335 code = EQ;
8336 }
8337
8338 validate_condition_mode (code, GET_MODE (compare_result));
8339
8340 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8341}
8342
8343
8344/* Emit the RTL for an sCOND pattern. */
8345
8346void
8347rs6000_emit_sCOND (code, result)
8348 enum rtx_code code;
8349 rtx result;
8350{
8351 rtx condition_rtx;
8352 enum machine_mode op_mode;
8353
8354 condition_rtx = rs6000_generate_compare (code);
8355
8356 op_mode = GET_MODE (rs6000_compare_op0);
8357 if (op_mode == VOIDmode)
8358 op_mode = GET_MODE (rs6000_compare_op1);
8359
8360 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8361 {
8362 PUT_MODE (condition_rtx, DImode);
8363 convert_move (result, condition_rtx, 0);
8364 }
8365 else
8366 {
8367 PUT_MODE (condition_rtx, SImode);
8368 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8369 }
8370}
8371
39a10a29
GK
8372/* Emit a branch of kind CODE to location LOC. */
8373
8374void
8375rs6000_emit_cbranch (code, loc)
8376 enum rtx_code code;
8377 rtx loc;
8378{
8379 rtx condition_rtx, loc_ref;
8380
8381 condition_rtx = rs6000_generate_compare (code);
8382 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8383 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8384 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8385 loc_ref, pc_rtx)));
8386}
8387
12a4e8c5
GK
8388/* Return the string to output a conditional branch to LABEL, which is
8389 the operand number of the label, or -1 if the branch is really a
8390 conditional return.
8391
8392 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8393 condition code register and its mode specifies what kind of
8394 comparison we made.
8395
8396 REVERSED is non-zero if we should reverse the sense of the comparison.
8397
8398 INSN is the insn. */
8399
8400char *
8401output_cbranch (op, label, reversed, insn)
8402 rtx op;
8403 const char * label;
8404 int reversed;
8405 rtx insn;
8406{
8407 static char string[64];
8408 enum rtx_code code = GET_CODE (op);
8409 rtx cc_reg = XEXP (op, 0);
8410 enum machine_mode mode = GET_MODE (cc_reg);
8411 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 8412 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
8413 int really_reversed = reversed ^ need_longbranch;
8414 char *s = string;
8415 const char *ccode;
8416 const char *pred;
8417 rtx note;
8418
39a10a29
GK
8419 validate_condition_mode (code, mode);
8420
8421 /* Work out which way this really branches. We could use
8422 reverse_condition_maybe_unordered here always but this
8423 makes the resulting assembler clearer. */
12a4e8c5 8424 if (really_reversed)
39a10a29 8425 code = rs6000_reverse_condition (mode, code);
12a4e8c5 8426
a3170dc6
AH
8427 if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
8428 {
8429 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8430 to the GT bit. */
8431 if (code == EQ)
8432 /* Opposite of GT. */
8433 code = UNLE;
8434 else if (code == NE)
8435 code = GT;
8436 else
8437 abort ();
8438 }
8439
39a10a29 8440 switch (code)
12a4e8c5
GK
8441 {
8442 /* Not all of these are actually distinct opcodes, but
8443 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
8444 case NE: case LTGT:
8445 ccode = "ne"; break;
8446 case EQ: case UNEQ:
8447 ccode = "eq"; break;
8448 case GE: case GEU:
8449 ccode = "ge"; break;
8450 case GT: case GTU: case UNGT:
8451 ccode = "gt"; break;
8452 case LE: case LEU:
8453 ccode = "le"; break;
8454 case LT: case LTU: case UNLT:
8455 ccode = "lt"; break;
12a4e8c5
GK
8456 case UNORDERED: ccode = "un"; break;
8457 case ORDERED: ccode = "nu"; break;
8458 case UNGE: ccode = "nl"; break;
8459 case UNLE: ccode = "ng"; break;
8460 default:
a4f6c312 8461 abort ();
12a4e8c5
GK
8462 }
8463
94a54f47
GK
8464 /* Maybe we have a guess as to how likely the branch is.
8465 The old mnemonics don't have a way to specify this information. */
f4857b9b 8466 pred = "";
12a4e8c5
GK
8467 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8468 if (note != NULL_RTX)
8469 {
8470 /* PROB is the difference from 50%. */
8471 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
8472 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8473
8474 /* Only hint for highly probable/improbable branches on newer
8475 cpus as static prediction overrides processor dynamic
8476 prediction. For older cpus we may as well always hint, but
8477 assume not taken for branches that are very close to 50% as a
8478 mispredicted taken branch is more expensive than a
8479 mispredicted not-taken branch. */
8480 if (always_hint
8481 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8482 {
8483 if (abs (prob) > REG_BR_PROB_BASE / 20
8484 && ((prob > 0) ^ need_longbranch))
8485 pred = "+";
8486 else
8487 pred = "-";
8488 }
12a4e8c5 8489 }
12a4e8c5
GK
8490
8491 if (label == NULL)
94a54f47 8492 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 8493 else
94a54f47 8494 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 8495
37c67319
GK
8496 /* We need to escape any '%' characters in the reg_names string.
8497 Assume they'd only be the first character... */
8498 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8499 *s++ = '%';
94a54f47 8500 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
8501
8502 if (label != NULL)
8503 {
8504 /* If the branch distance was too far, we may have to use an
8505 unconditional branch to go the distance. */
8506 if (need_longbranch)
44518ddd 8507 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
8508 else
8509 s += sprintf (s, ",%s", label);
8510 }
8511
8512 return string;
8513}
50a0b056
GK
8514
8515/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8516 operands of the last comparison is nonzero/true, FALSE_COND if it
8517 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 8518
50a0b056
GK
8519int
8520rs6000_emit_cmove (dest, op, true_cond, false_cond)
8521 rtx dest;
8522 rtx op;
8523 rtx true_cond;
8524 rtx false_cond;
8525{
8526 enum rtx_code code = GET_CODE (op);
8527 rtx op0 = rs6000_compare_op0;
8528 rtx op1 = rs6000_compare_op1;
8529 REAL_VALUE_TYPE c1;
3148ad6d
DJ
8530 enum machine_mode compare_mode = GET_MODE (op0);
8531 enum machine_mode result_mode = GET_MODE (dest);
50a0b056
GK
8532 rtx temp;
8533
3148ad6d 8534 /* These modes should always match. */
a3170dc6
AH
8535 if (GET_MODE (op1) != compare_mode
8536 /* In the isel case however, we can use a compare immediate, so
8537 op1 may be a small constant. */
8538 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 8539 return 0;
178c3eff 8540 if (GET_MODE (true_cond) != result_mode)
3148ad6d 8541 return 0;
178c3eff 8542 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
8543 return 0;
8544
50a0b056
GK
8545 /* First, work out if the hardware can do this at all, or
8546 if it's too slow... */
50a0b056 8547 if (! rs6000_compare_fp_p)
a3170dc6
AH
8548 {
8549 if (TARGET_ISEL)
8550 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8551 return 0;
8552 }
50a0b056
GK
8553
8554 /* Eliminate half of the comparisons by switching operands, this
8555 makes the remaining code simpler. */
8556 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8557 || code == LTGT || code == LT)
8558 {
8559 code = reverse_condition_maybe_unordered (code);
8560 temp = true_cond;
8561 true_cond = false_cond;
8562 false_cond = temp;
8563 }
8564
8565 /* UNEQ and LTGT take four instructions for a comparison with zero,
8566 it'll probably be faster to use a branch here too. */
8567 if (code == UNEQ)
8568 return 0;
8569
8570 if (GET_CODE (op1) == CONST_DOUBLE)
8571 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8572
8573 /* We're going to try to implement comparions by performing
8574 a subtract, then comparing against zero. Unfortunately,
8575 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 8576 know that the operand is finite and the comparison
50a0b056
GK
8577 would treat EQ different to UNORDERED, we can't do it. */
8578 if (! flag_unsafe_math_optimizations
8579 && code != GT && code != UNGE
8580 && (GET_CODE (op1) != CONST_DOUBLE || target_isinf (c1))
8581 /* Constructs of the form (a OP b ? a : b) are safe. */
8582 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8583 || (! rtx_equal_p (op0, true_cond)
8584 && ! rtx_equal_p (op1, true_cond))))
8585 return 0;
8586 /* At this point we know we can use fsel. */
8587
8588 /* Reduce the comparison to a comparison against zero. */
3148ad6d 8589 temp = gen_reg_rtx (compare_mode);
50a0b056 8590 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8591 gen_rtx_MINUS (compare_mode, op0, op1)));
50a0b056 8592 op0 = temp;
3148ad6d 8593 op1 = CONST0_RTX (compare_mode);
50a0b056
GK
8594
8595 /* If we don't care about NaNs we can reduce some of the comparisons
8596 down to faster ones. */
8597 if (flag_unsafe_math_optimizations)
8598 switch (code)
8599 {
8600 case GT:
8601 code = LE;
8602 temp = true_cond;
8603 true_cond = false_cond;
8604 false_cond = temp;
8605 break;
8606 case UNGE:
8607 code = GE;
8608 break;
8609 case UNEQ:
8610 code = EQ;
8611 break;
8612 default:
8613 break;
8614 }
8615
8616 /* Now, reduce everything down to a GE. */
8617 switch (code)
8618 {
8619 case GE:
8620 break;
8621
8622 case LE:
3148ad6d
DJ
8623 temp = gen_reg_rtx (compare_mode);
8624 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8625 op0 = temp;
8626 break;
8627
8628 case ORDERED:
3148ad6d
DJ
8629 temp = gen_reg_rtx (compare_mode);
8630 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
8631 op0 = temp;
8632 break;
8633
8634 case EQ:
3148ad6d 8635 temp = gen_reg_rtx (compare_mode);
50a0b056 8636 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
8637 gen_rtx_NEG (compare_mode,
8638 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
8639 op0 = temp;
8640 break;
8641
8642 case UNGE:
3148ad6d 8643 temp = gen_reg_rtx (result_mode);
50a0b056 8644 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8645 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8646 gen_rtx_GE (VOIDmode,
8647 op0, op1),
8648 true_cond, false_cond)));
8649 false_cond = temp;
8650 true_cond = false_cond;
8651
3148ad6d
DJ
8652 temp = gen_reg_rtx (compare_mode);
8653 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8654 op0 = temp;
8655 break;
8656
8657 case GT:
3148ad6d 8658 temp = gen_reg_rtx (result_mode);
50a0b056 8659 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8660 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8661 gen_rtx_GE (VOIDmode,
8662 op0, op1),
8663 true_cond, false_cond)));
8664 true_cond = temp;
8665 false_cond = true_cond;
8666
3148ad6d
DJ
8667 temp = gen_reg_rtx (compare_mode);
8668 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8669 op0 = temp;
8670 break;
8671
8672 default:
8673 abort ();
8674 }
8675
8676 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 8677 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8678 gen_rtx_GE (VOIDmode,
8679 op0, op1),
8680 true_cond, false_cond)));
8681 return 1;
8682}
8683
a3170dc6
AH
8684/* Same as above, but for ints (isel). */
8685
8686static int
8687rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
8688 rtx dest;
8689 rtx op;
8690 rtx true_cond;
8691 rtx false_cond;
8692{
8693 rtx condition_rtx, cr;
8694
8695 /* All isel implementations thus far are 32-bits. */
8696 if (GET_MODE (rs6000_compare_op0) != SImode)
8697 return 0;
8698
8699 /* We still have to do the compare, because isel doesn't do a
8700 compare, it just looks at the CRx bits set by a previous compare
8701 instruction. */
8702 condition_rtx = rs6000_generate_compare (GET_CODE (op));
8703 cr = XEXP (condition_rtx, 0);
8704
8705 if (GET_MODE (cr) == CCmode)
8706 emit_insn (gen_isel_signed (dest, condition_rtx,
8707 true_cond, false_cond, cr));
8708 else
8709 emit_insn (gen_isel_unsigned (dest, condition_rtx,
8710 true_cond, false_cond, cr));
8711
8712 return 1;
8713}
8714
8715const char *
8716output_isel (operands)
8717 rtx *operands;
8718{
8719 enum rtx_code code;
8720
8721 code = GET_CODE (operands[1]);
8722 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
8723 {
8724 PUT_CODE (operands[1], reverse_condition (code));
8725 return "isel %0,%3,%2,%j1";
8726 }
8727 else
8728 return "isel %0,%2,%3,%j1";
8729}
8730
50a0b056
GK
8731void
8732rs6000_emit_minmax (dest, code, op0, op1)
8733 rtx dest;
8734 enum rtx_code code;
8735 rtx op0;
8736 rtx op1;
8737{
8738 enum machine_mode mode = GET_MODE (op0);
5dc8d536 8739 enum rtx_code c;
50a0b056 8740 rtx target;
5dc8d536
AH
8741
8742 if (code == SMAX || code == SMIN)
8743 c = GE;
8744 else
8745 c = GEU;
8746
50a0b056 8747 if (code == SMAX || code == UMAX)
5dc8d536 8748 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8749 op0, op1, mode, 0);
8750 else
5dc8d536 8751 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8752 op1, op0, mode, 0);
8753 if (target == NULL_RTX)
8754 abort ();
8755 if (target != dest)
8756 emit_move_insn (dest, target);
8757}
12a4e8c5 8758\f
a4f6c312
SS
8759/* This page contains routines that are used to determine what the
8760 function prologue and epilogue code will do and write them out. */
9878760c 8761
a4f6c312
SS
8762/* Return the first fixed-point register that is required to be
8763 saved. 32 if none. */
9878760c
RK
8764
8765int
8766first_reg_to_save ()
8767{
8768 int first_reg;
8769
8770 /* Find lowest numbered live register. */
8771 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
8772 if (regs_ever_live[first_reg]
8773 && (! call_used_regs[first_reg]
1db02437 8774 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
8775 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
8776 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
8777 break;
8778
ee890fe2
SS
8779#if TARGET_MACHO
8780 if (flag_pic && current_function_uses_pic_offset_table &&
1db02437
FS
8781 (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM))
8782 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
8783#endif
8784
9878760c
RK
8785 return first_reg;
8786}
8787
8788/* Similar, for FP regs. */
8789
8790int
8791first_fp_reg_to_save ()
8792{
8793 int first_reg;
8794
8795 /* Find lowest numbered live register. */
8796 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8797 if (regs_ever_live[first_reg])
8798 break;
8799
8800 return first_reg;
8801}
00b960c7
AH
8802
8803/* Similar, for AltiVec regs. */
8804
8805static int
8806first_altivec_reg_to_save ()
8807{
8808 int i;
8809
8810 /* Stack frame remains as is unless we are in AltiVec ABI. */
8811 if (! TARGET_ALTIVEC_ABI)
8812 return LAST_ALTIVEC_REGNO + 1;
8813
8814 /* Find lowest numbered live register. */
8815 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8816 if (regs_ever_live[i])
8817 break;
8818
8819 return i;
8820}
8821
8822/* Return a 32-bit mask of the AltiVec registers we need to set in
8823 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
8824 the 32-bit word is 0. */
8825
8826static unsigned int
8827compute_vrsave_mask ()
8828{
8829 unsigned int i, mask = 0;
8830
8831 /* First, find out if we use _any_ altivec registers. */
8832 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8833 if (regs_ever_live[i])
8834 mask |= ALTIVEC_REG_BIT (i);
8835
8836 if (mask == 0)
8837 return mask;
8838
8839 /* Next, add all registers that are call-clobbered. We do this
8840 because post-reload register optimizers such as regrename_optimize
8841 may choose to use them. They never change the register class
8842 chosen by reload, so cannot create new uses of altivec registers
8843 if there were none before, so the early exit above is safe. */
8844 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
8845 altivec registers not saved in the mask, which might well make the
8846 adjustments below more effective in eliding the save/restore of
8847 VRSAVE in small functions. */
8848 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8849 if (call_used_regs[i])
8850 mask |= ALTIVEC_REG_BIT (i);
8851
8852 /* Next, remove the argument registers from the set. These must
8853 be in the VRSAVE mask set by the caller, so we don't need to add
8854 them in again. More importantly, the mask we compute here is
8855 used to generate CLOBBERs in the set_vrsave insn, and we do not
8856 wish the argument registers to die. */
8857 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
8858 mask &= ~ALTIVEC_REG_BIT (i);
8859
8860 /* Similarly, remove the return value from the set. */
8861 {
8862 bool yes = false;
8863 diddle_return_value (is_altivec_return_reg, &yes);
8864 if (yes)
8865 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
8866 }
8867
8868 return mask;
8869}
8870
8871static void
8872is_altivec_return_reg (reg, xyes)
8873 rtx reg;
8874 void *xyes;
8875{
8876 bool *yes = (bool *) xyes;
8877 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
8878 *yes = true;
8879}
8880
4697a36c
MM
8881\f
8882/* Calculate the stack information for the current function. This is
8883 complicated by having two separate calling sequences, the AIX calling
8884 sequence and the V.4 calling sequence.
8885
592696dd 8886 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 8887 32-bit 64-bit
4697a36c 8888 SP----> +---------------------------------------+
a260abc9 8889 | back chain to caller | 0 0
4697a36c 8890 +---------------------------------------+
a260abc9 8891 | saved CR | 4 8 (8-11)
4697a36c 8892 +---------------------------------------+
a260abc9 8893 | saved LR | 8 16
4697a36c 8894 +---------------------------------------+
a260abc9 8895 | reserved for compilers | 12 24
4697a36c 8896 +---------------------------------------+
a260abc9 8897 | reserved for binders | 16 32
4697a36c 8898 +---------------------------------------+
a260abc9 8899 | saved TOC pointer | 20 40
4697a36c 8900 +---------------------------------------+
a260abc9 8901 | Parameter save area (P) | 24 48
4697a36c 8902 +---------------------------------------+
a260abc9 8903 | Alloca space (A) | 24+P etc.
802a0058 8904 +---------------------------------------+
a7df97e6 8905 | Local variable space (L) | 24+P+A
4697a36c 8906 +---------------------------------------+
a7df97e6 8907 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 8908 +---------------------------------------+
00b960c7
AH
8909 | Save area for AltiVec registers (W) | 24+P+A+L+X
8910 +---------------------------------------+
8911 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
8912 +---------------------------------------+
8913 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 8914 +---------------------------------------+
00b960c7
AH
8915 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
8916 +---------------------------------------+
8917 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
8918 +---------------------------------------+
8919 old SP->| back chain to caller's caller |
8920 +---------------------------------------+
8921
5376a30c
KR
8922 The required alignment for AIX configurations is two words (i.e., 8
8923 or 16 bytes).
8924
8925
4697a36c
MM
8926 V.4 stack frames look like:
8927
8928 SP----> +---------------------------------------+
8929 | back chain to caller | 0
8930 +---------------------------------------+
5eb387b8 8931 | caller's saved LR | 4
4697a36c
MM
8932 +---------------------------------------+
8933 | Parameter save area (P) | 8
8934 +---------------------------------------+
a7df97e6
MM
8935 | Alloca space (A) | 8+P
8936 +---------------------------------------+
8937 | Varargs save area (V) | 8+P+A
8938 +---------------------------------------+
8939 | Local variable space (L) | 8+P+A+V
8940 +---------------------------------------+
8941 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 8942 +---------------------------------------+
00b960c7
AH
8943 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
8944 +---------------------------------------+
8945 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
8946 +---------------------------------------+
8947 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
8948 +---------------------------------------+
a3170dc6
AH
8949 | SPE: area for 64-bit GP registers |
8950 +---------------------------------------+
8951 | SPE alignment padding |
8952 +---------------------------------------+
00b960c7 8953 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 8954 +---------------------------------------+
00b960c7 8955 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 8956 +---------------------------------------+
00b960c7 8957 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
8958 +---------------------------------------+
8959 old SP->| back chain to caller's caller |
8960 +---------------------------------------+
b6c9286a 8961
5376a30c
KR
8962 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
8963 given. (But note below and in sysv4.h that we require only 8 and
8964 may round up the size of our stack frame anyways. The historical
8965 reason is early versions of powerpc-linux which didn't properly
8966 align the stack at program startup. A happy side-effect is that
8967 -mno-eabi libraries can be used with -meabi programs.)
8968
5376a30c
KR
8969 The EABI configuration defaults to the V.4 layout, unless
8970 -mcall-aix is used, in which case the AIX layout is used. However,
8971 the stack alignment requirements may differ. If -mno-eabi is not
8972 given, the required stack alignment is 8 bytes; if -mno-eabi is
8973 given, the required alignment is 16 bytes. (But see V.4 comment
8974 above.) */
4697a36c 8975
61b2fbe7
MM
8976#ifndef ABI_STACK_BOUNDARY
8977#define ABI_STACK_BOUNDARY STACK_BOUNDARY
8978#endif
8979
4697a36c
MM
8980rs6000_stack_t *
8981rs6000_stack_info ()
8982{
8983 static rs6000_stack_t info, zero_info;
8984 rs6000_stack_t *info_ptr = &info;
9ebbca7d 8985 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 8986 enum rs6000_abi abi;
83720594 8987 int ehrd_size;
b6c9286a 8988 int total_raw_size;
4697a36c 8989
a4f6c312 8990 /* Zero all fields portably. */
4697a36c
MM
8991 info = zero_info;
8992
a4f6c312 8993 /* Select which calling sequence. */
b6c9286a 8994 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 8995
a4f6c312 8996 /* Calculate which registers need to be saved & save area size. */
4697a36c 8997 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 8998 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 8999 even if it currently looks like we won't. */
2bfcf297 9000 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
9001 || (flag_pic == 1 && abi == ABI_V4)
9002 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
9003 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
9004 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
9005 else
9006 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 9007
a3170dc6
AH
9008 /* For the SPE, we have an additional upper 32-bits on each GPR.
9009 Ideally we should save the entire 64-bits only when the upper
9010 half is used in SIMD instructions. Since we only record
9011 registers live (not the size they are used in), this proves
9012 difficult because we'd have to traverse the instruction chain at
9013 the right time, taking reload into account. This is a real pain,
9014 so we opt to save the GPRs in 64-bits always. Anyone overly
9015 concerned with frame size can fix this. ;-).
9016
9017 So... since we save all GPRs (except the SP) in 64-bits, the
9018 traditional GP save area will be empty. */
9019 if (TARGET_SPE_ABI)
9020 info_ptr->gp_size = 0;
9021
4697a36c
MM
9022 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
9023 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
9024
00b960c7
AH
9025 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9026 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9027 - info_ptr->first_altivec_reg_save);
9028
592696dd 9029 /* Does this function call anything? */
71f123ca
FS
9030 info_ptr->calls_p = (! current_function_is_leaf
9031 || cfun->machine->ra_needs_full_frame);
b6c9286a 9032
a4f6c312 9033 /* Determine if we need to save the link register. */
71f123ca 9034 if (rs6000_ra_ever_killed ()
70f4f91c 9035 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
9036#ifdef TARGET_RELOCATABLE
9037 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9038#endif
9039 || (info_ptr->first_fp_reg_save != 64
9040 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 9041 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 9042 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
9043 || (DEFAULT_ABI == ABI_DARWIN
9044 && flag_pic
9045 && current_function_uses_pic_offset_table)
4697a36c
MM
9046 || info_ptr->calls_p)
9047 {
9048 info_ptr->lr_save_p = 1;
9ebbca7d 9049 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9050 }
9051
9ebbca7d
GK
9052 /* Determine if we need to save the condition code registers. */
9053 if (regs_ever_live[CR2_REGNO]
9054 || regs_ever_live[CR3_REGNO]
9055 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9056 {
9057 info_ptr->cr_save_p = 1;
f607bc57 9058 if (abi == ABI_V4)
4697a36c
MM
9059 info_ptr->cr_size = reg_size;
9060 }
9061
83720594
RH
9062 /* If the current function calls __builtin_eh_return, then we need
9063 to allocate stack space for registers that will hold data for
9064 the exception handler. */
9065 if (current_function_calls_eh_return)
9066 {
9067 unsigned int i;
9068 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9069 continue;
a3170dc6
AH
9070
9071 /* SPE saves EH registers in 64-bits. */
9072 ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9073 }
9074 else
9075 ehrd_size = 0;
9076
592696dd 9077 /* Determine various sizes. */
4697a36c
MM
9078 info_ptr->reg_size = reg_size;
9079 info_ptr->fixed_size = RS6000_SAVE_AREA;
9080 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9081 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9082 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9083 8);
00b960c7 9084
a3170dc6
AH
9085 if (TARGET_SPE_ABI)
9086 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9087 else
9088 info_ptr->spe_gp_size = 0;
9089
08b57fb3 9090 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9091 {
9092 info_ptr->vrsave_mask = compute_vrsave_mask ();
9093 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9094 }
9095 else
9096 {
9097 info_ptr->vrsave_mask = 0;
9098 info_ptr->vrsave_size = 0;
9099 }
b6c9286a 9100
592696dd 9101 /* Calculate the offsets. */
24d304eb 9102 switch (abi)
4697a36c 9103 {
b6c9286a 9104 case ABI_NONE:
24d304eb 9105 default:
b6c9286a
MM
9106 abort ();
9107
9108 case ABI_AIX:
9109 case ABI_AIX_NODESC:
ee890fe2 9110 case ABI_DARWIN:
b6c9286a
MM
9111 info_ptr->fp_save_offset = - info_ptr->fp_size;
9112 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9113
9114 if (TARGET_ALTIVEC_ABI)
9115 {
9116 info_ptr->vrsave_save_offset
9117 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9118
9119 /* Align stack so vector save area is on a quadword boundary. */
9120 if (info_ptr->altivec_size != 0)
9121 info_ptr->altivec_padding_size
9122 = 16 - (-info_ptr->vrsave_save_offset % 16);
9123 else
9124 info_ptr->altivec_padding_size = 0;
9125
9126 info_ptr->altivec_save_offset
9127 = info_ptr->vrsave_save_offset
9128 - info_ptr->altivec_padding_size
9129 - info_ptr->altivec_size;
9130
9131 /* Adjust for AltiVec case. */
9132 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9133 }
9134 else
9135 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9136 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9137 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9138 break;
9139
9140 case ABI_V4:
b6c9286a
MM
9141 info_ptr->fp_save_offset = - info_ptr->fp_size;
9142 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9143 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9144
a3170dc6
AH
9145 if (TARGET_SPE_ABI)
9146 {
9147 /* Align stack so SPE GPR save area is aligned on a
9148 double-word boundary. */
9149 if (info_ptr->spe_gp_size != 0)
9150 info_ptr->spe_padding_size
9151 = 8 - (-info_ptr->cr_save_offset % 8);
9152 else
9153 info_ptr->spe_padding_size = 0;
9154
9155 info_ptr->spe_gp_save_offset
9156 = info_ptr->cr_save_offset
9157 - info_ptr->spe_padding_size
9158 - info_ptr->spe_gp_size;
9159
9160 /* Adjust for SPE case. */
9161 info_ptr->toc_save_offset
9162 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9163 }
9164 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9165 {
9166 info_ptr->vrsave_save_offset
9167 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9168
9169 /* Align stack so vector save area is on a quadword boundary. */
9170 if (info_ptr->altivec_size != 0)
9171 info_ptr->altivec_padding_size
9172 = 16 - (-info_ptr->vrsave_save_offset % 16);
9173 else
9174 info_ptr->altivec_padding_size = 0;
9175
9176 info_ptr->altivec_save_offset
9177 = info_ptr->vrsave_save_offset
9178 - info_ptr->altivec_padding_size
9179 - info_ptr->altivec_size;
9180
9181 /* Adjust for AltiVec case. */
9182 info_ptr->toc_save_offset
9183 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9184 }
9185 else
9186 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9187 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9188 info_ptr->lr_save_offset = reg_size;
9189 break;
4697a36c
MM
9190 }
9191
00b960c7
AH
9192 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9193 + info_ptr->gp_size
9194 + info_ptr->altivec_size
9195 + info_ptr->altivec_padding_size
9196 + info_ptr->vrsave_size
a3170dc6
AH
9197 + info_ptr->spe_gp_size
9198 + info_ptr->spe_padding_size
00b960c7
AH
9199 + ehrd_size
9200 + info_ptr->cr_size
9201 + info_ptr->lr_size
9202 + info_ptr->vrsave_size
9203 + info_ptr->toc_size,
9204 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9205 ? 16 : 8);
9206
ff381587
MM
9207 total_raw_size = (info_ptr->vars_size
9208 + info_ptr->parm_size
ff381587
MM
9209 + info_ptr->save_size
9210 + info_ptr->varargs_size
9211 + info_ptr->fixed_size);
9212
a4f6c312
SS
9213 info_ptr->total_size =
9214 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9215
9216 /* Determine if we need to allocate any stack frame:
9217
a4f6c312
SS
9218 For AIX we need to push the stack if a frame pointer is needed
9219 (because the stack might be dynamically adjusted), if we are
9220 debugging, if we make calls, or if the sum of fp_save, gp_save,
9221 and local variables are more than the space needed to save all
9222 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9223 + 18*8 = 288 (GPR13 reserved).
ff381587 9224
a4f6c312
SS
9225 For V.4 we don't have the stack cushion that AIX uses, but assume
9226 that the debugger can handle stackless frames. */
ff381587
MM
9227
9228 if (info_ptr->calls_p)
9229 info_ptr->push_p = 1;
9230
f607bc57 9231 else if (abi == ABI_V4)
e72247f4 9232 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
9233
9234 else
9235 info_ptr->push_p = (frame_pointer_needed
ee890fe2 9236 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 9237 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 9238 > (TARGET_32BIT ? 220 : 288)));
ff381587 9239
a4f6c312 9240 /* Zero offsets if we're not saving those registers. */
8dda1a21 9241 if (info_ptr->fp_size == 0)
4697a36c
MM
9242 info_ptr->fp_save_offset = 0;
9243
8dda1a21 9244 if (info_ptr->gp_size == 0)
4697a36c
MM
9245 info_ptr->gp_save_offset = 0;
9246
00b960c7
AH
9247 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9248 info_ptr->altivec_save_offset = 0;
9249
9250 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9251 info_ptr->vrsave_save_offset = 0;
9252
a3170dc6
AH
9253 if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
9254 info_ptr->spe_gp_save_offset = 0;
9255
c81fc13e 9256 if (! info_ptr->lr_save_p)
4697a36c
MM
9257 info_ptr->lr_save_offset = 0;
9258
c81fc13e 9259 if (! info_ptr->cr_save_p)
4697a36c
MM
9260 info_ptr->cr_save_offset = 0;
9261
c81fc13e 9262 if (! info_ptr->toc_save_p)
b6c9286a
MM
9263 info_ptr->toc_save_offset = 0;
9264
4697a36c
MM
9265 return info_ptr;
9266}
9267
9268void
9269debug_stack_info (info)
9270 rs6000_stack_t *info;
9878760c 9271{
d330fd93 9272 const char *abi_string;
24d304eb 9273
c81fc13e 9274 if (! info)
4697a36c
MM
9275 info = rs6000_stack_info ();
9276
9277 fprintf (stderr, "\nStack information for function %s:\n",
9278 ((current_function_decl && DECL_NAME (current_function_decl))
9279 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9280 : "<unknown>"));
9281
24d304eb
RK
9282 switch (info->abi)
9283 {
b6c9286a
MM
9284 default: abi_string = "Unknown"; break;
9285 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9286 case ABI_AIX:
b6c9286a 9287 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9288 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9289 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9290 }
9291
9292 fprintf (stderr, "\tABI = %5s\n", abi_string);
9293
00b960c7
AH
9294 if (TARGET_ALTIVEC_ABI)
9295 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9296
a3170dc6
AH
9297 if (TARGET_SPE_ABI)
9298 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9299
4697a36c
MM
9300 if (info->first_gp_reg_save != 32)
9301 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9302
9303 if (info->first_fp_reg_save != 64)
9304 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9305
00b960c7
AH
9306 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9307 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9308 info->first_altivec_reg_save);
9309
4697a36c
MM
9310 if (info->lr_save_p)
9311 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9312
4697a36c
MM
9313 if (info->cr_save_p)
9314 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9315
b6c9286a
MM
9316 if (info->toc_save_p)
9317 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9318
00b960c7
AH
9319 if (info->vrsave_mask)
9320 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9321
4697a36c
MM
9322 if (info->push_p)
9323 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9324
9325 if (info->calls_p)
9326 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9327
4697a36c
MM
9328 if (info->gp_save_offset)
9329 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9330
9331 if (info->fp_save_offset)
9332 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9333
00b960c7
AH
9334 if (info->altivec_save_offset)
9335 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9336 info->altivec_save_offset);
9337
a3170dc6
AH
9338 if (info->spe_gp_save_offset)
9339 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9340 info->spe_gp_save_offset);
9341
00b960c7
AH
9342 if (info->vrsave_save_offset)
9343 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9344 info->vrsave_save_offset);
9345
4697a36c
MM
9346 if (info->lr_save_offset)
9347 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9348
9349 if (info->cr_save_offset)
9350 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9351
b6c9286a
MM
9352 if (info->toc_save_offset)
9353 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9354
4697a36c
MM
9355 if (info->varargs_save_offset)
9356 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9357
9358 if (info->total_size)
9359 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9360
9361 if (info->varargs_size)
9362 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9363
9364 if (info->vars_size)
9365 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9366
9367 if (info->parm_size)
9368 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9369
9370 if (info->fixed_size)
9371 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9372
9373 if (info->gp_size)
9374 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9375
a3170dc6
AH
9376 if (info->spe_gp_size)
9377 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9378
4697a36c
MM
9379 if (info->fp_size)
9380 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9381
00b960c7
AH
9382 if (info->altivec_size)
9383 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9384
9385 if (info->vrsave_size)
9386 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9387
9388 if (info->altivec_padding_size)
9389 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9390 info->altivec_padding_size);
9391
a3170dc6
AH
9392 if (info->spe_padding_size)
9393 fprintf (stderr, "\tspe_padding_size = %5d\n",
9394 info->spe_padding_size);
9395
a4f6c312 9396 if (info->lr_size)
ed947a96 9397 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9398
4697a36c
MM
9399 if (info->cr_size)
9400 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9401
a4f6c312 9402 if (info->toc_size)
b6c9286a
MM
9403 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9404
4697a36c
MM
9405 if (info->save_size)
9406 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9407
9408 if (info->reg_size != 4)
9409 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9410
9411 fprintf (stderr, "\n");
9878760c 9412}
71f123ca
FS
9413
9414rtx
9415rs6000_return_addr (count, frame)
9416 int count;
9417 rtx frame;
9418{
a4f6c312
SS
9419 /* Currently we don't optimize very well between prolog and body
9420 code and for PIC code the code can be actually quite bad, so
9421 don't try to be too clever here. */
f585a356 9422 if (count != 0 || flag_pic != 0)
71f123ca
FS
9423 {
9424 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9425
9426 return
9427 gen_rtx_MEM
9428 (Pmode,
9429 memory_address
9430 (Pmode,
9431 plus_constant (copy_to_reg
9432 (gen_rtx_MEM (Pmode,
9433 memory_address (Pmode, frame))),
9434 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9435 }
9436
9e2f7ec7 9437 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9438}
9439
5e1bf043
DJ
9440/* Say whether a function is a candidate for sibcall handling or not.
9441 We do not allow indirect calls to be optimized into sibling calls.
9442 Also, we can't do it if there are any vector parameters; there's
9443 nowhere to put the VRsave code so it works; note that functions with
9444 vector parameters are required to have a prototype, so the argument
9445 type info must be available here. (The tail recursion case can work
9446 with vector parameters, but there's no way to distinguish here.) */
9447int
9448function_ok_for_sibcall (fndecl)
9449 tree fndecl;
9450{
9451 tree type;
9452 if (fndecl)
9453 {
9454 if (TARGET_ALTIVEC_VRSAVE)
9455 {
9456 for (type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
9457 type; type = TREE_CHAIN (type))
9458 {
c15b529f 9459 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
5e1bf043
DJ
9460 return 0;
9461 }
9462 }
9463 if (DEFAULT_ABI == ABI_DARWIN
c15b529f 9464 || (TREE_ASM_WRITTEN (fndecl) && !flag_pic) || !TREE_PUBLIC (fndecl))
5e1bf043
DJ
9465 return 1;
9466 }
9467 return 0;
9468}
9469
9470/* function rewritten to handle sibcalls */
71f123ca
FS
9471static int
9472rs6000_ra_ever_killed ()
9473{
9474 rtx top;
5e1bf043
DJ
9475 rtx reg;
9476 rtx insn;
71f123ca
FS
9477
9478#ifdef ASM_OUTPUT_MI_THUNK
9479 if (current_function_is_thunk)
9480 return 0;
9481#endif
5e1bf043
DJ
9482 /* regs_ever_live has LR marked as used if any sibcalls
9483 are present. Which it is, but this should not force
9484 saving and restoring in the prologue/epilog. Likewise,
9485 reg_set_between_p thinks a sibcall clobbers LR, so
9486 that is inappropriate. */
9487 /* Also, the prologue can generate a store into LR that
9488 doesn't really count, like this:
9489 move LR->R0
9490 bcl to set PIC register
9491 move LR->R31
9492 move R0->LR
9493 When we're called from the epilog, we need to avoid counting
9494 this as a store; thus we ignore any insns with a REG_MAYBE_DEAD note. */
9495
71f123ca
FS
9496 push_topmost_sequence ();
9497 top = get_insns ();
9498 pop_topmost_sequence ();
5e1bf043 9499 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9500
5e1bf043
DJ
9501 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9502 {
9503 if (INSN_P (insn))
9504 {
9505 if (FIND_REG_INC_NOTE (insn, reg))
9506 return 1;
9507 else if (GET_CODE (insn) == CALL_INSN
c15b529f 9508 && !SIBLING_CALL_P (insn))
5e1bf043
DJ
9509 return 1;
9510 else if (set_of (reg, insn) != NULL_RTX
c15b529f 9511 && find_reg_note (insn, REG_MAYBE_DEAD, NULL_RTX) == 0)
5e1bf043
DJ
9512 return 1;
9513 }
9514 }
9515 return 0;
71f123ca 9516}
4697a36c 9517\f
8cd8f856
GK
9518/* Add a REG_MAYBE_DEAD note to the insn. */
9519static void
9520rs6000_maybe_dead (insn)
9521 rtx insn;
9522{
9523 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9524 const0_rtx,
9525 REG_NOTES (insn));
9526}
9527
9ebbca7d 9528/* Emit instructions needed to load the TOC register.
c7ca610e 9529 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9530 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9531
9532void
9ebbca7d
GK
9533rs6000_emit_load_toc_table (fromprolog)
9534 int fromprolog;
c7ca610e 9535{
9ebbca7d 9536 rtx dest;
1db02437 9537 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9538
2bfcf297 9539 if (TARGET_ELF && DEFAULT_ABI != ABI_AIX)
c7ca610e 9540 {
f607bc57 9541 if (DEFAULT_ABI == ABI_V4 && flag_pic == 1)
38c1f2d7 9542 {
9ebbca7d
GK
9543 rtx temp = (fromprolog
9544 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9545 : gen_reg_rtx (Pmode));
2bfcf297 9546 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
8cd8f856 9547 rs6000_maybe_dead (emit_move_insn (dest, temp));
38c1f2d7 9548 }
9ebbca7d
GK
9549 else if (flag_pic == 2)
9550 {
9551 char buf[30];
9552 rtx tempLR = (fromprolog
9553 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9554 : gen_reg_rtx (Pmode));
9555 rtx temp0 = (fromprolog
9556 ? gen_rtx_REG (Pmode, 0)
9557 : gen_reg_rtx (Pmode));
9558 rtx symF;
9559
9560 /* possibly create the toc section */
9561 if (! toc_initialized)
9562 {
9563 toc_section ();
9564 function_section (current_function_decl);
9565 }
9566
9567 if (fromprolog)
9568 {
9569 rtx symL;
9570
9571 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
a8a05998 9572 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
38c1f2d7 9573
9ebbca7d 9574 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
a8a05998 9575 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
38c1f2d7 9576
8cd8f856
GK
9577 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9578 symF)));
9579 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9580 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9581 symL,
9582 symF)));
9ebbca7d
GK
9583 }
9584 else
9585 {
9586 rtx tocsym;
9587 static int reload_toc_labelno = 0;
9588
b999aaeb 9589 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
38c1f2d7 9590
9ebbca7d 9591 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
a8a05998 9592 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9593
8cd8f856
GK
9594 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9595 symF,
9596 tocsym)));
9597 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9598 rs6000_maybe_dead (emit_move_insn (temp0,
9599 gen_rtx_MEM (Pmode, dest)));
9ebbca7d 9600 }
8cd8f856 9601 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d
GK
9602 }
9603 else if (flag_pic == 0 && TARGET_MINIMAL_TOC)
9604 {
9605 /* This is for AIX code running in non-PIC ELF. */
9606 char buf[30];
9607 rtx realsym;
38c1f2d7 9608 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
a8a05998 9609 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9610
8cd8f856
GK
9611 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9612 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9ebbca7d
GK
9613 }
9614 else
a4f6c312 9615 abort ();
9ebbca7d
GK
9616 }
9617 else
9618 {
9619 if (TARGET_32BIT)
8cd8f856 9620 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 9621 else
8cd8f856 9622 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d
GK
9623 }
9624}
9625
9626int
9627get_TOC_alias_set ()
9628{
9629 static int set = -1;
9630 if (set == -1)
9631 set = new_alias_set ();
9632 return set;
9633}
9634
9635/* This retuns nonzero if the current function uses the TOC. This is
9636 determined by the presence of (unspec ... 7), which is generated by
9637 the various load_toc_* patterns. */
a4f6c312 9638
9ebbca7d
GK
9639int
9640uses_TOC ()
9641{
9642 rtx insn;
38c1f2d7 9643
9ebbca7d 9644 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 9645 if (INSN_P (insn))
9ebbca7d
GK
9646 {
9647 rtx pat = PATTERN (insn);
9648 int i;
9649
8cd8f856 9650 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
9651 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9652 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9653 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9654 return 1;
38c1f2d7 9655 }
9ebbca7d
GK
9656 return 0;
9657}
38c1f2d7 9658
9ebbca7d 9659rtx
a4f6c312 9660create_TOC_reference (symbol)
9ebbca7d
GK
9661 rtx symbol;
9662{
a8a05998
ZW
9663 return gen_rtx_PLUS (Pmode,
9664 gen_rtx_REG (Pmode, TOC_REGISTER),
9665 gen_rtx_CONST (Pmode,
9666 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 9667 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 9668}
38c1f2d7 9669
9ebbca7d
GK
9670#if TARGET_AIX
9671/* __throw will restore its own return address to be the same as the
9672 return address of the function that the throw is being made to.
9673 This is unfortunate, because we want to check the original
9674 return address to see if we need to restore the TOC.
9675 So we have to squirrel it away here.
9676 This is used only in compiling __throw and __rethrow.
c7ca610e 9677
9ebbca7d
GK
9678 Most of this code should be removed by CSE. */
9679static rtx insn_after_throw;
c7ca610e 9680
a4f6c312 9681/* This does the saving... */
9ebbca7d
GK
9682void
9683rs6000_aix_emit_builtin_unwind_init ()
9684{
9685 rtx mem;
9686 rtx stack_top = gen_reg_rtx (Pmode);
9687 rtx opcode_addr = gen_reg_rtx (Pmode);
9688
9689 insn_after_throw = gen_reg_rtx (SImode);
9690
9691 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9692 emit_move_insn (stack_top, mem);
9693
9694 mem = gen_rtx_MEM (Pmode,
9695 gen_rtx_PLUS (Pmode, stack_top,
9696 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9697 emit_move_insn (opcode_addr, mem);
9698 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
9699}
9700
a4f6c312
SS
9701/* Emit insns to _restore_ the TOC register, at runtime (specifically
9702 in _eh.o). Only used on AIX.
9ebbca7d
GK
9703
9704 The idea is that on AIX, function calls look like this:
9705 bl somefunction-trampoline
9706 lwz r2,20(sp)
9707
a4f6c312 9708 and later,
9ebbca7d
GK
9709 somefunction-trampoline:
9710 stw r2,20(sp)
9711 ... load function address in the count register ...
9712 bctr
9713 or like this, if the linker determines that this is not a cross-module call
9714 and so the TOC need not be restored:
9715 bl somefunction
9716 nop
9717 or like this, if the compiler could determine that this is not a
9718 cross-module call:
9719 bl somefunction
9720 now, the tricky bit here is that register 2 is saved and restored
9721 by the _linker_, so we can't readily generate debugging information
9722 for it. So we need to go back up the call chain looking at the
9723 insns at return addresses to see which calls saved the TOC register
9724 and so see where it gets restored from.
9725
9726 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9727 just before the actual epilogue.
9728
9729 On the bright side, this incurs no space or time overhead unless an
9730 exception is thrown, except for the extra code in libgcc.a.
9731
9732 The parameter STACKSIZE is a register containing (at runtime)
9733 the amount to be popped off the stack in addition to the stack frame
9734 of this routine (which will be __throw or __rethrow, and so is
9735 guaranteed to have a stack frame). */
a4f6c312 9736
9ebbca7d
GK
9737void
9738rs6000_emit_eh_toc_restore (stacksize)
9739 rtx stacksize;
9740{
9741 rtx top_of_stack;
9742 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9743 rtx tocompare = gen_reg_rtx (SImode);
9744 rtx opcode = gen_reg_rtx (SImode);
9745 rtx opcode_addr = gen_reg_rtx (Pmode);
9746 rtx mem;
9747 rtx loop_start = gen_label_rtx ();
9748 rtx no_toc_restore_needed = gen_label_rtx ();
9749 rtx loop_exit = gen_label_rtx ();
9750
9751 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 9752 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9753 emit_move_insn (bottom_of_stack, mem);
9754
9755 top_of_stack = expand_binop (Pmode, add_optab,
9756 bottom_of_stack, stacksize,
9757 NULL_RTX, 1, OPTAB_WIDEN);
9758
2496c7bd
LB
9759 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9760 : 0xE8410028, SImode));
9ebbca7d
GK
9761
9762 if (insn_after_throw == NULL_RTX)
a4f6c312 9763 abort ();
9ebbca7d
GK
9764 emit_move_insn (opcode, insn_after_throw);
9765
6496a589 9766 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
9767 emit_label (loop_start);
9768
9769 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 9770 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9771 no_toc_restore_needed);
9772
9773 mem = gen_rtx_MEM (Pmode,
9774 gen_rtx_PLUS (Pmode, bottom_of_stack,
9775 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
9776 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
9777
9778 emit_label (no_toc_restore_needed);
9779 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 9780 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9781 loop_exit);
9782
9783 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 9784 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9785 emit_move_insn (bottom_of_stack, mem);
9786
9787 mem = gen_rtx_MEM (Pmode,
9788 gen_rtx_PLUS (Pmode, bottom_of_stack,
9789 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9790 emit_move_insn (opcode_addr, mem);
9791 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
9792
6496a589 9793 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 9794 emit_jump (loop_start);
6496a589 9795 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
9796 emit_label (loop_exit);
9797}
9798#endif /* TARGET_AIX */
38c1f2d7 9799\f
ba4828e0
RK
9800/* This ties together stack memory (MEM with an alias set of
9801 rs6000_sr_alias_set) and the change to the stack pointer. */
9802
9ebbca7d
GK
9803static void
9804rs6000_emit_stack_tie ()
9805{
ba4828e0
RK
9806 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
9807
9808 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9809 emit_insn (gen_stack_tie (mem));
9810}
38c1f2d7 9811
9ebbca7d
GK
9812/* Emit the correct code for allocating stack space, as insns.
9813 If COPY_R12, make sure a copy of the old frame is left in r12.
9814 The generated code may use hard register 0 as a temporary. */
9815
9816static void
9817rs6000_emit_allocate_stack (size, copy_r12)
9818 HOST_WIDE_INT size;
38c1f2d7
MM
9819 int copy_r12;
9820{
9ebbca7d
GK
9821 rtx insn;
9822 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9823 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
9824 rtx todec = GEN_INT (-size);
a157febd
GK
9825
9826 if (current_function_limit_stack)
9827 {
9828 if (REG_P (stack_limit_rtx)
9829 && REGNO (stack_limit_rtx) > 1
9830 && REGNO (stack_limit_rtx) <= 31)
9831 {
9ebbca7d
GK
9832 emit_insn (Pmode == SImode
9833 ? gen_addsi3 (tmp_reg,
9834 stack_limit_rtx,
9835 GEN_INT (size))
9836 : gen_adddi3 (tmp_reg,
9837 stack_limit_rtx,
9838 GEN_INT (size)));
9839
9840 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9841 const0_rtx));
a157febd
GK
9842 }
9843 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 9844 && TARGET_32BIT
f607bc57 9845 && DEFAULT_ABI == ABI_V4)
a157febd 9846 {
9ebbca7d
GK
9847 rtx toload = gen_rtx_CONST (VOIDmode,
9848 gen_rtx_PLUS (Pmode,
9849 stack_limit_rtx,
9850 GEN_INT (size)));
9851
9852 emit_insn (gen_elf_high (tmp_reg, toload));
9853 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
9854 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9855 const0_rtx));
a157febd
GK
9856 }
9857 else
9858 warning ("stack limit expression is not supported");
9859 }
9860
9ebbca7d
GK
9861 if (copy_r12 || ! TARGET_UPDATE)
9862 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
9863
38c1f2d7
MM
9864 if (TARGET_UPDATE)
9865 {
9ebbca7d 9866 if (size > 32767)
38c1f2d7 9867 {
9ebbca7d
GK
9868 /* Need a note here so that try_split doesn't get confused. */
9869 if (get_last_insn() == NULL_RTX)
9870 emit_note (0, NOTE_INSN_DELETED);
9871 insn = emit_move_insn (tmp_reg, todec);
9872 try_split (PATTERN (insn), insn, 0);
9873 todec = tmp_reg;
38c1f2d7 9874 }
9ebbca7d
GK
9875
9876 if (Pmode == SImode)
9877 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
9878 todec, stack_reg));
9879 else
9880 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
9881 todec, stack_reg));
38c1f2d7
MM
9882 }
9883 else
9884 {
9ebbca7d
GK
9885 if (Pmode == SImode)
9886 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
38c1f2d7 9887 else
9ebbca7d
GK
9888 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
9889 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
9890 gen_rtx_REG (Pmode, 12));
9891 }
9892
9893 RTX_FRAME_RELATED_P (insn) = 1;
9894 REG_NOTES (insn) =
9895 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9896 gen_rtx_SET (VOIDmode, stack_reg,
9897 gen_rtx_PLUS (Pmode, stack_reg,
9898 GEN_INT (-size))),
9899 REG_NOTES (insn));
9900}
9901
9aa86737
AH
9902/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
9903 knows that:
9904
9905 (mem (plus (blah) (regXX)))
9906
9907 is really:
9908
9909 (mem (plus (blah) (const VALUE_OF_REGXX))). */
9910
9911static void
9912altivec_frame_fixup (insn, reg, val)
9913 rtx insn, reg;
9914 HOST_WIDE_INT val;
9915{
9916 rtx real;
9917
9918 real = copy_rtx (PATTERN (insn));
9919
9920 real = replace_rtx (real, reg, GEN_INT (val));
9921
9922 RTX_FRAME_RELATED_P (insn) = 1;
9923 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9924 real,
9925 REG_NOTES (insn));
9926}
9927
a4f6c312
SS
9928/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
9929 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
9930 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
9931 deduce these equivalences by itself so it wasn't necessary to hold
9932 its hand so much. */
9ebbca7d
GK
9933
9934static void
9935rs6000_frame_related (insn, reg, val, reg2, rreg)
9936 rtx insn;
9937 rtx reg;
9938 HOST_WIDE_INT val;
9939 rtx reg2;
9940 rtx rreg;
9941{
9942 rtx real, temp;
9943
e56c4463
JL
9944 /* copy_rtx will not make unique copies of registers, so we need to
9945 ensure we don't have unwanted sharing here. */
9946 if (reg == reg2)
9947 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9948
9949 if (reg == rreg)
9950 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9951
9ebbca7d
GK
9952 real = copy_rtx (PATTERN (insn));
9953
89e7058f
AH
9954 if (reg2 != NULL_RTX)
9955 real = replace_rtx (real, reg2, rreg);
9956
9ebbca7d
GK
9957 real = replace_rtx (real, reg,
9958 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
9959 STACK_POINTER_REGNUM),
9960 GEN_INT (val)));
9961
9962 /* We expect that 'real' is either a SET or a PARALLEL containing
9963 SETs (and possibly other stuff). In a PARALLEL, all the SETs
9964 are important so they all have to be marked RTX_FRAME_RELATED_P. */
9965
9966 if (GET_CODE (real) == SET)
9967 {
9968 rtx set = real;
9969
9970 temp = simplify_rtx (SET_SRC (set));
9971 if (temp)
9972 SET_SRC (set) = temp;
9973 temp = simplify_rtx (SET_DEST (set));
9974 if (temp)
9975 SET_DEST (set) = temp;
9976 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 9977 {
9ebbca7d
GK
9978 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9979 if (temp)
9980 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 9981 }
38c1f2d7 9982 }
9ebbca7d
GK
9983 else if (GET_CODE (real) == PARALLEL)
9984 {
9985 int i;
9986 for (i = 0; i < XVECLEN (real, 0); i++)
9987 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
9988 {
9989 rtx set = XVECEXP (real, 0, i);
9990
9991 temp = simplify_rtx (SET_SRC (set));
9992 if (temp)
9993 SET_SRC (set) = temp;
9994 temp = simplify_rtx (SET_DEST (set));
9995 if (temp)
9996 SET_DEST (set) = temp;
9997 if (GET_CODE (SET_DEST (set)) == MEM)
9998 {
9999 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10000 if (temp)
10001 XEXP (SET_DEST (set), 0) = temp;
10002 }
10003 RTX_FRAME_RELATED_P (set) = 1;
10004 }
10005 }
10006 else
a4f6c312 10007 abort ();
9ebbca7d 10008
9ebbca7d
GK
10009 RTX_FRAME_RELATED_P (insn) = 1;
10010 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10011 real,
10012 REG_NOTES (insn));
38c1f2d7
MM
10013}
10014
00b960c7
AH
10015/* Returns an insn that has a vrsave set operation with the
10016 appropriate CLOBBERs. */
10017
10018static rtx
9aa86737 10019generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
10020 rtx reg;
10021 rs6000_stack_t *info;
9aa86737 10022 int epiloguep;
00b960c7
AH
10023{
10024 int nclobs, i;
10025 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 10026 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 10027
a004eb82
AH
10028 clobs[0]
10029 = gen_rtx_SET (VOIDmode,
10030 vrsave,
10031 gen_rtx_UNSPEC_VOLATILE (SImode,
10032 gen_rtvec (2, reg, vrsave),
10033 30));
00b960c7
AH
10034
10035 nclobs = 1;
10036
9aa86737
AH
10037 /* We need to clobber the registers in the mask so the scheduler
10038 does not move sets to VRSAVE before sets of AltiVec registers.
10039
10040 However, if the function receives nonlocal gotos, reload will set
10041 all call saved registers live. We will end up with:
10042
10043 (set (reg 999) (mem))
10044 (parallel [ (set (reg vrsave) (unspec blah))
10045 (clobber (reg 999))])
10046
10047 The clobber will cause the store into reg 999 to be dead, and
10048 flow will attempt to delete an epilogue insn. In this case, we
10049 need an unspec use/set of the register. */
00b960c7
AH
10050
10051 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10052 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10053 {
10054 if (!epiloguep || call_used_regs [i])
10055 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10056 gen_rtx_REG (V4SImode, i));
10057 else
10058 {
10059 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10060
10061 clobs[nclobs++]
a004eb82
AH
10062 = gen_rtx_SET (VOIDmode,
10063 reg,
10064 gen_rtx_UNSPEC (V4SImode,
10065 gen_rtvec (1, reg), 27));
9aa86737
AH
10066 }
10067 }
00b960c7
AH
10068
10069 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10070
10071 for (i = 0; i < nclobs; ++i)
10072 XVECEXP (insn, 0, i) = clobs[i];
10073
10074 return insn;
10075}
10076
89e7058f
AH
10077/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10078 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10079
10080static void
10081emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10082 rtx frame_reg;
10083 rtx frame_ptr;
10084 enum machine_mode mode;
10085 unsigned int regno;
10086 int offset;
10087 int total_size;
10088{
10089 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10090 rtx replacea, replaceb;
10091
10092 int_rtx = GEN_INT (offset);
10093
10094 /* Some cases that need register indexed addressing. */
10095 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10096 || (TARGET_SPE_ABI
10097 && SPE_VECTOR_MODE (mode)
10098 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10099 {
10100 /* Whomever calls us must make sure r11 is available in the
10101 flow path of instructions in the prologue. */
10102 offset_rtx = gen_rtx_REG (Pmode, 11);
10103 emit_move_insn (offset_rtx, int_rtx);
10104
10105 replacea = offset_rtx;
10106 replaceb = int_rtx;
10107 }
10108 else
10109 {
10110 offset_rtx = int_rtx;
10111 replacea = NULL_RTX;
10112 replaceb = NULL_RTX;
10113 }
10114
10115 reg = gen_rtx_REG (mode, regno);
10116 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10117 mem = gen_rtx_MEM (mode, addr);
10118 set_mem_alias_set (mem, rs6000_sr_alias_set);
10119
10120 insn = emit_move_insn (mem, reg);
10121
10122 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10123}
10124
a3170dc6
AH
10125/* Emit an offset memory reference suitable for a frame store, while
10126 converting to a valid addressing mode. */
10127
10128static rtx
10129gen_frame_mem_offset (mode, reg, offset)
10130 enum machine_mode mode;
10131 rtx reg;
10132 int offset;
10133{
10134 rtx int_rtx, offset_rtx;
10135
10136 int_rtx = GEN_INT (offset);
10137
10138 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10139 {
10140 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10141 emit_move_insn (offset_rtx, int_rtx);
10142 }
10143 else
10144 offset_rtx = int_rtx;
10145
10146 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10147}
10148
9ebbca7d
GK
10149/* Emit function prologue as insns. */
10150
9878760c 10151void
83720594 10152rs6000_emit_prologue ()
9878760c 10153{
4697a36c 10154 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10155 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10156 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10157 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10158 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10159 rtx frame_reg_rtx = sp_reg_rtx;
10160 rtx cr_save_rtx = NULL;
10161 rtx insn;
10162 int saving_FPRs_inline;
10163 int using_store_multiple;
10164 HOST_WIDE_INT sp_offset = 0;
10165
a3170dc6
AH
10166 if (TARGET_SPE_ABI)
10167 {
10168 reg_mode = V2SImode;
10169 reg_size = 8;
10170 }
10171
9ebbca7d 10172 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10173 && !TARGET_SPE_ABI
9ebbca7d
GK
10174 && info->first_gp_reg_save < 31);
10175 saving_FPRs_inline = (info->first_fp_reg_save == 64
10176 || FP_SAVE_INLINE (info->first_fp_reg_save));
10177
10178 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10179 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10180 {
10181 if (info->total_size < 32767)
10182 sp_offset = info->total_size;
10183 else
10184 frame_reg_rtx = frame_ptr_rtx;
10185 rs6000_emit_allocate_stack (info->total_size,
10186 (frame_reg_rtx != sp_reg_rtx
10187 && (info->cr_save_p
10188 || info->lr_save_p
10189 || info->first_fp_reg_save < 64
10190 || info->first_gp_reg_save < 32
10191 )));
10192 if (frame_reg_rtx != sp_reg_rtx)
10193 rs6000_emit_stack_tie ();
10194 }
10195
9aa86737
AH
10196 /* Save AltiVec registers if needed. */
10197 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10198 {
10199 int i;
10200
10201 /* There should be a non inline version of this, for when we
10202 are saving lots of vector registers. */
10203 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10204 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10205 {
10206 rtx areg, savereg, mem;
10207 int offset;
10208
10209 offset = info->altivec_save_offset + sp_offset
10210 + 16 * (i - info->first_altivec_reg_save);
10211
10212 savereg = gen_rtx_REG (V4SImode, i);
10213
10214 areg = gen_rtx_REG (Pmode, 0);
10215 emit_move_insn (areg, GEN_INT (offset));
10216
10217 /* AltiVec addressing mode is [reg+reg]. */
10218 mem = gen_rtx_MEM (V4SImode,
10219 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10220
10221 set_mem_alias_set (mem, rs6000_sr_alias_set);
10222
10223 insn = emit_move_insn (mem, savereg);
10224
10225 altivec_frame_fixup (insn, areg, offset);
10226 }
10227 }
10228
10229 /* VRSAVE is a bit vector representing which AltiVec registers
10230 are used. The OS uses this to determine which vector
10231 registers to save on a context switch. We need to save
10232 VRSAVE on the stack frame, add whatever AltiVec registers we
10233 used in this function, and do the corresponding magic in the
10234 epilogue. */
10235
10236 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10237 {
a004eb82 10238 rtx reg, mem, vrsave;
9aa86737
AH
10239 int offset;
10240
10241 /* Get VRSAVE onto a GPR. */
10242 reg = gen_rtx_REG (SImode, 12);
a004eb82 10243 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10244 if (TARGET_MACHO)
10245 emit_insn (gen_get_vrsave_internal (reg));
10246 else
10247 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10248
10249 /* Save VRSAVE. */
10250 offset = info->vrsave_save_offset + sp_offset;
10251 mem
10252 = gen_rtx_MEM (SImode,
10253 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10254 set_mem_alias_set (mem, rs6000_sr_alias_set);
10255 insn = emit_move_insn (mem, reg);
10256
10257 /* Include the registers in the mask. */
10258 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10259
10260 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10261 }
10262
9ebbca7d
GK
10263 /* If we use the link register, get it into r0. */
10264 if (info->lr_save_p)
71f123ca 10265 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10266 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10267
10268 /* If we need to save CR, put it into r12. */
10269 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10270 {
10271 cr_save_rtx = gen_rtx_REG (SImode, 12);
10272 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10273 }
10274
a4f6c312
SS
10275 /* Do any required saving of fpr's. If only one or two to save, do
10276 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10277 if (saving_FPRs_inline)
10278 {
10279 int i;
10280 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10281 if ((regs_ever_live[info->first_fp_reg_save+i]
10282 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10283 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10284 info->first_fp_reg_save + i,
10285 info->fp_save_offset + sp_offset + 8 * i,
10286 info->total_size);
9ebbca7d
GK
10287 }
10288 else if (info->first_fp_reg_save != 64)
10289 {
10290 int i;
10291 char rname[30];
520a57c8 10292 const char *alloc_rname;
9ebbca7d
GK
10293 rtvec p;
10294 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10295
10296 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10297 gen_rtx_REG (Pmode,
10298 LINK_REGISTER_REGNUM));
10299 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10300 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10301 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10302 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10303 gen_rtx_SYMBOL_REF (Pmode,
10304 alloc_rname));
10305 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10306 {
10307 rtx addr, reg, mem;
10308 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10309 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10310 GEN_INT (info->fp_save_offset
10311 + sp_offset + 8*i));
10312 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10313 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10314
10315 RTVEC_ELT (p, i + 2) = 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);
10320 }
b6c9286a 10321
9ebbca7d
GK
10322 /* Save GPRs. This is done as a PARALLEL if we are using
10323 the store-multiple instructions. */
10324 if (using_store_multiple)
b6c9286a 10325 {
308c142a 10326 rtvec p;
9ebbca7d
GK
10327 int i;
10328 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10329 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10330 {
10331 rtx addr, reg, mem;
10332 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10333 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10334 GEN_INT (info->gp_save_offset
10335 + sp_offset
10336 + reg_size * i));
10337 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10338 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10339
10340 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10341 }
10342 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10343 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10344 NULL_RTX, NULL_RTX);
b6c9286a
MM
10345 }
10346 else
10347 {
9ebbca7d
GK
10348 int i;
10349 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10350 if ((regs_ever_live[info->first_gp_reg_save+i]
10351 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10352 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10353 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10354 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10355 {
10356 rtx addr, reg, mem;
10357 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10358
10359 if (TARGET_SPE_ABI)
10360 {
10361 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10362 rtx b;
10363
10364 if (!SPE_CONST_OFFSET_OK (offset))
10365 {
10366 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10367 emit_move_insn (b, GEN_INT (offset));
10368 }
10369 else
10370 b = GEN_INT (offset);
10371
10372 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10373 mem = gen_rtx_MEM (V2SImode, addr);
10374 set_mem_alias_set (mem, rs6000_sr_alias_set);
10375 insn = emit_move_insn (mem, reg);
10376
10377 if (GET_CODE (b) == CONST_INT)
10378 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10379 NULL_RTX, NULL_RTX);
10380 else
10381 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10382 b, GEN_INT (offset));
10383 }
10384 else
10385 {
10386 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10387 GEN_INT (info->gp_save_offset
10388 + sp_offset
10389 + reg_size * i));
10390 mem = gen_rtx_MEM (reg_mode, addr);
10391 set_mem_alias_set (mem, rs6000_sr_alias_set);
10392
10393 insn = emit_move_insn (mem, reg);
10394 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10395 NULL_RTX, NULL_RTX);
10396 }
10397 }
9ebbca7d
GK
10398 }
10399
83720594
RH
10400 /* ??? There's no need to emit actual instructions here, but it's the
10401 easiest way to get the frame unwind information emitted. */
10402 if (current_function_calls_eh_return)
10403 {
78e1b90d
DE
10404 unsigned int i, regno;
10405
83720594
RH
10406 for (i = 0; ; ++i)
10407 {
83720594
RH
10408 regno = EH_RETURN_DATA_REGNO (i);
10409 if (regno == INVALID_REGNUM)
10410 break;
10411
89e7058f
AH
10412 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10413 info->ehrd_offset + sp_offset
10414 + reg_size * (int) i,
10415 info->total_size);
83720594
RH
10416 }
10417 }
10418
9ebbca7d
GK
10419 /* Save lr if we used it. */
10420 if (info->lr_save_p)
10421 {
10422 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10423 GEN_INT (info->lr_save_offset + sp_offset));
10424 rtx reg = gen_rtx_REG (Pmode, 0);
10425 rtx mem = gen_rtx_MEM (Pmode, addr);
10426 /* This should not be of rs6000_sr_alias_set, because of
10427 __builtin_return_address. */
10428
10429 insn = emit_move_insn (mem, reg);
10430 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10431 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10432 }
10433
10434 /* Save CR if we use any that must be preserved. */
10435 if (info->cr_save_p)
10436 {
10437 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10438 GEN_INT (info->cr_save_offset + sp_offset));
10439 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10440
10441 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10442
10443 /* If r12 was used to hold the original sp, copy cr into r0 now
10444 that it's free. */
10445 if (REGNO (frame_reg_rtx) == 12)
10446 {
10447 cr_save_rtx = gen_rtx_REG (SImode, 0);
10448 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10449 }
10450 insn = emit_move_insn (mem, cr_save_rtx);
10451
10452 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10453 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10454 OK. All we have to do is specify that _one_ condition code
10455 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10456 will then restore all the call-saved registers.
10457 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10458 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10459 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10460 }
10461
10462 /* Update stack and set back pointer unless this is V.4,
10463 for which it was done previously. */
f607bc57 10464 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10465 rs6000_emit_allocate_stack (info->total_size, FALSE);
10466
10467 /* Set frame pointer, if needed. */
10468 if (frame_pointer_needed)
10469 {
a3170dc6 10470 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10471 sp_reg_rtx);
10472 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10473 }
9878760c 10474
1db02437 10475 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10476 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10477 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10478 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10479 {
10480 /* If emit_load_toc_table will use the link register, we need to save
10481 it. We use R11 for this purpose because emit_load_toc_table
10482 can use register 0. This allows us to use a plain 'blr' to return
10483 from the procedure more often. */
d5fa86ba
GK
10484 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10485 && ! info->lr_save_p
10486 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10487 if (save_LR_around_toc_setup)
10488 emit_move_insn (gen_rtx_REG (Pmode, 11),
10489 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10490
10491 rs6000_emit_load_toc_table (TRUE);
10492
10493 if (save_LR_around_toc_setup)
10494 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10495 gen_rtx_REG (Pmode, 11));
10496 }
ee890fe2
SS
10497
10498 if (DEFAULT_ABI == ABI_DARWIN
10499 && flag_pic && current_function_uses_pic_offset_table)
10500 {
10501 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
10502
10503 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest)));
10504
10505 rs6000_maybe_dead (
1db02437 10506 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10507 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10508 }
9ebbca7d
GK
10509}
10510
9ebbca7d 10511/* Write function prologue. */
a4f6c312 10512
08c148a8
NB
10513static void
10514rs6000_output_function_prologue (file, size)
9ebbca7d 10515 FILE *file;
08c148a8 10516 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10517{
10518 rs6000_stack_t *info = rs6000_stack_info ();
10519
4697a36c
MM
10520 if (TARGET_DEBUG_STACK)
10521 debug_stack_info (info);
9878760c 10522
a4f6c312
SS
10523 /* Write .extern for any function we will call to save and restore
10524 fp values. */
10525 if (info->first_fp_reg_save < 64
10526 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10527 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10528 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10529 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10530 RESTORE_FP_SUFFIX);
9878760c 10531
c764f757
RK
10532 /* Write .extern for AIX common mode routines, if needed. */
10533 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10534 {
f6709c70
JW
10535 fputs ("\t.extern __mulh\n", file);
10536 fputs ("\t.extern __mull\n", file);
10537 fputs ("\t.extern __divss\n", file);
10538 fputs ("\t.extern __divus\n", file);
10539 fputs ("\t.extern __quoss\n", file);
10540 fputs ("\t.extern __quous\n", file);
c764f757
RK
10541 common_mode_defined = 1;
10542 }
9878760c 10543
9ebbca7d 10544 if (! HAVE_prologue)
979721f8 10545 {
9ebbca7d 10546 start_sequence ();
9dda4cc8 10547
a4f6c312
SS
10548 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10549 the "toplevel" insn chain. */
9ebbca7d
GK
10550 emit_note (0, NOTE_INSN_DELETED);
10551 rs6000_emit_prologue ();
10552 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10553
10554 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10555 {
10556 rtx insn;
10557 unsigned addr = 0;
10558 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10559 {
10560 INSN_ADDRESSES_NEW (insn, addr);
10561 addr += 4;
10562 }
10563 }
9dda4cc8 10564
9ebbca7d 10565 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10566 debug_rtx_list (get_insns (), 100);
10567 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10568 end_sequence ();
979721f8
MM
10569 }
10570
9ebbca7d
GK
10571 rs6000_pic_labelno++;
10572}
10573
10574/* Emit function epilogue as insns.
9878760c 10575
9ebbca7d
GK
10576 At present, dwarf2out_frame_debug_expr doesn't understand
10577 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10578 anywhere in the epilogue. Most of the insns below would in any case
10579 need special notes to explain where r11 is in relation to the stack. */
9878760c 10580
9ebbca7d 10581void
83720594 10582rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
10583 int sibcall;
10584{
10585 rs6000_stack_t *info;
10586 int restoring_FPRs_inline;
10587 int using_load_multiple;
10588 int using_mfcr_multiple;
10589 int use_backchain_to_restore_sp;
10590 int sp_offset = 0;
10591 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10592 rtx frame_reg_rtx = sp_reg_rtx;
10593 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10594 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10595 int i;
10596
a3170dc6
AH
10597 if (TARGET_SPE_ABI)
10598 {
10599 reg_mode = V2SImode;
10600 reg_size = 8;
10601 }
10602
9ebbca7d
GK
10603 info = rs6000_stack_info ();
10604 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10605 && !TARGET_SPE_ABI
9ebbca7d
GK
10606 && info->first_gp_reg_save < 31);
10607 restoring_FPRs_inline = (sibcall
83720594 10608 || current_function_calls_eh_return
9ebbca7d
GK
10609 || info->first_fp_reg_save == 64
10610 || FP_SAVE_INLINE (info->first_fp_reg_save));
10611 use_backchain_to_restore_sp = (frame_pointer_needed
10612 || current_function_calls_alloca
10613 || info->total_size > 32767);
10614 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10615 || rs6000_cpu == PROCESSOR_PPC603
10616 || rs6000_cpu == PROCESSOR_PPC750
10617 || optimize_size);
10618
10619 /* If we have a frame pointer, a call to alloca, or a large stack
10620 frame, restore the old stack pointer using the backchain. Otherwise,
10621 we know what size to update it with. */
10622 if (use_backchain_to_restore_sp)
bacbde18 10623 {
9ebbca7d
GK
10624 /* Under V.4, don't reset the stack pointer until after we're done
10625 loading the saved registers. */
f607bc57 10626 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 10627 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 10628
9ebbca7d
GK
10629 emit_move_insn (frame_reg_rtx,
10630 gen_rtx_MEM (Pmode, sp_reg_rtx));
10631
bacbde18 10632 }
9ebbca7d 10633 else if (info->push_p)
85638c0d 10634 {
f607bc57 10635 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10636 sp_offset = info->total_size;
10637 else
10638 {
10639 emit_insn (TARGET_32BIT
10640 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10641 GEN_INT (info->total_size))
10642 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10643 GEN_INT (info->total_size)));
10644 }
85638c0d 10645 }
9ebbca7d 10646
9aa86737
AH
10647 /* Restore AltiVec registers if needed. */
10648 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10649 {
10650 int i;
10651
10652 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10653 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10654 {
10655 rtx addr, areg, mem;
10656
10657 areg = gen_rtx_REG (Pmode, 0);
10658 emit_move_insn
10659 (areg, GEN_INT (info->altivec_save_offset
10660 + sp_offset
10661 + 16 * (i - info->first_altivec_reg_save)));
10662
10663 /* AltiVec addressing mode is [reg+reg]. */
10664 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10665 mem = gen_rtx_MEM (V4SImode, addr);
10666 set_mem_alias_set (mem, rs6000_sr_alias_set);
10667
10668 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10669 }
10670 }
10671
10672 /* Restore VRSAVE if needed. */
10673 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10674 {
10675 rtx addr, mem, reg;
10676
10677 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10678 GEN_INT (info->vrsave_save_offset + sp_offset));
10679 mem = gen_rtx_MEM (SImode, addr);
10680 set_mem_alias_set (mem, rs6000_sr_alias_set);
10681 reg = gen_rtx_REG (SImode, 12);
10682 emit_move_insn (reg, mem);
10683
10684 emit_insn (generate_set_vrsave (reg, info, 1));
10685 }
10686
9ebbca7d
GK
10687 /* Get the old lr if we saved it. */
10688 if (info->lr_save_p)
b6c9286a 10689 {
a3170dc6
AH
10690 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10691 info->lr_save_offset + sp_offset);
ba4828e0
RK
10692
10693 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10694
9ebbca7d 10695 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 10696 }
9ebbca7d
GK
10697
10698 /* Get the old cr if we saved it. */
10699 if (info->cr_save_p)
10700 {
10701 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10702 GEN_INT (info->cr_save_offset + sp_offset));
10703 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10704
10705 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10706
9ebbca7d
GK
10707 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10708 }
10709
10710 /* Set LR here to try to overlap restores below. */
4697a36c 10711 if (info->lr_save_p)
9ebbca7d
GK
10712 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10713 gen_rtx_REG (Pmode, 0));
10714
83720594
RH
10715 /* Load exception handler data registers, if needed. */
10716 if (current_function_calls_eh_return)
10717 {
78e1b90d
DE
10718 unsigned int i, regno;
10719
83720594
RH
10720 for (i = 0; ; ++i)
10721 {
a3170dc6 10722 rtx mem;
83720594
RH
10723
10724 regno = EH_RETURN_DATA_REGNO (i);
10725 if (regno == INVALID_REGNUM)
10726 break;
10727
a3170dc6
AH
10728 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
10729 info->ehrd_offset + sp_offset
10730 + reg_size * (int) i);
ba4828e0 10731 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
10732
10733 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
10734 }
10735 }
9ebbca7d
GK
10736
10737 /* Restore GPRs. This is done as a PARALLEL if we are using
10738 the load-multiple instructions. */
10739 if (using_load_multiple)
979721f8 10740 {
9ebbca7d
GK
10741 rtvec p;
10742 p = rtvec_alloc (32 - info->first_gp_reg_save);
10743 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 10744 {
9ebbca7d
GK
10745 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10746 GEN_INT (info->gp_save_offset
10747 + sp_offset
10748 + reg_size * i));
10749 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
10750
10751 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10752
10753 RTVEC_ELT (p, i) =
10754 gen_rtx_SET (VOIDmode,
10755 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
10756 mem);
979721f8 10757 }
9ebbca7d 10758 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 10759 }
9ebbca7d
GK
10760 else
10761 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10762 if ((regs_ever_live[info->first_gp_reg_save+i]
10763 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10764 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10765 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10766 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
10767 {
10768 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10769 GEN_INT (info->gp_save_offset
10770 + sp_offset
10771 + reg_size * i));
10772 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10773
a3170dc6
AH
10774 /* Restore 64-bit quantities for SPE. */
10775 if (TARGET_SPE_ABI)
10776 {
10777 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10778 rtx b;
10779
10780 if (!SPE_CONST_OFFSET_OK (offset))
10781 {
10782 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10783 emit_move_insn (b, GEN_INT (offset));
10784 }
10785 else
10786 b = GEN_INT (offset);
10787
10788 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10789 mem = gen_rtx_MEM (V2SImode, addr);
10790 }
10791
ba4828e0 10792 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10793
10794 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 10795 info->first_gp_reg_save + i), mem);
9ebbca7d 10796 }
9878760c 10797
9ebbca7d
GK
10798 /* Restore fpr's if we need to do it without calling a function. */
10799 if (restoring_FPRs_inline)
10800 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10801 if ((regs_ever_live[info->first_fp_reg_save+i]
10802 && ! call_used_regs[info->first_fp_reg_save+i]))
10803 {
10804 rtx addr, mem;
10805 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10806 GEN_INT (info->fp_save_offset
10807 + sp_offset
a4f6c312 10808 + 8 * i));
9ebbca7d 10809 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10810 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10811
10812 emit_move_insn (gen_rtx_REG (DFmode,
10813 info->first_fp_reg_save + i),
10814 mem);
10815 }
8d30c4ee 10816
9ebbca7d
GK
10817 /* If we saved cr, restore it here. Just those that were used. */
10818 if (info->cr_save_p)
979721f8 10819 {
9ebbca7d 10820 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 10821 int count = 0;
9ebbca7d
GK
10822
10823 if (using_mfcr_multiple)
979721f8 10824 {
9ebbca7d
GK
10825 for (i = 0; i < 8; i++)
10826 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 10827 count++;
9ebbca7d 10828 if (count == 0)
e35b9579
GK
10829 abort ();
10830 }
10831
10832 if (using_mfcr_multiple && count > 1)
10833 {
10834 rtvec p;
10835 int ndx;
9ebbca7d 10836
e35b9579 10837 p = rtvec_alloc (count);
9ebbca7d 10838
e35b9579 10839 ndx = 0;
9ebbca7d
GK
10840 for (i = 0; i < 8; i++)
10841 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
10842 {
10843 rtvec r = rtvec_alloc (2);
10844 RTVEC_ELT (r, 0) = r12_rtx;
10845 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 10846 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
10847 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
10848 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 10849 ndx++;
9ebbca7d
GK
10850 }
10851 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
10852 if (ndx != count)
10853 abort ();
979721f8
MM
10854 }
10855 else
9ebbca7d
GK
10856 for (i = 0; i < 8; i++)
10857 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 10858 {
9ebbca7d
GK
10859 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
10860 CR0_REGNO+i),
10861 r12_rtx));
979721f8 10862 }
979721f8
MM
10863 }
10864
9ebbca7d
GK
10865 /* If this is V.4, unwind the stack pointer after all of the loads
10866 have been done. We need to emit a block here so that sched
10867 doesn't decide to move the sp change before the register restores
10868 (which may not have any obvious dependency on the stack). This
10869 doesn't hurt performance, because there is no scheduling that can
10870 be done after this point. */
f607bc57 10871 if (DEFAULT_ABI == ABI_V4)
b6c9286a 10872 {
9ebbca7d
GK
10873 if (frame_reg_rtx != sp_reg_rtx)
10874 rs6000_emit_stack_tie ();
b6c9286a 10875
9ebbca7d 10876 if (use_backchain_to_restore_sp)
b6c9286a 10877 {
9ebbca7d 10878 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 10879 }
9ebbca7d 10880 else if (sp_offset != 0)
13f1623b 10881 {
9ebbca7d
GK
10882 emit_insn (Pmode == SImode
10883 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10884 GEN_INT (sp_offset))
10885 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10886 GEN_INT (sp_offset)));
13f1623b 10887 }
9ebbca7d 10888 }
b6c9286a 10889
83720594
RH
10890 if (current_function_calls_eh_return)
10891 {
10892 rtx sa = EH_RETURN_STACKADJ_RTX;
10893 emit_insn (Pmode == SImode
10894 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
10895 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
10896 }
10897
9ebbca7d
GK
10898 if (!sibcall)
10899 {
10900 rtvec p;
10901 if (! restoring_FPRs_inline)
10902 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
10903 else
10904 p = rtvec_alloc (2);
b6c9286a 10905
e35b9579
GK
10906 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
10907 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
10908 gen_rtx_REG (Pmode,
10909 LINK_REGISTER_REGNUM));
9ebbca7d
GK
10910
10911 /* If we have to restore more than two FP registers, branch to the
10912 restore function. It will return to our caller. */
10913 if (! restoring_FPRs_inline)
10914 {
10915 int i;
10916 char rname[30];
520a57c8 10917 const char *alloc_rname;
979721f8 10918
9ebbca7d
GK
10919 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
10920 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 10921 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10922 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
10923 gen_rtx_SYMBOL_REF (Pmode,
10924 alloc_rname));
b6c9286a 10925
9ebbca7d
GK
10926 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10927 {
10928 rtx addr, mem;
10929 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
10930 GEN_INT (info->fp_save_offset + 8*i));
10931 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10932 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10933
10934 RTVEC_ELT (p, i+3) =
10935 gen_rtx_SET (VOIDmode,
10936 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
10937 mem);
b6c9286a
MM
10938 }
10939 }
9ebbca7d
GK
10940
10941 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 10942 }
9878760c
RK
10943}
10944
10945/* Write function epilogue. */
10946
08c148a8
NB
10947static void
10948rs6000_output_function_epilogue (file, size)
9878760c 10949 FILE *file;
08c148a8 10950 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 10951{
4697a36c 10952 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 10953
9ebbca7d 10954 if (! HAVE_epilogue)
9878760c 10955 {
9ebbca7d
GK
10956 rtx insn = get_last_insn ();
10957 /* If the last insn was a BARRIER, we don't have to write anything except
10958 the trace table. */
10959 if (GET_CODE (insn) == NOTE)
10960 insn = prev_nonnote_insn (insn);
10961 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 10962 {
9ebbca7d
GK
10963 /* This is slightly ugly, but at least we don't have two
10964 copies of the epilogue-emitting code. */
10965 start_sequence ();
10966
10967 /* A NOTE_INSN_DELETED is supposed to be at the start
10968 and end of the "toplevel" insn chain. */
10969 emit_note (0, NOTE_INSN_DELETED);
10970 rs6000_emit_epilogue (FALSE);
10971 emit_note (0, NOTE_INSN_DELETED);
10972
178c3eff
DJ
10973 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10974 {
10975 rtx insn;
10976 unsigned addr = 0;
10977 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10978 {
10979 INSN_ADDRESSES_NEW (insn, addr);
10980 addr += 4;
10981 }
10982 }
10983
9ebbca7d 10984 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10985 debug_rtx_list (get_insns (), 100);
10986 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10987 end_sequence ();
4697a36c 10988 }
9878760c 10989 }
b4ac57ab 10990
9b30bae2 10991 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
10992 on its format.
10993
10994 We don't output a traceback table if -finhibit-size-directive was
10995 used. The documentation for -finhibit-size-directive reads
10996 ``don't output a @code{.size} assembler directive, or anything
10997 else that would cause trouble if the function is split in the
10998 middle, and the two halves are placed at locations far apart in
10999 memory.'' The traceback table has this property, since it
11000 includes the offset from the start of the function to the
4d30c363
MM
11001 traceback table itself.
11002
11003 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 11004 different traceback table. */
57ac7be9
AM
11005 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
11006 && rs6000_traceback != traceback_none)
9b30bae2 11007 {
3cce094d 11008 const char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
3ac88239 11009 const char *language_string = lang_hooks.name;
6041bf2f 11010 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 11011 int i;
57ac7be9
AM
11012 int optional_tbtab;
11013
11014 if (rs6000_traceback == traceback_full)
11015 optional_tbtab = 1;
11016 else if (rs6000_traceback == traceback_part)
11017 optional_tbtab = 0;
11018 else
11019 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 11020
b6c9286a
MM
11021 while (*fname == '.') /* V.4 encodes . in the name */
11022 fname++;
11023
314fc5a9
ILT
11024 /* Need label immediately before tbtab, so we can compute its offset
11025 from the function start. */
11026 if (*fname == '*')
11027 ++fname;
11028 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11029 ASM_OUTPUT_LABEL (file, fname);
11030
11031 /* The .tbtab pseudo-op can only be used for the first eight
11032 expressions, since it can't handle the possibly variable
11033 length fields that follow. However, if you omit the optional
11034 fields, the assembler outputs zeros for all optional fields
11035 anyways, giving each variable length field is minimum length
11036 (as defined in sys/debug.h). Thus we can not use the .tbtab
11037 pseudo-op at all. */
11038
11039 /* An all-zero word flags the start of the tbtab, for debuggers
11040 that have to find it by searching forward from the entry
11041 point or from the current pc. */
19d2d16f 11042 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11043
11044 /* Tbtab format type. Use format type 0. */
19d2d16f 11045 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11046
11047 /* Language type. Unfortunately, there doesn't seem to be any
11048 official way to get this info, so we use language_string. C
11049 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11050 value for C for now. There is no official value for Java,
6f573ff9 11051 although IBM appears to be using 13. There is no official value
f710504c 11052 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11053 if (! strcmp (language_string, "GNU C")
e2c953b6 11054 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11055 i = 0;
11056 else if (! strcmp (language_string, "GNU F77"))
11057 i = 1;
11058 else if (! strcmp (language_string, "GNU Ada"))
11059 i = 3;
8b83775b 11060 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11061 i = 2;
11062 else if (! strcmp (language_string, "GNU C++"))
11063 i = 9;
9517ead8
AG
11064 else if (! strcmp (language_string, "GNU Java"))
11065 i = 13;
6f573ff9
JL
11066 else if (! strcmp (language_string, "GNU CHILL"))
11067 i = 44;
314fc5a9
ILT
11068 else
11069 abort ();
11070 fprintf (file, "%d,", i);
11071
11072 /* 8 single bit fields: global linkage (not set for C extern linkage,
11073 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11074 from start of procedure stored in tbtab, internal function, function
11075 has controlled storage, function has no toc, function uses fp,
11076 function logs/aborts fp operations. */
11077 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11078 fprintf (file, "%d,",
11079 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11080
11081 /* 6 bitfields: function is interrupt handler, name present in
11082 proc table, function calls alloca, on condition directives
11083 (controls stack walks, 3 bits), saves condition reg, saves
11084 link reg. */
11085 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11086 set up as a frame pointer, even when there is no alloca call. */
11087 fprintf (file, "%d,",
6041bf2f
DE
11088 ((optional_tbtab << 6)
11089 | ((optional_tbtab & frame_pointer_needed) << 5)
11090 | (info->cr_save_p << 1)
11091 | (info->lr_save_p)));
314fc5a9 11092
6041bf2f 11093 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11094 (6 bits). */
11095 fprintf (file, "%d,",
4697a36c 11096 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11097
11098 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11099 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11100
6041bf2f
DE
11101 if (optional_tbtab)
11102 {
11103 /* Compute the parameter info from the function decl argument
11104 list. */
11105 tree decl;
11106 int next_parm_info_bit = 31;
314fc5a9 11107
6041bf2f
DE
11108 for (decl = DECL_ARGUMENTS (current_function_decl);
11109 decl; decl = TREE_CHAIN (decl))
11110 {
11111 rtx parameter = DECL_INCOMING_RTL (decl);
11112 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11113
6041bf2f
DE
11114 if (GET_CODE (parameter) == REG)
11115 {
11116 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11117 {
11118 int bits;
11119
11120 float_parms++;
11121
11122 if (mode == SFmode)
11123 bits = 0x2;
11124 else if (mode == DFmode)
11125 bits = 0x3;
11126 else
11127 abort ();
11128
11129 /* If only one bit will fit, don't or in this entry. */
11130 if (next_parm_info_bit > 0)
11131 parm_info |= (bits << (next_parm_info_bit - 1));
11132 next_parm_info_bit -= 2;
11133 }
11134 else
11135 {
11136 fixed_parms += ((GET_MODE_SIZE (mode)
11137 + (UNITS_PER_WORD - 1))
11138 / UNITS_PER_WORD);
11139 next_parm_info_bit -= 1;
11140 }
11141 }
11142 }
11143 }
314fc5a9
ILT
11144
11145 /* Number of fixed point parameters. */
11146 /* This is actually the number of words of fixed point parameters; thus
11147 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11148 fprintf (file, "%d,", fixed_parms);
11149
11150 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11151 all on stack. */
11152 /* This is actually the number of fp registers that hold parameters;
11153 and thus the maximum value is 13. */
11154 /* Set parameters on stack bit if parameters are not in their original
11155 registers, regardless of whether they are on the stack? Xlc
11156 seems to set the bit when not optimizing. */
11157 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11158
6041bf2f
DE
11159 if (! optional_tbtab)
11160 return;
11161
314fc5a9
ILT
11162 /* Optional fields follow. Some are variable length. */
11163
11164 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11165 11 double float. */
11166 /* There is an entry for each parameter in a register, in the order that
11167 they occur in the parameter list. Any intervening arguments on the
11168 stack are ignored. If the list overflows a long (max possible length
11169 34 bits) then completely leave off all elements that don't fit. */
11170 /* Only emit this long if there was at least one parameter. */
11171 if (fixed_parms || float_parms)
11172 fprintf (file, "\t.long %d\n", parm_info);
11173
11174 /* Offset from start of code to tb table. */
19d2d16f 11175 fputs ("\t.long ", file);
314fc5a9 11176 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11177#if TARGET_AIX
11178 RS6000_OUTPUT_BASENAME (file, fname);
11179#else
9ebbca7d 11180 assemble_name (file, fname);
54ee9799 11181#endif
19d2d16f 11182 fputs ("-.", file);
54ee9799
DE
11183#if TARGET_AIX
11184 RS6000_OUTPUT_BASENAME (file, fname);
11185#else
9ebbca7d 11186 assemble_name (file, fname);
54ee9799 11187#endif
19d2d16f 11188 putc ('\n', file);
314fc5a9
ILT
11189
11190 /* Interrupt handler mask. */
11191 /* Omit this long, since we never set the interrupt handler bit
11192 above. */
11193
11194 /* Number of CTL (controlled storage) anchors. */
11195 /* Omit this long, since the has_ctl bit is never set above. */
11196
11197 /* Displacement into stack of each CTL anchor. */
11198 /* Omit this list of longs, because there are no CTL anchors. */
11199
11200 /* Length of function name. */
296b8152 11201 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11202
11203 /* Function name. */
11204 assemble_string (fname, strlen (fname));
11205
11206 /* Register for alloca automatic storage; this is always reg 31.
11207 Only emit this if the alloca bit was set above. */
11208 if (frame_pointer_needed)
19d2d16f 11209 fputs ("\t.byte 31\n", file);
b1765bde
DE
11210
11211 fputs ("\t.align 2\n", file);
9b30bae2 11212 }
9878760c 11213}
17167fd8 11214\f
a4f6c312
SS
11215/* A C compound statement that outputs the assembler code for a thunk
11216 function, used to implement C++ virtual function calls with
11217 multiple inheritance. The thunk acts as a wrapper around a virtual
11218 function, adjusting the implicit object parameter before handing
11219 control off to the real function.
11220
11221 First, emit code to add the integer DELTA to the location that
11222 contains the incoming first argument. Assume that this argument
11223 contains a pointer, and is the one used to pass the `this' pointer
11224 in C++. This is the incoming argument *before* the function
11225 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11226 values of all other incoming arguments.
17167fd8
MM
11227
11228 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11229 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11230 not touch the return address. Hence returning from FUNCTION will
11231 return to whoever called the current `thunk'.
17167fd8 11232
a4f6c312
SS
11233 The effect must be as if FUNCTION had been called directly with the
11234 adjusted first argument. This macro is responsible for emitting
11235 all of the code for a thunk function; output_function_prologue()
11236 and output_function_epilogue() are not invoked.
17167fd8 11237
a4f6c312
SS
11238 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11239 been extracted from it.) It might possibly be useful on some
11240 targets, but probably not.
17167fd8 11241
a4f6c312
SS
11242 If you do not define this macro, the target-independent code in the
11243 C++ frontend will generate a less efficient heavyweight thunk that
11244 calls FUNCTION instead of jumping to it. The generic approach does
11245 not support varargs. */
17167fd8
MM
11246
11247void
11248output_mi_thunk (file, thunk_fndecl, delta, function)
11249 FILE *file;
d330fd93 11250 tree thunk_fndecl ATTRIBUTE_UNUSED;
17167fd8
MM
11251 int delta;
11252 tree function;
11253{
a4f6c312
SS
11254 const char *this_reg =
11255 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
d330fd93 11256 const char *prefix;
3cce094d 11257 const char *fname;
d330fd93 11258 const char *r0 = reg_names[0];
d330fd93
KG
11259 const char *toc = reg_names[2];
11260 const char *schain = reg_names[11];
11261 const char *r12 = reg_names[12];
17167fd8
MM
11262 char buf[512];
11263 static int labelno = 0;
11264
a4f6c312 11265 /* Small constants that can be done by one add instruction. */
17167fd8
MM
11266 if (delta >= -32768 && delta <= 32767)
11267 {
22b4a3b0 11268 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11269 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta, this_reg);
11270 else
11271 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
11272 }
11273
a4f6c312 11274 /* Large constants that can be done by one addis instruction. */
17167fd8
MM
11275 else if ((delta & 0xffff) == 0 && num_insns_constant_wide (delta) == 1)
11276 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11277 delta >> 16);
11278
11279 /* 32-bit constants that can be done by an add and addis instruction. */
11280 else if (TARGET_32BIT || num_insns_constant_wide (delta) == 1)
11281 {
a4f6c312
SS
11282 /* Break into two pieces, propagating the sign bit from the low
11283 word to the upper word. */
17167fd8
MM
11284 int delta_high = delta >> 16;
11285 int delta_low = delta & 0xffff;
11286 if ((delta_low & 0x8000) != 0)
11287 {
11288 delta_high++;
11289 delta_low = (delta_low ^ 0x8000) - 0x8000; /* sign extend */
11290 }
11291
11292 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11293 delta_high);
11294
22b4a3b0 11295 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11296 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
11297 else
11298 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
11299 }
11300
11301 /* 64-bit constants, fixme */
11302 else
11303 abort ();
11304
11305 /* Get the prefix in front of the names. */
11306 switch (DEFAULT_ABI)
11307 {
11308 default:
11309 abort ();
11310
11311 case ABI_AIX:
11312 prefix = ".";
11313 break;
11314
11315 case ABI_V4:
11316 case ABI_AIX_NODESC:
17167fd8
MM
11317 prefix = "";
11318 break;
17167fd8
MM
11319 }
11320
11321 /* If the function is compiled in this module, jump to it directly.
11322 Otherwise, load up its address and jump to it. */
11323
11324 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
42820a49 11325
9ebbca7d 11326 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
a5c76ee6
ZW
11327 && (! lookup_attribute ("longcall",
11328 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11329 || lookup_attribute ("shortcall",
11330 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
11331
17167fd8
MM
11332 {
11333 fprintf (file, "\tb %s", prefix);
11334 assemble_name (file, fname);
22b4a3b0 11335 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
949ea356 11336 putc ('\n', file);
17167fd8
MM
11337 }
11338
11339 else
11340 {
11341 switch (DEFAULT_ABI)
11342 {
11343 default:
17167fd8
MM
11344 abort ();
11345
11346 case ABI_AIX:
11347 /* Set up a TOC entry for the function. */
11348 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
11349 toc_section ();
11350 ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
11351 labelno++;
11352
fa9b5c6b
DE
11353 if (TARGET_MINIMAL_TOC)
11354 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
11355 else
11356 {
11357 fputs ("\t.tc ", file);
11358 assemble_name (file, fname);
11359 fputs ("[TC],", file);
11360 }
11361 assemble_name (file, fname);
17167fd8 11362 putc ('\n', file);
b4d330e1
DE
11363 if (TARGET_ELF)
11364 function_section (current_function_decl);
11365 else
11366 text_section();
468e8dba
DE
11367 if (TARGET_MINIMAL_TOC)
11368 asm_fprintf (file, (TARGET_32BIT)
11369 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
11370 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
d2574c50 11371 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
17167fd8 11372 assemble_name (file, buf);
468e8dba
DE
11373 if (TARGET_ELF && TARGET_MINIMAL_TOC)
11374 fputs ("-(.LCTOC1)", file);
11375 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
17167fd8
MM
11376 asm_fprintf (file,
11377 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
11378 r0, r12);
11379
11380 asm_fprintf (file,
11381 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
11382 toc, r12);
11383
11384 asm_fprintf (file, "\tmtctr %s\n", r0);
11385 asm_fprintf (file,
11386 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
11387 schain, r12);
11388
11389 asm_fprintf (file, "\tbctr\n");
11390 break;
11391
9ebbca7d 11392 case ABI_AIX_NODESC:
17167fd8 11393 case ABI_V4:
22b4a3b0
FS
11394 fprintf (file, "\tb %s", prefix);
11395 assemble_name (file, fname);
11396 if (flag_pic) fputs ("@plt", file);
949ea356 11397 putc ('\n', file);
22b4a3b0 11398 break;
ee890fe2
SS
11399
11400#if TARGET_MACHO
11401 case ABI_DARWIN:
11402 fprintf (file, "\tb %s", prefix);
11403 if (flag_pic && !machopic_name_defined_p (fname))
11404 assemble_name (file, machopic_stub_name (fname));
11405 else
11406 assemble_name (file, fname);
11407 putc ('\n', file);
11408 break;
11409#endif
9ebbca7d
GK
11410 }
11411 }
11412}
42820a49 11413
9ebbca7d
GK
11414\f
11415/* A quick summary of the various types of 'constant-pool tables'
11416 under PowerPC:
11417
11418 Target Flags Name One table per
11419 AIX (none) AIX TOC object file
11420 AIX -mfull-toc AIX TOC object file
11421 AIX -mminimal-toc AIX minimal TOC translation unit
11422 SVR4/EABI (none) SVR4 SDATA object file
11423 SVR4/EABI -fpic SVR4 pic object file
11424 SVR4/EABI -fPIC SVR4 PIC translation unit
11425 SVR4/EABI -mrelocatable EABI TOC function
11426 SVR4/EABI -maix AIX TOC object file
11427 SVR4/EABI -maix -mminimal-toc
11428 AIX minimal TOC translation unit
11429
11430 Name Reg. Set by entries contains:
11431 made by addrs? fp? sum?
11432
11433 AIX TOC 2 crt0 as Y option option
11434 AIX minimal TOC 30 prolog gcc Y Y option
11435 SVR4 SDATA 13 crt0 gcc N Y N
11436 SVR4 pic 30 prolog ld Y not yet N
11437 SVR4 PIC 30 prolog gcc Y option option
11438 EABI TOC 30 prolog gcc Y option option
11439
11440*/
11441
11442/* Hash table stuff for keeping track of TOC entries. */
11443
11444struct toc_hash_struct
11445{
11446 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
11447 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
11448 rtx key;
a9098fd0 11449 enum machine_mode key_mode;
9ebbca7d
GK
11450 int labelno;
11451};
17167fd8 11452
9ebbca7d
GK
11453static htab_t toc_hash_table;
11454
11455/* Hash functions for the hash table. */
11456
11457static unsigned
11458rs6000_hash_constant (k)
11459 rtx k;
11460{
a9098fd0 11461 unsigned result = (GET_CODE (k) << 3) ^ GET_MODE (k);
9ebbca7d
GK
11462 const char *format = GET_RTX_FORMAT (GET_CODE (k));
11463 int flen = strlen (format);
11464 int fidx;
11465
11466 if (GET_CODE (k) == LABEL_REF)
b3a646eb 11467 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
9ebbca7d 11468
5692c7bc 11469 if (GET_CODE (k) == CODE_LABEL)
9ebbca7d
GK
11470 fidx = 3;
11471 else
11472 fidx = 0;
11473
11474 for (; fidx < flen; fidx++)
11475 switch (format[fidx])
11476 {
11477 case 's':
11478 {
11479 unsigned i, len;
11480 const char *str = XSTR (k, fidx);
11481 len = strlen (str);
11482 result = result * 613 + len;
11483 for (i = 0; i < len; i++)
11484 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11485 break;
11486 }
9ebbca7d
GK
11487 case 'u':
11488 case 'e':
11489 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11490 break;
11491 case 'i':
11492 case 'n':
11493 result = result * 613 + (unsigned) XINT (k, fidx);
11494 break;
11495 case 'w':
11496 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11497 result = result * 613 + (unsigned) XWINT (k, fidx);
11498 else
11499 {
11500 size_t i;
11501 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11502 result = result * 613 + (unsigned) (XWINT (k, fidx)
11503 >> CHAR_BIT * i);
11504 }
11505 break;
11506 default:
a4f6c312 11507 abort ();
9ebbca7d
GK
11508 }
11509 return result;
11510}
11511
11512static unsigned
11513toc_hash_function (hash_entry)
11514 const void * hash_entry;
11515{
a9098fd0
GK
11516 const struct toc_hash_struct *thc =
11517 (const struct toc_hash_struct *) hash_entry;
11518 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11519}
11520
11521/* Compare H1 and H2 for equivalence. */
11522
11523static int
11524toc_hash_eq (h1, h2)
11525 const void * h1;
11526 const void * h2;
11527{
11528 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11529 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11530
a9098fd0
GK
11531 if (((const struct toc_hash_struct *) h1)->key_mode
11532 != ((const struct toc_hash_struct *) h2)->key_mode)
11533 return 0;
11534
5692c7bc 11535 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11536}
11537
11538/* Mark the hash table-entry HASH_ENTRY. */
11539
11540static int
11541toc_hash_mark_entry (hash_slot, unused)
2eba1afa 11542 void ** hash_slot;
9ebbca7d
GK
11543 void * unused ATTRIBUTE_UNUSED;
11544{
11545 const struct toc_hash_struct * hash_entry =
11546 *(const struct toc_hash_struct **) hash_slot;
11547 rtx r = hash_entry->key;
11548 ggc_set_mark (hash_entry);
a4f6c312 11549 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
9ebbca7d
GK
11550 if (GET_CODE (r) == LABEL_REF)
11551 {
11552 ggc_set_mark (r);
11553 ggc_set_mark (XEXP (r, 0));
11554 }
11555 else
11556 ggc_mark_rtx (r);
11557 return 1;
11558}
11559
11560/* Mark all the elements of the TOC hash-table *HT. */
11561
11562static void
11563toc_hash_mark_table (vht)
11564 void *vht;
11565{
11566 htab_t *ht = vht;
11567
11568 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
17167fd8
MM
11569}
11570
28e510bd
MM
11571/* These are the names given by the C++ front-end to vtables, and
11572 vtable-like objects. Ideally, this logic should not be here;
11573 instead, there should be some programmatic way of inquiring as
11574 to whether or not an object is a vtable. */
11575
11576#define VTABLE_NAME_P(NAME) \
11577 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11578 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11579 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11580 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11581
11582void
11583rs6000_output_symbol_ref (file, x)
11584 FILE *file;
11585 rtx x;
11586{
11587 /* Currently C++ toc references to vtables can be emitted before it
11588 is decided whether the vtable is public or private. If this is
11589 the case, then the linker will eventually complain that there is
11590 a reference to an unknown section. Thus, for vtables only,
11591 we emit the TOC reference to reference the symbol and not the
11592 section. */
11593 const char *name = XSTR (x, 0);
54ee9799
DE
11594
11595 if (VTABLE_NAME_P (name))
11596 {
11597 RS6000_OUTPUT_BASENAME (file, name);
11598 }
11599 else
11600 assemble_name (file, name);
28e510bd
MM
11601}
11602
a4f6c312
SS
11603/* Output a TOC entry. We derive the entry name from what is being
11604 written. */
9878760c
RK
11605
11606void
a9098fd0 11607output_toc (file, x, labelno, mode)
9878760c
RK
11608 FILE *file;
11609 rtx x;
11610 int labelno;
a9098fd0 11611 enum machine_mode mode;
9878760c
RK
11612{
11613 char buf[256];
3cce094d 11614 const char *name = buf;
ec940faa 11615 const char *real_name;
9878760c
RK
11616 rtx base = x;
11617 int offset = 0;
11618
4697a36c
MM
11619 if (TARGET_NO_TOC)
11620 abort ();
11621
9ebbca7d
GK
11622 /* When the linker won't eliminate them, don't output duplicate
11623 TOC entries (this happens on AIX if there is any kind of TOC,
1f8f4a0b
MM
11624 and on SVR4 under -fPIC or -mrelocatable). */
11625 if (TARGET_TOC)
9ebbca7d
GK
11626 {
11627 struct toc_hash_struct *h;
11628 void * * found;
11629
11630 h = ggc_alloc (sizeof (*h));
11631 h->key = x;
a9098fd0 11632 h->key_mode = mode;
9ebbca7d
GK
11633 h->labelno = labelno;
11634
11635 found = htab_find_slot (toc_hash_table, h, 1);
11636 if (*found == NULL)
11637 *found = h;
11638 else /* This is indeed a duplicate.
11639 Set this label equal to that label. */
11640 {
11641 fputs ("\t.set ", file);
11642 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11643 fprintf (file, "%d,", labelno);
11644 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11645 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11646 found)->labelno));
11647 return;
11648 }
11649 }
11650
11651 /* If we're going to put a double constant in the TOC, make sure it's
11652 aligned properly when strict alignment is on. */
ff1720ed
RK
11653 if (GET_CODE (x) == CONST_DOUBLE
11654 && STRICT_ALIGNMENT
a9098fd0 11655 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
11656 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11657 ASM_OUTPUT_ALIGN (file, 3);
11658 }
11659
9ebbca7d 11660 ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
9878760c 11661
37c37a57
RK
11662 /* Handle FP constants specially. Note that if we have a minimal
11663 TOC, things we put here aren't actually in the TOC, so we can allow
11664 FP constants. */
a9098fd0 11665 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 11666 {
042259f2
DE
11667 REAL_VALUE_TYPE rv;
11668 long k[2];
0adc764e 11669
042259f2
DE
11670 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11671 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 11672
13ded975
DE
11673 if (TARGET_64BIT)
11674 {
11675 if (TARGET_MINIMAL_TOC)
2bfcf297 11676 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11677 else
2f0552b6
AM
11678 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11679 k[0] & 0xffffffff, k[1] & 0xffffffff);
11680 fprintf (file, "0x%lx%08lx\n",
11681 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11682 return;
11683 }
1875cc88 11684 else
13ded975
DE
11685 {
11686 if (TARGET_MINIMAL_TOC)
2bfcf297 11687 fputs ("\t.long ", file);
13ded975 11688 else
2f0552b6
AM
11689 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11690 k[0] & 0xffffffff, k[1] & 0xffffffff);
11691 fprintf (file, "0x%lx,0x%lx\n",
11692 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11693 return;
11694 }
9878760c 11695 }
a9098fd0 11696 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 11697 {
042259f2
DE
11698 REAL_VALUE_TYPE rv;
11699 long l;
9878760c 11700
042259f2
DE
11701 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11702 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11703
31bfaa0b
DE
11704 if (TARGET_64BIT)
11705 {
11706 if (TARGET_MINIMAL_TOC)
2bfcf297 11707 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 11708 else
2f0552b6
AM
11709 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11710 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
11711 return;
11712 }
042259f2 11713 else
31bfaa0b
DE
11714 {
11715 if (TARGET_MINIMAL_TOC)
2bfcf297 11716 fputs ("\t.long ", file);
31bfaa0b 11717 else
2f0552b6
AM
11718 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11719 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
11720 return;
11721 }
042259f2 11722 }
f176e826 11723 else if (GET_MODE (x) == VOIDmode
a9098fd0 11724 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 11725 {
e2c953b6 11726 unsigned HOST_WIDE_INT low;
042259f2
DE
11727 HOST_WIDE_INT high;
11728
11729 if (GET_CODE (x) == CONST_DOUBLE)
11730 {
11731 low = CONST_DOUBLE_LOW (x);
11732 high = CONST_DOUBLE_HIGH (x);
11733 }
11734 else
11735#if HOST_BITS_PER_WIDE_INT == 32
11736 {
11737 low = INTVAL (x);
0858c623 11738 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
11739 }
11740#else
11741 {
0858c623 11742 low = INTVAL (x) & 0xffffffff;
042259f2
DE
11743 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11744 }
11745#endif
9878760c 11746
a9098fd0
GK
11747 /* TOC entries are always Pmode-sized, but since this
11748 is a bigendian machine then if we're putting smaller
11749 integer constants in the TOC we have to pad them.
11750 (This is still a win over putting the constants in
11751 a separate constant pool, because then we'd have
02a4ec28
FS
11752 to have both a TOC entry _and_ the actual constant.)
11753
11754 For a 32-bit target, CONST_INT values are loaded and shifted
11755 entirely within `low' and can be stored in one TOC entry. */
11756
11757 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 11758 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
11759
11760 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
11761 {
11762#if HOST_BITS_PER_WIDE_INT == 32
11763 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11764 POINTER_SIZE, &low, &high, 0);
11765#else
11766 low |= high << 32;
11767 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11768 high = (HOST_WIDE_INT) low >> 32;
11769 low &= 0xffffffff;
11770#endif
11771 }
a9098fd0 11772
13ded975
DE
11773 if (TARGET_64BIT)
11774 {
11775 if (TARGET_MINIMAL_TOC)
2bfcf297 11776 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11777 else
2f0552b6
AM
11778 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
11779 (long) high & 0xffffffff, (long) low & 0xffffffff);
11780 fprintf (file, "0x%lx%08lx\n",
11781 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
11782 return;
11783 }
1875cc88 11784 else
13ded975 11785 {
02a4ec28
FS
11786 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
11787 {
11788 if (TARGET_MINIMAL_TOC)
2bfcf297 11789 fputs ("\t.long ", file);
02a4ec28 11790 else
2bfcf297 11791 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
11792 (long) high & 0xffffffff, (long) low & 0xffffffff);
11793 fprintf (file, "0x%lx,0x%lx\n",
11794 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 11795 }
13ded975 11796 else
02a4ec28
FS
11797 {
11798 if (TARGET_MINIMAL_TOC)
2bfcf297 11799 fputs ("\t.long ", file);
02a4ec28 11800 else
2f0552b6
AM
11801 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
11802 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 11803 }
13ded975
DE
11804 return;
11805 }
9878760c
RK
11806 }
11807
11808 if (GET_CODE (x) == CONST)
11809 {
2bfcf297
DB
11810 if (GET_CODE (XEXP (x, 0)) != PLUS)
11811 abort ();
11812
9878760c
RK
11813 base = XEXP (XEXP (x, 0), 0);
11814 offset = INTVAL (XEXP (XEXP (x, 0), 1));
11815 }
11816
11817 if (GET_CODE (base) == SYMBOL_REF)
11818 name = XSTR (base, 0);
11819 else if (GET_CODE (base) == LABEL_REF)
11820 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
11821 else if (GET_CODE (base) == CODE_LABEL)
11822 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
11823 else
11824 abort ();
11825
772c5265 11826 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 11827 if (TARGET_MINIMAL_TOC)
2bfcf297 11828 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
11829 else
11830 {
b6c9286a 11831 fprintf (file, "\t.tc %s", real_name);
9878760c 11832
1875cc88
JW
11833 if (offset < 0)
11834 fprintf (file, ".N%d", - offset);
11835 else if (offset)
11836 fprintf (file, ".P%d", offset);
9878760c 11837
19d2d16f 11838 fputs ("[TC],", file);
1875cc88 11839 }
581bc4de
MM
11840
11841 /* Currently C++ toc references to vtables can be emitted before it
11842 is decided whether the vtable is public or private. If this is
11843 the case, then the linker will eventually complain that there is
11844 a TOC reference to an unknown section. Thus, for vtables only,
11845 we emit the TOC reference to reference the symbol and not the
11846 section. */
28e510bd 11847 if (VTABLE_NAME_P (name))
581bc4de 11848 {
54ee9799 11849 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
11850 if (offset < 0)
11851 fprintf (file, "%d", offset);
11852 else if (offset > 0)
11853 fprintf (file, "+%d", offset);
11854 }
11855 else
11856 output_addr_const (file, x);
19d2d16f 11857 putc ('\n', file);
9878760c
RK
11858}
11859\f
11860/* Output an assembler pseudo-op to write an ASCII string of N characters
11861 starting at P to FILE.
11862
11863 On the RS/6000, we have to do this using the .byte operation and
11864 write out special characters outside the quoted string.
11865 Also, the assembler is broken; very long strings are truncated,
a4f6c312 11866 so we must artificially break them up early. */
9878760c
RK
11867
11868void
11869output_ascii (file, p, n)
11870 FILE *file;
d330fd93 11871 const char *p;
9878760c
RK
11872 int n;
11873{
11874 char c;
11875 int i, count_string;
d330fd93
KG
11876 const char *for_string = "\t.byte \"";
11877 const char *for_decimal = "\t.byte ";
11878 const char *to_close = NULL;
9878760c
RK
11879
11880 count_string = 0;
11881 for (i = 0; i < n; i++)
11882 {
11883 c = *p++;
11884 if (c >= ' ' && c < 0177)
11885 {
11886 if (for_string)
11887 fputs (for_string, file);
11888 putc (c, file);
11889
11890 /* Write two quotes to get one. */
11891 if (c == '"')
11892 {
11893 putc (c, file);
11894 ++count_string;
11895 }
11896
11897 for_string = NULL;
11898 for_decimal = "\"\n\t.byte ";
11899 to_close = "\"\n";
11900 ++count_string;
11901
11902 if (count_string >= 512)
11903 {
11904 fputs (to_close, file);
11905
11906 for_string = "\t.byte \"";
11907 for_decimal = "\t.byte ";
11908 to_close = NULL;
11909 count_string = 0;
11910 }
11911 }
11912 else
11913 {
11914 if (for_decimal)
11915 fputs (for_decimal, file);
11916 fprintf (file, "%d", c);
11917
11918 for_string = "\n\t.byte \"";
11919 for_decimal = ", ";
11920 to_close = "\n";
11921 count_string = 0;
11922 }
11923 }
11924
11925 /* Now close the string if we have written one. Then end the line. */
11926 if (to_close)
9ebbca7d 11927 fputs (to_close, file);
9878760c
RK
11928}
11929\f
11930/* Generate a unique section name for FILENAME for a section type
11931 represented by SECTION_DESC. Output goes into BUF.
11932
11933 SECTION_DESC can be any string, as long as it is different for each
11934 possible section type.
11935
11936 We name the section in the same manner as xlc. The name begins with an
11937 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
11938 names) with the last period replaced by the string SECTION_DESC. If
11939 FILENAME does not contain a period, SECTION_DESC is appended to the end of
11940 the name. */
9878760c
RK
11941
11942void
11943rs6000_gen_section_name (buf, filename, section_desc)
11944 char **buf;
9ebbca7d
GK
11945 const char *filename;
11946 const char *section_desc;
9878760c 11947{
9ebbca7d 11948 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
11949 char *p;
11950 int len;
9878760c
RK
11951
11952 after_last_slash = filename;
11953 for (q = filename; *q; q++)
11e5fe42
RK
11954 {
11955 if (*q == '/')
11956 after_last_slash = q + 1;
11957 else if (*q == '.')
11958 last_period = q;
11959 }
9878760c 11960
11e5fe42 11961 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 11962 *buf = (char *) xmalloc (len);
9878760c
RK
11963
11964 p = *buf;
11965 *p++ = '_';
11966
11967 for (q = after_last_slash; *q; q++)
11968 {
11e5fe42 11969 if (q == last_period)
9878760c
RK
11970 {
11971 strcpy (p, section_desc);
11972 p += strlen (section_desc);
9878760c
RK
11973 }
11974
e9a780ec 11975 else if (ISALNUM (*q))
9878760c
RK
11976 *p++ = *q;
11977 }
11978
11e5fe42 11979 if (last_period == 0)
9878760c
RK
11980 strcpy (p, section_desc);
11981 else
11982 *p = '\0';
11983}
e165f3f0 11984\f
a4f6c312 11985/* Emit profile function. */
411707f4 11986
411707f4
CC
11987void
11988output_profile_hook (labelno)
57ac7be9 11989 int labelno ATTRIBUTE_UNUSED;
411707f4 11990{
8480e480
CC
11991 if (DEFAULT_ABI == ABI_AIX)
11992 {
57ac7be9
AM
11993#ifdef NO_PROFILE_COUNTERS
11994 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
11995#else
8480e480 11996 char buf[30];
40501e5f 11997 const char *label_name;
8480e480 11998 rtx fun;
411707f4 11999
8480e480 12000 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 12001 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 12002 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 12003
8480e480
CC
12004 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
12005 fun, Pmode);
57ac7be9 12006#endif
8480e480 12007 }
ee890fe2
SS
12008 else if (DEFAULT_ABI == ABI_DARWIN)
12009 {
d5fa86ba 12010 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
12011 int caller_addr_regno = LINK_REGISTER_REGNUM;
12012
12013 /* Be conservative and always set this, at least for now. */
12014 current_function_uses_pic_offset_table = 1;
12015
12016#if TARGET_MACHO
12017 /* For PIC code, set up a stub and collect the caller's address
12018 from r0, which is where the prologue puts it. */
12019 if (flag_pic)
12020 {
12021 mcount_name = machopic_stub_name (mcount_name);
12022 if (current_function_uses_pic_offset_table)
12023 caller_addr_regno = 0;
12024 }
12025#endif
12026 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
12027 0, VOIDmode, 1,
12028 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12029 }
411707f4
CC
12030}
12031
a4f6c312 12032/* Write function profiler code. */
e165f3f0
RK
12033
12034void
12035output_function_profiler (file, labelno)
12036 FILE *file;
12037 int labelno;
12038{
3daf36a4 12039 char buf[100];
09eeeacb 12040 int save_lr = 8;
e165f3f0 12041
3daf36a4 12042 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 12043 switch (DEFAULT_ABI)
3daf36a4 12044 {
38c1f2d7
MM
12045 default:
12046 abort ();
12047
12048 case ABI_V4:
09eeeacb
AM
12049 save_lr = 4;
12050 /* Fall through. */
12051
38c1f2d7 12052 case ABI_AIX_NODESC:
09eeeacb
AM
12053 if (!TARGET_32BIT)
12054 {
12055 warning ("no profiling of 64-bit code for this ABI");
12056 return;
12057 }
38c1f2d7
MM
12058 fprintf (file, "\tmflr %s\n", reg_names[0]);
12059 if (flag_pic == 1)
12060 {
dfdfa60f 12061 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12062 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12063 reg_names[0], save_lr, reg_names[1]);
17167fd8 12064 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12065 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12066 assemble_name (file, buf);
17167fd8 12067 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12068 }
9ebbca7d 12069 else if (flag_pic > 1)
38c1f2d7 12070 {
09eeeacb
AM
12071 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12072 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12073 /* Now, we need to get the address of the label. */
12074 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12075 assemble_name (file, buf);
9ebbca7d
GK
12076 fputs ("-.\n1:", file);
12077 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12078 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12079 reg_names[0], reg_names[11]);
12080 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12081 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12082 }
38c1f2d7
MM
12083 else
12084 {
17167fd8 12085 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12086 assemble_name (file, buf);
dfdfa60f 12087 fputs ("@ha\n", file);
09eeeacb
AM
12088 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12089 reg_names[0], save_lr, reg_names[1]);
a260abc9 12090 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12091 assemble_name (file, buf);
17167fd8 12092 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12093 }
12094
09eeeacb
AM
12095 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12096 {
12097 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12098 reg_names[STATIC_CHAIN_REGNUM],
12099 12, reg_names[1]);
12100 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12101 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12102 reg_names[STATIC_CHAIN_REGNUM],
12103 12, reg_names[1]);
12104 }
12105 else
12106 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12107 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12108 break;
12109
12110 case ABI_AIX:
ee890fe2 12111 case ABI_DARWIN:
a4f6c312 12112 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7
MM
12113 break;
12114 }
e165f3f0 12115}
a251ffd0
TG
12116
12117/* Adjust the cost of a scheduling dependency. Return the new cost of
12118 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12119
c237e94a 12120static int
a06faf84 12121rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12122 rtx insn;
12123 rtx link;
296b8152 12124 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12125 int cost;
12126{
12127 if (! recog_memoized (insn))
12128 return 0;
12129
12130 if (REG_NOTE_KIND (link) != 0)
12131 return 0;
12132
12133 if (REG_NOTE_KIND (link) == 0)
12134 {
ed947a96
DJ
12135 /* Data dependency; DEP_INSN writes a register that INSN reads
12136 some cycles later. */
12137 switch (get_attr_type (insn))
12138 {
12139 case TYPE_JMPREG:
309323c2 12140 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12141 a mtctr and bctr (and mtlr and br/blr). The first
12142 scheduling pass will not know about this latency since
12143 the mtctr instruction, which has the latency associated
12144 to it, will be generated by reload. */
309323c2 12145 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12146 case TYPE_BRANCH:
12147 /* Leave some extra cycles between a compare and its
12148 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12149 if ((rs6000_cpu_attr == CPU_PPC603
12150 || rs6000_cpu_attr == CPU_PPC604
12151 || rs6000_cpu_attr == CPU_PPC604E
12152 || rs6000_cpu_attr == CPU_PPC620
12153 || rs6000_cpu_attr == CPU_PPC630
12154 || rs6000_cpu_attr == CPU_PPC750
12155 || rs6000_cpu_attr == CPU_PPC7400
12156 || rs6000_cpu_attr == CPU_PPC7450
12157 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12158 && recog_memoized (dep_insn)
12159 && (INSN_CODE (dep_insn) >= 0)
12160 && (get_attr_type (dep_insn) == TYPE_COMPARE
12161 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12162 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
12163 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
12164 return cost + 2;
12165 default:
12166 break;
12167 }
a251ffd0
TG
12168 /* Fall out to return default cost. */
12169 }
12170
12171 return cost;
12172}
b6c9286a 12173
a4f6c312
SS
12174/* A C statement (sans semicolon) to update the integer scheduling
12175 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12176 INSN earlier, increase the priority to execute INSN later. Do not
12177 define this macro if you do not need to adjust the scheduling
12178 priorities of insns. */
bef84347 12179
c237e94a 12180static int
bef84347 12181rs6000_adjust_priority (insn, priority)
d330fd93 12182 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12183 int priority;
12184{
a4f6c312
SS
12185 /* On machines (like the 750) which have asymmetric integer units,
12186 where one integer unit can do multiply and divides and the other
12187 can't, reduce the priority of multiply/divide so it is scheduled
12188 before other integer operations. */
bef84347
VM
12189
12190#if 0
2c3c49de 12191 if (! INSN_P (insn))
bef84347
VM
12192 return priority;
12193
12194 if (GET_CODE (PATTERN (insn)) == USE)
12195 return priority;
12196
12197 switch (rs6000_cpu_attr) {
12198 case CPU_PPC750:
12199 switch (get_attr_type (insn))
12200 {
12201 default:
12202 break;
12203
12204 case TYPE_IMUL:
12205 case TYPE_IDIV:
3cb999d8
DE
12206 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12207 priority, priority);
bef84347
VM
12208 if (priority >= 0 && priority < 0x01000000)
12209 priority >>= 3;
12210 break;
12211 }
12212 }
12213#endif
12214
12215 return priority;
12216}
12217
a4f6c312
SS
12218/* Return how many instructions the machine can issue per cycle. */
12219
c237e94a
ZW
12220static int
12221rs6000_issue_rate ()
b6c9286a
MM
12222{
12223 switch (rs6000_cpu_attr) {
3cb999d8
DE
12224 case CPU_RIOS1: /* ? */
12225 case CPU_RS64A:
12226 case CPU_PPC601: /* ? */
ed947a96 12227 case CPU_PPC7450:
3cb999d8 12228 return 3;
b6c9286a 12229 case CPU_PPC603:
bef84347 12230 case CPU_PPC750:
ed947a96 12231 case CPU_PPC7400:
bef84347 12232 return 2;
3cb999d8 12233 case CPU_RIOS2:
b6c9286a 12234 case CPU_PPC604:
19684119 12235 case CPU_PPC604E:
b6c9286a 12236 case CPU_PPC620:
3cb999d8 12237 case CPU_PPC630:
309323c2 12238 case CPU_POWER4:
b6c9286a
MM
12239 return 4;
12240 default:
12241 return 1;
12242 }
12243}
12244
b6c9286a 12245\f
b6c9286a
MM
12246/* Length in units of the trampoline for entering a nested function. */
12247
12248int
12249rs6000_trampoline_size ()
12250{
12251 int ret = 0;
12252
12253 switch (DEFAULT_ABI)
12254 {
12255 default:
12256 abort ();
12257
12258 case ABI_AIX:
8f802bfb 12259 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12260 break;
12261
4dabc42d 12262 case ABI_DARWIN:
b6c9286a
MM
12263 case ABI_V4:
12264 case ABI_AIX_NODESC:
03a7e1a5 12265 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12266 break;
b6c9286a
MM
12267 }
12268
12269 return ret;
12270}
12271
12272/* Emit RTL insns to initialize the variable parts of a trampoline.
12273 FNADDR is an RTX for the address of the function's pure code.
12274 CXT is an RTX for the static chain value for the function. */
12275
12276void
12277rs6000_initialize_trampoline (addr, fnaddr, cxt)
12278 rtx addr;
12279 rtx fnaddr;
12280 rtx cxt;
12281{
ac2a93a1 12282 enum machine_mode pmode = Pmode;
8bd04c56
MM
12283 int regsize = (TARGET_32BIT) ? 4 : 8;
12284 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12285
12286 switch (DEFAULT_ABI)
12287 {
12288 default:
12289 abort ();
12290
8bd04c56 12291/* Macros to shorten the code expansions below. */
39403d82 12292#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12293#define MEM_PLUS(addr,offset) \
12294 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12295
b6c9286a
MM
12296 /* Under AIX, just build the 3 word function descriptor */
12297 case ABI_AIX:
8bd04c56
MM
12298 {
12299 rtx fn_reg = gen_reg_rtx (pmode);
12300 rtx toc_reg = gen_reg_rtx (pmode);
12301 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12302 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12303 emit_move_insn (MEM_DEREF (addr), fn_reg);
12304 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12305 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12306 }
b6c9286a
MM
12307 break;
12308
4dabc42d
TC
12309 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12310 case ABI_DARWIN:
b6c9286a
MM
12311 case ABI_V4:
12312 case ABI_AIX_NODESC:
39403d82 12313 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12314 FALSE, VOIDmode, 4,
12315 addr, pmode,
12316 GEN_INT (rs6000_trampoline_size ()), SImode,
12317 fnaddr, pmode,
12318 ctx_reg, pmode);
b6c9286a 12319 break;
b6c9286a
MM
12320 }
12321
12322 return;
12323}
7509c759
MM
12324
12325\f
91d231cb 12326/* Table of valid machine attributes. */
a4f6c312 12327
91d231cb 12328const struct attribute_spec rs6000_attribute_table[] =
7509c759 12329{
91d231cb 12330 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12331 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12332 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12333 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12334};
7509c759 12335
a5c76ee6
ZW
12336/* Handle a "longcall" or "shortcall" attribute; arguments as in
12337 struct attribute_spec.handler. */
a4f6c312 12338
91d231cb
JM
12339static tree
12340rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12341 tree *node;
12342 tree name;
12343 tree args ATTRIBUTE_UNUSED;
12344 int flags ATTRIBUTE_UNUSED;
12345 bool *no_add_attrs;
12346{
12347 if (TREE_CODE (*node) != FUNCTION_TYPE
12348 && TREE_CODE (*node) != FIELD_DECL
12349 && TREE_CODE (*node) != TYPE_DECL)
12350 {
12351 warning ("`%s' attribute only applies to functions",
12352 IDENTIFIER_POINTER (name));
12353 *no_add_attrs = true;
12354 }
6a4cee5f 12355
91d231cb 12356 return NULL_TREE;
7509c759
MM
12357}
12358
a5c76ee6
ZW
12359/* Set longcall attributes on all functions declared when
12360 rs6000_default_long_calls is true. */
12361static void
12362rs6000_set_default_type_attributes (type)
12363 tree type;
12364{
12365 if (rs6000_default_long_calls
12366 && (TREE_CODE (type) == FUNCTION_TYPE
12367 || TREE_CODE (type) == METHOD_TYPE))
12368 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12369 NULL_TREE,
12370 TYPE_ATTRIBUTES (type));
12371}
12372
3cb999d8
DE
12373/* Return a reference suitable for calling a function with the
12374 longcall attribute. */
a4f6c312 12375
6a4cee5f
MM
12376struct rtx_def *
12377rs6000_longcall_ref (call_ref)
12378 rtx call_ref;
12379{
d330fd93 12380 const char *call_name;
6a4cee5f
MM
12381 tree node;
12382
12383 if (GET_CODE (call_ref) != SYMBOL_REF)
12384 return call_ref;
12385
12386 /* System V adds '.' to the internal name, so skip them. */
12387 call_name = XSTR (call_ref, 0);
12388 if (*call_name == '.')
12389 {
12390 while (*call_name == '.')
12391 call_name++;
12392
12393 node = get_identifier (call_name);
39403d82 12394 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12395 }
12396
12397 return force_reg (Pmode, call_ref);
12398}
12399
7509c759 12400\f
b64a1b53
RH
12401#ifdef USING_ELFOS_H
12402
7509c759
MM
12403/* A C statement or statements to switch to the appropriate section
12404 for output of RTX in mode MODE. You can assume that RTX is some
12405 kind of constant in RTL. The argument MODE is redundant except in
12406 the case of a `const_int' rtx. Select the section by calling
12407 `text_section' or one of the alternatives for other sections.
12408
12409 Do not define this macro if you put all constants in the read-only
12410 data section. */
12411
b64a1b53
RH
12412static void
12413rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12414 enum machine_mode mode;
7509c759 12415 rtx x;
b64a1b53 12416 unsigned HOST_WIDE_INT align;
7509c759 12417{
a9098fd0 12418 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12419 toc_section ();
7509c759 12420 else
b64a1b53 12421 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12422}
12423
12424/* A C statement or statements to switch to the appropriate
12425 section for output of DECL. DECL is either a `VAR_DECL' node
12426 or a constant of some sort. RELOC indicates whether forming
12427 the initial value of DECL requires link-time relocations. */
12428
ae46c4e0
RH
12429static void
12430rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12431 tree decl;
12432 int reloc;
ae46c4e0 12433 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
7509c759
MM
12434{
12435 int size = int_size_in_bytes (TREE_TYPE (decl));
63019373
GK
12436 int needs_sdata;
12437 int readonly;
12438 static void (* const sec_funcs[4]) PARAMS ((void)) = {
d48bc59a 12439 &readonly_data_section,
63019373
GK
12440 &sdata2_section,
12441 &data_section,
12442 &sdata_section
12443 };
12444
12445 needs_sdata = (size > 0
12446 && size <= g_switch_value
12447 && rs6000_sdata != SDATA_NONE
12448 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
7509c759
MM
12449
12450 if (TREE_CODE (decl) == STRING_CST)
63019373 12451 readonly = ! flag_writable_strings;
a9098fd0 12452 else if (TREE_CODE (decl) == VAR_DECL)
63019373
GK
12453 readonly = (! (flag_pic && reloc)
12454 && TREE_READONLY (decl)
12455 && ! TREE_SIDE_EFFECTS (decl)
12456 && DECL_INITIAL (decl)
12457 && DECL_INITIAL (decl) != error_mark_node
12458 && TREE_CONSTANT (DECL_INITIAL (decl)));
ac4f7ad9
GK
12459 else if (TREE_CODE (decl) == CONSTRUCTOR)
12460 readonly = (! (flag_pic && reloc)
ac4f7ad9 12461 && ! TREE_SIDE_EFFECTS (decl)
f3afc192 12462 && TREE_CONSTANT (decl));
7509c759 12463 else
63019373
GK
12464 readonly = 1;
12465 if (needs_sdata && rs6000_sdata != SDATA_EABI)
12466 readonly = 0;
12467
12468 (*sec_funcs[(readonly ? 0 : 2) + (needs_sdata ? 1 : 0)])();
12469}
12470
12471/* A C statement to build up a unique section name, expressed as a
12472 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12473 RELOC indicates whether the initial value of EXP requires
12474 link-time relocations. If you do not define this macro, GCC will use
12475 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12476 macro can now be called for uninitialized data items as well as
63019373
GK
12477 initialised data and functions. */
12478
ae46c4e0
RH
12479static void
12480rs6000_elf_unique_section (decl, reloc)
63019373
GK
12481 tree decl;
12482 int reloc;
12483{
63019373
GK
12484 int len;
12485 int sec;
12486 const char *name;
12487 char *string;
12488 const char *prefix;
12489
12490 static const char *const prefixes[7][2] =
12491 {
63019373
GK
12492 { ".rodata.", ".gnu.linkonce.r." },
12493 { ".sdata2.", ".gnu.linkonce.s2." },
12494 { ".data.", ".gnu.linkonce.d." },
12495 { ".sdata.", ".gnu.linkonce.s." },
12496 { ".bss.", ".gnu.linkonce.b." },
5b8c2356
AM
12497 { ".sbss.", ".gnu.linkonce.sb." },
12498 { ".text.", ".gnu.linkonce.t." }
63019373 12499 };
63019373 12500
5b8c2356
AM
12501 if (TREE_CODE (decl) == FUNCTION_DECL)
12502 sec = 6;
63019373 12503 else
5b8c2356
AM
12504 {
12505 int readonly;
12506 int needs_sdata;
12507 int size;
12508
12509 readonly = 1;
12510 if (TREE_CODE (decl) == STRING_CST)
12511 readonly = ! flag_writable_strings;
12512 else if (TREE_CODE (decl) == VAR_DECL)
12513 readonly = (! (flag_pic && reloc)
12514 && TREE_READONLY (decl)
12515 && ! TREE_SIDE_EFFECTS (decl)
12516 && TREE_CONSTANT (DECL_INITIAL (decl)));
12517
12518 size = int_size_in_bytes (TREE_TYPE (decl));
12519 needs_sdata = (size > 0
12520 && size <= g_switch_value
12521 && rs6000_sdata != SDATA_NONE
12522 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)));
12523
12524 if (DECL_INITIAL (decl) == 0
12525 || DECL_INITIAL (decl) == error_mark_node)
12526 sec = 4;
12527 else if (! readonly)
12528 sec = 2;
12529 else
12530 sec = 0;
63019373 12531
5b8c2356
AM
12532 if (needs_sdata)
12533 {
12534 /* .sdata2 is only for EABI. */
12535 if (sec == 0 && rs6000_sdata != SDATA_EABI)
12536 sec = 2;
12537 sec += 1;
12538 }
12539 }
63019373 12540
772c5265
RH
12541 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
12542 name = (*targetm.strip_name_encoding) (name);
63019373
GK
12543 prefix = prefixes[sec][DECL_ONE_ONLY (decl)];
12544 len = strlen (name) + strlen (prefix);
12545 string = alloca (len + 1);
12546
12547 sprintf (string, "%s%s", prefix, name);
12548
12549 DECL_SECTION_NAME (decl) = build_string (len, string);
7509c759 12550}
d9407988
MM
12551
12552\f
d9407988
MM
12553/* If we are referencing a function that is static or is known to be
12554 in this file, make the SYMBOL_REF special. We can use this to indicate
12555 that we can branch to this function without emitting a no-op after the
9ebbca7d 12556 call. For real AIX calling sequences, we also replace the
d9407988
MM
12557 function name with the real name (1 or 2 leading .'s), rather than
12558 the function descriptor name. This saves a lot of overriding code
a260abc9 12559 to read the prefixes. */
d9407988 12560
fb49053f
RH
12561static void
12562rs6000_elf_encode_section_info (decl, first)
d9407988 12563 tree decl;
b2003250 12564 int first;
d9407988 12565{
b2003250
RH
12566 if (!first)
12567 return;
12568
d9407988
MM
12569 if (TREE_CODE (decl) == FUNCTION_DECL)
12570 {
12571 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
8f1b829e 12572 if ((TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
c81fc13e 12573 && ! DECL_WEAK (decl))
d9407988
MM
12574 SYMBOL_REF_FLAG (sym_ref) = 1;
12575
9ebbca7d 12576 if (DEFAULT_ABI == ABI_AIX)
d9407988 12577 {
ff669a6c
RH
12578 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12579 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12580 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12581 str[0] = '.';
12582 str[1] = '.';
12583 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12584
520a57c8 12585 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12586 }
12587 }
12588 else if (rs6000_sdata != SDATA_NONE
f607bc57 12589 && DEFAULT_ABI == ABI_V4
d9407988
MM
12590 && TREE_CODE (decl) == VAR_DECL)
12591 {
12592 int size = int_size_in_bytes (TREE_TYPE (decl));
12593 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12594 const char *name = (char *)0;
d9407988
MM
12595 int len = 0;
12596
12597 if (section_name)
12598 {
12599 if (TREE_CODE (section_name) == STRING_CST)
12600 {
12601 name = TREE_STRING_POINTER (section_name);
12602 len = TREE_STRING_LENGTH (section_name);
12603 }
12604 else
12605 abort ();
12606 }
12607
12608 if ((size > 0 && size <= g_switch_value)
12609 || (name
5f59ecb7 12610 && ((len == sizeof (".sdata") - 1
3cb999d8 12611 && strcmp (name, ".sdata") == 0)
5f59ecb7 12612 || (len == sizeof (".sdata2") - 1
3cb999d8 12613 && strcmp (name, ".sdata2") == 0)
5f59ecb7 12614 || (len == sizeof (".sbss") - 1
3cb999d8 12615 && strcmp (name, ".sbss") == 0)
5f59ecb7 12616 || (len == sizeof (".sbss2") - 1
3cb999d8 12617 && strcmp (name, ".sbss2") == 0)
5f59ecb7 12618 || (len == sizeof (".PPC.EMB.sdata0") - 1
3cb999d8 12619 && strcmp (name, ".PPC.EMB.sdata0") == 0)
5f59ecb7 12620 || (len == sizeof (".PPC.EMB.sbss0") - 1
3cb999d8 12621 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d9407988
MM
12622 {
12623 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
ff669a6c 12624 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 12625 char *str = alloca (len + 2);
ff669a6c 12626
ff669a6c
RH
12627 str[0] = '@';
12628 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 12629 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
12630 }
12631 }
12632}
12633
772c5265
RH
12634static const char *
12635rs6000_elf_strip_name_encoding (str)
12636 const char *str;
12637{
12638 while (*str == '*' || *str == '@')
12639 str++;
12640 return str;
12641}
12642
b91da81f 12643#endif /* USING_ELFOS_H */
000034eb 12644
a6c2a102 12645\f
000034eb 12646/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
12647 ADDR can be effectively incremented by incrementing REG.
12648
12649 r0 is special and we must not select it as an address
12650 register by this routine since our caller will try to
12651 increment the returned register via an "la" instruction. */
000034eb
DE
12652
12653struct rtx_def *
12654find_addr_reg (addr)
12655 rtx addr;
12656{
12657 while (GET_CODE (addr) == PLUS)
12658 {
02441cd6
JL
12659 if (GET_CODE (XEXP (addr, 0)) == REG
12660 && REGNO (XEXP (addr, 0)) != 0)
000034eb 12661 addr = XEXP (addr, 0);
02441cd6
JL
12662 else if (GET_CODE (XEXP (addr, 1)) == REG
12663 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
12664 addr = XEXP (addr, 1);
12665 else if (CONSTANT_P (XEXP (addr, 0)))
12666 addr = XEXP (addr, 1);
12667 else if (CONSTANT_P (XEXP (addr, 1)))
12668 addr = XEXP (addr, 0);
12669 else
12670 abort ();
12671 }
02441cd6 12672 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
12673 return addr;
12674 abort ();
12675}
12676
a6c2a102
DE
12677void
12678rs6000_fatal_bad_address (op)
12679 rtx op;
12680{
12681 fatal_insn ("bad address", op);
12682}
c8023011
MM
12683
12684/* Called to register all of our global variables with the garbage
12685 collector. */
12686
12687static void
12688rs6000_add_gc_roots ()
12689{
9ebbca7d
GK
12690 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
12691 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
12692 toc_hash_mark_table);
ee890fe2
SS
12693}
12694
12695#if TARGET_MACHO
12696
12697#if 0
12698/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12699 reference and a constant. */
12700
12701int
12702symbolic_operand (op)
592696dd 12703 rtx op;
ee890fe2
SS
12704{
12705 switch (GET_CODE (op))
12706 {
12707 case SYMBOL_REF:
12708 case LABEL_REF:
12709 return 1;
12710 case CONST:
12711 op = XEXP (op, 0);
12712 return (GET_CODE (op) == SYMBOL_REF ||
12713 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12714 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12715 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12716 default:
12717 return 0;
12718 }
c8023011 12719}
ee890fe2
SS
12720#endif
12721
12722#ifdef RS6000_LONG_BRANCH
12723
12724static tree stub_list = 0;
12725
12726/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12727 procedure calls to the linked list. */
12728
12729void
12730add_compiler_stub (label_name, function_name, line_number)
12731 tree label_name;
12732 tree function_name;
12733 int line_number;
12734{
12735 tree stub = build_tree_list (function_name, label_name);
12736 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12737 TREE_CHAIN (stub) = stub_list;
12738 stub_list = stub;
12739}
12740
12741#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12742#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12743#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12744
a4f6c312
SS
12745/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12746 handling procedure calls from the linked list and initializes the
12747 linked list. */
ee890fe2 12748
a4f6c312
SS
12749void
12750output_compiler_stub ()
ee890fe2
SS
12751{
12752 char tmp_buf[256];
12753 char label_buf[256];
308c142a 12754 tree stub;
ee890fe2
SS
12755
12756 if (!flag_pic)
12757 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12758 {
12759 fprintf (asm_out_file,
12760 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12761
12762#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12763 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12764 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12765#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12766
12767 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12768 strcpy (label_buf,
12769 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12770 else
12771 {
12772 label_buf[0] = '_';
12773 strcpy (label_buf+1,
12774 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12775 }
12776
12777 strcpy (tmp_buf, "lis r12,hi16(");
12778 strcat (tmp_buf, label_buf);
12779 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12780 strcat (tmp_buf, label_buf);
12781 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12782 output_asm_insn (tmp_buf, 0);
12783
12784#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12785 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12786 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12787#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12788 }
12789
12790 stub_list = 0;
12791}
12792
12793/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12794 already there or not. */
12795
a4f6c312
SS
12796int
12797no_previous_def (function_name)
ee890fe2
SS
12798 tree function_name;
12799{
12800 tree stub;
12801 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12802 if (function_name == STUB_FUNCTION_NAME (stub))
12803 return 0;
12804 return 1;
12805}
12806
12807/* GET_PREV_LABEL gets the label name from the previous definition of
12808 the function. */
12809
a4f6c312
SS
12810tree
12811get_prev_label (function_name)
ee890fe2
SS
12812 tree function_name;
12813{
12814 tree stub;
12815 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12816 if (function_name == STUB_FUNCTION_NAME (stub))
12817 return STUB_LABEL_NAME (stub);
12818 return 0;
12819}
12820
12821/* INSN is either a function call or a millicode call. It may have an
12822 unconditional jump in its delay slot.
12823
12824 CALL_DEST is the routine we are calling. */
12825
12826char *
12827output_call (insn, call_dest, operand_number)
12828 rtx insn;
12829 rtx call_dest;
12830 int operand_number;
12831{
12832 static char buf[256];
12833 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
12834 {
12835 tree labelname;
12836 tree funname = get_identifier (XSTR (call_dest, 0));
12837
12838 if (no_previous_def (funname))
12839 {
308c142a 12840 int line_number = 0;
ee890fe2
SS
12841 rtx label_rtx = gen_label_rtx ();
12842 char *label_buf, temp_buf[256];
12843 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
12844 CODE_LABEL_NUMBER (label_rtx));
12845 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
12846 labelname = get_identifier (label_buf);
12847 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
12848 if (insn)
12849 line_number = NOTE_LINE_NUMBER (insn);
12850 add_compiler_stub (labelname, funname, line_number);
12851 }
12852 else
12853 labelname = get_prev_label (funname);
12854
12855 sprintf (buf, "jbsr %%z%d,%.246s",
12856 operand_number, IDENTIFIER_POINTER (labelname));
12857 return buf;
12858 }
12859 else
12860 {
12861 sprintf (buf, "bl %%z%d", operand_number);
12862 return buf;
12863 }
12864}
12865
12866#endif /* RS6000_LONG_BRANCH */
12867
12868#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
12869 do { \
83182544 12870 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
12871 char *buffer_ = (BUF); \
12872 if (symbol_[0] == '"') \
12873 { \
12874 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
12875 } \
12876 else if (name_needs_quotes(symbol_)) \
12877 { \
12878 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
12879 } \
12880 else \
12881 { \
12882 sprintf(buffer_, "L%d$%s", (N), symbol_); \
12883 } \
12884 } while (0)
12885
12886
12887/* Generate PIC and indirect symbol stubs. */
12888
12889void
12890machopic_output_stub (file, symb, stub)
12891 FILE *file;
12892 const char *symb, *stub;
12893{
12894 unsigned int length;
a4f6c312
SS
12895 char *symbol_name, *lazy_ptr_name;
12896 char *local_label_0;
ee890fe2
SS
12897 static int label = 0;
12898
df56a27f 12899 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 12900 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 12901
ee890fe2
SS
12902 label += 1;
12903
ee890fe2
SS
12904 length = strlen (symb);
12905 symbol_name = alloca (length + 32);
12906 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
12907
12908 lazy_ptr_name = alloca (length + 32);
12909 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
12910
12911 local_label_0 = alloca (length + 32);
12912 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
12913
ee890fe2
SS
12914 if (flag_pic == 2)
12915 machopic_picsymbol_stub_section ();
12916 else
12917 machopic_symbol_stub_section ();
12918
12919 fprintf (file, "%s:\n", stub);
12920 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12921
12922 if (flag_pic == 2)
12923 {
12924 fprintf (file, "\tmflr r0\n");
12925 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
12926 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
12927 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
12928 lazy_ptr_name, local_label_0);
12929 fprintf (file, "\tmtlr r0\n");
12930 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
12931 lazy_ptr_name, local_label_0);
12932 fprintf (file, "\tmtctr r12\n");
12933 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
12934 lazy_ptr_name, local_label_0);
12935 fprintf (file, "\tbctr\n");
12936 }
12937 else
12938 fprintf (file, "non-pure not supported\n");
12939
12940 machopic_lazy_symbol_ptr_section ();
12941 fprintf (file, "%s:\n", lazy_ptr_name);
12942 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12943 fprintf (file, "\t.long dyld_stub_binding_helper\n");
12944}
12945
12946/* Legitimize PIC addresses. If the address is already
12947 position-independent, we return ORIG. Newly generated
12948 position-independent addresses go into a reg. This is REG if non
12949 zero, otherwise we allocate register(s) as necessary. */
12950
c859cda6 12951#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
12952
12953rtx
12954rs6000_machopic_legitimize_pic_address (orig, mode, reg)
12955 rtx orig;
12956 enum machine_mode mode;
12957 rtx reg;
12958{
12959 rtx base, offset;
12960
12961 if (reg == NULL && ! reload_in_progress && ! reload_completed)
12962 reg = gen_reg_rtx (Pmode);
12963
12964 if (GET_CODE (orig) == CONST)
12965 {
12966 if (GET_CODE (XEXP (orig, 0)) == PLUS
12967 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
12968 return orig;
12969
12970 if (GET_CODE (XEXP (orig, 0)) == PLUS)
12971 {
a4f6c312
SS
12972 base =
12973 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
12974 Pmode, reg);
12975 offset =
12976 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
12977 Pmode, reg);
ee890fe2
SS
12978 }
12979 else
12980 abort ();
12981
12982 if (GET_CODE (offset) == CONST_INT)
12983 {
12984 if (SMALL_INT (offset))
ed8908e7 12985 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
12986 else if (! reload_in_progress && ! reload_completed)
12987 offset = force_reg (Pmode, offset);
12988 else
c859cda6
DJ
12989 {
12990 rtx mem = force_const_mem (Pmode, orig);
12991 return machopic_legitimize_pic_address (mem, Pmode, reg);
12992 }
ee890fe2
SS
12993 }
12994 return gen_rtx (PLUS, Pmode, base, offset);
12995 }
12996
12997 /* Fall back on generic machopic code. */
12998 return machopic_legitimize_pic_address (orig, mode, reg);
12999}
13000
13001/* This is just a placeholder to make linking work without having to
13002 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
13003 ever needed for Darwin (not too likely!) this would have to get a
13004 real definition. */
13005
13006void
13007toc_section ()
13008{
13009}
13010
13011#endif /* TARGET_MACHO */
7c262518
RH
13012
13013#if TARGET_ELF
13014static unsigned int
13015rs6000_elf_section_type_flags (decl, name, reloc)
13016 tree decl;
13017 const char *name;
13018 int reloc;
13019{
13020 unsigned int flags = default_section_type_flags (decl, name, reloc);
13021
270fc29b
RH
13022 if (TARGET_RELOCATABLE)
13023 flags |= SECTION_WRITE;
7c262518 13024
d0101753 13025 return flags;
7c262518 13026}
d9f6800d
RH
13027
13028/* Record an element in the table of global constructors. SYMBOL is
13029 a SYMBOL_REF of the function to be called; PRIORITY is a number
13030 between 0 and MAX_INIT_PRIORITY.
13031
13032 This differs from default_named_section_asm_out_constructor in
13033 that we have special handling for -mrelocatable. */
13034
13035static void
13036rs6000_elf_asm_out_constructor (symbol, priority)
13037 rtx symbol;
13038 int priority;
13039{
13040 const char *section = ".ctors";
13041 char buf[16];
13042
13043 if (priority != DEFAULT_INIT_PRIORITY)
13044 {
13045 sprintf (buf, ".ctors.%.5u",
13046 /* Invert the numbering so the linker puts us in the proper
13047 order; constructors are run from right to left, and the
13048 linker sorts in increasing order. */
13049 MAX_INIT_PRIORITY - priority);
13050 section = buf;
13051 }
13052
715bdd29
RH
13053 named_section_flags (section, SECTION_WRITE);
13054 assemble_align (POINTER_SIZE);
d9f6800d
RH
13055
13056 if (TARGET_RELOCATABLE)
13057 {
13058 fputs ("\t.long (", asm_out_file);
13059 output_addr_const (asm_out_file, symbol);
13060 fputs (")@fixup\n", asm_out_file);
13061 }
13062 else
c8af3574 13063 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
13064}
13065
13066static void
13067rs6000_elf_asm_out_destructor (symbol, priority)
13068 rtx symbol;
13069 int priority;
13070{
13071 const char *section = ".dtors";
13072 char buf[16];
13073
13074 if (priority != DEFAULT_INIT_PRIORITY)
13075 {
13076 sprintf (buf, ".dtors.%.5u",
13077 /* Invert the numbering so the linker puts us in the proper
13078 order; constructors are run from right to left, and the
13079 linker sorts in increasing order. */
13080 MAX_INIT_PRIORITY - priority);
13081 section = buf;
13082 }
13083
715bdd29
RH
13084 named_section_flags (section, SECTION_WRITE);
13085 assemble_align (POINTER_SIZE);
d9f6800d
RH
13086
13087 if (TARGET_RELOCATABLE)
13088 {
13089 fputs ("\t.long (", asm_out_file);
13090 output_addr_const (asm_out_file, symbol);
13091 fputs (")@fixup\n", asm_out_file);
13092 }
13093 else
c8af3574 13094 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 13095}
7c262518
RH
13096#endif
13097
cbaaba19 13098#if TARGET_XCOFF
7c262518 13099static void
b275d088
DE
13100rs6000_xcoff_asm_globalize_label (stream, name)
13101 FILE *stream;
13102 const char *name;
13103{
13104 fputs (GLOBAL_ASM_OP, stream);
13105 RS6000_OUTPUT_BASENAME (stream, name);
13106 putc ('\n', stream);
13107}
13108
13109static void
13110rs6000_xcoff_asm_named_section (name, flags)
7c262518
RH
13111 const char *name;
13112 unsigned int flags ATTRIBUTE_UNUSED;
7c262518
RH
13113{
13114 fprintf (asm_out_file, "\t.csect %s\n", name);
13115}
ae46c4e0
RH
13116
13117static void
13118rs6000_xcoff_select_section (exp, reloc, align)
13119 tree exp;
13120 int reloc;
13121 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13122{
13123 if ((TREE_CODE (exp) == STRING_CST
13124 && ! flag_writable_strings)
13125 || (TREE_CODE_CLASS (TREE_CODE (exp)) == 'd'
13126 && TREE_READONLY (exp) && ! TREE_THIS_VOLATILE (exp)
13127 && DECL_INITIAL (exp)
13128 && (DECL_INITIAL (exp) == error_mark_node
13129 || TREE_CONSTANT (DECL_INITIAL (exp)))
13130 && ! (reloc)))
13131 {
13132 if (TREE_PUBLIC (exp))
13133 read_only_data_section ();
13134 else
13135 read_only_private_data_section ();
13136 }
13137 else
13138 {
13139 if (TREE_PUBLIC (exp))
13140 data_section ();
13141 else
13142 private_data_section ();
13143 }
13144}
13145
13146static void
13147rs6000_xcoff_unique_section (decl, reloc)
13148 tree decl;
772c5265 13149 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13150{
13151 const char *name;
13152 char *string;
13153 size_t len;
13154
13155 if (TREE_CODE (decl) == FUNCTION_DECL)
13156 {
13157 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13158 len = strlen (name) + 5;
13159 string = alloca (len + 1);
13160 sprintf (string, ".%s[PR]", name);
13161 DECL_SECTION_NAME (decl) = build_string (len, string);
13162 }
13163}
b64a1b53 13164
fb49053f
RH
13165/* Select section for constant in constant pool.
13166
13167 On RS/6000, all constants are in the private read-only data area.
13168 However, if this is being placed in the TOC it must be output as a
13169 toc entry. */
13170
b64a1b53
RH
13171static void
13172rs6000_xcoff_select_rtx_section (mode, x, align)
13173 enum machine_mode mode;
13174 rtx x;
13175 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13176{
13177 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13178 toc_section ();
13179 else
13180 read_only_private_data_section ();
13181}
772c5265
RH
13182
13183/* Remove any trailing [DS] or the like from the symbol name. */
13184
13185static const char *
13186rs6000_xcoff_strip_name_encoding (name)
13187 const char *name;
13188{
13189 size_t len;
13190 if (*name == '*')
13191 name++;
13192 len = strlen (name);
13193 if (name[len - 1] == ']')
13194 return ggc_alloc_string (name, len - 4);
13195 else
13196 return name;
13197}
13198
cbaaba19 13199#endif /* TARGET_XCOFF */
fb49053f
RH
13200
13201/* Note that this is also used for ELF64. */
13202
13203static void
13204rs6000_xcoff_encode_section_info (decl, first)
13205 tree decl;
13206 int first ATTRIBUTE_UNUSED;
13207{
13208 if (TREE_CODE (decl) == FUNCTION_DECL
13209 && (TREE_ASM_WRITTEN (decl) || ! TREE_PUBLIC (decl))
13210 && ! DECL_WEAK (decl))
13211 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13212}