]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
libgcc2.c (__udiv_w_sdiv): Use attribute ((always_inline)) when inlining it into...
[thirdparty/gcc.git] / gcc / config / rs6000 / rs6000.c
CommitLineData
9878760c 1/* Subroutines used for code generation on IBM RS/6000.
9ebbca7d 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
95385cbb 3 2000, 2001, 2002 Free Software Foundation, Inc.
fab3bcc3 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
9878760c
RK
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
c15c9075
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
9878760c 22
956d6950 23#include "config.h"
c4d38ccb 24#include "system.h"
9878760c
RK
25#include "rtl.h"
26#include "regs.h"
27#include "hard-reg-set.h"
28#include "real.h"
29#include "insn-config.h"
30#include "conditions.h"
9878760c
RK
31#include "insn-attr.h"
32#include "flags.h"
33#include "recog.h"
9878760c 34#include "obstack.h"
9b30bae2 35#include "tree.h"
dfafc897 36#include "expr.h"
2fc1c679 37#include "optabs.h"
2a430ec1 38#include "except.h"
a7df97e6 39#include "function.h"
296b8152 40#include "output.h"
d5fa86ba 41#include "basic-block.h"
d0101753 42#include "integrate.h"
296b8152 43#include "toplev.h"
c8023011 44#include "ggc.h"
9ebbca7d
GK
45#include "hashtab.h"
46#include "tm_p.h"
672a6f42
NB
47#include "target.h"
48#include "target-def.h"
3ac88239 49#include "langhooks.h"
24ea750e 50#include "reload.h"
9b30bae2 51
7509c759
MM
52#ifndef TARGET_NO_PROTOTYPE
53#define TARGET_NO_PROTOTYPE 0
54#endif
55
9878760c
RK
56#define min(A,B) ((A) < (B) ? (A) : (B))
57#define max(A,B) ((A) > (B) ? (A) : (B))
58
5248c961
RK
59/* Target cpu type */
60
61enum processor_type rs6000_cpu;
8e3f41e7
MM
62struct rs6000_cpu_select rs6000_select[3] =
63{
815cdc52
MM
64 /* switch name, tune arch */
65 { (const char *)0, "--with-cpu=", 1, 1 },
66 { (const char *)0, "-mcpu=", 1, 1 },
67 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 68};
5248c961 69
6fa3f289
ZW
70/* Size of long double */
71const char *rs6000_long_double_size_string;
72int rs6000_long_double_type_size;
73
74/* Whether -mabi=altivec has appeared */
75int rs6000_altivec_abi;
76
08b57fb3
AH
77/* Whether VRSAVE instructions should be generated. */
78int rs6000_altivec_vrsave;
79
80/* String from -mvrsave= option. */
81const char *rs6000_altivec_vrsave_string;
82
a3170dc6
AH
83/* Nonzero if we want SPE ABI extensions. */
84int rs6000_spe_abi;
85
86/* Whether isel instructions should be generated. */
87int rs6000_isel;
88
89/* Nonzero if we have FPRs. */
90int rs6000_fprs = 1;
91
92/* String from -misel=. */
93const char *rs6000_isel_string;
94
a0ab749a 95/* Set to nonzero once AIX common-mode calls have been defined. */
c764f757 96static int common_mode_defined;
c81bebd7 97
0e5dbd9b
DE
98/* Private copy of original value of flag_pic for ABI_AIX. */
99static int rs6000_flag_pic;
100
9878760c
RK
101/* Save information from a "cmpxx" operation until the branch or scc is
102 emitted. */
9878760c
RK
103rtx rs6000_compare_op0, rs6000_compare_op1;
104int rs6000_compare_fp_p;
874a0744 105
874a0744
MM
106/* Label number of label created for -mrelocatable, to call to so we can
107 get the address of the GOT section */
108int rs6000_pic_labelno;
c81bebd7 109
b91da81f 110#ifdef USING_ELFOS_H
c81bebd7 111/* Which abi to adhere to */
815cdc52 112const char *rs6000_abi_name = RS6000_ABI_NAME;
d9407988
MM
113
114/* Semantics of the small data area */
115enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
116
117/* Which small data model to use */
815cdc52 118const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
119
120/* Counter for labels which are to be placed in .fixup. */
121int fixuplabelno = 0;
874a0744 122#endif
4697a36c 123
b6c9286a
MM
124/* ABI enumeration available for subtarget to use. */
125enum rs6000_abi rs6000_current_abi;
126
0ac081f6
AH
127/* ABI string from -mabi= option. */
128const char *rs6000_abi_string;
129
38c1f2d7 130/* Debug flags */
815cdc52 131const char *rs6000_debug_name;
38c1f2d7
MM
132int rs6000_debug_stack; /* debug stack applications */
133int rs6000_debug_arg; /* debug argument handling */
134
57ac7be9
AM
135const char *rs6000_traceback_name;
136static enum {
137 traceback_default = 0,
138 traceback_none,
139 traceback_part,
140 traceback_full
141} rs6000_traceback;
142
38c1f2d7
MM
143/* Flag to say the TOC is initialized */
144int toc_initialized;
9ebbca7d 145char toc_label_name[10];
38c1f2d7 146
9ebbca7d
GK
147/* Alias set for saves and restores from the rs6000 stack. */
148static int rs6000_sr_alias_set;
c8023011 149
a5c76ee6
ZW
150/* Call distance, overridden by -mlongcall and #pragma longcall(1).
151 The only place that looks at this is rs6000_set_default_type_attributes;
152 everywhere else should rely on the presence or absence of a longcall
153 attribute on the function declaration. */
154int rs6000_default_long_calls;
155const char *rs6000_longcall_switch;
156
a3170dc6
AH
157struct builtin_description
158{
159 /* mask is not const because we're going to alter it below. This
160 nonsense will go away when we rewrite the -march infrastructure
161 to give us more target flag bits. */
162 unsigned int mask;
163 const enum insn_code icode;
164 const char *const name;
165 const enum rs6000_builtins code;
166};
167
9ebbca7d
GK
168static void rs6000_add_gc_roots PARAMS ((void));
169static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
39a10a29
GK
170static void validate_condition_mode
171 PARAMS ((enum rtx_code, enum machine_mode));
172static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
e50f5f3d 173static void rs6000_maybe_dead PARAMS ((rtx));
9ebbca7d
GK
174static void rs6000_emit_stack_tie PARAMS ((void));
175static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
89e7058f
AH
176static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
177 unsigned int, int, int));
a3170dc6 178static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
9ebbca7d
GK
179static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
180static unsigned rs6000_hash_constant PARAMS ((rtx));
181static unsigned toc_hash_function PARAMS ((const void *));
182static int toc_hash_eq PARAMS ((const void *, const void *));
2eba1afa 183static int toc_hash_mark_entry PARAMS ((void **, void *));
9ebbca7d
GK
184static void toc_hash_mark_table PARAMS ((void *));
185static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
e2500fed 186static struct machine_function * rs6000_init_machine_status PARAMS ((void));
301d03af 187static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
5add3202 188#ifdef HAVE_GAS_HIDDEN
93638d7a 189static void rs6000_assemble_visibility PARAMS ((tree, const char *));
5add3202 190#endif
71f123ca 191static int rs6000_ra_ever_killed PARAMS ((void));
91d231cb
JM
192static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
193const struct attribute_spec rs6000_attribute_table[];
a5c76ee6 194static void rs6000_set_default_type_attributes PARAMS ((tree));
08c148a8
NB
195static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
196static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
3961e8fe
RH
197static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
198 HOST_WIDE_INT, tree));
2bfcf297
DB
199static rtx rs6000_emit_set_long_const PARAMS ((rtx,
200 HOST_WIDE_INT, HOST_WIDE_INT));
7c262518
RH
201#if TARGET_ELF
202static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
203 int));
d9f6800d
RH
204static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
205static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
ae46c4e0
RH
206static void rs6000_elf_select_section PARAMS ((tree, int,
207 unsigned HOST_WIDE_INT));
208static void rs6000_elf_unique_section PARAMS ((tree, int));
b64a1b53
RH
209static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
210 unsigned HOST_WIDE_INT));
0e5dbd9b
DE
211static void rs6000_elf_encode_section_info PARAMS ((tree, int))
212 ATTRIBUTE_UNUSED;
772c5265 213static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
0e5dbd9b 214static bool rs6000_elf_in_small_data_p PARAMS ((tree));
7c262518 215#endif
cbaaba19 216#if TARGET_XCOFF
b275d088
DE
217static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
218static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
ae46c4e0
RH
219static void rs6000_xcoff_select_section PARAMS ((tree, int,
220 unsigned HOST_WIDE_INT));
221static void rs6000_xcoff_unique_section PARAMS ((tree, int));
b64a1b53
RH
222static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
223 unsigned HOST_WIDE_INT));
772c5265 224static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
5add3202 225static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
7c262518 226#endif
fb49053f
RH
227static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
228 ATTRIBUTE_UNUSED;
2bcc50d0 229static bool rs6000_binds_local_p PARAMS ((tree));
c237e94a
ZW
230static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
231static int rs6000_adjust_priority PARAMS ((rtx, int));
232static int rs6000_issue_rate PARAMS ((void));
233
6fa3f289 234static void rs6000_init_builtins PARAMS ((void));
92898235
AH
235static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
236static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
237static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 238static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
92898235 239static void altivec_init_builtins PARAMS ((void));
a3170dc6
AH
240static void rs6000_common_init_builtins PARAMS ((void));
241
242static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
243 int, enum rs6000_builtins,
244 enum rs6000_builtins));
245static void spe_init_builtins PARAMS ((void));
246static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
247static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
248static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
249static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
250
92898235 251static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
3a9b8c7e
AH
252static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
253static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
254static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
100c4561 255static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 256static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
6525c0e7 257static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 258static void rs6000_parse_abi_options PARAMS ((void));
08b57fb3 259static void rs6000_parse_vrsave_option PARAMS ((void));
a3170dc6 260static void rs6000_parse_isel_option PARAMS ((void));
00b960c7
AH
261static int first_altivec_reg_to_save PARAMS ((void));
262static unsigned int compute_vrsave_mask PARAMS ((void));
263static void is_altivec_return_reg PARAMS ((rtx, void *));
9aa86737
AH
264static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
265static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
69ef87e2 266static int easy_vector_constant PARAMS ((rtx));
c81bebd7
MM
267\f
268/* Default register names. */
269char rs6000_reg_names[][8] =
270{
802a0058
MM
271 "0", "1", "2", "3", "4", "5", "6", "7",
272 "8", "9", "10", "11", "12", "13", "14", "15",
273 "16", "17", "18", "19", "20", "21", "22", "23",
274 "24", "25", "26", "27", "28", "29", "30", "31",
275 "0", "1", "2", "3", "4", "5", "6", "7",
276 "8", "9", "10", "11", "12", "13", "14", "15",
277 "16", "17", "18", "19", "20", "21", "22", "23",
278 "24", "25", "26", "27", "28", "29", "30", "31",
279 "mq", "lr", "ctr","ap",
280 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
281 "xer",
282 /* AltiVec registers. */
0cd5e3a1
AH
283 "0", "1", "2", "3", "4", "5", "6", "7",
284 "8", "9", "10", "11", "12", "13", "14", "15",
285 "16", "17", "18", "19", "20", "21", "22", "23",
286 "24", "25", "26", "27", "28", "29", "30", "31",
0ac081f6 287 "vrsave"
c81bebd7
MM
288};
289
290#ifdef TARGET_REGNAMES
8b60264b 291static const char alt_reg_names[][8] =
c81bebd7 292{
802a0058
MM
293 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
294 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
295 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
296 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
297 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
298 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
299 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
300 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
301 "mq", "lr", "ctr", "ap",
302 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6
AH
303 "xer",
304 /* AltiVec registers. */
305 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
306 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
307 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
308 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
76a773f3 309 "vrsave"
c81bebd7
MM
310};
311#endif
9878760c 312\f
daf11973
MM
313#ifndef MASK_STRICT_ALIGN
314#define MASK_STRICT_ALIGN 0
315#endif
3961e8fe
RH
316
317/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
318#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
672a6f42
NB
319\f
320/* Initialize the GCC target structure. */
91d231cb
JM
321#undef TARGET_ATTRIBUTE_TABLE
322#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
323#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
324#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 325
301d03af
RS
326#undef TARGET_ASM_ALIGNED_DI_OP
327#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
328
329/* Default unaligned ops are only provided for ELF. Find the ops needed
330 for non-ELF systems. */
331#ifndef OBJECT_FORMAT_ELF
cbaaba19 332#if TARGET_XCOFF
ae6c1efd 333/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
334 64-bit targets. */
335#undef TARGET_ASM_UNALIGNED_HI_OP
336#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
337#undef TARGET_ASM_UNALIGNED_SI_OP
338#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
339#undef TARGET_ASM_UNALIGNED_DI_OP
340#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
341#else
342/* For Darwin. */
343#undef TARGET_ASM_UNALIGNED_HI_OP
344#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
345#undef TARGET_ASM_UNALIGNED_SI_OP
346#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
347#endif
348#endif
349
350/* This hook deals with fixups for relocatable code and DI-mode objects
351 in 64-bit code. */
352#undef TARGET_ASM_INTEGER
353#define TARGET_ASM_INTEGER rs6000_assemble_integer
354
93638d7a
AM
355#ifdef HAVE_GAS_HIDDEN
356#undef TARGET_ASM_ASSEMBLE_VISIBILITY
357#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
358#endif
359
08c148a8
NB
360#undef TARGET_ASM_FUNCTION_PROLOGUE
361#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
362#undef TARGET_ASM_FUNCTION_EPILOGUE
363#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
364
c237e94a
ZW
365#undef TARGET_SCHED_ISSUE_RATE
366#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
367#undef TARGET_SCHED_ADJUST_COST
368#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
369#undef TARGET_SCHED_ADJUST_PRIORITY
370#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
371
0ac081f6
AH
372#undef TARGET_INIT_BUILTINS
373#define TARGET_INIT_BUILTINS rs6000_init_builtins
374
375#undef TARGET_EXPAND_BUILTIN
376#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
377
0e5dbd9b
DE
378#undef TARGET_BINDS_LOCAL_P
379#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
380
3961e8fe
RH
381#undef TARGET_ASM_OUTPUT_MI_THUNK
382#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
383
384/* ??? Should work everywhere, but ask dje@watson.ibm.com before
385 enabling for AIX. */
386#if TARGET_OBJECT_FORMAT != OBJECT_XCOFF
387#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
388#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
389#endif
00b960c7 390
f6897b10 391struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 392\f
5248c961
RK
393/* Override command line options. Mostly we process the processor
394 type and sometimes adjust other TARGET_ options. */
395
396void
8e3f41e7 397rs6000_override_options (default_cpu)
d330fd93 398 const char *default_cpu;
5248c961 399{
c4d38ccb 400 size_t i, j;
8e3f41e7 401 struct rs6000_cpu_select *ptr;
5248c961 402
85638c0d
RK
403 /* Simplify the entries below by making a mask for any POWER
404 variant and any PowerPC variant. */
405
938937d8 406#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
407#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
408 | MASK_PPC_GFXOPT | MASK_POWERPC64)
409#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 410
5248c961
RK
411 static struct ptt
412 {
8b60264b
KG
413 const char *const name; /* Canonical processor name. */
414 const enum processor_type processor; /* Processor type enum value. */
415 const int target_enable; /* Target flags to enable. */
416 const int target_disable; /* Target flags to disable. */
417 } const processor_target_table[]
cf27b467
MM
418 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
419 POWER_MASKS | POWERPC_MASKS},
db7f1e43 420 {"power", PROCESSOR_POWER,
938937d8 421 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 422 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
423 {"power2", PROCESSOR_POWER,
424 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
425 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
426 {"power3", PROCESSOR_PPC630,
427 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
428 POWER_MASKS | MASK_PPC_GPOPT},
309323c2
DE
429 {"power4", PROCESSOR_POWER4,
430 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
431 POWER_MASKS | MASK_PPC_GPOPT},
db7f1e43
RK
432 {"powerpc", PROCESSOR_POWERPC,
433 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 434 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
435 {"powerpc64", PROCESSOR_POWERPC64,
436 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
437 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 438 {"rios", PROCESSOR_RIOS1,
938937d8 439 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
440 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
441 {"rios1", PROCESSOR_RIOS1,
938937d8 442 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
443 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
444 {"rsc", PROCESSOR_PPC601,
938937d8 445 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
446 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
447 {"rsc1", PROCESSOR_PPC601,
938937d8 448 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
449 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
450 {"rios2", PROCESSOR_RIOS2,
938937d8 451 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 452 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
453 {"rs64a", PROCESSOR_RS64A,
454 MASK_POWERPC | MASK_NEW_MNEMONICS,
455 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
456 {"401", PROCESSOR_PPC403,
457 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
458 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 459 {"403", PROCESSOR_PPC403,
daf11973 460 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 461 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
462 {"405", PROCESSOR_PPC405,
463 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
464 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
465 {"505", PROCESSOR_MPCCORE,
466 MASK_POWERPC | MASK_NEW_MNEMONICS,
467 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 468 {"601", PROCESSOR_PPC601,
938937d8 469 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 470 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 471 {"602", PROCESSOR_PPC603,
cf27b467
MM
472 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
473 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 474 {"603", PROCESSOR_PPC603,
68c49ffa
RK
475 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
476 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
477 {"603e", PROCESSOR_PPC603,
478 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
479 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 480 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
481 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
482 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 483 {"604", PROCESSOR_PPC604,
b6c9286a
MM
484 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
485 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 486 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
487 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
488 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 489 {"620", PROCESSOR_PPC620,
68c49ffa 490 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
a260abc9 491 POWER_MASKS | MASK_PPC_GPOPT},
3cb999d8
DE
492 {"630", PROCESSOR_PPC630,
493 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
494 POWER_MASKS | MASK_PPC_GPOPT},
bef84347
VM
495 {"740", PROCESSOR_PPC750,
496 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
497 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
498 {"750", PROCESSOR_PPC750,
499 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
500 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
501 {"7400", PROCESSOR_PPC7400,
502 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
503 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
504 {"7450", PROCESSOR_PPC7450,
505 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
506 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a3170dc6
AH
507 {"8540", PROCESSOR_PPC8540,
508 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
509 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
510 {"801", PROCESSOR_MPCCORE,
511 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
512 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
513 {"821", PROCESSOR_MPCCORE,
514 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
515 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
516 {"823", PROCESSOR_MPCCORE,
517 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
518 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
519 {"860", PROCESSOR_MPCCORE,
520 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
521 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 522
ca7558fc 523 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 524
a4f6c312
SS
525 /* Save current -mmultiple/-mno-multiple status. */
526 int multiple = TARGET_MULTIPLE;
527 /* Save current -mstring/-mno-string status. */
528 int string = TARGET_STRING;
8a61d227 529
a4f6c312 530 /* Identify the processor type. */
8e3f41e7 531 rs6000_select[0].string = default_cpu;
3cb999d8 532 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 533
b6a1cbae 534 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 535 {
8e3f41e7
MM
536 ptr = &rs6000_select[i];
537 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 538 {
8e3f41e7
MM
539 for (j = 0; j < ptt_size; j++)
540 if (! strcmp (ptr->string, processor_target_table[j].name))
541 {
542 if (ptr->set_tune_p)
543 rs6000_cpu = processor_target_table[j].processor;
544
545 if (ptr->set_arch_p)
546 {
547 target_flags |= processor_target_table[j].target_enable;
548 target_flags &= ~processor_target_table[j].target_disable;
549 }
550 break;
551 }
552
4406229e 553 if (j == ptt_size)
8e3f41e7 554 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
555 }
556 }
8a61d227 557
a3170dc6
AH
558 if (rs6000_cpu == PROCESSOR_PPC8540)
559 rs6000_isel = 1;
560
a4f6c312
SS
561 /* If we are optimizing big endian systems for space, use the store
562 multiple instructions. */
ef792183
MM
563 if (BYTES_BIG_ENDIAN && optimize_size)
564 target_flags |= MASK_MULTIPLE;
565
8a61d227
MM
566 /* If -mmultiple or -mno-multiple was explicitly used, don't
567 override with the processor default */
568 if (TARGET_MULTIPLE_SET)
569 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 570
a4f6c312
SS
571 /* If -mstring or -mno-string was explicitly used, don't override
572 with the processor default. */
938937d8 573 if (TARGET_STRING_SET)
1f5515bf 574 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 575
a4f6c312
SS
576 /* Don't allow -mmultiple or -mstring on little endian systems
577 unless the cpu is a 750, because the hardware doesn't support the
578 instructions used in little endian mode, and causes an alignment
579 trap. The 750 does not cause an alignment trap (except when the
580 target is unaligned). */
bef84347 581
bfc79d3b 582 if (! BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
583 {
584 if (TARGET_MULTIPLE)
585 {
586 target_flags &= ~MASK_MULTIPLE;
587 if (TARGET_MULTIPLE_SET)
588 warning ("-mmultiple is not supported on little endian systems");
589 }
590
591 if (TARGET_STRING)
592 {
593 target_flags &= ~MASK_STRING;
938937d8
MM
594 if (TARGET_STRING_SET)
595 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
596 }
597 }
3933e0e1 598
ee2ca2a2 599 if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
a260abc9 600 {
0e5dbd9b 601 rs6000_flag_pic = flag_pic;
ee2ca2a2 602 flag_pic = 0;
a260abc9
DE
603 }
604
c72bfda7
SS
605 /* For Darwin, always silently make -fpic and -fPIC identical. */
606 if (flag_pic == 1 && DEFAULT_ABI == ABI_DARWIN)
607 flag_pic = 2;
608
38c1f2d7
MM
609 /* Set debug flags */
610 if (rs6000_debug_name)
611 {
bfc79d3b 612 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 613 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 614 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 615 rs6000_debug_stack = 1;
bfc79d3b 616 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
617 rs6000_debug_arg = 1;
618 else
c725bd79 619 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
620 }
621
57ac7be9
AM
622 if (rs6000_traceback_name)
623 {
624 if (! strncmp (rs6000_traceback_name, "full", 4))
625 rs6000_traceback = traceback_full;
626 else if (! strncmp (rs6000_traceback_name, "part", 4))
627 rs6000_traceback = traceback_part;
628 else if (! strncmp (rs6000_traceback_name, "no", 2))
629 rs6000_traceback = traceback_none;
630 else
631 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
632 rs6000_traceback_name);
633 }
634
6fa3f289
ZW
635 /* Set size of long double */
636 rs6000_long_double_type_size = 64;
637 if (rs6000_long_double_size_string)
638 {
639 char *tail;
640 int size = strtol (rs6000_long_double_size_string, &tail, 10);
641 if (*tail != '\0' || (size != 64 && size != 128))
642 error ("Unknown switch -mlong-double-%s",
643 rs6000_long_double_size_string);
644 else
645 rs6000_long_double_type_size = size;
646 }
647
0ac081f6
AH
648 /* Handle -mabi= options. */
649 rs6000_parse_abi_options ();
650
08b57fb3
AH
651 /* Handle -mvrsave= option. */
652 rs6000_parse_vrsave_option ();
653
a3170dc6
AH
654 /* Handle -misel= option. */
655 rs6000_parse_isel_option ();
656
a7ae18e2
AH
657#ifdef SUBTARGET_OVERRIDE_OPTIONS
658 SUBTARGET_OVERRIDE_OPTIONS;
659#endif
660#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
661 SUBSUBTARGET_OVERRIDE_OPTIONS;
662#endif
663
a5c76ee6
ZW
664 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
665 using TARGET_OPTIONS to handle a toggle switch, but we're out of
666 bits in target_flags so TARGET_SWITCHES cannot be used.
667 Assumption here is that rs6000_longcall_switch points into the
668 text of the complete option, rather than being a copy, so we can
669 scan back for the presence or absence of the no- modifier. */
670 if (rs6000_longcall_switch)
671 {
672 const char *base = rs6000_longcall_switch;
673 while (base[-1] != 'm') base--;
674
675 if (*rs6000_longcall_switch != '\0')
676 error ("invalid option `%s'", base);
677 rs6000_default_long_calls = (base[0] != 'n');
678 }
679
c81bebd7 680#ifdef TARGET_REGNAMES
a4f6c312
SS
681 /* If the user desires alternate register names, copy in the
682 alternate names now. */
c81bebd7 683 if (TARGET_REGNAMES)
4e135bdd 684 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
685#endif
686
6fa3f289
ZW
687 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
688 If -maix-struct-return or -msvr4-struct-return was explicitly
689 used, don't override with the ABI default. */
690 if (!(target_flags & MASK_AIX_STRUCT_RET_SET))
691 {
692 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
693 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
694 else
695 target_flags |= MASK_AIX_STRUCT_RET;
696 }
697
fcce224d
DE
698 if (TARGET_LONG_DOUBLE_128
699 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
700 real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
701
c8023011
MM
702 /* Register global variables with the garbage collector. */
703 rs6000_add_gc_roots ();
9ebbca7d
GK
704
705 /* Allocate an alias set for register saves & restores from stack. */
706 rs6000_sr_alias_set = new_alias_set ();
707
708 if (TARGET_TOC)
709 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 710
301d03af
RS
711 /* We can only guarantee the availability of DI pseudo-ops when
712 assembling for 64-bit targets. */
ae6c1efd 713 if (!TARGET_64BIT)
301d03af
RS
714 {
715 targetm.asm_out.aligned_op.di = NULL;
716 targetm.asm_out.unaligned_op.di = NULL;
717 }
718
71f123ca
FS
719 /* Arrange to save and restore machine status around nested functions. */
720 init_machine_status = rs6000_init_machine_status;
5248c961 721}
5accd822 722
a3170dc6
AH
723/* Handle -misel= option. */
724static void
725rs6000_parse_isel_option ()
726{
727 if (rs6000_isel_string == 0)
728 return;
729 else if (! strcmp (rs6000_isel_string, "yes"))
730 rs6000_isel = 1;
731 else if (! strcmp (rs6000_isel_string, "no"))
732 rs6000_isel = 0;
733 else
734 error ("unknown -misel= option specified: '%s'",
735 rs6000_isel_string);
736}
737
08b57fb3
AH
738/* Handle -mvrsave= options. */
739static void
740rs6000_parse_vrsave_option ()
741{
742 /* Generate VRSAVE instructions by default. */
743 if (rs6000_altivec_vrsave_string == 0
744 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
745 rs6000_altivec_vrsave = 1;
746 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
747 rs6000_altivec_vrsave = 0;
748 else
749 error ("unknown -mvrsave= option specified: '%s'",
750 rs6000_altivec_vrsave_string);
751}
752
0ac081f6 753/* Handle -mabi= options. */
00b960c7
AH
754static void
755rs6000_parse_abi_options ()
0ac081f6
AH
756{
757 if (rs6000_abi_string == 0)
758 return;
759 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 760 rs6000_altivec_abi = 1;
76a773f3
AH
761 else if (! strcmp (rs6000_abi_string, "no-altivec"))
762 rs6000_altivec_abi = 0;
a3170dc6
AH
763 else if (! strcmp (rs6000_abi_string, "spe"))
764 rs6000_spe_abi = 1;
765 else if (! strcmp (rs6000_abi_string, "no-spe"))
766 rs6000_spe_abi = 0;
0ac081f6 767 else
c725bd79 768 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
769}
770
5accd822
DE
771void
772optimization_options (level, size)
e2c953b6 773 int level ATTRIBUTE_UNUSED;
5accd822
DE
774 int size ATTRIBUTE_UNUSED;
775{
5accd822 776}
3cfa4909
MM
777\f
778/* Do anything needed at the start of the asm file. */
779
780void
781rs6000_file_start (file, default_cpu)
782 FILE *file;
d330fd93 783 const char *default_cpu;
3cfa4909 784{
c4d38ccb 785 size_t i;
3cfa4909 786 char buffer[80];
d330fd93 787 const char *start = buffer;
3cfa4909
MM
788 struct rs6000_cpu_select *ptr;
789
790 if (flag_verbose_asm)
791 {
792 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
793 rs6000_select[0].string = default_cpu;
794
b6a1cbae 795 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
796 {
797 ptr = &rs6000_select[i];
798 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
799 {
800 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
801 start = "";
802 }
803 }
804
b91da81f 805#ifdef USING_ELFOS_H
3cfa4909
MM
806 switch (rs6000_sdata)
807 {
808 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
809 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
810 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
811 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
812 }
813
814 if (rs6000_sdata && g_switch_value)
815 {
816 fprintf (file, "%s -G %d", start, g_switch_value);
817 start = "";
818 }
819#endif
820
821 if (*start == '\0')
949ea356 822 putc ('\n', file);
3cfa4909
MM
823 }
824}
5248c961 825\f
a0ab749a 826/* Return nonzero if this function is known to have a null epilogue. */
9878760c
RK
827
828int
829direct_return ()
830{
4697a36c
MM
831 if (reload_completed)
832 {
833 rs6000_stack_t *info = rs6000_stack_info ();
834
835 if (info->first_gp_reg_save == 32
836 && info->first_fp_reg_save == 64
00b960c7 837 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
838 && ! info->lr_save_p
839 && ! info->cr_save_p
00b960c7 840 && info->vrsave_mask == 0
c81fc13e 841 && ! info->push_p)
4697a36c
MM
842 return 1;
843 }
844
845 return 0;
9878760c
RK
846}
847
848/* Returns 1 always. */
849
850int
851any_operand (op, mode)
592696dd 852 rtx op ATTRIBUTE_UNUSED;
296b8152 853 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
854{
855 return 1;
856}
857
a4f6c312 858/* Returns 1 if op is the count register. */
38c1f2d7 859int
a4f6c312 860count_register_operand (op, mode)
592696dd 861 rtx op;
296b8152 862 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
863{
864 if (GET_CODE (op) != REG)
865 return 0;
866
867 if (REGNO (op) == COUNT_REGISTER_REGNUM)
868 return 1;
869
870 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
871 return 1;
872
873 return 0;
874}
875
0ec4e2a8
AH
876/* Returns 1 if op is an altivec register. */
877int
878altivec_register_operand (op, mode)
879 rtx op;
880 enum machine_mode mode ATTRIBUTE_UNUSED;
881{
882
883 return (register_operand (op, mode)
884 && (GET_CODE (op) != REG
885 || REGNO (op) > FIRST_PSEUDO_REGISTER
886 || ALTIVEC_REGNO_P (REGNO (op))));
887}
888
38c1f2d7 889int
a4f6c312 890xer_operand (op, mode)
592696dd 891 rtx op;
296b8152 892 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
893{
894 if (GET_CODE (op) != REG)
895 return 0;
896
9ebbca7d 897 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
898 return 1;
899
802a0058
MM
900 return 0;
901}
902
c859cda6 903/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 904 by such constants completes more quickly. */
c859cda6
DJ
905
906int
907s8bit_cint_operand (op, mode)
908 rtx op;
909 enum machine_mode mode ATTRIBUTE_UNUSED;
910{
911 return ( GET_CODE (op) == CONST_INT
912 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
913}
914
9878760c
RK
915/* Return 1 if OP is a constant that can fit in a D field. */
916
917int
918short_cint_operand (op, mode)
592696dd 919 rtx op;
296b8152 920 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 921{
5f59ecb7
DE
922 return (GET_CODE (op) == CONST_INT
923 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
924}
925
5519a4f9 926/* Similar for an unsigned D field. */
9878760c
RK
927
928int
929u_short_cint_operand (op, mode)
592696dd 930 rtx op;
296b8152 931 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 932{
19684119 933 return (GET_CODE (op) == CONST_INT
c1f11548 934 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
935}
936
dcfedcd0
RK
937/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
938
939int
940non_short_cint_operand (op, mode)
592696dd 941 rtx op;
296b8152 942 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
943{
944 return (GET_CODE (op) == CONST_INT
a7653a2c 945 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
946}
947
2bfcf297
DB
948/* Returns 1 if OP is a CONST_INT that is a positive value
949 and an exact power of 2. */
950
951int
952exact_log2_cint_operand (op, mode)
592696dd 953 rtx op;
2bfcf297
DB
954 enum machine_mode mode ATTRIBUTE_UNUSED;
955{
956 return (GET_CODE (op) == CONST_INT
957 && INTVAL (op) > 0
958 && exact_log2 (INTVAL (op)) >= 0);
959}
960
9878760c
RK
961/* Returns 1 if OP is a register that is not special (i.e., not MQ,
962 ctr, or lr). */
963
964int
cd2b37d9 965gpc_reg_operand (op, mode)
592696dd 966 rtx op;
9878760c
RK
967 enum machine_mode mode;
968{
969 return (register_operand (op, mode)
802a0058 970 && (GET_CODE (op) != REG
9ebbca7d
GK
971 || (REGNO (op) >= ARG_POINTER_REGNUM
972 && !XER_REGNO_P (REGNO (op)))
973 || REGNO (op) < MQ_REGNO));
9878760c
RK
974}
975
976/* Returns 1 if OP is either a pseudo-register or a register denoting a
977 CR field. */
978
979int
980cc_reg_operand (op, mode)
592696dd 981 rtx op;
9878760c
RK
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_P (REGNO (op))));
988}
989
815cdc52
MM
990/* Returns 1 if OP is either a pseudo-register or a register denoting a
991 CR field that isn't CR0. */
992
993int
994cc_reg_not_cr0_operand (op, mode)
592696dd 995 rtx op;
815cdc52
MM
996 enum machine_mode mode;
997{
998 return (register_operand (op, mode)
999 && (GET_CODE (op) != REG
1000 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1001 || CR_REGNO_NOT_CR0_P (REGNO (op))));
1002}
1003
a4f6c312
SS
1004/* Returns 1 if OP is either a constant integer valid for a D-field or
1005 a non-special register. If a register, it must be in the proper
1006 mode unless MODE is VOIDmode. */
9878760c
RK
1007
1008int
1009reg_or_short_operand (op, mode)
592696dd 1010 rtx op;
9878760c
RK
1011 enum machine_mode mode;
1012{
f5a28898 1013 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1014}
1015
a4f6c312
SS
1016/* Similar, except check if the negation of the constant would be
1017 valid for a D-field. */
9878760c
RK
1018
1019int
1020reg_or_neg_short_operand (op, mode)
592696dd 1021 rtx op;
9878760c
RK
1022 enum machine_mode mode;
1023{
1024 if (GET_CODE (op) == CONST_INT)
1025 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1026
cd2b37d9 1027 return gpc_reg_operand (op, mode);
9878760c
RK
1028}
1029
768070a0
TR
1030/* Returns 1 if OP is either a constant integer valid for a DS-field or
1031 a non-special register. If a register, it must be in the proper
1032 mode unless MODE is VOIDmode. */
1033
1034int
1035reg_or_aligned_short_operand (op, mode)
1036 rtx op;
1037 enum machine_mode mode;
1038{
1039 if (gpc_reg_operand (op, mode))
1040 return 1;
1041 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1042 return 1;
1043
1044 return 0;
1045}
1046
1047
a4f6c312
SS
1048/* Return 1 if the operand is either a register or an integer whose
1049 high-order 16 bits are zero. */
9878760c
RK
1050
1051int
1052reg_or_u_short_operand (op, mode)
592696dd 1053 rtx op;
9878760c
RK
1054 enum machine_mode mode;
1055{
e675f625 1056 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1057}
1058
1059/* Return 1 is the operand is either a non-special register or ANY
1060 constant integer. */
1061
1062int
1063reg_or_cint_operand (op, mode)
592696dd 1064 rtx op;
9878760c
RK
1065 enum machine_mode mode;
1066{
a4f6c312 1067 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1068}
1069
1070/* Return 1 is the operand is either a non-special register or ANY
1071 32-bit signed constant integer. */
1072
1073int
1074reg_or_arith_cint_operand (op, mode)
592696dd 1075 rtx op;
f6bf7de2
DE
1076 enum machine_mode mode;
1077{
a4f6c312
SS
1078 return (gpc_reg_operand (op, mode)
1079 || (GET_CODE (op) == CONST_INT
f6bf7de2 1080#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1081 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1082 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1083#endif
a4f6c312 1084 ));
9878760c
RK
1085}
1086
2bfcf297
DB
1087/* Return 1 is the operand is either a non-special register or a 32-bit
1088 signed constant integer valid for 64-bit addition. */
1089
1090int
1091reg_or_add_cint64_operand (op, mode)
592696dd 1092 rtx op;
2bfcf297
DB
1093 enum machine_mode mode;
1094{
a4f6c312
SS
1095 return (gpc_reg_operand (op, mode)
1096 || (GET_CODE (op) == CONST_INT
a65c591c 1097#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1098 && INTVAL (op) < 0x7fff8000
a65c591c 1099#else
a4f6c312
SS
1100 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1101 < 0x100000000ll)
2bfcf297 1102#endif
a4f6c312 1103 ));
2bfcf297
DB
1104}
1105
1106/* Return 1 is the operand is either a non-special register or a 32-bit
1107 signed constant integer valid for 64-bit subtraction. */
1108
1109int
1110reg_or_sub_cint64_operand (op, mode)
592696dd 1111 rtx op;
2bfcf297
DB
1112 enum machine_mode mode;
1113{
a4f6c312
SS
1114 return (gpc_reg_operand (op, mode)
1115 || (GET_CODE (op) == CONST_INT
a65c591c 1116#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1117 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1118#else
a4f6c312
SS
1119 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1120 < 0x100000000ll)
2bfcf297 1121#endif
a4f6c312 1122 ));
2bfcf297
DB
1123}
1124
9ebbca7d
GK
1125/* Return 1 is the operand is either a non-special register or ANY
1126 32-bit unsigned constant integer. */
1127
1128int
1d328b19 1129reg_or_logical_cint_operand (op, mode)
592696dd 1130 rtx op;
9ebbca7d
GK
1131 enum machine_mode mode;
1132{
1d328b19
GK
1133 if (GET_CODE (op) == CONST_INT)
1134 {
1135 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1136 {
1137 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1138 abort ();
1d328b19
GK
1139
1140 if (INTVAL (op) < 0)
1141 return 0;
1142 }
1143
1144 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1145 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1146 }
1147 else if (GET_CODE (op) == CONST_DOUBLE)
1148 {
1149 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1150 || mode != DImode)
a4f6c312 1151 abort ();
1d328b19
GK
1152
1153 return CONST_DOUBLE_HIGH (op) == 0;
1154 }
1155 else
1156 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1157}
1158
51d3e7d6 1159/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1160
1161int
1162got_operand (op, mode)
592696dd 1163 rtx op;
296b8152 1164 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1165{
1166 return (GET_CODE (op) == SYMBOL_REF
1167 || GET_CODE (op) == CONST
1168 || GET_CODE (op) == LABEL_REF);
1169}
1170
38c1f2d7
MM
1171/* Return 1 if the operand is a simple references that can be loaded via
1172 the GOT (labels involving addition aren't allowed). */
1173
1174int
1175got_no_const_operand (op, mode)
592696dd 1176 rtx op;
296b8152 1177 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1178{
1179 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1180}
1181
4e74d8ec
MM
1182/* Return the number of instructions it takes to form a constant in an
1183 integer register. */
1184
1185static int
1186num_insns_constant_wide (value)
1187 HOST_WIDE_INT value;
1188{
1189 /* signed constant loadable with {cal|addi} */
5f59ecb7 1190 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1191 return 1;
1192
4e74d8ec 1193 /* constant loadable with {cau|addis} */
5f59ecb7 1194 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1195 return 1;
1196
5f59ecb7 1197#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1198 else if (TARGET_POWERPC64)
4e74d8ec 1199 {
a65c591c
DE
1200 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1201 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1202
a65c591c 1203 if (high == 0 || high == -1)
4e74d8ec
MM
1204 return 2;
1205
a65c591c 1206 high >>= 1;
4e74d8ec 1207
a65c591c 1208 if (low == 0)
4e74d8ec 1209 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1210 else
1211 return (num_insns_constant_wide (high)
e396202a 1212 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1213 }
1214#endif
1215
1216 else
1217 return 2;
1218}
1219
1220int
1221num_insns_constant (op, mode)
1222 rtx op;
1223 enum machine_mode mode;
1224{
4e74d8ec 1225 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1226 {
1227#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1228 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1229 && mask64_operand (op, mode))
0d30d435
DE
1230 return 2;
1231 else
1232#endif
1233 return num_insns_constant_wide (INTVAL (op));
1234 }
4e74d8ec 1235
6fc48950
MM
1236 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1237 {
1238 long l;
1239 REAL_VALUE_TYPE rv;
1240
1241 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1242 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1243 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1244 }
1245
47ad8c61 1246 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1247 {
47ad8c61
MM
1248 HOST_WIDE_INT low;
1249 HOST_WIDE_INT high;
1250 long l[2];
1251 REAL_VALUE_TYPE rv;
1252 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1253
47ad8c61
MM
1254 if (mode == VOIDmode || mode == DImode)
1255 {
1256 high = CONST_DOUBLE_HIGH (op);
1257 low = CONST_DOUBLE_LOW (op);
1258 }
1259 else
1260 {
1261 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1262 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1263 high = l[endian];
1264 low = l[1 - endian];
1265 }
4e74d8ec 1266
47ad8c61
MM
1267 if (TARGET_32BIT)
1268 return (num_insns_constant_wide (low)
1269 + num_insns_constant_wide (high));
4e74d8ec
MM
1270
1271 else
47ad8c61 1272 {
e72247f4 1273 if (high == 0 && low >= 0)
47ad8c61
MM
1274 return num_insns_constant_wide (low);
1275
e72247f4 1276 else if (high == -1 && low < 0)
47ad8c61
MM
1277 return num_insns_constant_wide (low);
1278
a260abc9
DE
1279 else if (mask64_operand (op, mode))
1280 return 2;
1281
47ad8c61
MM
1282 else if (low == 0)
1283 return num_insns_constant_wide (high) + 1;
1284
1285 else
1286 return (num_insns_constant_wide (high)
1287 + num_insns_constant_wide (low) + 1);
1288 }
4e74d8ec
MM
1289 }
1290
1291 else
1292 abort ();
1293}
1294
a4f6c312
SS
1295/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1296 register with one instruction per word. We only do this if we can
1297 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1298
1299int
1300easy_fp_constant (op, mode)
592696dd
SS
1301 rtx op;
1302 enum machine_mode mode;
9878760c 1303{
9878760c
RK
1304 if (GET_CODE (op) != CONST_DOUBLE
1305 || GET_MODE (op) != mode
4e74d8ec 1306 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1307 return 0;
1308
a4f6c312 1309 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1310 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1311 && mode != DImode)
b6c9286a
MM
1312 return 1;
1313
a4f6c312 1314 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1315 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1316 return 0;
1317
5ae4759c 1318#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1319 /* Similarly if we are using -mrelocatable, consider all constants
1320 to be hard. */
5ae4759c
MM
1321 if (TARGET_RELOCATABLE)
1322 return 0;
1323#endif
1324
fcce224d
DE
1325 if (mode == TFmode)
1326 {
1327 long k[4];
1328 REAL_VALUE_TYPE rv;
1329
1330 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1331 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
1332
1333 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1334 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
1335 && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
1336 && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
1337 }
1338
1339 else if (mode == DFmode)
042259f2
DE
1340 {
1341 long k[2];
1342 REAL_VALUE_TYPE rv;
1343
1344 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1345 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1346
a65c591c
DE
1347 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1348 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1349 }
4e74d8ec
MM
1350
1351 else if (mode == SFmode)
042259f2
DE
1352 {
1353 long l;
1354 REAL_VALUE_TYPE rv;
1355
1356 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1357 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1358
4e74d8ec 1359 return num_insns_constant_wide (l) == 1;
042259f2 1360 }
4e74d8ec 1361
a260abc9 1362 else if (mode == DImode)
c81fc13e 1363 return ((TARGET_POWERPC64
a260abc9
DE
1364 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1365 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1366
a9098fd0
GK
1367 else if (mode == SImode)
1368 return 1;
4e74d8ec
MM
1369 else
1370 abort ();
9878760c 1371}
8f75773e 1372
69ef87e2
AH
1373/* Return 1 if the operand is a CONST_INT and can be put into a
1374 register with one instruction. */
1375
1376static int
1377easy_vector_constant (op)
1378 rtx op;
1379{
1380 rtx elt;
1381 int units, i;
1382
1383 if (GET_CODE (op) != CONST_VECTOR)
1384 return 0;
1385
1386 units = CONST_VECTOR_NUNITS (op);
1387
1388 /* We can generate 0 easily. Look for that. */
1389 for (i = 0; i < units; ++i)
1390 {
1391 elt = CONST_VECTOR_ELT (op, i);
1392
1393 /* We could probably simplify this by just checking for equality
1394 with CONST0_RTX for the current mode, but let's be safe
1395 instead. */
1396
98ef3137
JJ
1397 switch (GET_CODE (elt))
1398 {
1399 case CONST_INT:
1400 if (INTVAL (elt) != 0)
1401 return 0;
1402 break;
1403 case CONST_DOUBLE:
1404 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1405 return 0;
1406 break;
1407 default:
1408 return 0;
1409 }
69ef87e2
AH
1410 }
1411
1412 /* We could probably generate a few other constants trivially, but
1413 gcc doesn't generate them yet. FIXME later. */
98ef3137 1414 return 1;
69ef87e2
AH
1415}
1416
1417/* Return 1 if the operand is the constant 0. This works for scalars
1418 as well as vectors. */
1419int
1420zero_constant (op, mode)
1421 rtx op;
1422 enum machine_mode mode;
1423{
1424 return op == CONST0_RTX (mode);
1425}
1426
50a0b056
GK
1427/* Return 1 if the operand is 0.0. */
1428int
1429zero_fp_constant (op, mode)
592696dd
SS
1430 rtx op;
1431 enum machine_mode mode;
50a0b056
GK
1432{
1433 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1434}
1435
a4f6c312
SS
1436/* Return 1 if the operand is in volatile memory. Note that during
1437 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1438 volatile memory references. So this function allows us to
1439 recognize volatile references where its safe. */
1440
1441int
1442volatile_mem_operand (op, mode)
592696dd 1443 rtx op;
b6c9286a
MM
1444 enum machine_mode mode;
1445{
1446 if (GET_CODE (op) != MEM)
1447 return 0;
1448
1449 if (!MEM_VOLATILE_P (op))
1450 return 0;
1451
1452 if (mode != GET_MODE (op))
1453 return 0;
1454
1455 if (reload_completed)
1456 return memory_operand (op, mode);
1457
1458 if (reload_in_progress)
1459 return strict_memory_address_p (mode, XEXP (op, 0));
1460
1461 return memory_address_p (mode, XEXP (op, 0));
1462}
1463
97f6e72f 1464/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1465
1466int
97f6e72f 1467offsettable_mem_operand (op, mode)
592696dd 1468 rtx op;
914c2e77
RK
1469 enum machine_mode mode;
1470{
97f6e72f 1471 return ((GET_CODE (op) == MEM)
677a9668 1472 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1473 mode, XEXP (op, 0)));
914c2e77
RK
1474}
1475
9878760c
RK
1476/* Return 1 if the operand is either an easy FP constant (see above) or
1477 memory. */
1478
1479int
1480mem_or_easy_const_operand (op, mode)
592696dd 1481 rtx op;
9878760c
RK
1482 enum machine_mode mode;
1483{
1484 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1485}
1486
1487/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1488 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1489
1490int
1491add_operand (op, mode)
592696dd 1492 rtx op;
9878760c
RK
1493 enum machine_mode mode;
1494{
2bfcf297 1495 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1496 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1497 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1498
1499 return gpc_reg_operand (op, mode);
9878760c
RK
1500}
1501
dcfedcd0
RK
1502/* Return 1 if OP is a constant but not a valid add_operand. */
1503
1504int
1505non_add_cint_operand (op, mode)
592696dd 1506 rtx op;
296b8152 1507 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1508{
1509 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1510 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1511 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1512}
1513
9878760c
RK
1514/* Return 1 if the operand is a non-special register or a constant that
1515 can be used as the operand of an OR or XOR insn on the RS/6000. */
1516
1517int
1518logical_operand (op, mode)
592696dd 1519 rtx op;
9878760c
RK
1520 enum machine_mode mode;
1521{
40501e5f 1522 HOST_WIDE_INT opl, oph;
1d328b19 1523
dfbdccdb
GK
1524 if (gpc_reg_operand (op, mode))
1525 return 1;
1d328b19 1526
dfbdccdb 1527 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1528 {
1529 opl = INTVAL (op) & GET_MODE_MASK (mode);
1530
1531#if HOST_BITS_PER_WIDE_INT <= 32
1532 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1533 return 0;
1534#endif
1535 }
dfbdccdb
GK
1536 else if (GET_CODE (op) == CONST_DOUBLE)
1537 {
1d328b19 1538 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1539 abort ();
1d328b19
GK
1540
1541 opl = CONST_DOUBLE_LOW (op);
1542 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1543 if (oph != 0)
38886f37 1544 return 0;
dfbdccdb
GK
1545 }
1546 else
1547 return 0;
1d328b19 1548
40501e5f
AM
1549 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1550 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1551}
1552
dcfedcd0 1553/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1554 above), but could be split into one. */
dcfedcd0
RK
1555
1556int
1557non_logical_cint_operand (op, mode)
592696dd 1558 rtx op;
5f59ecb7 1559 enum machine_mode mode;
dcfedcd0 1560{
dfbdccdb 1561 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1562 && ! logical_operand (op, mode)
1563 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1564}
1565
19ba8161 1566/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1567 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1568 Reject all ones and all zeros, since these should have been optimized
1569 away and confuse the making of MB and ME. */
1570
1571int
19ba8161 1572mask_operand (op, mode)
592696dd 1573 rtx op;
19ba8161 1574 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1575{
02071907 1576 HOST_WIDE_INT c, lsb;
9878760c 1577
19ba8161
DE
1578 if (GET_CODE (op) != CONST_INT)
1579 return 0;
1580
1581 c = INTVAL (op);
1582
57deb3a1
AM
1583 /* Fail in 64-bit mode if the mask wraps around because the upper
1584 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1585 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1586 return 0;
1587
c5059423
AM
1588 /* We don't change the number of transitions by inverting,
1589 so make sure we start with the LS bit zero. */
1590 if (c & 1)
1591 c = ~c;
1592
1593 /* Reject all zeros or all ones. */
1594 if (c == 0)
9878760c
RK
1595 return 0;
1596
c5059423
AM
1597 /* Find the first transition. */
1598 lsb = c & -c;
1599
1600 /* Invert to look for a second transition. */
1601 c = ~c;
9878760c 1602
c5059423
AM
1603 /* Erase first transition. */
1604 c &= -lsb;
9878760c 1605
c5059423
AM
1606 /* Find the second transition (if any). */
1607 lsb = c & -c;
1608
1609 /* Match if all the bits above are 1's (or c is zero). */
1610 return c == -lsb;
9878760c
RK
1611}
1612
0ba1b2ff
AM
1613/* Return 1 for the PowerPC64 rlwinm corner case. */
1614
1615int
1616mask_operand_wrap (op, mode)
1617 rtx op;
1618 enum machine_mode mode ATTRIBUTE_UNUSED;
1619{
1620 HOST_WIDE_INT c, lsb;
1621
1622 if (GET_CODE (op) != CONST_INT)
1623 return 0;
1624
1625 c = INTVAL (op);
1626
1627 if ((c & 0x80000001) != 0x80000001)
1628 return 0;
1629
1630 c = ~c;
1631 if (c == 0)
1632 return 0;
1633
1634 lsb = c & -c;
1635 c = ~c;
1636 c &= -lsb;
1637 lsb = c & -c;
1638 return c == -lsb;
1639}
1640
a260abc9
DE
1641/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1642 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1643 Reject all zeros, since zero should have been optimized away and
1644 confuses the making of MB and ME. */
9878760c
RK
1645
1646int
a260abc9 1647mask64_operand (op, mode)
592696dd 1648 rtx op;
0ba1b2ff 1649 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1650{
1651 if (GET_CODE (op) == CONST_INT)
1652 {
02071907 1653 HOST_WIDE_INT c, lsb;
a260abc9 1654
c5059423 1655 c = INTVAL (op);
a260abc9 1656
0ba1b2ff 1657 /* Reject all zeros. */
c5059423 1658 if (c == 0)
e2c953b6
DE
1659 return 0;
1660
0ba1b2ff
AM
1661 /* We don't change the number of transitions by inverting,
1662 so make sure we start with the LS bit zero. */
1663 if (c & 1)
1664 c = ~c;
1665
c5059423
AM
1666 /* Find the transition, and check that all bits above are 1's. */
1667 lsb = c & -c;
1668 return c == -lsb;
e2c953b6 1669 }
0ba1b2ff
AM
1670 return 0;
1671}
1672
1673/* Like mask64_operand, but allow up to three transitions. This
1674 predicate is used by insn patterns that generate two rldicl or
1675 rldicr machine insns. */
1676
1677int
1678mask64_2_operand (op, mode)
1679 rtx op;
1680 enum machine_mode mode ATTRIBUTE_UNUSED;
1681{
1682 if (GET_CODE (op) == CONST_INT)
a260abc9 1683 {
0ba1b2ff 1684 HOST_WIDE_INT c, lsb;
a260abc9 1685
0ba1b2ff 1686 c = INTVAL (op);
a260abc9 1687
0ba1b2ff
AM
1688 /* Disallow all zeros. */
1689 if (c == 0)
1690 return 0;
a260abc9 1691
0ba1b2ff
AM
1692 /* We don't change the number of transitions by inverting,
1693 so make sure we start with the LS bit zero. */
1694 if (c & 1)
1695 c = ~c;
a260abc9 1696
0ba1b2ff
AM
1697 /* Find the first transition. */
1698 lsb = c & -c;
a260abc9 1699
0ba1b2ff
AM
1700 /* Invert to look for a second transition. */
1701 c = ~c;
1702
1703 /* Erase first transition. */
1704 c &= -lsb;
1705
1706 /* Find the second transition. */
1707 lsb = c & -c;
1708
1709 /* Invert to look for a third transition. */
1710 c = ~c;
1711
1712 /* Erase second transition. */
1713 c &= -lsb;
1714
1715 /* Find the third transition (if any). */
1716 lsb = c & -c;
1717
1718 /* Match if all the bits above are 1's (or c is zero). */
1719 return c == -lsb;
1720 }
1721 return 0;
1722}
1723
1724/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1725 implement ANDing by the mask IN. */
1726void
1727build_mask64_2_operands (in, out)
1728 rtx in;
1729 rtx *out;
1730{
1731#if HOST_BITS_PER_WIDE_INT >= 64
1732 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1733 int shift;
1734
1735 if (GET_CODE (in) != CONST_INT)
1736 abort ();
1737
1738 c = INTVAL (in);
1739 if (c & 1)
1740 {
1741 /* Assume c initially something like 0x00fff000000fffff. The idea
1742 is to rotate the word so that the middle ^^^^^^ group of zeros
1743 is at the MS end and can be cleared with an rldicl mask. We then
1744 rotate back and clear off the MS ^^ group of zeros with a
1745 second rldicl. */
1746 c = ~c; /* c == 0xff000ffffff00000 */
1747 lsb = c & -c; /* lsb == 0x0000000000100000 */
1748 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1749 c = ~c; /* c == 0x00fff000000fffff */
1750 c &= -lsb; /* c == 0x00fff00000000000 */
1751 lsb = c & -c; /* lsb == 0x0000100000000000 */
1752 c = ~c; /* c == 0xff000fffffffffff */
1753 c &= -lsb; /* c == 0xff00000000000000 */
1754 shift = 0;
1755 while ((lsb >>= 1) != 0)
1756 shift++; /* shift == 44 on exit from loop */
1757 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1758 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1759 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1760 }
1761 else
0ba1b2ff
AM
1762 {
1763 /* Assume c initially something like 0xff000f0000000000. The idea
1764 is to rotate the word so that the ^^^ middle group of zeros
1765 is at the LS end and can be cleared with an rldicr mask. We then
1766 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1767 a second rldicr. */
1768 lsb = c & -c; /* lsb == 0x0000010000000000 */
1769 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1770 c = ~c; /* c == 0x00fff0ffffffffff */
1771 c &= -lsb; /* c == 0x00fff00000000000 */
1772 lsb = c & -c; /* lsb == 0x0000100000000000 */
1773 c = ~c; /* c == 0xff000fffffffffff */
1774 c &= -lsb; /* c == 0xff00000000000000 */
1775 shift = 0;
1776 while ((lsb >>= 1) != 0)
1777 shift++; /* shift == 44 on exit from loop */
1778 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1779 m1 >>= shift; /* m1 == 0x0000000000000fff */
1780 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1781 }
1782
1783 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1784 masks will be all 1's. We are guaranteed more than one transition. */
1785 out[0] = GEN_INT (64 - shift);
1786 out[1] = GEN_INT (m1);
1787 out[2] = GEN_INT (shift);
1788 out[3] = GEN_INT (m2);
1789#else
045572c7
GK
1790 (void)in;
1791 (void)out;
0ba1b2ff
AM
1792 abort ();
1793#endif
a260abc9
DE
1794}
1795
1796/* Return 1 if the operand is either a non-special register or a constant
1797 that can be used as the operand of a PowerPC64 logical AND insn. */
1798
1799int
1800and64_operand (op, mode)
592696dd 1801 rtx op;
9878760c
RK
1802 enum machine_mode mode;
1803{
a4f6c312 1804 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1805 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1806
1807 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1808}
1809
0ba1b2ff
AM
1810/* Like the above, but also match constants that can be implemented
1811 with two rldicl or rldicr insns. */
1812
1813int
1814and64_2_operand (op, mode)
1815 rtx op;
1816 enum machine_mode mode;
1817{
1818 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1819 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1820
1821 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1822}
1823
a260abc9
DE
1824/* Return 1 if the operand is either a non-special register or a
1825 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1826
1827int
a260abc9 1828and_operand (op, mode)
592696dd 1829 rtx op;
a260abc9 1830 enum machine_mode mode;
dcfedcd0 1831{
a4f6c312 1832 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1833 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1834
1835 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1836}
1837
9878760c
RK
1838/* Return 1 if the operand is a general register or memory operand. */
1839
1840int
1841reg_or_mem_operand (op, mode)
592696dd
SS
1842 rtx op;
1843 enum machine_mode mode;
9878760c 1844{
b6c9286a
MM
1845 return (gpc_reg_operand (op, mode)
1846 || memory_operand (op, mode)
1847 || volatile_mem_operand (op, mode));
9878760c
RK
1848}
1849
a7a813f7 1850/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1851 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1852 instruction. */
1853
1854int
1855lwa_operand (op, mode)
592696dd
SS
1856 rtx op;
1857 enum machine_mode mode;
a7a813f7
RK
1858{
1859 rtx inner = op;
1860
1861 if (reload_completed && GET_CODE (inner) == SUBREG)
1862 inner = SUBREG_REG (inner);
1863
1864 return gpc_reg_operand (inner, mode)
1865 || (memory_operand (inner, mode)
1866 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1867 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1868 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1869 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1870 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1871}
1872
cc4d5fec
JH
1873/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1874
1875int
1876symbol_ref_operand (op, mode)
1877 rtx op;
1878 enum machine_mode mode;
1879{
1880 if (mode != VOIDmode && GET_MODE (op) != mode)
1881 return 0;
1882
1883 return (GET_CODE (op) == SYMBOL_REF);
1884}
1885
9878760c 1886/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1887 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1888
1889int
1890call_operand (op, mode)
592696dd 1891 rtx op;
9878760c
RK
1892 enum machine_mode mode;
1893{
1894 if (mode != VOIDmode && GET_MODE (op) != mode)
1895 return 0;
1896
1897 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1898 || (GET_CODE (op) == REG
1899 && (REGNO (op) == LINK_REGISTER_REGNUM
1900 || REGNO (op) == COUNT_REGISTER_REGNUM
1901 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1902}
1903
2af3d377 1904/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1905 this file and the function is not weakly defined. */
2af3d377
RK
1906
1907int
1908current_file_function_operand (op, mode)
592696dd 1909 rtx op;
296b8152 1910 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1911{
1912 return (GET_CODE (op) == SYMBOL_REF
1913 && (SYMBOL_REF_FLAG (op)
8f1b829e 1914 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1915 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1916}
1917
9878760c
RK
1918/* Return 1 if this operand is a valid input for a move insn. */
1919
1920int
1921input_operand (op, mode)
592696dd 1922 rtx op;
9878760c
RK
1923 enum machine_mode mode;
1924{
eb4e8003 1925 /* Memory is always valid. */
9878760c
RK
1926 if (memory_operand (op, mode))
1927 return 1;
1928
34792e82 1929 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1930 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1931 return 1;
1932
eb4e8003
RK
1933 /* For floating-point, easy constants are valid. */
1934 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1935 && CONSTANT_P (op)
1936 && easy_fp_constant (op, mode))
1937 return 1;
1938
4e74d8ec
MM
1939 /* Allow any integer constant. */
1940 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1941 && (GET_CODE (op) == CONST_INT
e675f625 1942 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1943 return 1;
1944
eb4e8003
RK
1945 /* For floating-point or multi-word mode, the only remaining valid type
1946 is a register. */
9878760c
RK
1947 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1948 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1949 return register_operand (op, mode);
9878760c 1950
88fe15a1
RK
1951 /* The only cases left are integral modes one word or smaller (we
1952 do not get called for MODE_CC values). These can be in any
1953 register. */
1954 if (register_operand (op, mode))
a8b3aeda 1955 return 1;
88fe15a1 1956
84cf9dda 1957 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 1958 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
1959 return 1;
1960
9ebbca7d
GK
1961 /* A constant pool expression (relative to the TOC) is valid */
1962 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
1963 return 1;
1964
88228c4b
MM
1965 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
1966 to be valid. */
f607bc57 1967 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
1968 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
1969 && small_data_operand (op, Pmode))
1970 return 1;
1971
042259f2 1972 return 0;
9878760c 1973}
7509c759 1974
a4f6c312 1975/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
1976
1977int
1978small_data_operand (op, mode)
296b8152
KG
1979 rtx op ATTRIBUTE_UNUSED;
1980 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 1981{
38c1f2d7 1982#if TARGET_ELF
5f59ecb7 1983 rtx sym_ref;
7509c759 1984
d9407988 1985 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 1986 return 0;
a54d04b7 1987
f607bc57 1988 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
1989 return 0;
1990
88228c4b
MM
1991 if (GET_CODE (op) == SYMBOL_REF)
1992 sym_ref = op;
1993
1994 else if (GET_CODE (op) != CONST
1995 || GET_CODE (XEXP (op, 0)) != PLUS
1996 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
1997 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
1998 return 0;
1999
88228c4b 2000 else
dbf55e53
MM
2001 {
2002 rtx sum = XEXP (op, 0);
2003 HOST_WIDE_INT summand;
2004
2005 /* We have to be careful here, because it is the referenced address
2006 that must be 32k from _SDA_BASE_, not just the symbol. */
2007 summand = INTVAL (XEXP (sum, 1));
2008 if (summand < 0 || summand > g_switch_value)
2009 return 0;
2010
2011 sym_ref = XEXP (sum, 0);
2012 }
88228c4b
MM
2013
2014 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
2015 return 0;
2016
2017 return 1;
d9407988
MM
2018
2019#else
2020 return 0;
2021#endif
7509c759 2022}
9ebbca7d
GK
2023\f
2024static int
2025constant_pool_expr_1 (op, have_sym, have_toc)
2026 rtx op;
2027 int *have_sym;
2028 int *have_toc;
2029{
2030 switch (GET_CODE(op))
2031 {
2032 case SYMBOL_REF:
a4f6c312
SS
2033 if (CONSTANT_POOL_ADDRESS_P (op))
2034 {
2035 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2036 {
2037 *have_sym = 1;
2038 return 1;
2039 }
2040 else
2041 return 0;
2042 }
2043 else if (! strcmp (XSTR (op, 0), toc_label_name))
2044 {
2045 *have_toc = 1;
2046 return 1;
2047 }
2048 else
2049 return 0;
9ebbca7d
GK
2050 case PLUS:
2051 case MINUS:
c1f11548
DE
2052 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2053 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2054 case CONST:
a4f6c312 2055 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2056 case CONST_INT:
a4f6c312 2057 return 1;
9ebbca7d 2058 default:
a4f6c312 2059 return 0;
9ebbca7d
GK
2060 }
2061}
2062
2063int
2064constant_pool_expr_p (op)
2065 rtx op;
2066{
2067 int have_sym = 0;
2068 int have_toc = 0;
2069 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2070}
2071
2072int
2073toc_relative_expr_p (op)
2074 rtx op;
2075{
2076 int have_sym = 0;
2077 int have_toc = 0;
2078 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2079}
2080
2081/* Try machine-dependent ways of modifying an illegitimate address
2082 to be legitimate. If we find one, return the new, valid address.
2083 This is used from only one place: `memory_address' in explow.c.
2084
a4f6c312
SS
2085 OLDX is the address as it was before break_out_memory_refs was
2086 called. In some cases it is useful to look at this to decide what
2087 needs to be done.
9ebbca7d 2088
a4f6c312 2089 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2090
a4f6c312
SS
2091 It is always safe for this function to do nothing. It exists to
2092 recognize opportunities to optimize the output.
9ebbca7d
GK
2093
2094 On RS/6000, first check for the sum of a register with a constant
2095 integer that is out of range. If so, generate code to add the
2096 constant with the low-order 16 bits masked to the register and force
2097 this result into another register (this can be done with `cau').
2098 Then generate an address of REG+(CONST&0xffff), allowing for the
2099 possibility of bit 16 being a one.
2100
2101 Then check for the sum of a register and something not constant, try to
2102 load the other things into a register and return the sum. */
2103rtx
2104rs6000_legitimize_address (x, oldx, mode)
2105 rtx x;
2106 rtx oldx ATTRIBUTE_UNUSED;
2107 enum machine_mode mode;
0ac081f6 2108{
9ebbca7d
GK
2109 if (GET_CODE (x) == PLUS
2110 && GET_CODE (XEXP (x, 0)) == REG
2111 && GET_CODE (XEXP (x, 1)) == CONST_INT
2112 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2113 {
2114 HOST_WIDE_INT high_int, low_int;
2115 rtx sum;
a65c591c
DE
2116 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2117 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2118 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2119 GEN_INT (high_int)), 0);
2120 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2121 }
2122 else if (GET_CODE (x) == PLUS
2123 && GET_CODE (XEXP (x, 0)) == REG
2124 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2125 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2126 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2127 || TARGET_POWERPC64
fcce224d 2128 || (mode != DFmode && mode != TFmode))
9ebbca7d
GK
2129 && (TARGET_POWERPC64 || mode != DImode)
2130 && mode != TImode)
2131 {
2132 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2133 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2134 }
0ac081f6
AH
2135 else if (ALTIVEC_VECTOR_MODE (mode))
2136 {
2137 rtx reg;
2138
2139 /* Make sure both operands are registers. */
2140 if (GET_CODE (x) == PLUS)
9f85ed45 2141 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2142 force_reg (Pmode, XEXP (x, 1)));
2143
2144 reg = force_reg (Pmode, x);
2145 return reg;
2146 }
a3170dc6
AH
2147 else if (SPE_VECTOR_MODE (mode))
2148 {
2149 /* We accept [reg + reg] and [reg + OFFSET]. */
2150
2151 if (GET_CODE (x) == PLUS)
2152 {
2153 rtx op1 = XEXP (x, 0);
2154 rtx op2 = XEXP (x, 1);
2155
2156 op1 = force_reg (Pmode, op1);
2157
2158 if (GET_CODE (op2) != REG
2159 && (GET_CODE (op2) != CONST_INT
2160 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2161 op2 = force_reg (Pmode, op2);
2162
2163 return gen_rtx_PLUS (Pmode, op1, op2);
2164 }
2165
2166 return force_reg (Pmode, x);
2167 }
9ebbca7d
GK
2168 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2169 && GET_CODE (x) != CONST_INT
2170 && GET_CODE (x) != CONST_DOUBLE
2171 && CONSTANT_P (x)
6ac7bf2c
GK
2172 && GET_MODE_NUNITS (mode) == 1
2173 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2174 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2175 {
2176 rtx reg = gen_reg_rtx (Pmode);
2177 emit_insn (gen_elf_high (reg, (x)));
2178 return gen_rtx_LO_SUM (Pmode, reg, (x));
2179 }
ee890fe2
SS
2180 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2181 && ! flag_pic
2182 && GET_CODE (x) != CONST_INT
2183 && GET_CODE (x) != CONST_DOUBLE
2184 && CONSTANT_P (x)
a3170dc6 2185 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2186 && mode != DImode
2187 && mode != TImode)
2188 {
2189 rtx reg = gen_reg_rtx (Pmode);
2190 emit_insn (gen_macho_high (reg, (x)));
2191 return gen_rtx_LO_SUM (Pmode, reg, (x));
2192 }
9ebbca7d
GK
2193 else if (TARGET_TOC
2194 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2195 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2196 {
2197 return create_TOC_reference (x);
2198 }
2199 else
2200 return NULL_RTX;
2201}
258bfae2 2202
24ea750e
DJ
2203/* The convention appears to be to define this wherever it is used.
2204 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2205 is now used here. */
2206#ifndef REG_MODE_OK_FOR_BASE_P
2207#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2208#endif
2209
2210/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2211 replace the input X, or the original X if no replacement is called for.
2212 The output parameter *WIN is 1 if the calling macro should goto WIN,
2213 0 if it should not.
2214
2215 For RS/6000, we wish to handle large displacements off a base
2216 register by splitting the addend across an addiu/addis and the mem insn.
2217 This cuts number of extra insns needed from 3 to 1.
2218
2219 On Darwin, we use this to generate code for floating point constants.
2220 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2221 The Darwin code is inside #if TARGET_MACHO because only then is
2222 machopic_function_base_name() defined. */
2223rtx
2224rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2225 rtx x;
2226 enum machine_mode mode;
2227 int opnum;
2228 int type;
2229 int ind_levels ATTRIBUTE_UNUSED;
2230 int *win;
2231{
2232 /* We must recognize output that we have already generated ourselves. */
2233 if (GET_CODE (x) == PLUS
2234 && GET_CODE (XEXP (x, 0)) == PLUS
2235 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2236 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2237 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2238 {
2239 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2240 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2241 opnum, (enum reload_type)type);
2242 *win = 1;
2243 return x;
2244 }
3deb2758 2245
24ea750e
DJ
2246#if TARGET_MACHO
2247 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2248 && GET_CODE (x) == LO_SUM
2249 && GET_CODE (XEXP (x, 0)) == PLUS
2250 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2251 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2252 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2253 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2254 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2255 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2256 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2257 {
2258 /* Result of previous invocation of this function on Darwin
6f317ef3 2259 floating point constant. */
24ea750e
DJ
2260 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2261 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2262 opnum, (enum reload_type)type);
2263 *win = 1;
2264 return x;
2265 }
2266#endif
2267 if (GET_CODE (x) == PLUS
2268 && GET_CODE (XEXP (x, 0)) == REG
2269 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2270 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2271 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 2272 && !SPE_VECTOR_MODE (mode)
78c875e8 2273 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2274 {
2275 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2276 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2277 HOST_WIDE_INT high
2278 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2279
2280 /* Check for 32-bit overflow. */
2281 if (high + low != val)
2282 {
2283 *win = 0;
2284 return x;
2285 }
2286
2287 /* Reload the high part into a base reg; leave the low part
2288 in the mem directly. */
2289
2290 x = gen_rtx_PLUS (GET_MODE (x),
2291 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2292 GEN_INT (high)),
2293 GEN_INT (low));
2294
2295 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2296 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2297 opnum, (enum reload_type)type);
2298 *win = 1;
2299 return x;
2300 }
2301#if TARGET_MACHO
2302 if (GET_CODE (x) == SYMBOL_REF
2303 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2304 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2305 && flag_pic)
2306 {
2307 /* Darwin load of floating point constant. */
2308 rtx offset = gen_rtx (CONST, Pmode,
2309 gen_rtx (MINUS, Pmode, x,
2310 gen_rtx (SYMBOL_REF, Pmode,
2311 machopic_function_base_name ())));
2312 x = gen_rtx (LO_SUM, GET_MODE (x),
2313 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2314 gen_rtx (HIGH, Pmode, offset)), offset);
2315 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2316 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2317 opnum, (enum reload_type)type);
2318 *win = 1;
2319 return x;
2320 }
2321#endif
2322 if (TARGET_TOC
c1f11548
DE
2323 && CONSTANT_POOL_EXPR_P (x)
2324 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2325 {
2326 (x) = create_TOC_reference (x);
2327 *win = 1;
2328 return x;
2329 }
2330 *win = 0;
2331 return x;
2332}
2333
258bfae2
FS
2334/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2335 that is a valid memory address for an instruction.
2336 The MODE argument is the machine mode for the MEM expression
2337 that wants to use this address.
2338
2339 On the RS/6000, there are four valid address: a SYMBOL_REF that
2340 refers to a constant pool entry of an address (or the sum of it
2341 plus a constant), a short (16-bit signed) constant plus a register,
2342 the sum of two registers, or a register indirect, possibly with an
2343 auto-increment. For DFmode and DImode with an constant plus register,
2344 we must ensure that both words are addressable or PowerPC64 with offset
2345 word aligned.
2346
2347 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2348 32-bit DImode, TImode), indexed addressing cannot be used because
2349 adjacent memory cells are accessed by adding word-sized offsets
2350 during assembly output. */
2351int
2352rs6000_legitimate_address (mode, x, reg_ok_strict)
2353 enum machine_mode mode;
2354 rtx x;
2355 int reg_ok_strict;
2356{
2357 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2358 return 1;
2359 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2360 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2361 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2362 && TARGET_UPDATE
2363 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2364 return 1;
2365 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2366 return 1;
2367 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2368 return 1;
2369 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2370 if (! reg_ok_strict
2371 && GET_CODE (x) == PLUS
2372 && GET_CODE (XEXP (x, 0)) == REG
2373 && XEXP (x, 0) == virtual_stack_vars_rtx
2374 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2375 return 1;
2376 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2377 return 1;
2378 if (mode != TImode
a3170dc6
AH
2379 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2380 || TARGET_POWERPC64
fcce224d 2381 || (mode != DFmode && mode != TFmode))
258bfae2
FS
2382 && (TARGET_POWERPC64 || mode != DImode)
2383 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2384 return 1;
2385 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2386 return 1;
2387 return 0;
2388}
fb4d4348 2389\f
a4f6c312
SS
2390/* Try to output insns to set TARGET equal to the constant C if it can
2391 be done in less than N insns. Do all computations in MODE.
2392 Returns the place where the output has been placed if it can be
2393 done and the insns have been emitted. If it would take more than N
2394 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2395
2396rtx
2397rs6000_emit_set_const (dest, mode, source, n)
2398 rtx dest, source;
2399 enum machine_mode mode;
2400 int n ATTRIBUTE_UNUSED;
2401{
af8cb5c5 2402 rtx result, insn, set;
2bfcf297
DB
2403 HOST_WIDE_INT c0, c1;
2404
af8cb5c5 2405 if (mode == QImode || mode == HImode)
2bfcf297
DB
2406 {
2407 if (dest == NULL)
2408 dest = gen_reg_rtx (mode);
2409 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2410 return dest;
2411 }
af8cb5c5 2412 else if (mode == SImode)
2bfcf297 2413 {
af8cb5c5
DE
2414 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2415
2416 emit_insn (gen_rtx_SET (VOIDmode, result,
2417 GEN_INT (INTVAL (source)
2418 & (~ (HOST_WIDE_INT) 0xffff))));
2419 emit_insn (gen_rtx_SET (VOIDmode, dest,
2420 gen_rtx_IOR (SImode, result,
2421 GEN_INT (INTVAL (source) & 0xffff))));
2422 result = dest;
2bfcf297 2423 }
af8cb5c5 2424 else if (mode == DImode)
2bfcf297 2425 {
af8cb5c5
DE
2426 if (GET_CODE (source) == CONST_INT)
2427 {
2428 c0 = INTVAL (source);
2429 c1 = -(c0 < 0);
2430 }
2431 else if (GET_CODE (source) == CONST_DOUBLE)
2432 {
2bfcf297 2433#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
2434 c0 = CONST_DOUBLE_LOW (source);
2435 c1 = -(c0 < 0);
2bfcf297 2436#else
af8cb5c5
DE
2437 c0 = CONST_DOUBLE_LOW (source);
2438 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 2439#endif
af8cb5c5
DE
2440 }
2441 else
2442 abort ();
2443
2444 result = rs6000_emit_set_long_const (dest, c0, c1);
2bfcf297
DB
2445 }
2446 else
a4f6c312 2447 abort ();
2bfcf297 2448
af8cb5c5
DE
2449 insn = get_last_insn ();
2450 set = single_set (insn);
2451 if (! CONSTANT_P (SET_SRC (set)))
2452 set_unique_reg_note (insn, REG_EQUAL, source);
2453
2454 return result;
2bfcf297
DB
2455}
2456
2457/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2458 fall back to a straight forward decomposition. We do this to avoid
2459 exponential run times encountered when looking for longer sequences
2460 with rs6000_emit_set_const. */
2461static rtx
2462rs6000_emit_set_long_const (dest, c1, c2)
2463 rtx dest;
2464 HOST_WIDE_INT c1, c2;
2465{
2466 if (!TARGET_POWERPC64)
2467 {
2468 rtx operand1, operand2;
2469
2470 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2471 DImode);
2472 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2473 DImode);
2474 emit_move_insn (operand1, GEN_INT (c1));
2475 emit_move_insn (operand2, GEN_INT (c2));
2476 }
2477 else
2478 {
bc06712d 2479 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2480
bc06712d
TR
2481 ud1 = c1 & 0xffff;
2482 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2483#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2484 c2 = c1 >> 32;
2bfcf297 2485#endif
bc06712d
TR
2486 ud3 = c2 & 0xffff;
2487 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2488
bc06712d
TR
2489 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2490 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2491 {
bc06712d
TR
2492 if (ud1 & 0x8000)
2493 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2494 else
2495 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2496 }
2bfcf297 2497
bc06712d
TR
2498 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2499 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2500 {
bc06712d
TR
2501 if (ud2 & 0x8000)
2502 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2503 - 0x80000000));
252b88f7 2504 else
bc06712d
TR
2505 emit_move_insn (dest, GEN_INT (ud2 << 16));
2506 if (ud1 != 0)
2507 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2508 }
bc06712d
TR
2509 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2510 || (ud4 == 0 && ! (ud3 & 0x8000)))
2511 {
2512 if (ud3 & 0x8000)
2513 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2514 - 0x80000000));
2515 else
2516 emit_move_insn (dest, GEN_INT (ud3 << 16));
2517
2518 if (ud2 != 0)
2519 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2520 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2521 if (ud1 != 0)
2522 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2523 }
2524 else
2525 {
2526 if (ud4 & 0x8000)
2527 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2528 - 0x80000000));
2529 else
2530 emit_move_insn (dest, GEN_INT (ud4 << 16));
2531
2532 if (ud3 != 0)
2533 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2534
bc06712d
TR
2535 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2536 if (ud2 != 0)
2537 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2538 GEN_INT (ud2 << 16)));
2539 if (ud1 != 0)
2540 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2541 }
2542 }
2bfcf297
DB
2543 return dest;
2544}
2545
fb4d4348
GK
2546/* Emit a move from SOURCE to DEST in mode MODE. */
2547void
2548rs6000_emit_move (dest, source, mode)
2549 rtx dest;
2550 rtx source;
2551 enum machine_mode mode;
2552{
2553 rtx operands[2];
2554 operands[0] = dest;
2555 operands[1] = source;
2556
2557 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2558 if (GET_CODE (operands[1]) == CONST_DOUBLE
2559 && ! FLOAT_MODE_P (mode)
2560 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2561 {
2562 /* FIXME. This should never happen. */
2563 /* Since it seems that it does, do the safe thing and convert
2564 to a CONST_INT. */
2496c7bd 2565 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2566 }
2567 if (GET_CODE (operands[1]) == CONST_DOUBLE
2568 && ! FLOAT_MODE_P (mode)
2569 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2570 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2571 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2572 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2573 abort ();
c9e8cb32
DD
2574
2575 /* Check if GCC is setting up a block move that will end up using FP
2576 registers as temporaries. We must make sure this is acceptable. */
2577 if (GET_CODE (operands[0]) == MEM
2578 && GET_CODE (operands[1]) == MEM
2579 && mode == DImode
41543739
GK
2580 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2581 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2582 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2583 ? 32 : MEM_ALIGN (operands[0])))
2584 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2585 ? 32
2586 : MEM_ALIGN (operands[1]))))
2587 && ! MEM_VOLATILE_P (operands [0])
2588 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2589 {
41543739
GK
2590 emit_move_insn (adjust_address (operands[0], SImode, 0),
2591 adjust_address (operands[1], SImode, 0));
2592 emit_move_insn (adjust_address (operands[0], SImode, 4),
2593 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2594 return;
2595 }
fb4d4348 2596
67cef334
DE
2597 if (!no_new_pseudos)
2598 {
2599 if (GET_CODE (operands[1]) == MEM && optimize > 0
2600 && (mode == QImode || mode == HImode || mode == SImode)
2601 && GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
2602 {
2603 rtx reg = gen_reg_rtx (word_mode);
2604
2605 emit_insn (gen_rtx_SET (word_mode, reg,
2606 gen_rtx_ZERO_EXTEND (word_mode,
2607 operands[1])));
2608 operands[1] = gen_lowpart (mode, reg);
2609 }
2610 if (GET_CODE (operands[0]) != REG)
2611 operands[1] = force_reg (mode, operands[1]);
2612 }
a9098fd0 2613
a3170dc6
AH
2614 if (mode == SFmode && ! TARGET_POWERPC
2615 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2616 && GET_CODE (operands[0]) == MEM)
fb4d4348 2617 {
ffc14f31
GK
2618 int regnum;
2619
2620 if (reload_in_progress || reload_completed)
2621 regnum = true_regnum (operands[1]);
2622 else if (GET_CODE (operands[1]) == REG)
2623 regnum = REGNO (operands[1]);
2624 else
2625 regnum = -1;
fb4d4348
GK
2626
2627 /* If operands[1] is a register, on POWER it may have
2628 double-precision data in it, so truncate it to single
2629 precision. */
2630 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2631 {
2632 rtx newreg;
2633 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2634 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2635 operands[1] = newreg;
2636 }
2637 }
2638
a9098fd0
GK
2639 /* Handle the case where reload calls us with an invalid address;
2640 and the case of CONSTANT_P_RTX. */
16861f33 2641 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2642 && (! general_operand (operands[1], mode)
2643 || ! nonimmediate_operand (operands[0], mode)
2644 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2645 {
2646 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2647 return;
2648 }
a9098fd0 2649
fb4d4348
GK
2650 /* FIXME: In the long term, this switch statement should go away
2651 and be replaced by a sequence of tests based on things like
2652 mode == Pmode. */
2653 switch (mode)
2654 {
2655 case HImode:
2656 case QImode:
2657 if (CONSTANT_P (operands[1])
2658 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2659 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2660 break;
2661
06f4e019 2662 case TFmode:
fb4d4348
GK
2663 case DFmode:
2664 case SFmode:
2665 if (CONSTANT_P (operands[1])
2666 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2667 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2668 break;
2669
0ac081f6
AH
2670 case V16QImode:
2671 case V8HImode:
2672 case V4SFmode:
2673 case V4SImode:
a3170dc6
AH
2674 case V4HImode:
2675 case V2SFmode:
2676 case V2SImode:
00a892b8 2677 case V1DImode:
69ef87e2
AH
2678 if (CONSTANT_P (operands[1])
2679 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2680 operands[1] = force_const_mem (mode, operands[1]);
2681 break;
2682
fb4d4348 2683 case SImode:
a9098fd0 2684 case DImode:
fb4d4348
GK
2685 /* Use default pattern for address of ELF small data */
2686 if (TARGET_ELF
a9098fd0 2687 && mode == Pmode
f607bc57 2688 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2689 && (GET_CODE (operands[1]) == SYMBOL_REF
2690 || GET_CODE (operands[1]) == CONST)
2691 && small_data_operand (operands[1], mode))
fb4d4348
GK
2692 {
2693 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2694 return;
2695 }
2696
f607bc57 2697 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2698 && mode == Pmode && mode == SImode
2699 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2700 {
2701 emit_insn (gen_movsi_got (operands[0], operands[1]));
2702 return;
2703 }
2704
ee890fe2
SS
2705 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2706 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2707 && mode == Pmode
fb4d4348
GK
2708 && CONSTANT_P (operands[1])
2709 && GET_CODE (operands[1]) != HIGH
2710 && GET_CODE (operands[1]) != CONST_INT)
2711 {
a9098fd0 2712 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2713
2714 /* If this is a function address on -mcall-aixdesc,
2715 convert it to the address of the descriptor. */
2716 if (DEFAULT_ABI == ABI_AIX
2717 && GET_CODE (operands[1]) == SYMBOL_REF
2718 && XSTR (operands[1], 0)[0] == '.')
2719 {
2720 const char *name = XSTR (operands[1], 0);
2721 rtx new_ref;
2722 while (*name == '.')
2723 name++;
2724 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2725 CONSTANT_POOL_ADDRESS_P (new_ref)
2726 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2727 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2728 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2729 operands[1] = new_ref;
2730 }
7509c759 2731
ee890fe2
SS
2732 if (DEFAULT_ABI == ABI_DARWIN)
2733 {
2734 emit_insn (gen_macho_high (target, operands[1]));
2735 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2736 return;
2737 }
2738
fb4d4348
GK
2739 emit_insn (gen_elf_high (target, operands[1]));
2740 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2741 return;
2742 }
2743
a9098fd0
GK
2744 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2745 and we have put it in the TOC, we just need to make a TOC-relative
2746 reference to it. */
2747 if (TARGET_TOC
2748 && GET_CODE (operands[1]) == SYMBOL_REF
2749 && CONSTANT_POOL_EXPR_P (operands[1])
2750 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2751 get_pool_mode (operands[1])))
fb4d4348 2752 {
a9098fd0 2753 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2754 }
a9098fd0
GK
2755 else if (mode == Pmode
2756 && CONSTANT_P (operands[1])
38886f37
AO
2757 && ((GET_CODE (operands[1]) != CONST_INT
2758 && ! easy_fp_constant (operands[1], mode))
2759 || (GET_CODE (operands[1]) == CONST_INT
2760 && num_insns_constant (operands[1], mode) > 2)
2761 || (GET_CODE (operands[0]) == REG
2762 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2763 && GET_CODE (operands[1]) != HIGH
2764 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2765 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2766 {
2767 /* Emit a USE operation so that the constant isn't deleted if
2768 expensive optimizations are turned on because nobody
2769 references it. This should only be done for operands that
2770 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2771 This should not be done for operands that contain LABEL_REFs.
2772 For now, we just handle the obvious case. */
2773 if (GET_CODE (operands[1]) != LABEL_REF)
2774 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2775
c859cda6 2776#if TARGET_MACHO
ee890fe2
SS
2777 /* Darwin uses a special PIC legitimizer. */
2778 if (DEFAULT_ABI == ABI_DARWIN && flag_pic)
2779 {
ee890fe2
SS
2780 operands[1] =
2781 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2782 operands[0]);
2783 if (operands[0] != operands[1])
2784 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2785 return;
2786 }
c859cda6 2787#endif
ee890fe2 2788
fb4d4348
GK
2789 /* If we are to limit the number of things we put in the TOC and
2790 this is a symbol plus a constant we can add in one insn,
2791 just put the symbol in the TOC and add the constant. Don't do
2792 this if reload is in progress. */
2793 if (GET_CODE (operands[1]) == CONST
2794 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2795 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2796 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2797 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2798 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2799 && ! side_effects_p (operands[0]))
2800 {
a4f6c312
SS
2801 rtx sym =
2802 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2803 rtx other = XEXP (XEXP (operands[1], 0), 1);
2804
a9098fd0
GK
2805 sym = force_reg (mode, sym);
2806 if (mode == SImode)
2807 emit_insn (gen_addsi3 (operands[0], sym, other));
2808 else
2809 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2810 return;
2811 }
2812
a9098fd0 2813 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2814
2815 if (TARGET_TOC
d34c5b80
DE
2816 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2817 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2818 get_pool_constant (XEXP (operands[1], 0)),
2819 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2820 {
ba4828e0
RK
2821 operands[1]
2822 = gen_rtx_MEM (mode,
2823 create_TOC_reference (XEXP (operands[1], 0)));
2824 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2825 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2826 }
fb4d4348
GK
2827 }
2828 break;
a9098fd0 2829
fb4d4348
GK
2830 case TImode:
2831 if (GET_CODE (operands[0]) == MEM
2832 && GET_CODE (XEXP (operands[0], 0)) != REG
2833 && ! reload_in_progress)
792760b9
RK
2834 operands[0]
2835 = replace_equiv_address (operands[0],
2836 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2837
2838 if (GET_CODE (operands[1]) == MEM
2839 && GET_CODE (XEXP (operands[1], 0)) != REG
2840 && ! reload_in_progress)
792760b9
RK
2841 operands[1]
2842 = replace_equiv_address (operands[1],
2843 copy_addr_to_reg (XEXP (operands[1], 0)));
fb4d4348
GK
2844 break;
2845
2846 default:
2847 abort ();
2848 }
2849
a9098fd0
GK
2850 /* Above, we may have called force_const_mem which may have returned
2851 an invalid address. If we can, fix this up; otherwise, reload will
2852 have to deal with it. */
2853 if (GET_CODE (operands[1]) == MEM
2854 && ! memory_address_p (mode, XEXP (operands[1], 0))
2855 && ! reload_in_progress)
f4ef873c 2856 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2857
fb4d4348 2858 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2859 return;
fb4d4348 2860}
4697a36c
MM
2861\f
2862/* Initialize a variable CUM of type CUMULATIVE_ARGS
2863 for a call to a function whose data type is FNTYPE.
2864 For a library call, FNTYPE is 0.
2865
2866 For incoming args we set the number of arguments in the prototype large
1c20ae99 2867 so we never return a PARALLEL. */
4697a36c
MM
2868
2869void
2870init_cumulative_args (cum, fntype, libname, incoming)
2871 CUMULATIVE_ARGS *cum;
2872 tree fntype;
296b8152 2873 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2874 int incoming;
2875{
2876 static CUMULATIVE_ARGS zero_cumulative;
2877
2878 *cum = zero_cumulative;
2879 cum->words = 0;
2880 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2881 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2882 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2883 cum->call_cookie = CALL_NORMAL;
4cc833b7 2884 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2885
2886 if (incoming)
bd227acc 2887 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2888
2889 else if (cum->prototype)
2890 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2891 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2892 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2893
2894 else
2895 cum->nargs_prototype = 0;
2896
2897 cum->orig_nargs = cum->nargs_prototype;
7509c759 2898
a5c76ee6
ZW
2899 /* Check for a longcall attribute. */
2900 if (fntype
2901 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2902 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2903 cum->call_cookie = CALL_LONG;
2904
4697a36c
MM
2905 if (TARGET_DEBUG_ARG)
2906 {
2907 fprintf (stderr, "\ninit_cumulative_args:");
2908 if (fntype)
2909 {
2910 tree ret_type = TREE_TYPE (fntype);
2911 fprintf (stderr, " ret code = %s,",
2912 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2913 }
2914
6a4cee5f
MM
2915 if (cum->call_cookie & CALL_LONG)
2916 fprintf (stderr, " longcall,");
2917
4697a36c
MM
2918 fprintf (stderr, " proto = %d, nargs = %d\n",
2919 cum->prototype, cum->nargs_prototype);
2920 }
2921}
2922\f
c229cba9
DE
2923/* If defined, a C expression which determines whether, and in which
2924 direction, to pad out an argument with extra space. The value
2925 should be of type `enum direction': either `upward' to pad above
2926 the argument, `downward' to pad below, or `none' to inhibit
2927 padding.
2928
2929 For the AIX ABI structs are always stored left shifted in their
2930 argument slot. */
2931
9ebbca7d 2932enum direction
c229cba9
DE
2933function_arg_padding (mode, type)
2934 enum machine_mode mode;
2935 tree type;
2936{
c85f7c16 2937 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 2938 return upward;
c229cba9
DE
2939
2940 /* This is the default definition. */
2941 return (! BYTES_BIG_ENDIAN
9ebbca7d 2942 ? upward
c229cba9
DE
2943 : ((mode == BLKmode
2944 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
2945 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
2946 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 2947 ? downward : upward));
c229cba9
DE
2948}
2949
b6c9286a
MM
2950/* If defined, a C expression that gives the alignment boundary, in bits,
2951 of an argument with the specified mode and type. If it is not defined,
2952 PARM_BOUNDARY is used for all arguments.
2953
2310f99a 2954 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
2955
2956int
2957function_arg_boundary (mode, type)
2958 enum machine_mode mode;
9ebbca7d 2959 tree type ATTRIBUTE_UNUSED;
b6c9286a 2960{
f607bc57 2961 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 2962 return 64;
a3170dc6
AH
2963 else if (SPE_VECTOR_MODE (mode))
2964 return 64;
0ac081f6
AH
2965 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2966 return 128;
9ebbca7d 2967 else
b6c9286a 2968 return PARM_BOUNDARY;
b6c9286a
MM
2969}
2970\f
4697a36c
MM
2971/* Update the data in CUM to advance over an argument
2972 of mode MODE and data type TYPE.
2973 (TYPE is null for libcalls where that information may not be available.) */
2974
2975void
2976function_arg_advance (cum, mode, type, named)
2977 CUMULATIVE_ARGS *cum;
2978 enum machine_mode mode;
2979 tree type;
2980 int named;
2981{
2982 cum->nargs_prototype--;
2983
0ac081f6
AH
2984 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
2985 {
2986 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
2987 cum->vregno++;
2988 else
2989 cum->words += RS6000_ARG_SIZE (mode, type);
2990 }
a4b0320c
AH
2991 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
2992 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
2993 cum->sysv_gregno++;
f607bc57 2994 else if (DEFAULT_ABI == ABI_V4)
4697a36c 2995 {
a3170dc6 2996 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 2997 && (mode == SFmode || mode == DFmode))
4697a36c 2998 {
4cc833b7
RH
2999 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3000 cum->fregno++;
3001 else
3002 {
3003 if (mode == DFmode)
3004 cum->words += cum->words & 1;
d34c5b80 3005 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 3006 }
4697a36c 3007 }
4cc833b7
RH
3008 else
3009 {
3010 int n_words;
3011 int gregno = cum->sysv_gregno;
3012
3013 /* Aggregates and IEEE quad get passed by reference. */
3014 if ((type && AGGREGATE_TYPE_P (type))
3015 || mode == TFmode)
3016 n_words = 1;
3017 else
d34c5b80 3018 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3019
a4b0320c 3020 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3021 if (n_words == 2 && (gregno & 1) == 0)
3022 gregno += 1;
3023
a4b0320c
AH
3024 /* Long long and SPE vectors are not split between registers
3025 and stack. */
4cc833b7
RH
3026 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
3027 {
3028 /* Long long is aligned on the stack. */
3029 if (n_words == 2)
3030 cum->words += cum->words & 1;
3031 cum->words += n_words;
3032 }
4697a36c 3033
4cc833b7
RH
3034 /* Note: continuing to accumulate gregno past when we've started
3035 spilling to the stack indicates the fact that we've started
3036 spilling to the stack to expand_builtin_saveregs. */
3037 cum->sysv_gregno = gregno + n_words;
3038 }
4697a36c 3039
4cc833b7
RH
3040 if (TARGET_DEBUG_ARG)
3041 {
3042 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3043 cum->words, cum->fregno);
3044 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3045 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3046 fprintf (stderr, "mode = %4s, named = %d\n",
3047 GET_MODE_NAME (mode), named);
3048 }
4697a36c
MM
3049 }
3050 else
4cc833b7
RH
3051 {
3052 int align = (TARGET_32BIT && (cum->words & 1) != 0
3053 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 3054
d34c5b80 3055 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 3056
a3170dc6
AH
3057 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3058 && TARGET_HARD_FLOAT && TARGET_FPRS)
fcce224d 3059 cum->fregno += (mode == TFmode ? 2 : 1);
4cc833b7
RH
3060
3061 if (TARGET_DEBUG_ARG)
3062 {
3063 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3064 cum->words, cum->fregno);
3065 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3066 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3067 fprintf (stderr, "named = %d, align = %d\n", named, align);
3068 }
3069 }
4697a36c
MM
3070}
3071\f
3072/* Determine where to put an argument to a function.
3073 Value is zero to push the argument on the stack,
3074 or a hard register in which to store the argument.
3075
3076 MODE is the argument's machine mode.
3077 TYPE is the data type of the argument (as a tree).
3078 This is null for libcalls where that information may
3079 not be available.
3080 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3081 the preceding args and about the function being called.
3082 NAMED is nonzero if this argument is a named parameter
3083 (otherwise it is an extra parameter matching an ellipsis).
3084
3085 On RS/6000 the first eight words of non-FP are normally in registers
3086 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3087 Under V.4, the first 8 FP args are in registers.
3088
3089 If this is floating-point and no prototype is specified, we use
3090 both an FP and integer register (or possibly FP reg and stack). Library
3091 functions (when TYPE is zero) always have the proper types for args,
3092 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3093 doesn't support PARALLEL anyway. */
4697a36c
MM
3094
3095struct rtx_def *
3096function_arg (cum, mode, type, named)
3097 CUMULATIVE_ARGS *cum;
3098 enum machine_mode mode;
3099 tree type;
20c29ebe 3100 int named;
4697a36c 3101{
4cc833b7 3102 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3103
a4f6c312
SS
3104 /* Return a marker to indicate whether CR1 needs to set or clear the
3105 bit that V.4 uses to say fp args were passed in registers.
3106 Assume that we don't need the marker for software floating point,
3107 or compiler generated library calls. */
4697a36c
MM
3108 if (mode == VOIDmode)
3109 {
f607bc57 3110 if (abi == ABI_V4
7509c759 3111 && cum->nargs_prototype < 0
4697a36c 3112 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3113 {
a3170dc6
AH
3114 /* For the SPE, we need to crxor CR6 always. */
3115 if (TARGET_SPE_ABI)
3116 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3117 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3118 return GEN_INT (cum->call_cookie
3119 | ((cum->fregno == FP_ARG_MIN_REG)
3120 ? CALL_V4_SET_FP_ARGS
3121 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3122 }
4697a36c 3123
7509c759 3124 return GEN_INT (cum->call_cookie);
4697a36c
MM
3125 }
3126
0ac081f6
AH
3127 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3128 {
20c29ebe 3129 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3130 return gen_rtx_REG (mode, cum->vregno);
3131 else
3132 return NULL;
3133 }
a4b0320c 3134 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3135 {
a4b0320c 3136 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3137 return gen_rtx_REG (mode, cum->sysv_gregno);
3138 else
3139 return NULL;
3140 }
f607bc57 3141 else if (abi == ABI_V4)
4697a36c 3142 {
a3170dc6 3143 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3144 && (mode == SFmode || mode == DFmode))
3145 {
3146 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3147 return gen_rtx_REG (mode, cum->fregno);
3148 else
3149 return NULL;
3150 }
3151 else
3152 {
3153 int n_words;
3154 int gregno = cum->sysv_gregno;
3155
3156 /* Aggregates and IEEE quad get passed by reference. */
3157 if ((type && AGGREGATE_TYPE_P (type))
3158 || mode == TFmode)
3159 n_words = 1;
3160 else
d34c5b80 3161 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3162
a4b0320c 3163 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3164 if (n_words == 2 && (gregno & 1) == 0)
3165 gregno += 1;
3166
a4b0320c
AH
3167 /* Long long and SPE vectors are not split between registers
3168 and stack. */
4cc833b7 3169 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3170 {
3171 /* SPE vectors in ... get split into 2 registers. */
3172 if (TARGET_SPE && TARGET_SPE_ABI
3173 && SPE_VECTOR_MODE (mode) && !named)
3174 {
3175 rtx r1, r2;
3176 enum machine_mode m = GET_MODE_INNER (mode);
3177
f9dd72da
AH
3178 if (mode == V1DImode)
3179 m = SImode;
3180
a4b0320c
AH
3181 r1 = gen_rtx_REG (m, gregno);
3182 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3183 r2 = gen_rtx_REG (m, gregno + 1);
3184 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3185 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3186 }
3187 return gen_rtx_REG (mode, gregno);
3188 }
4cc833b7
RH
3189 else
3190 return NULL;
3191 }
4697a36c 3192 }
4cc833b7
RH
3193 else
3194 {
3195 int align = (TARGET_32BIT && (cum->words & 1) != 0
3196 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3197 int align_words = cum->words + align;
4697a36c 3198
4cc833b7
RH
3199 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3200 return NULL_RTX;
3201
3202 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3203 {
3204 if (! type
3205 || ((cum->nargs_prototype > 0)
3206 /* IBM AIX extended its linkage convention definition always
3207 to require FP args after register save area hole on the
3208 stack. */
3209 && (DEFAULT_ABI != ABI_AIX
3210 || ! TARGET_XL_CALL
3211 || (align_words < GP_ARG_NUM_REG))))
3212 return gen_rtx_REG (mode, cum->fregno);
3213
3214 return gen_rtx_PARALLEL (mode,
3215 gen_rtvec (2,
39403d82 3216 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3217 ((align_words >= GP_ARG_NUM_REG)
3218 ? NULL_RTX
3219 : (align_words
d34c5b80 3220 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3221 > GP_ARG_NUM_REG
3222 /* If this is partially on the stack, then
3223 we only include the portion actually
3224 in registers here. */
39403d82 3225 ? gen_rtx_REG (SImode,
1c20ae99 3226 GP_ARG_MIN_REG + align_words)
39403d82 3227 : gen_rtx_REG (mode,
1c20ae99
JW
3228 GP_ARG_MIN_REG + align_words))),
3229 const0_rtx),
39403d82
DE
3230 gen_rtx_EXPR_LIST (VOIDmode,
3231 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3232 const0_rtx)));
4cc833b7
RH
3233 }
3234 else if (align_words < GP_ARG_NUM_REG)
3235 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3236 else
3237 return NULL_RTX;
4697a36c 3238 }
4697a36c
MM
3239}
3240\f
3241/* For an arg passed partly in registers and partly in memory,
3242 this is the number of registers used.
3243 For args passed entirely in registers or entirely in memory, zero. */
3244
3245int
3246function_arg_partial_nregs (cum, mode, type, named)
3247 CUMULATIVE_ARGS *cum;
3248 enum machine_mode mode;
3249 tree type;
d34c5b80 3250 int named ATTRIBUTE_UNUSED;
4697a36c 3251{
f607bc57 3252 if (DEFAULT_ABI == ABI_V4)
4697a36c 3253 return 0;
4697a36c 3254
0ac081f6
AH
3255 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3256 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3257 {
3258 if (cum->nargs_prototype >= 0)
3259 return 0;
3260 }
3261
3262 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3263 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3264 {
3265 int ret = GP_ARG_NUM_REG - cum->words;
3266 if (ret && TARGET_DEBUG_ARG)
3267 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3268
3269 return ret;
3270 }
3271
3272 return 0;
3273}
3274\f
3275/* A C expression that indicates when an argument must be passed by
3276 reference. If nonzero for an argument, a copy of that argument is
3277 made in memory and a pointer to the argument is passed instead of
3278 the argument itself. The pointer is passed in whatever way is
3279 appropriate for passing a pointer to that type.
3280
3281 Under V.4, structures and unions are passed by reference. */
3282
3283int
3284function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3285 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3286 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3287 tree type;
296b8152 3288 int named ATTRIBUTE_UNUSED;
4697a36c 3289{
f607bc57 3290 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3291 && ((type && AGGREGATE_TYPE_P (type))
3292 || mode == TFmode))
4697a36c
MM
3293 {
3294 if (TARGET_DEBUG_ARG)
3295 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3296
3297 return 1;
3298 }
4697a36c
MM
3299
3300 return 0;
3301}
4697a36c
MM
3302\f
3303/* Perform any needed actions needed for a function that is receiving a
3304 variable number of arguments.
3305
3306 CUM is as above.
3307
3308 MODE and TYPE are the mode and type of the current parameter.
3309
3310 PRETEND_SIZE is a variable that should be set to the amount of stack
3311 that must be pushed by the prolog to pretend that our caller pushed
3312 it.
3313
3314 Normally, this macro will push all remaining incoming registers on the
3315 stack and set PRETEND_SIZE to the length of the registers pushed. */
3316
3317void
3318setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3319 CUMULATIVE_ARGS *cum;
3320 enum machine_mode mode;
3321 tree type;
3322 int *pretend_size;
3323 int no_rtl;
3324
3325{
4cc833b7
RH
3326 CUMULATIVE_ARGS next_cum;
3327 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3328 rtx save_area = NULL_RTX, mem;
dfafc897 3329 int first_reg_offset, set;
d34c5b80
DE
3330 tree fntype;
3331 int stdarg_p;
4697a36c 3332
d34c5b80
DE
3333 fntype = TREE_TYPE (current_function_decl);
3334 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3335 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3336 != void_type_node));
4cc833b7 3337
d34c5b80
DE
3338 /* For varargs, we do not want to skip the dummy va_dcl argument.
3339 For stdargs, we do want to skip the last named argument. */
3340 next_cum = *cum;
3341 if (stdarg_p)
3342 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3343
f607bc57 3344 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3345 {
4cc833b7 3346 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3347 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3348 if (! no_rtl)
2c4974b7 3349 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3350 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3351
3352 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3353 }
60e2d0ca 3354 else
4697a36c 3355 {
d34c5b80 3356 first_reg_offset = next_cum.words;
4cc833b7 3357 save_area = virtual_incoming_args_rtx;
00dba523 3358 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3359
3360 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3361 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3362 }
4697a36c 3363
dfafc897 3364 set = get_varargs_alias_set ();
c81fc13e 3365 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3366 {
dfafc897
FS
3367 mem = gen_rtx_MEM (BLKmode,
3368 plus_constant (save_area,
3369 first_reg_offset * reg_size)),
ba4828e0 3370 set_mem_alias_set (mem, set);
8ac61af7 3371 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3372
4cc833b7 3373 move_block_from_reg
dfafc897 3374 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3375 GP_ARG_NUM_REG - first_reg_offset,
3376 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
3377
3378 /* ??? Does ABI_V4 need this at all? */
4697a36c
MM
3379 *pretend_size = (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD;
3380 }
3381
4697a36c 3382 /* Save FP registers if needed. */
f607bc57 3383 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3384 && TARGET_HARD_FLOAT && TARGET_FPRS
3385 && ! no_rtl
4cc833b7 3386 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3387 {
4cc833b7 3388 int fregno = next_cum.fregno;
9ebbca7d 3389 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3390 rtx lab = gen_label_rtx ();
3391 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3392
4cc833b7 3393 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3394 pc_rtx,
39403d82 3395 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3396 gen_rtx_NE (VOIDmode, cr1,
3397 const0_rtx),
39403d82 3398 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3399 pc_rtx)));
3400
4cc833b7
RH
3401 while (fregno <= FP_ARG_V4_MAX_REG)
3402 {
dfafc897 3403 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3404 set_mem_alias_set (mem, set);
dfafc897 3405 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3406 fregno++;
3407 off += 8;
4697a36c 3408 }
4cc833b7
RH
3409
3410 emit_label (lab);
4697a36c 3411 }
4697a36c 3412}
4697a36c 3413
dfafc897 3414/* Create the va_list data type. */
2c4974b7 3415
dfafc897
FS
3416tree
3417rs6000_build_va_list ()
3418{
bab45a51 3419 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3420
9ebbca7d
GK
3421 /* For AIX, prefer 'char *' because that's what the system
3422 header files like. */
f607bc57 3423 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3424 return build_pointer_type (char_type_node);
dfafc897 3425
f1e639b1 3426 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3427 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3428
9ebbca7d
GK
3429 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3430 unsigned_char_type_node);
3431 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3432 unsigned_char_type_node);
dfafc897
FS
3433 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3434 ptr_type_node);
3435 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3436 ptr_type_node);
3437
3438 DECL_FIELD_CONTEXT (f_gpr) = record;
3439 DECL_FIELD_CONTEXT (f_fpr) = record;
3440 DECL_FIELD_CONTEXT (f_ovf) = record;
3441 DECL_FIELD_CONTEXT (f_sav) = record;
3442
bab45a51
FS
3443 TREE_CHAIN (record) = type_decl;
3444 TYPE_NAME (record) = type_decl;
dfafc897
FS
3445 TYPE_FIELDS (record) = f_gpr;
3446 TREE_CHAIN (f_gpr) = f_fpr;
3447 TREE_CHAIN (f_fpr) = f_ovf;
3448 TREE_CHAIN (f_ovf) = f_sav;
3449
3450 layout_type (record);
3451
3452 /* The correct type is an array type of one element. */
3453 return build_array_type (record, build_index_type (size_zero_node));
3454}
3455
3456/* Implement va_start. */
3457
3458void
e5faf155 3459rs6000_va_start (valist, nextarg)
dfafc897
FS
3460 tree valist;
3461 rtx nextarg;
4697a36c 3462{
dfafc897
FS
3463 HOST_WIDE_INT words, n_gpr, n_fpr;
3464 tree f_gpr, f_fpr, f_ovf, f_sav;
3465 tree gpr, fpr, ovf, sav, t;
2c4974b7 3466
dfafc897 3467 /* Only SVR4 needs something special. */
f607bc57 3468 if (DEFAULT_ABI != ABI_V4)
dfafc897 3469 {
e5faf155 3470 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3471 return;
3472 }
3473
973a648b 3474 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3475 f_fpr = TREE_CHAIN (f_gpr);
3476 f_ovf = TREE_CHAIN (f_fpr);
3477 f_sav = TREE_CHAIN (f_ovf);
3478
8ebecc3b 3479 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3480 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3481 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3482 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3483 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3484
3485 /* Count number of gp and fp argument registers used. */
4cc833b7 3486 words = current_function_args_info.words;
dfafc897
FS
3487 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3488 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3489
3490 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3491 {
3492 fputs ("va_start: words = ", stderr);
3493 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3494 fputs (", n_gpr = ", stderr);
3495 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3496 fputs (", n_fpr = ", stderr);
3497 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3498 putc ('\n', stderr);
3499 }
dfafc897
FS
3500
3501 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3502 TREE_SIDE_EFFECTS (t) = 1;
3503 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3504
3505 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3506 TREE_SIDE_EFFECTS (t) = 1;
3507 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3508
3509 /* Find the overflow area. */
3510 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3511 if (words != 0)
3512 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3513 build_int_2 (words * UNITS_PER_WORD, 0));
3514 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3515 TREE_SIDE_EFFECTS (t) = 1;
3516 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3517
3518 /* Find the register save area. */
3519 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3520 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3521 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3522 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3523 TREE_SIDE_EFFECTS (t) = 1;
3524 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3525}
3526
3527/* Implement va_arg. */
3528
3529rtx
3530rs6000_va_arg (valist, type)
3531 tree valist, type;
3532{
3533 tree f_gpr, f_fpr, f_ovf, f_sav;
3534 tree gpr, fpr, ovf, sav, reg, t, u;
3535 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3536 rtx lab_false, lab_over, addr_rtx, r;
3537
f607bc57 3538 if (DEFAULT_ABI != ABI_V4)
2a55fd42 3539 return std_expand_builtin_va_arg (valist, type);
dfafc897 3540
973a648b 3541 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3542 f_fpr = TREE_CHAIN (f_gpr);
3543 f_ovf = TREE_CHAIN (f_fpr);
3544 f_sav = TREE_CHAIN (f_ovf);
3545
8ebecc3b 3546 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3547 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3548 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3549 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3550 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3551
3552 size = int_size_in_bytes (type);
3553 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3554
dfafc897 3555 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3556 {
dfafc897
FS
3557 /* Aggregates and long doubles are passed by reference. */
3558 indirect_p = 1;
3559 reg = gpr;
3560 n_reg = 1;
3561 sav_ofs = 0;
3562 sav_scale = 4;
d3294cd9
FS
3563 size = UNITS_PER_WORD;
3564 rsize = 1;
dfafc897 3565 }
a3170dc6 3566 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3567 {
3568 /* FP args go in FP registers, if present. */
3569 indirect_p = 0;
3570 reg = fpr;
3571 n_reg = 1;
3572 sav_ofs = 8*4;
3573 sav_scale = 8;
4cc833b7 3574 }
dfafc897
FS
3575 else
3576 {
3577 /* Otherwise into GP registers. */
3578 indirect_p = 0;
3579 reg = gpr;
3580 n_reg = rsize;
3581 sav_ofs = 0;
3582 sav_scale = 4;
3583 }
3584
a4f6c312 3585 /* Pull the value out of the saved registers ... */
dfafc897
FS
3586
3587 lab_false = gen_label_rtx ();
3588 lab_over = gen_label_rtx ();
3589 addr_rtx = gen_reg_rtx (Pmode);
3590
16861f33
AH
3591 /* AltiVec vectors never go in registers. */
3592 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3593 {
41daaf0e
AH
3594 TREE_THIS_VOLATILE (reg) = 1;
3595 emit_cmp_and_jump_insns
3596 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3597 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3598 lab_false);
dfafc897 3599
41daaf0e
AH
3600 /* Long long is aligned in the registers. */
3601 if (n_reg > 1)
3602 {
3603 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3604 build_int_2 (n_reg - 1, 0));
3605 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3606 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3607 TREE_SIDE_EFFECTS (u) = 1;
3608 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3609 }
2c4974b7 3610
41daaf0e
AH
3611 if (sav_ofs)
3612 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3613 else
3614 t = sav;
2c4974b7 3615
41daaf0e
AH
3616 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3617 build_int_2 (n_reg, 0));
3618 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3619
41daaf0e
AH
3620 u = build1 (CONVERT_EXPR, integer_type_node, u);
3621 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3622
41daaf0e
AH
3623 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3624 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3625
41daaf0e
AH
3626 t = build (PLUS_EXPR, ptr_type_node, t, u);
3627 TREE_SIDE_EFFECTS (t) = 1;
3628
3629 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3630 if (r != addr_rtx)
3631 emit_move_insn (addr_rtx, r);
3632
3633 emit_jump_insn (gen_jump (lab_over));
3634 emit_barrier ();
3635 }
dfafc897 3636
dfafc897
FS
3637 emit_label (lab_false);
3638
a4f6c312 3639 /* ... otherwise out of the overflow area. */
dfafc897 3640
41daaf0e
AH
3641 /* Make sure we don't find reg 7 for the next int arg.
3642
3643 All AltiVec vectors go in the overflow area. So in the AltiVec
3644 case we need to get the vectors from the overflow area, but
3645 remember where the GPRs and FPRs are. */
16861f33
AH
3646 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3647 || !TARGET_ALTIVEC))
dfafc897
FS
3648 {
3649 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3650 TREE_SIDE_EFFECTS (t) = 1;
3651 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3652 }
3653
3654 /* Care for on-stack alignment if needed. */
3655 if (rsize <= 1)
3656 t = ovf;
3657 else
3658 {
41daaf0e
AH
3659 int align;
3660
16861f33
AH
3661 /* AltiVec vectors are 16 byte aligned. */
3662 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3663 align = 15;
3664 else
3665 align = 7;
3666
3667 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3668 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3669 }
3670 t = save_expr (t);
3671
3672 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3673 if (r != addr_rtx)
3674 emit_move_insn (addr_rtx, r);
3675
3676 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3677 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3678 TREE_SIDE_EFFECTS (t) = 1;
3679 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3680
3681 emit_label (lab_over);
3682
3683 if (indirect_p)
3684 {
3685 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3686 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3687 emit_move_insn (addr_rtx, r);
3688 }
3689
3690 return addr_rtx;
4697a36c 3691}
0ac081f6
AH
3692
3693/* Builtins. */
3694
6a2dd09a
RS
3695#define def_builtin(MASK, NAME, TYPE, CODE) \
3696do { \
3697 if ((MASK) & target_flags) \
3698 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3699 NULL, NULL_TREE); \
0ac081f6
AH
3700} while (0)
3701
24408032
AH
3702/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3703
2212663f 3704static const struct builtin_description bdesc_3arg[] =
24408032
AH
3705{
3706 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3707 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3708 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3709 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3710 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3711 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3712 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3713 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3714 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3715 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3716 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3717 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3718 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3719 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3720 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3721 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3722 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3723 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3724 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3725 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3726 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3727 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3728 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3729};
2212663f 3730
95385cbb
AH
3731/* DST operations: void foo (void *, const int, const char). */
3732
3733static const struct builtin_description bdesc_dst[] =
3734{
3735 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3736 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3737 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3738 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3739};
3740
2212663f 3741/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3742
a3170dc6 3743static struct builtin_description bdesc_2arg[] =
0ac081f6 3744{
f18c054f
DB
3745 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3746 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3747 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3748 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3749 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3750 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3751 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3752 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3753 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3754 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3755 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3756 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3757 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3758 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3759 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3760 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3761 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3762 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3763 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3764 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3765 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3766 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3767 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3768 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3769 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3770 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3771 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3772 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3773 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3774 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3775 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3776 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3777 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3778 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3779 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3780 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3781 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3782 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
3783 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3784 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3785 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3786 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3787 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3788 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3789 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3790 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3791 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3792 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3793 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3794 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3795 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3796 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3797 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3798 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3799 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3800 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3801 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3802 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3803 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3804 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3805 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3806 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3807 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3808 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3809 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3810 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3811 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3812 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3813 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3814 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3815 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3816 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3817 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3818 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3819 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3820 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3821 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3822 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3823 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3824 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3825 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3826 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3827 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3828 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3829 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3830 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3831 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3832 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3833 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3834 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3835 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3836 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3837 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3838 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3839 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3840 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3841 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3842 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3843 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3844 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3845 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3846 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3847 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3848 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3849 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3850 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3851 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3852 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3853 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3854 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3855 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3856 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3857 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
3858
3859 /* Place holder, leave as first spe builtin. */
3860 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3861 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3862 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3863 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3864 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3865 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3866 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3867 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3868 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3869 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3870 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3871 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3872 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3873 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3874 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3875 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3876 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3877 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3878 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3879 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3880 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3881 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3882 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3883 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3884 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3885 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3886 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3887 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3888 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3889 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3890 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3891 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3892 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3893 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3894 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3895 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3896 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3897 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3898 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
3899 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
3900 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
3901 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
3902 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
3903 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
3904 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
3905 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
3906 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
3907 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
3908 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
3909 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
3910 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
3911 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
3912 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
3913 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
3914 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
3915 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
3916 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
3917 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
3918 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
3919 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
3920 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
3921 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
3922 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
3923 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
3924 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
3925 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
3926 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
3927 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
3928 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
3929 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
3930 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
3931 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
3932 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
3933 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
3934 { 0, CODE_FOR_spe_evmwlsmf, "__builtin_spe_evmwlsmf", SPE_BUILTIN_EVMWLSMF },
3935 { 0, CODE_FOR_spe_evmwlsmfa, "__builtin_spe_evmwlsmfa", SPE_BUILTIN_EVMWLSMFA },
3936 { 0, CODE_FOR_spe_evmwlsmfaaw, "__builtin_spe_evmwlsmfaaw", SPE_BUILTIN_EVMWLSMFAAW },
3937 { 0, CODE_FOR_spe_evmwlsmfanw, "__builtin_spe_evmwlsmfanw", SPE_BUILTIN_EVMWLSMFANW },
3938 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
3939 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
3940 { 0, CODE_FOR_spe_evmwlssf, "__builtin_spe_evmwlssf", SPE_BUILTIN_EVMWLSSF },
3941 { 0, CODE_FOR_spe_evmwlssfa, "__builtin_spe_evmwlssfa", SPE_BUILTIN_EVMWLSSFA },
3942 { 0, CODE_FOR_spe_evmwlssfaaw, "__builtin_spe_evmwlssfaaw", SPE_BUILTIN_EVMWLSSFAAW },
3943 { 0, CODE_FOR_spe_evmwlssfanw, "__builtin_spe_evmwlssfanw", SPE_BUILTIN_EVMWLSSFANW },
3944 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
3945 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
3946 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
3947 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
3948 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
3949 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
3950 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
3951 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
3952 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
3953 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
3954 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
3955 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
3956 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
3957 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
3958 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
3959 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
3960 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
3961 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
3962 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
3963 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
3964 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
3965 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
3966 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
3967 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
3968 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
3969 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
3970 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
3971 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
3972 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
3973 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
3974 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
3975 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
3976 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
3977
3978 /* SPE binary operations expecting a 5-bit unsigned literal. */
3979 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
3980
3981 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
3982 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
3983 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
3984 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
3985 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
3986 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
3987 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
3988 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
3989 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
3990 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
3991 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
3992 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
3993 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
3994 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
3995 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
3996 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
3997 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
3998 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
3999 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
4000 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
4001 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
4002 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
4003 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
4004 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
4005 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
4006 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
4007
4008 /* Place-holder. Leave as last binary SPE builtin. */
4009 { 0, CODE_FOR_spe_evxor, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
4010};
4011
4012/* AltiVec predicates. */
4013
4014struct builtin_description_predicates
4015{
4016 const unsigned int mask;
4017 const enum insn_code icode;
4018 const char *opcode;
4019 const char *const name;
4020 const enum rs6000_builtins code;
4021};
4022
4023static const struct builtin_description_predicates bdesc_altivec_preds[] =
4024{
4025 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
4026 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
4027 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
4028 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
4029 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
4030 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
4031 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
4032 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
4033 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
4034 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
4035 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
4036 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
4037 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 4038};
24408032 4039
a3170dc6
AH
4040/* SPE predicates. */
4041static struct builtin_description bdesc_spe_predicates[] =
4042{
4043 /* Place-holder. Leave as first. */
4044 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
4045 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
4046 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
4047 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4048 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4049 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4050 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4051 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4052 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4053 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4054 /* Place-holder. Leave as last. */
4055 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4056};
4057
4058/* SPE evsel predicates. */
4059static struct builtin_description bdesc_spe_evsel[] =
4060{
4061 /* Place-holder. Leave as first. */
4062 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4063 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4064 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4065 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4066 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4067 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4068 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4069 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4070 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4071 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4072 /* Place-holder. Leave as last. */
4073 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4074};
4075
100c4561
AH
4076/* ABS* opreations. */
4077
4078static const struct builtin_description bdesc_abs[] =
4079{
4080 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4081 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4082 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4083 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4084 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4085 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4086 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4087};
4088
617e0e1d
DB
4089/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4090 foo (VECa). */
24408032 4091
a3170dc6 4092static struct builtin_description bdesc_1arg[] =
2212663f 4093{
617e0e1d
DB
4094 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4095 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4096 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4097 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4098 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4099 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4100 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4101 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4102 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4103 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4104 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4105 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4106 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4107 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4108 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4109 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4110 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4111
4112 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4113 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4114 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4115 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4116 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4117 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4118 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4119 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4120 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4121 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4122 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4123 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4124 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4125 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4126 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4127 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4128 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4129 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4130 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4131 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4132 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4133 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4134 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4135 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4136 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4137 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4138 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4139 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4140 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4141 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4142 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4143 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4144
4145 /* Place-holder. Leave as last unary SPE builtin. */
4146 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4147};
4148
4149static rtx
92898235 4150rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4151 enum insn_code icode;
4152 tree arglist;
4153 rtx target;
4154{
4155 rtx pat;
4156 tree arg0 = TREE_VALUE (arglist);
4157 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4158 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4159 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4160
0559cc77
DE
4161 if (icode == CODE_FOR_nothing)
4162 /* Builtin not supported on this processor. */
4163 return 0;
4164
20e26713
AH
4165 /* If we got invalid arguments bail out before generating bad rtl. */
4166 if (arg0 == error_mark_node)
9a171fcd 4167 return const0_rtx;
20e26713 4168
0559cc77
DE
4169 if (icode == CODE_FOR_altivec_vspltisb
4170 || icode == CODE_FOR_altivec_vspltish
4171 || icode == CODE_FOR_altivec_vspltisw
4172 || icode == CODE_FOR_spe_evsplatfi
4173 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4174 {
4175 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4176 if (GET_CODE (op0) != CONST_INT
4177 || INTVAL (op0) > 0x1f
4178 || INTVAL (op0) < -0x1f)
4179 {
4180 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4181 return const0_rtx;
b44140e7 4182 }
b44140e7
AH
4183 }
4184
c62f2db5 4185 if (target == 0
2212663f
DB
4186 || GET_MODE (target) != tmode
4187 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4188 target = gen_reg_rtx (tmode);
4189
4190 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4191 op0 = copy_to_mode_reg (mode0, op0);
4192
4193 pat = GEN_FCN (icode) (target, op0);
4194 if (! pat)
4195 return 0;
4196 emit_insn (pat);
0ac081f6 4197
2212663f
DB
4198 return target;
4199}
ae4b4a02 4200
100c4561
AH
4201static rtx
4202altivec_expand_abs_builtin (icode, arglist, target)
4203 enum insn_code icode;
4204 tree arglist;
4205 rtx target;
4206{
4207 rtx pat, scratch1, scratch2;
4208 tree arg0 = TREE_VALUE (arglist);
4209 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4210 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4211 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4212
4213 /* If we have invalid arguments, bail out before generating bad rtl. */
4214 if (arg0 == error_mark_node)
9a171fcd 4215 return const0_rtx;
100c4561
AH
4216
4217 if (target == 0
4218 || GET_MODE (target) != tmode
4219 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4220 target = gen_reg_rtx (tmode);
4221
4222 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4223 op0 = copy_to_mode_reg (mode0, op0);
4224
4225 scratch1 = gen_reg_rtx (mode0);
4226 scratch2 = gen_reg_rtx (mode0);
4227
4228 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4229 if (! pat)
4230 return 0;
4231 emit_insn (pat);
4232
4233 return target;
4234}
4235
0ac081f6 4236static rtx
92898235 4237rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4238 enum insn_code icode;
4239 tree arglist;
4240 rtx target;
4241{
4242 rtx pat;
4243 tree arg0 = TREE_VALUE (arglist);
4244 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4245 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4246 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4247 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4248 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4249 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4250
0559cc77
DE
4251 if (icode == CODE_FOR_nothing)
4252 /* Builtin not supported on this processor. */
4253 return 0;
4254
20e26713
AH
4255 /* If we got invalid arguments bail out before generating bad rtl. */
4256 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4257 return const0_rtx;
20e26713 4258
0559cc77
DE
4259 if (icode == CODE_FOR_altivec_vcfux
4260 || icode == CODE_FOR_altivec_vcfsx
4261 || icode == CODE_FOR_altivec_vctsxs
4262 || icode == CODE_FOR_altivec_vctuxs
4263 || icode == CODE_FOR_altivec_vspltb
4264 || icode == CODE_FOR_altivec_vsplth
4265 || icode == CODE_FOR_altivec_vspltw
4266 || icode == CODE_FOR_spe_evaddiw
4267 || icode == CODE_FOR_spe_evldd
4268 || icode == CODE_FOR_spe_evldh
4269 || icode == CODE_FOR_spe_evldw
4270 || icode == CODE_FOR_spe_evlhhesplat
4271 || icode == CODE_FOR_spe_evlhhossplat
4272 || icode == CODE_FOR_spe_evlhhousplat
4273 || icode == CODE_FOR_spe_evlwhe
4274 || icode == CODE_FOR_spe_evlwhos
4275 || icode == CODE_FOR_spe_evlwhou
4276 || icode == CODE_FOR_spe_evlwhsplat
4277 || icode == CODE_FOR_spe_evlwwsplat
4278 || icode == CODE_FOR_spe_evrlwi
4279 || icode == CODE_FOR_spe_evslwi
4280 || icode == CODE_FOR_spe_evsrwis
4281 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4282 {
4283 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4284 if (TREE_CODE (arg1) != INTEGER_CST
4285 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4286 {
4287 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4288 return const0_rtx;
b44140e7 4289 }
b44140e7
AH
4290 }
4291
c62f2db5 4292 if (target == 0
0ac081f6
AH
4293 || GET_MODE (target) != tmode
4294 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4295 target = gen_reg_rtx (tmode);
4296
4297 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4298 op0 = copy_to_mode_reg (mode0, op0);
4299 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4300 op1 = copy_to_mode_reg (mode1, op1);
4301
4302 pat = GEN_FCN (icode) (target, op0, op1);
4303 if (! pat)
4304 return 0;
4305 emit_insn (pat);
4306
4307 return target;
4308}
6525c0e7 4309
ae4b4a02
AH
4310static rtx
4311altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4312 enum insn_code icode;
4313 const char *opcode;
4314 tree arglist;
4315 rtx target;
4316{
4317 rtx pat, scratch;
4318 tree cr6_form = TREE_VALUE (arglist);
4319 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4320 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4321 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4322 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4323 enum machine_mode tmode = SImode;
4324 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4325 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4326 int cr6_form_int;
4327
4328 if (TREE_CODE (cr6_form) != INTEGER_CST)
4329 {
4330 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4331 return const0_rtx;
ae4b4a02
AH
4332 }
4333 else
4334 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4335
4336 if (mode0 != mode1)
4337 abort ();
4338
4339 /* If we have invalid arguments, bail out before generating bad rtl. */
4340 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4341 return const0_rtx;
ae4b4a02
AH
4342
4343 if (target == 0
4344 || GET_MODE (target) != tmode
4345 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4346 target = gen_reg_rtx (tmode);
4347
4348 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4349 op0 = copy_to_mode_reg (mode0, op0);
4350 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4351 op1 = copy_to_mode_reg (mode1, op1);
4352
4353 scratch = gen_reg_rtx (mode0);
4354
4355 pat = GEN_FCN (icode) (scratch, op0, op1,
4356 gen_rtx (SYMBOL_REF, Pmode, opcode));
4357 if (! pat)
4358 return 0;
4359 emit_insn (pat);
4360
4361 /* The vec_any* and vec_all* predicates use the same opcodes for two
4362 different operations, but the bits in CR6 will be different
4363 depending on what information we want. So we have to play tricks
4364 with CR6 to get the right bits out.
4365
4366 If you think this is disgusting, look at the specs for the
4367 AltiVec predicates. */
4368
4369 switch (cr6_form_int)
4370 {
4371 case 0:
4372 emit_insn (gen_cr6_test_for_zero (target));
4373 break;
4374 case 1:
4375 emit_insn (gen_cr6_test_for_zero_reverse (target));
4376 break;
4377 case 2:
4378 emit_insn (gen_cr6_test_for_lt (target));
4379 break;
4380 case 3:
4381 emit_insn (gen_cr6_test_for_lt_reverse (target));
4382 break;
4383 default:
4384 error ("argument 1 of __builtin_altivec_predicate is out of range");
4385 break;
4386 }
4387
4388 return target;
4389}
4390
6525c0e7
AH
4391static rtx
4392altivec_expand_stv_builtin (icode, arglist)
4393 enum insn_code icode;
4394 tree arglist;
4395{
4396 tree arg0 = TREE_VALUE (arglist);
4397 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4398 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4399 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4400 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4401 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4402 rtx pat;
4403 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4404 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4405 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4406
4407 /* Invalid arguments. Bail before doing anything stoopid! */
4408 if (arg0 == error_mark_node
4409 || arg1 == error_mark_node
4410 || arg2 == error_mark_node)
9a171fcd 4411 return const0_rtx;
6525c0e7
AH
4412
4413 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4414 op0 = copy_to_mode_reg (mode2, op0);
4415 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4416 op1 = copy_to_mode_reg (mode0, op1);
4417 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4418 op2 = copy_to_mode_reg (mode1, op2);
4419
4420 pat = GEN_FCN (icode) (op1, op2, op0);
4421 if (pat)
4422 emit_insn (pat);
4423 return NULL_RTX;
4424}
4425
2212663f 4426static rtx
92898235 4427rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4428 enum insn_code icode;
4429 tree arglist;
4430 rtx target;
4431{
4432 rtx pat;
4433 tree arg0 = TREE_VALUE (arglist);
4434 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4435 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4436 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4437 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4438 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4439 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4440 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4441 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4442 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4443
774b5662
DE
4444 if (icode == CODE_FOR_nothing)
4445 /* Builtin not supported on this processor. */
4446 return 0;
4447
20e26713
AH
4448 /* If we got invalid arguments bail out before generating bad rtl. */
4449 if (arg0 == error_mark_node
4450 || arg1 == error_mark_node
4451 || arg2 == error_mark_node)
9a171fcd 4452 return const0_rtx;
20e26713 4453
774b5662
DE
4454 if (icode == CODE_FOR_altivec_vsldoi_4sf
4455 || icode == CODE_FOR_altivec_vsldoi_4si
4456 || icode == CODE_FOR_altivec_vsldoi_8hi
4457 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4458 {
4459 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4460 if (TREE_CODE (arg2) != INTEGER_CST
4461 || TREE_INT_CST_LOW (arg2) & ~0xf)
4462 {
4463 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4464 return const0_rtx;
b44140e7 4465 }
b44140e7
AH
4466 }
4467
c62f2db5 4468 if (target == 0
2212663f
DB
4469 || GET_MODE (target) != tmode
4470 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4471 target = gen_reg_rtx (tmode);
4472
4473 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4474 op0 = copy_to_mode_reg (mode0, op0);
4475 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4476 op1 = copy_to_mode_reg (mode1, op1);
4477 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4478 op2 = copy_to_mode_reg (mode2, op2);
4479
4480 pat = GEN_FCN (icode) (target, op0, op1, op2);
4481 if (! pat)
4482 return 0;
4483 emit_insn (pat);
4484
4485 return target;
4486}
92898235 4487
3a9b8c7e 4488/* Expand the lvx builtins. */
0ac081f6 4489static rtx
3a9b8c7e 4490altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4491 tree exp;
4492 rtx target;
92898235 4493 bool *expandedp;
0ac081f6 4494{
0ac081f6
AH
4495 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4496 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4497 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4498 tree arg0;
4499 enum machine_mode tmode, mode0;
7c3abc73 4500 rtx pat, op0;
3a9b8c7e 4501 enum insn_code icode;
92898235 4502
0ac081f6
AH
4503 switch (fcode)
4504 {
f18c054f
DB
4505 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4506 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4507 break;
f18c054f
DB
4508 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4509 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4510 break;
4511 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4512 icode = CODE_FOR_altivec_lvx_4si;
4513 break;
4514 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4515 icode = CODE_FOR_altivec_lvx_4sf;
4516 break;
4517 default:
4518 *expandedp = false;
4519 return NULL_RTX;
4520 }
0ac081f6 4521
3a9b8c7e 4522 *expandedp = true;
f18c054f 4523
3a9b8c7e
AH
4524 arg0 = TREE_VALUE (arglist);
4525 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4526 tmode = insn_data[icode].operand[0].mode;
4527 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4528
3a9b8c7e
AH
4529 if (target == 0
4530 || GET_MODE (target) != tmode
4531 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4532 target = gen_reg_rtx (tmode);
24408032 4533
3a9b8c7e
AH
4534 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4535 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4536
3a9b8c7e
AH
4537 pat = GEN_FCN (icode) (target, op0);
4538 if (! pat)
4539 return 0;
4540 emit_insn (pat);
4541 return target;
4542}
f18c054f 4543
3a9b8c7e
AH
4544/* Expand the stvx builtins. */
4545static rtx
4546altivec_expand_st_builtin (exp, target, expandedp)
4547 tree exp;
7c3abc73 4548 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4549 bool *expandedp;
4550{
4551 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4552 tree arglist = TREE_OPERAND (exp, 1);
4553 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4554 tree arg0, arg1;
4555 enum machine_mode mode0, mode1;
7c3abc73 4556 rtx pat, op0, op1;
3a9b8c7e 4557 enum insn_code icode;
f18c054f 4558
3a9b8c7e
AH
4559 switch (fcode)
4560 {
4561 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4562 icode = CODE_FOR_altivec_stvx_16qi;
4563 break;
4564 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4565 icode = CODE_FOR_altivec_stvx_8hi;
4566 break;
4567 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4568 icode = CODE_FOR_altivec_stvx_4si;
4569 break;
4570 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4571 icode = CODE_FOR_altivec_stvx_4sf;
4572 break;
4573 default:
4574 *expandedp = false;
4575 return NULL_RTX;
4576 }
24408032 4577
3a9b8c7e
AH
4578 arg0 = TREE_VALUE (arglist);
4579 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4580 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4581 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4582 mode0 = insn_data[icode].operand[0].mode;
4583 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4584
3a9b8c7e
AH
4585 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4586 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4587 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4588 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4589
3a9b8c7e
AH
4590 pat = GEN_FCN (icode) (op0, op1);
4591 if (pat)
4592 emit_insn (pat);
f18c054f 4593
3a9b8c7e
AH
4594 *expandedp = true;
4595 return NULL_RTX;
4596}
f18c054f 4597
3a9b8c7e
AH
4598/* Expand the dst builtins. */
4599static rtx
4600altivec_expand_dst_builtin (exp, target, expandedp)
4601 tree exp;
7c3abc73 4602 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4603 bool *expandedp;
4604{
4605 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4606 tree arglist = TREE_OPERAND (exp, 1);
4607 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4608 tree arg0, arg1, arg2;
4609 enum machine_mode mode0, mode1, mode2;
7c3abc73 4610 rtx pat, op0, op1, op2;
3a9b8c7e 4611 struct builtin_description *d;
a3170dc6 4612 size_t i;
f18c054f 4613
3a9b8c7e 4614 *expandedp = false;
f18c054f 4615
3a9b8c7e
AH
4616 /* Handle DST variants. */
4617 d = (struct builtin_description *) bdesc_dst;
4618 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4619 if (d->code == fcode)
4620 {
4621 arg0 = TREE_VALUE (arglist);
4622 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4623 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4624 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4625 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4626 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4627 mode0 = insn_data[d->icode].operand[0].mode;
4628 mode1 = insn_data[d->icode].operand[1].mode;
4629 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4630
3a9b8c7e
AH
4631 /* Invalid arguments, bail out before generating bad rtl. */
4632 if (arg0 == error_mark_node
4633 || arg1 == error_mark_node
4634 || arg2 == error_mark_node)
4635 return const0_rtx;
f18c054f 4636
3a9b8c7e
AH
4637 if (TREE_CODE (arg2) != INTEGER_CST
4638 || TREE_INT_CST_LOW (arg2) & ~0x3)
4639 {
4640 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4641 return const0_rtx;
4642 }
f18c054f 4643
3a9b8c7e
AH
4644 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4645 op0 = copy_to_mode_reg (mode0, op0);
4646 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4647 op1 = copy_to_mode_reg (mode1, op1);
24408032 4648
3a9b8c7e
AH
4649 pat = GEN_FCN (d->icode) (op0, op1, op2);
4650 if (pat != 0)
4651 emit_insn (pat);
f18c054f 4652
3a9b8c7e
AH
4653 *expandedp = true;
4654 return NULL_RTX;
4655 }
f18c054f 4656
3a9b8c7e
AH
4657 return NULL_RTX;
4658}
24408032 4659
3a9b8c7e
AH
4660/* Expand the builtin in EXP and store the result in TARGET. Store
4661 true in *EXPANDEDP if we found a builtin to expand. */
4662static rtx
4663altivec_expand_builtin (exp, target, expandedp)
4664 tree exp;
4665 rtx target;
4666 bool *expandedp;
4667{
4668 struct builtin_description *d;
4669 struct builtin_description_predicates *dp;
4670 size_t i;
4671 enum insn_code icode;
4672 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4673 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4674 tree arg0;
4675 rtx op0, pat;
4676 enum machine_mode tmode, mode0;
3a9b8c7e 4677 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4678
3a9b8c7e
AH
4679 target = altivec_expand_ld_builtin (exp, target, expandedp);
4680 if (*expandedp)
4681 return target;
0ac081f6 4682
3a9b8c7e
AH
4683 target = altivec_expand_st_builtin (exp, target, expandedp);
4684 if (*expandedp)
4685 return target;
4686
4687 target = altivec_expand_dst_builtin (exp, target, expandedp);
4688 if (*expandedp)
4689 return target;
4690
4691 *expandedp = true;
95385cbb 4692
3a9b8c7e
AH
4693 switch (fcode)
4694 {
6525c0e7
AH
4695 case ALTIVEC_BUILTIN_STVX:
4696 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4697 case ALTIVEC_BUILTIN_STVEBX:
4698 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4699 case ALTIVEC_BUILTIN_STVEHX:
4700 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4701 case ALTIVEC_BUILTIN_STVEWX:
4702 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4703 case ALTIVEC_BUILTIN_STVXL:
4704 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4705
95385cbb
AH
4706 case ALTIVEC_BUILTIN_MFVSCR:
4707 icode = CODE_FOR_altivec_mfvscr;
4708 tmode = insn_data[icode].operand[0].mode;
4709
4710 if (target == 0
4711 || GET_MODE (target) != tmode
4712 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4713 target = gen_reg_rtx (tmode);
4714
4715 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4716 if (! pat)
4717 return 0;
4718 emit_insn (pat);
95385cbb
AH
4719 return target;
4720
4721 case ALTIVEC_BUILTIN_MTVSCR:
4722 icode = CODE_FOR_altivec_mtvscr;
4723 arg0 = TREE_VALUE (arglist);
4724 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4725 mode0 = insn_data[icode].operand[0].mode;
4726
4727 /* If we got invalid arguments bail out before generating bad rtl. */
4728 if (arg0 == error_mark_node)
9a171fcd 4729 return const0_rtx;
95385cbb
AH
4730
4731 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4732 op0 = copy_to_mode_reg (mode0, op0);
4733
4734 pat = GEN_FCN (icode) (op0);
4735 if (pat)
4736 emit_insn (pat);
4737 return NULL_RTX;
3a9b8c7e 4738
95385cbb
AH
4739 case ALTIVEC_BUILTIN_DSSALL:
4740 emit_insn (gen_altivec_dssall ());
4741 return NULL_RTX;
4742
4743 case ALTIVEC_BUILTIN_DSS:
4744 icode = CODE_FOR_altivec_dss;
4745 arg0 = TREE_VALUE (arglist);
4746 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4747 mode0 = insn_data[icode].operand[0].mode;
4748
4749 /* If we got invalid arguments bail out before generating bad rtl. */
4750 if (arg0 == error_mark_node)
9a171fcd 4751 return const0_rtx;
95385cbb 4752
b44140e7
AH
4753 if (TREE_CODE (arg0) != INTEGER_CST
4754 || TREE_INT_CST_LOW (arg0) & ~0x3)
4755 {
4756 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4757 return const0_rtx;
b44140e7
AH
4758 }
4759
95385cbb
AH
4760 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4761 op0 = copy_to_mode_reg (mode0, op0);
4762
4763 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4764 return NULL_RTX;
4765 }
24408032 4766
100c4561
AH
4767 /* Expand abs* operations. */
4768 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4769 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4770 if (d->code == fcode)
4771 return altivec_expand_abs_builtin (d->icode, arglist, target);
4772
ae4b4a02
AH
4773 /* Expand the AltiVec predicates. */
4774 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4775 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4776 if (dp->code == fcode)
4777 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4778
6525c0e7
AH
4779 /* LV* are funky. We initialized them differently. */
4780 switch (fcode)
4781 {
4782 case ALTIVEC_BUILTIN_LVSL:
92898235 4783 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
4784 arglist, target);
4785 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
4786 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4787 arglist, target);
6525c0e7 4788 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
4789 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4790 arglist, target);
6525c0e7 4791 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
4792 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4793 arglist, target);
6525c0e7 4794 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
4795 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4796 arglist, target);
6525c0e7 4797 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
4798 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4799 arglist, target);
6525c0e7 4800 case ALTIVEC_BUILTIN_LVX:
92898235
AH
4801 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4802 arglist, target);
6525c0e7
AH
4803 default:
4804 break;
4805 /* Fall through. */
4806 }
95385cbb 4807
92898235 4808 *expandedp = false;
0ac081f6
AH
4809 return NULL_RTX;
4810}
4811
a3170dc6
AH
4812/* Binops that need to be initialized manually, but can be expanded
4813 automagically by rs6000_expand_binop_builtin. */
4814static struct builtin_description bdesc_2arg_spe[] =
4815{
4816 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4817 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4818 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4819 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4820 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4821 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4822 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4823 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4824 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4825 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4826 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4827 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4828 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4829 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4830 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4831 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4832 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4833 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4834 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4835 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4836 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4837 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4838};
4839
4840/* Expand the builtin in EXP and store the result in TARGET. Store
4841 true in *EXPANDEDP if we found a builtin to expand.
4842
4843 This expands the SPE builtins that are not simple unary and binary
4844 operations. */
4845static rtx
4846spe_expand_builtin (exp, target, expandedp)
4847 tree exp;
4848 rtx target;
4849 bool *expandedp;
4850{
4851 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4852 tree arglist = TREE_OPERAND (exp, 1);
4853 tree arg1, arg0;
4854 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4855 enum insn_code icode;
4856 enum machine_mode tmode, mode0;
4857 rtx pat, op0;
4858 struct builtin_description *d;
4859 size_t i;
4860
4861 *expandedp = true;
4862
4863 /* Syntax check for a 5-bit unsigned immediate. */
4864 switch (fcode)
4865 {
4866 case SPE_BUILTIN_EVSTDD:
4867 case SPE_BUILTIN_EVSTDH:
4868 case SPE_BUILTIN_EVSTDW:
4869 case SPE_BUILTIN_EVSTWHE:
4870 case SPE_BUILTIN_EVSTWHO:
4871 case SPE_BUILTIN_EVSTWWE:
4872 case SPE_BUILTIN_EVSTWWO:
4873 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4874 if (TREE_CODE (arg1) != INTEGER_CST
4875 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4876 {
4877 error ("argument 2 must be a 5-bit unsigned literal");
4878 return const0_rtx;
4879 }
4880 break;
4881 default:
4882 break;
4883 }
4884
4885 d = (struct builtin_description *) bdesc_2arg_spe;
4886 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4887 if (d->code == fcode)
4888 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4889
4890 d = (struct builtin_description *) bdesc_spe_predicates;
4891 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4892 if (d->code == fcode)
4893 return spe_expand_predicate_builtin (d->icode, arglist, target);
4894
4895 d = (struct builtin_description *) bdesc_spe_evsel;
4896 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4897 if (d->code == fcode)
4898 return spe_expand_evsel_builtin (d->icode, arglist, target);
4899
4900 switch (fcode)
4901 {
4902 case SPE_BUILTIN_EVSTDDX:
4903 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4904 case SPE_BUILTIN_EVSTDHX:
4905 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4906 case SPE_BUILTIN_EVSTDWX:
4907 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
4908 case SPE_BUILTIN_EVSTWHEX:
4909 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
4910 case SPE_BUILTIN_EVSTWHOX:
4911 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
4912 case SPE_BUILTIN_EVSTWWEX:
4913 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
4914 case SPE_BUILTIN_EVSTWWOX:
4915 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
4916 case SPE_BUILTIN_EVSTDD:
4917 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
4918 case SPE_BUILTIN_EVSTDH:
4919 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
4920 case SPE_BUILTIN_EVSTDW:
4921 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
4922 case SPE_BUILTIN_EVSTWHE:
4923 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
4924 case SPE_BUILTIN_EVSTWHO:
4925 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
4926 case SPE_BUILTIN_EVSTWWE:
4927 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
4928 case SPE_BUILTIN_EVSTWWO:
4929 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
4930 case SPE_BUILTIN_MFSPEFSCR:
4931 icode = CODE_FOR_spe_mfspefscr;
4932 tmode = insn_data[icode].operand[0].mode;
4933
4934 if (target == 0
4935 || GET_MODE (target) != tmode
4936 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4937 target = gen_reg_rtx (tmode);
4938
4939 pat = GEN_FCN (icode) (target);
4940 if (! pat)
4941 return 0;
4942 emit_insn (pat);
4943 return target;
4944 case SPE_BUILTIN_MTSPEFSCR:
4945 icode = CODE_FOR_spe_mtspefscr;
4946 arg0 = TREE_VALUE (arglist);
4947 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4948 mode0 = insn_data[icode].operand[0].mode;
4949
4950 if (arg0 == error_mark_node)
4951 return const0_rtx;
4952
4953 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4954 op0 = copy_to_mode_reg (mode0, op0);
4955
4956 pat = GEN_FCN (icode) (op0);
4957 if (pat)
4958 emit_insn (pat);
4959 return NULL_RTX;
4960 default:
4961 break;
4962 }
4963
4964 *expandedp = false;
4965 return NULL_RTX;
4966}
4967
4968static rtx
4969spe_expand_predicate_builtin (icode, arglist, target)
4970 enum insn_code icode;
4971 tree arglist;
4972 rtx target;
4973{
4974 rtx pat, scratch, tmp;
4975 tree form = TREE_VALUE (arglist);
4976 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4977 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4978 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4979 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4980 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4981 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4982 int form_int;
4983 enum rtx_code code;
4984
4985 if (TREE_CODE (form) != INTEGER_CST)
4986 {
4987 error ("argument 1 of __builtin_spe_predicate must be a constant");
4988 return const0_rtx;
4989 }
4990 else
4991 form_int = TREE_INT_CST_LOW (form);
4992
4993 if (mode0 != mode1)
4994 abort ();
4995
4996 if (arg0 == error_mark_node || arg1 == error_mark_node)
4997 return const0_rtx;
4998
4999 if (target == 0
5000 || GET_MODE (target) != SImode
5001 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
5002 target = gen_reg_rtx (SImode);
5003
5004 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5005 op0 = copy_to_mode_reg (mode0, op0);
5006 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
5007 op1 = copy_to_mode_reg (mode1, op1);
5008
5009 scratch = gen_reg_rtx (CCmode);
5010
5011 pat = GEN_FCN (icode) (scratch, op0, op1);
5012 if (! pat)
5013 return const0_rtx;
5014 emit_insn (pat);
5015
5016 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
5017 _lower_. We use one compare, but look in different bits of the
5018 CR for each variant.
5019
5020 There are 2 elements in each SPE simd type (upper/lower). The CR
5021 bits are set as follows:
5022
5023 BIT0 | BIT 1 | BIT 2 | BIT 3
5024 U | L | (U | L) | (U & L)
5025
5026 So, for an "all" relationship, BIT 3 would be set.
5027 For an "any" relationship, BIT 2 would be set. Etc.
5028
5029 Following traditional nomenclature, these bits map to:
5030
5031 BIT0 | BIT 1 | BIT 2 | BIT 3
5032 LT | GT | EQ | OV
5033
5034 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
5035 */
5036
5037 switch (form_int)
5038 {
5039 /* All variant. OV bit. */
5040 case 0:
5041 /* We need to get to the OV bit, which is the ORDERED bit. We
5042 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
5043 that's ugly and will trigger a validate_condition_mode abort.
5044 So let's just use another pattern. */
5045 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
5046 return target;
5047 /* Any variant. EQ bit. */
5048 case 1:
5049 code = EQ;
5050 break;
5051 /* Upper variant. LT bit. */
5052 case 2:
5053 code = LT;
5054 break;
5055 /* Lower variant. GT bit. */
5056 case 3:
5057 code = GT;
5058 break;
5059 default:
5060 error ("argument 1 of __builtin_spe_predicate is out of range");
5061 return const0_rtx;
5062 }
5063
5064 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5065 emit_move_insn (target, tmp);
5066
5067 return target;
5068}
5069
5070/* The evsel builtins look like this:
5071
5072 e = __builtin_spe_evsel_OP (a, b, c, d);
5073
5074 and work like this:
5075
5076 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5077 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5078*/
5079
5080static rtx
5081spe_expand_evsel_builtin (icode, arglist, target)
5082 enum insn_code icode;
5083 tree arglist;
5084 rtx target;
5085{
5086 rtx pat, scratch;
5087 tree arg0 = TREE_VALUE (arglist);
5088 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5089 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5090 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5091 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5092 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5093 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5094 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5095 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5096 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5097
5098 if (mode0 != mode1)
5099 abort ();
5100
5101 if (arg0 == error_mark_node || arg1 == error_mark_node
5102 || arg2 == error_mark_node || arg3 == error_mark_node)
5103 return const0_rtx;
5104
5105 if (target == 0
5106 || GET_MODE (target) != mode0
5107 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5108 target = gen_reg_rtx (mode0);
5109
5110 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5111 op0 = copy_to_mode_reg (mode0, op0);
5112 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5113 op1 = copy_to_mode_reg (mode0, op1);
5114 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5115 op2 = copy_to_mode_reg (mode0, op2);
5116 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5117 op3 = copy_to_mode_reg (mode0, op3);
5118
5119 /* Generate the compare. */
5120 scratch = gen_reg_rtx (CCmode);
5121 pat = GEN_FCN (icode) (scratch, op0, op1);
5122 if (! pat)
5123 return const0_rtx;
5124 emit_insn (pat);
5125
5126 if (mode0 == V2SImode)
5127 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5128 else
5129 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5130
5131 return target;
5132}
5133
0ac081f6
AH
5134/* Expand an expression EXP that calls a built-in function,
5135 with result going to TARGET if that's convenient
5136 (and in mode MODE if that's convenient).
5137 SUBTARGET may be used as the target for computing one of EXP's operands.
5138 IGNORE is nonzero if the value is to be ignored. */
5139
5140static rtx
5141rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5142 tree exp;
5143 rtx target;
00b960c7
AH
5144 rtx subtarget ATTRIBUTE_UNUSED;
5145 enum machine_mode mode ATTRIBUTE_UNUSED;
5146 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5147{
92898235
AH
5148 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5149 tree arglist = TREE_OPERAND (exp, 1);
5150 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5151 struct builtin_description *d;
5152 size_t i;
5153 rtx ret;
5154 bool success;
5155
0ac081f6 5156 if (TARGET_ALTIVEC)
92898235
AH
5157 {
5158 ret = altivec_expand_builtin (exp, target, &success);
5159
a3170dc6
AH
5160 if (success)
5161 return ret;
5162 }
5163 if (TARGET_SPE)
5164 {
5165 ret = spe_expand_builtin (exp, target, &success);
5166
92898235
AH
5167 if (success)
5168 return ret;
5169 }
5170
0559cc77
DE
5171 if (TARGET_ALTIVEC || TARGET_SPE)
5172 {
5173 /* Handle simple unary operations. */
5174 d = (struct builtin_description *) bdesc_1arg;
5175 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5176 if (d->code == fcode)
5177 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5178
5179 /* Handle simple binary operations. */
5180 d = (struct builtin_description *) bdesc_2arg;
5181 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5182 if (d->code == fcode)
5183 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5184
5185 /* Handle simple ternary operations. */
5186 d = (struct builtin_description *) bdesc_3arg;
5187 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5188 if (d->code == fcode)
5189 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5190 }
0ac081f6
AH
5191
5192 abort ();
92898235 5193 return NULL_RTX;
0ac081f6
AH
5194}
5195
5196static void
6fa3f289 5197rs6000_init_builtins ()
0ac081f6 5198{
a3170dc6
AH
5199 if (TARGET_SPE)
5200 spe_init_builtins ();
0ac081f6
AH
5201 if (TARGET_ALTIVEC)
5202 altivec_init_builtins ();
0559cc77
DE
5203 if (TARGET_ALTIVEC || TARGET_SPE)
5204 rs6000_common_init_builtins ();
0ac081f6
AH
5205}
5206
a3170dc6
AH
5207/* Search through a set of builtins and enable the mask bits.
5208 DESC is an array of builtins.
5209 SIZE is the totaly number of builtins.
5210 START is the builtin enum at which to start.
5211 END is the builtin enum at which to end. */
0ac081f6 5212static void
a3170dc6
AH
5213enable_mask_for_builtins (desc, size, start, end)
5214 struct builtin_description *desc;
5215 int size;
5216 enum rs6000_builtins start, end;
5217{
5218 int i;
5219
5220 for (i = 0; i < size; ++i)
5221 if (desc[i].code == start)
5222 break;
5223
5224 if (i == size)
5225 return;
5226
5227 for (; i < size; ++i)
5228 {
5229 /* Flip all the bits on. */
5230 desc[i].mask = target_flags;
5231 if (desc[i].code == end)
5232 break;
5233 }
5234}
5235
5236static void
b24c9d35 5237spe_init_builtins ()
0ac081f6 5238{
a3170dc6
AH
5239 tree endlink = void_list_node;
5240 tree puint_type_node = build_pointer_type (unsigned_type_node);
5241 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5242 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5243 struct builtin_description *d;
0ac081f6
AH
5244 size_t i;
5245
a3170dc6
AH
5246 tree v2si_ftype_4_v2si
5247 = build_function_type
5248 (V2SI_type_node,
5249 tree_cons (NULL_TREE, V2SI_type_node,
5250 tree_cons (NULL_TREE, V2SI_type_node,
5251 tree_cons (NULL_TREE, V2SI_type_node,
5252 tree_cons (NULL_TREE, V2SI_type_node,
5253 endlink)))));
5254
5255 tree v2sf_ftype_4_v2sf
5256 = build_function_type
5257 (V2SF_type_node,
5258 tree_cons (NULL_TREE, V2SF_type_node,
5259 tree_cons (NULL_TREE, V2SF_type_node,
5260 tree_cons (NULL_TREE, V2SF_type_node,
5261 tree_cons (NULL_TREE, V2SF_type_node,
5262 endlink)))));
5263
5264 tree int_ftype_int_v2si_v2si
5265 = build_function_type
5266 (integer_type_node,
5267 tree_cons (NULL_TREE, integer_type_node,
5268 tree_cons (NULL_TREE, V2SI_type_node,
5269 tree_cons (NULL_TREE, V2SI_type_node,
5270 endlink))));
5271
5272 tree int_ftype_int_v2sf_v2sf
5273 = build_function_type
5274 (integer_type_node,
5275 tree_cons (NULL_TREE, integer_type_node,
5276 tree_cons (NULL_TREE, V2SF_type_node,
5277 tree_cons (NULL_TREE, V2SF_type_node,
5278 endlink))));
5279
5280 tree void_ftype_v2si_puint_int
5281 = build_function_type (void_type_node,
5282 tree_cons (NULL_TREE, V2SI_type_node,
5283 tree_cons (NULL_TREE, puint_type_node,
5284 tree_cons (NULL_TREE,
5285 integer_type_node,
5286 endlink))));
5287
5288 tree void_ftype_v2si_puint_char
5289 = build_function_type (void_type_node,
5290 tree_cons (NULL_TREE, V2SI_type_node,
5291 tree_cons (NULL_TREE, puint_type_node,
5292 tree_cons (NULL_TREE,
5293 char_type_node,
5294 endlink))));
5295
5296 tree void_ftype_v2si_pv2si_int
5297 = build_function_type (void_type_node,
5298 tree_cons (NULL_TREE, V2SI_type_node,
5299 tree_cons (NULL_TREE, pv2si_type_node,
5300 tree_cons (NULL_TREE,
5301 integer_type_node,
5302 endlink))));
5303
5304 tree void_ftype_v2si_pv2si_char
5305 = build_function_type (void_type_node,
5306 tree_cons (NULL_TREE, V2SI_type_node,
5307 tree_cons (NULL_TREE, pv2si_type_node,
5308 tree_cons (NULL_TREE,
5309 char_type_node,
5310 endlink))));
5311
5312 tree void_ftype_int
5313 = build_function_type (void_type_node,
5314 tree_cons (NULL_TREE, integer_type_node, endlink));
5315
5316 tree int_ftype_void
5317 = build_function_type (integer_type_node,
5318 tree_cons (NULL_TREE, void_type_node, endlink));
5319
5320 tree v2si_ftype_pv2si_int
5321 = build_function_type (V2SI_type_node,
5322 tree_cons (NULL_TREE, pv2si_type_node,
5323 tree_cons (NULL_TREE, integer_type_node,
5324 endlink)));
5325
5326 tree v2si_ftype_puint_int
5327 = build_function_type (V2SI_type_node,
5328 tree_cons (NULL_TREE, puint_type_node,
5329 tree_cons (NULL_TREE, integer_type_node,
5330 endlink)));
5331
5332 tree v2si_ftype_pushort_int
5333 = build_function_type (V2SI_type_node,
5334 tree_cons (NULL_TREE, pushort_type_node,
5335 tree_cons (NULL_TREE, integer_type_node,
5336 endlink)));
5337
5338 /* The initialization of the simple binary and unary builtins is
5339 done in rs6000_common_init_builtins, but we have to enable the
5340 mask bits here manually because we have run out of `target_flags'
5341 bits. We really need to redesign this mask business. */
5342
5343 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5344 ARRAY_SIZE (bdesc_2arg),
5345 SPE_BUILTIN_EVADDW,
5346 SPE_BUILTIN_EVXOR);
5347 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5348 ARRAY_SIZE (bdesc_1arg),
5349 SPE_BUILTIN_EVABS,
5350 SPE_BUILTIN_EVSUBFUSIAAW);
5351 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5352 ARRAY_SIZE (bdesc_spe_predicates),
5353 SPE_BUILTIN_EVCMPEQ,
5354 SPE_BUILTIN_EVFSTSTLT);
5355 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5356 ARRAY_SIZE (bdesc_spe_evsel),
5357 SPE_BUILTIN_EVSEL_CMPGTS,
5358 SPE_BUILTIN_EVSEL_FSTSTEQ);
5359
5360 /* Initialize irregular SPE builtins. */
5361
5362 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5363 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5364 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5365 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5366 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5367 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5368 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5369 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5370 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5371 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5372 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5373 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5374 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5375 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5376 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5377 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5378
5379 /* Loads. */
5380 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5381 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5382 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5383 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5384 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5385 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5386 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5387 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5388 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5389 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5390 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5391 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5392 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5393 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5394 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5395 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5396 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5397 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5398 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5399 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5400 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5401 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5402
5403 /* Predicates. */
5404 d = (struct builtin_description *) bdesc_spe_predicates;
5405 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5406 {
5407 tree type;
5408
5409 switch (insn_data[d->icode].operand[1].mode)
5410 {
5411 case V2SImode:
5412 type = int_ftype_int_v2si_v2si;
5413 break;
5414 case V2SFmode:
5415 type = int_ftype_int_v2sf_v2sf;
5416 break;
5417 default:
5418 abort ();
5419 }
5420
5421 def_builtin (d->mask, d->name, type, d->code);
5422 }
5423
5424 /* Evsel predicates. */
5425 d = (struct builtin_description *) bdesc_spe_evsel;
5426 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5427 {
5428 tree type;
5429
5430 switch (insn_data[d->icode].operand[1].mode)
5431 {
5432 case V2SImode:
5433 type = v2si_ftype_4_v2si;
5434 break;
5435 case V2SFmode:
5436 type = v2sf_ftype_4_v2sf;
5437 break;
5438 default:
5439 abort ();
5440 }
5441
5442 def_builtin (d->mask, d->name, type, d->code);
5443 }
5444}
5445
5446static void
b24c9d35 5447altivec_init_builtins ()
a3170dc6
AH
5448{
5449 struct builtin_description *d;
5450 struct builtin_description_predicates *dp;
5451 size_t i;
5452 tree pfloat_type_node = build_pointer_type (float_type_node);
5453 tree pint_type_node = build_pointer_type (integer_type_node);
5454 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5455 tree pchar_type_node = build_pointer_type (char_type_node);
5456
5457 tree pvoid_type_node = build_pointer_type (void_type_node);
5458
5459 tree int_ftype_int_v4si_v4si
5460 = build_function_type_list (integer_type_node,
5461 integer_type_node, V4SI_type_node,
5462 V4SI_type_node, NULL_TREE);
f18c054f 5463 tree v4sf_ftype_pfloat
b4de2f7d 5464 = build_function_type_list (V4SF_type_node, pfloat_type_node, NULL_TREE);
a3170dc6 5465 tree void_ftype_pfloat_v4sf
b4de2f7d 5466 = build_function_type_list (void_type_node,
a3170dc6
AH
5467 pfloat_type_node, V4SF_type_node, NULL_TREE);
5468 tree v4si_ftype_pint
5469 = build_function_type_list (V4SI_type_node, pint_type_node, NULL_TREE); tree void_ftype_pint_v4si
b4de2f7d
AH
5470 = build_function_type_list (void_type_node,
5471 pint_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5472 tree v8hi_ftype_pshort
5473 = build_function_type_list (V8HI_type_node, pshort_type_node, NULL_TREE);
f18c054f 5474 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5475 = build_function_type_list (void_type_node,
5476 pshort_type_node, V8HI_type_node, NULL_TREE);
a3170dc6
AH
5477 tree v16qi_ftype_pchar
5478 = build_function_type_list (V16QI_type_node, pchar_type_node, NULL_TREE);
f18c054f 5479 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5480 = build_function_type_list (void_type_node,
5481 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5482 tree void_ftype_v4si
b4de2f7d 5483 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5484 tree v8hi_ftype_void
5485 = build_function_type (V8HI_type_node, void_list_node);
5486 tree void_ftype_void
5487 = build_function_type (void_type_node, void_list_node);
5488 tree void_ftype_qi
5489 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
5490 tree v16qi_ftype_int_pvoid
5491 = build_function_type_list (V16QI_type_node,
5492 integer_type_node, pvoid_type_node, NULL_TREE);
5493 tree v8hi_ftype_int_pvoid
5494 = build_function_type_list (V8HI_type_node,
5495 integer_type_node, pvoid_type_node, NULL_TREE);
5496 tree v4si_ftype_int_pvoid
5497 = build_function_type_list (V4SI_type_node,
5498 integer_type_node, pvoid_type_node, NULL_TREE);
14b32f4e 5499 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5500 = build_function_type_list (void_type_node,
5501 V4SI_type_node, integer_type_node,
5502 pvoid_type_node, NULL_TREE);
6525c0e7 5503 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5504 = build_function_type_list (void_type_node,
5505 V16QI_type_node, integer_type_node,
5506 pvoid_type_node, NULL_TREE);
6525c0e7 5507 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5508 = build_function_type_list (void_type_node,
5509 V8HI_type_node, integer_type_node,
5510 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5511 tree int_ftype_int_v8hi_v8hi
5512 = build_function_type_list (integer_type_node,
5513 integer_type_node, V8HI_type_node,
5514 V8HI_type_node, NULL_TREE);
5515 tree int_ftype_int_v16qi_v16qi
5516 = build_function_type_list (integer_type_node,
5517 integer_type_node, V16QI_type_node,
5518 V16QI_type_node, NULL_TREE);
5519 tree int_ftype_int_v4sf_v4sf
5520 = build_function_type_list (integer_type_node,
5521 integer_type_node, V4SF_type_node,
5522 V4SF_type_node, NULL_TREE);
5523 tree v4si_ftype_v4si
5524 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5525 tree v8hi_ftype_v8hi
5526 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5527 tree v16qi_ftype_v16qi
5528 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5529 tree v4sf_ftype_v4sf
5530 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5531 tree void_ftype_pvoid_int_char
5532 = build_function_type_list (void_type_node,
5533 pvoid_type_node, integer_type_node,
5534 char_type_node, NULL_TREE);
5535
5536 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pfloat, ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5537 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf, ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5538 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pint, ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5539 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si, ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5540 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pshort, ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5541 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi, ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5542 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pchar, ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5543 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi, ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
5544 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5545 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5546 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5547 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
5548 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSL);
5549 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVSR);
5550 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEBX);
5551 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEHX);
5552 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVEWX);
5553 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVXL);
5554 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pvoid, ALTIVEC_BUILTIN_LVX);
5555 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5556 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5557 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5558 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5559 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5560
5561 /* Add the DST variants. */
5562 d = (struct builtin_description *) bdesc_dst;
5563 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
5564 def_builtin (d->mask, d->name, void_ftype_pvoid_int_char, d->code);
5565
5566 /* Initialize the predicates. */
5567 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5568 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5569 {
5570 enum machine_mode mode1;
5571 tree type;
5572
5573 mode1 = insn_data[dp->icode].operand[1].mode;
5574
5575 switch (mode1)
5576 {
5577 case V4SImode:
5578 type = int_ftype_int_v4si_v4si;
5579 break;
5580 case V8HImode:
5581 type = int_ftype_int_v8hi_v8hi;
5582 break;
5583 case V16QImode:
5584 type = int_ftype_int_v16qi_v16qi;
5585 break;
5586 case V4SFmode:
5587 type = int_ftype_int_v4sf_v4sf;
5588 break;
5589 default:
5590 abort ();
5591 }
5592
5593 def_builtin (dp->mask, dp->name, type, dp->code);
5594 }
5595
5596 /* Initialize the abs* operators. */
5597 d = (struct builtin_description *) bdesc_abs;
5598 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5599 {
5600 enum machine_mode mode0;
5601 tree type;
5602
5603 mode0 = insn_data[d->icode].operand[0].mode;
5604
5605 switch (mode0)
5606 {
5607 case V4SImode:
5608 type = v4si_ftype_v4si;
5609 break;
5610 case V8HImode:
5611 type = v8hi_ftype_v8hi;
5612 break;
5613 case V16QImode:
5614 type = v16qi_ftype_v16qi;
5615 break;
5616 case V4SFmode:
5617 type = v4sf_ftype_v4sf;
5618 break;
5619 default:
5620 abort ();
5621 }
5622
5623 def_builtin (d->mask, d->name, type, d->code);
5624 }
5625}
5626
5627static void
b24c9d35 5628rs6000_common_init_builtins ()
a3170dc6
AH
5629{
5630 struct builtin_description *d;
5631 size_t i;
5632
5633 tree v4sf_ftype_v4sf_v4sf_v16qi
5634 = build_function_type_list (V4SF_type_node,
5635 V4SF_type_node, V4SF_type_node,
5636 V16QI_type_node, NULL_TREE);
5637 tree v4si_ftype_v4si_v4si_v16qi
5638 = build_function_type_list (V4SI_type_node,
5639 V4SI_type_node, V4SI_type_node,
5640 V16QI_type_node, NULL_TREE);
5641 tree v8hi_ftype_v8hi_v8hi_v16qi
5642 = build_function_type_list (V8HI_type_node,
5643 V8HI_type_node, V8HI_type_node,
5644 V16QI_type_node, NULL_TREE);
5645 tree v16qi_ftype_v16qi_v16qi_v16qi
5646 = build_function_type_list (V16QI_type_node,
5647 V16QI_type_node, V16QI_type_node,
5648 V16QI_type_node, NULL_TREE);
5649 tree v4si_ftype_char
5650 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5651 tree v8hi_ftype_char
5652 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5653 tree v16qi_ftype_char
5654 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5655 tree v8hi_ftype_v16qi
5656 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5657 tree v4sf_ftype_v4sf
5658 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5659
5660 tree v2si_ftype_v2si_v2si
5661 = build_function_type_list (V2SI_type_node,
5662 V2SI_type_node, V2SI_type_node, NULL_TREE);
5663
5664 tree v2sf_ftype_v2sf_v2sf
5665 = build_function_type_list (V2SF_type_node,
5666 V2SF_type_node, V2SF_type_node, NULL_TREE);
5667
5668 tree v2si_ftype_int_int
5669 = build_function_type_list (V2SI_type_node,
5670 integer_type_node, integer_type_node,
5671 NULL_TREE);
5672
5673 tree v2si_ftype_v2si
5674 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5675
5676 tree v2sf_ftype_v2sf
5677 = build_function_type_list (V2SF_type_node,
5678 V2SF_type_node, NULL_TREE);
5679
5680 tree v2sf_ftype_v2si
5681 = build_function_type_list (V2SF_type_node,
5682 V2SI_type_node, NULL_TREE);
5683
5684 tree v2si_ftype_v2sf
5685 = build_function_type_list (V2SI_type_node,
5686 V2SF_type_node, NULL_TREE);
5687
5688 tree v2si_ftype_v2si_char
5689 = build_function_type_list (V2SI_type_node,
5690 V2SI_type_node, char_type_node, NULL_TREE);
5691
5692 tree v2si_ftype_int_char
5693 = build_function_type_list (V2SI_type_node,
5694 integer_type_node, char_type_node, NULL_TREE);
5695
5696 tree v2si_ftype_char
5697 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5698
5699 tree int_ftype_int_int
5700 = build_function_type_list (integer_type_node,
5701 integer_type_node, integer_type_node,
5702 NULL_TREE);
95385cbb 5703
0ac081f6 5704 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5705 = build_function_type_list (V4SI_type_node,
5706 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5707 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5708 = build_function_type_list (V4SF_type_node,
5709 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5710 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5711 = build_function_type_list (V4SI_type_node,
5712 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5713 tree v4si_ftype_v4si_char
b4de2f7d
AH
5714 = build_function_type_list (V4SI_type_node,
5715 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5716 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5717 = build_function_type_list (V8HI_type_node,
5718 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5719 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5720 = build_function_type_list (V16QI_type_node,
5721 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5722 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5723 = build_function_type_list (V16QI_type_node,
5724 V16QI_type_node, V16QI_type_node,
5725 char_type_node, NULL_TREE);
24408032 5726 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5727 = build_function_type_list (V8HI_type_node,
5728 V8HI_type_node, V8HI_type_node,
5729 char_type_node, NULL_TREE);
24408032 5730 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5731 = build_function_type_list (V4SI_type_node,
5732 V4SI_type_node, V4SI_type_node,
5733 char_type_node, NULL_TREE);
24408032 5734 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5735 = build_function_type_list (V4SF_type_node,
5736 V4SF_type_node, V4SF_type_node,
5737 char_type_node, NULL_TREE);
0ac081f6 5738 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5739 = build_function_type_list (V4SF_type_node,
5740 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5741 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5742 = build_function_type_list (V4SF_type_node,
5743 V4SF_type_node, V4SF_type_node,
5744 V4SI_type_node, NULL_TREE);
2212663f 5745 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5746 = build_function_type_list (V4SF_type_node,
5747 V4SF_type_node, V4SF_type_node,
5748 V4SF_type_node, NULL_TREE);
617e0e1d 5749 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
5750 = build_function_type_list (V4SI_type_node,
5751 V4SI_type_node, V4SI_type_node,
5752 V4SI_type_node, NULL_TREE);
0ac081f6 5753 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
5754 = build_function_type_list (V8HI_type_node,
5755 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 5756 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
5757 = build_function_type_list (V8HI_type_node,
5758 V8HI_type_node, V8HI_type_node,
5759 V8HI_type_node, NULL_TREE);
2212663f 5760 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
5761 = build_function_type_list (V4SI_type_node,
5762 V8HI_type_node, V8HI_type_node,
5763 V4SI_type_node, NULL_TREE);
2212663f 5764 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
5765 = build_function_type_list (V4SI_type_node,
5766 V16QI_type_node, V16QI_type_node,
5767 V4SI_type_node, NULL_TREE);
0ac081f6 5768 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
5769 = build_function_type_list (V16QI_type_node,
5770 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5771 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
5772 = build_function_type_list (V4SI_type_node,
5773 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 5774 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
5775 = build_function_type_list (V8HI_type_node,
5776 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5777 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
5778 = build_function_type_list (V4SI_type_node,
5779 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5780 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
5781 = build_function_type_list (V8HI_type_node,
5782 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 5783 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
5784 = build_function_type_list (V16QI_type_node,
5785 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5786 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
5787 = build_function_type_list (V4SI_type_node,
5788 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 5789 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
5790 = build_function_type_list (V4SI_type_node,
5791 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5792 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
5793 = build_function_type_list (V4SI_type_node,
5794 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5795 tree v4si_ftype_v8hi
5796 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5797 tree int_ftype_v4si_v4si
5798 = build_function_type_list (integer_type_node,
5799 V4SI_type_node, V4SI_type_node, NULL_TREE);
5800 tree int_ftype_v4sf_v4sf
5801 = build_function_type_list (integer_type_node,
5802 V4SF_type_node, V4SF_type_node, NULL_TREE);
5803 tree int_ftype_v16qi_v16qi
5804 = build_function_type_list (integer_type_node,
5805 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5806 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
5807 = build_function_type_list (integer_type_node,
5808 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5809
6f317ef3 5810 /* Add the simple ternary operators. */
2212663f 5811 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 5812 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
5813 {
5814
5815 enum machine_mode mode0, mode1, mode2, mode3;
5816 tree type;
5817
0559cc77 5818 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5819 continue;
5820
5821 mode0 = insn_data[d->icode].operand[0].mode;
5822 mode1 = insn_data[d->icode].operand[1].mode;
5823 mode2 = insn_data[d->icode].operand[2].mode;
5824 mode3 = insn_data[d->icode].operand[3].mode;
5825
5826 /* When all four are of the same mode. */
5827 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5828 {
5829 switch (mode0)
5830 {
617e0e1d
DB
5831 case V4SImode:
5832 type = v4si_ftype_v4si_v4si_v4si;
5833 break;
2212663f
DB
5834 case V4SFmode:
5835 type = v4sf_ftype_v4sf_v4sf_v4sf;
5836 break;
5837 case V8HImode:
5838 type = v8hi_ftype_v8hi_v8hi_v8hi;
5839 break;
5840 case V16QImode:
5841 type = v16qi_ftype_v16qi_v16qi_v16qi;
5842 break;
5843 default:
5844 abort();
5845 }
5846 }
5847 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5848 {
5849 switch (mode0)
5850 {
5851 case V4SImode:
5852 type = v4si_ftype_v4si_v4si_v16qi;
5853 break;
5854 case V4SFmode:
5855 type = v4sf_ftype_v4sf_v4sf_v16qi;
5856 break;
5857 case V8HImode:
5858 type = v8hi_ftype_v8hi_v8hi_v16qi;
5859 break;
5860 case V16QImode:
5861 type = v16qi_ftype_v16qi_v16qi_v16qi;
5862 break;
5863 default:
5864 abort();
5865 }
5866 }
5867 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5868 && mode3 == V4SImode)
24408032 5869 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
5870 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5871 && mode3 == V4SImode)
24408032 5872 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
5873 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5874 && mode3 == V4SImode)
24408032
AH
5875 type = v4sf_ftype_v4sf_v4sf_v4si;
5876
5877 /* vchar, vchar, vchar, 4 bit literal. */
5878 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5879 && mode3 == QImode)
5880 type = v16qi_ftype_v16qi_v16qi_char;
5881
5882 /* vshort, vshort, vshort, 4 bit literal. */
5883 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5884 && mode3 == QImode)
5885 type = v8hi_ftype_v8hi_v8hi_char;
5886
5887 /* vint, vint, vint, 4 bit literal. */
5888 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
5889 && mode3 == QImode)
5890 type = v4si_ftype_v4si_v4si_char;
5891
5892 /* vfloat, vfloat, vfloat, 4 bit literal. */
5893 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
5894 && mode3 == QImode)
5895 type = v4sf_ftype_v4sf_v4sf_char;
5896
2212663f
DB
5897 else
5898 abort ();
5899
5900 def_builtin (d->mask, d->name, type, d->code);
5901 }
5902
0ac081f6 5903 /* Add the simple binary operators. */
00b960c7 5904 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 5905 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
5906 {
5907 enum machine_mode mode0, mode1, mode2;
5908 tree type;
5909
0559cc77 5910 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
5911 continue;
5912
5913 mode0 = insn_data[d->icode].operand[0].mode;
5914 mode1 = insn_data[d->icode].operand[1].mode;
5915 mode2 = insn_data[d->icode].operand[2].mode;
5916
5917 /* When all three operands are of the same mode. */
5918 if (mode0 == mode1 && mode1 == mode2)
5919 {
5920 switch (mode0)
5921 {
5922 case V4SFmode:
5923 type = v4sf_ftype_v4sf_v4sf;
5924 break;
5925 case V4SImode:
5926 type = v4si_ftype_v4si_v4si;
5927 break;
5928 case V16QImode:
5929 type = v16qi_ftype_v16qi_v16qi;
5930 break;
5931 case V8HImode:
5932 type = v8hi_ftype_v8hi_v8hi;
5933 break;
a3170dc6
AH
5934 case V2SImode:
5935 type = v2si_ftype_v2si_v2si;
5936 break;
5937 case V2SFmode:
5938 type = v2sf_ftype_v2sf_v2sf;
5939 break;
5940 case SImode:
5941 type = int_ftype_int_int;
5942 break;
0ac081f6
AH
5943 default:
5944 abort ();
5945 }
5946 }
5947
5948 /* A few other combos we really don't want to do manually. */
5949
5950 /* vint, vfloat, vfloat. */
5951 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
5952 type = v4si_ftype_v4sf_v4sf;
5953
5954 /* vshort, vchar, vchar. */
5955 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
5956 type = v8hi_ftype_v16qi_v16qi;
5957
5958 /* vint, vshort, vshort. */
5959 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
5960 type = v4si_ftype_v8hi_v8hi;
5961
5962 /* vshort, vint, vint. */
5963 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
5964 type = v8hi_ftype_v4si_v4si;
5965
5966 /* vchar, vshort, vshort. */
5967 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
5968 type = v16qi_ftype_v8hi_v8hi;
5969
5970 /* vint, vchar, vint. */
5971 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
5972 type = v4si_ftype_v16qi_v4si;
5973
fa066a23
AH
5974 /* vint, vchar, vchar. */
5975 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
5976 type = v4si_ftype_v16qi_v16qi;
5977
0ac081f6
AH
5978 /* vint, vshort, vint. */
5979 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
5980 type = v4si_ftype_v8hi_v4si;
2212663f
DB
5981
5982 /* vint, vint, 5 bit literal. */
5983 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
5984 type = v4si_ftype_v4si_char;
5985
5986 /* vshort, vshort, 5 bit literal. */
5987 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
5988 type = v8hi_ftype_v8hi_char;
5989
5990 /* vchar, vchar, 5 bit literal. */
5991 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
5992 type = v16qi_ftype_v16qi_char;
0ac081f6 5993
617e0e1d
DB
5994 /* vfloat, vint, 5 bit literal. */
5995 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
5996 type = v4sf_ftype_v4si_char;
5997
5998 /* vint, vfloat, 5 bit literal. */
5999 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
6000 type = v4si_ftype_v4sf_char;
6001
a3170dc6
AH
6002 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
6003 type = v2si_ftype_int_int;
6004
6005 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
6006 type = v2si_ftype_v2si_char;
6007
6008 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
6009 type = v2si_ftype_int_char;
6010
0ac081f6
AH
6011 /* int, x, x. */
6012 else if (mode0 == SImode)
6013 {
6014 switch (mode1)
6015 {
6016 case V4SImode:
6017 type = int_ftype_v4si_v4si;
6018 break;
6019 case V4SFmode:
6020 type = int_ftype_v4sf_v4sf;
6021 break;
6022 case V16QImode:
6023 type = int_ftype_v16qi_v16qi;
6024 break;
6025 case V8HImode:
6026 type = int_ftype_v8hi_v8hi;
6027 break;
6028 default:
6029 abort ();
6030 }
6031 }
6032
6033 else
6034 abort ();
6035
2212663f
DB
6036 def_builtin (d->mask, d->name, type, d->code);
6037 }
24408032 6038
2212663f
DB
6039 /* Add the simple unary operators. */
6040 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 6041 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
6042 {
6043 enum machine_mode mode0, mode1;
6044 tree type;
6045
0559cc77 6046 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
6047 continue;
6048
6049 mode0 = insn_data[d->icode].operand[0].mode;
6050 mode1 = insn_data[d->icode].operand[1].mode;
6051
6052 if (mode0 == V4SImode && mode1 == QImode)
6053 type = v4si_ftype_char;
6054 else if (mode0 == V8HImode && mode1 == QImode)
6055 type = v8hi_ftype_char;
6056 else if (mode0 == V16QImode && mode1 == QImode)
6057 type = v16qi_ftype_char;
617e0e1d
DB
6058 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6059 type = v4sf_ftype_v4sf;
20e26713
AH
6060 else if (mode0 == V8HImode && mode1 == V16QImode)
6061 type = v8hi_ftype_v16qi;
6062 else if (mode0 == V4SImode && mode1 == V8HImode)
6063 type = v4si_ftype_v8hi;
a3170dc6
AH
6064 else if (mode0 == V2SImode && mode1 == V2SImode)
6065 type = v2si_ftype_v2si;
6066 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6067 type = v2sf_ftype_v2sf;
6068 else if (mode0 == V2SFmode && mode1 == V2SImode)
6069 type = v2sf_ftype_v2si;
6070 else if (mode0 == V2SImode && mode1 == V2SFmode)
6071 type = v2si_ftype_v2sf;
6072 else if (mode0 == V2SImode && mode1 == QImode)
6073 type = v2si_ftype_char;
2212663f
DB
6074 else
6075 abort ();
6076
0ac081f6
AH
6077 def_builtin (d->mask, d->name, type, d->code);
6078 }
6079}
6080
35aff10b 6081\f
7e69e155
MM
6082/* Expand a block move operation, and return 1 if successful. Return 0
6083 if we should let the compiler generate normal code.
6084
6085 operands[0] is the destination
6086 operands[1] is the source
6087 operands[2] is the length
6088 operands[3] is the alignment */
6089
3933e0e1
MM
6090#define MAX_MOVE_REG 4
6091
7e69e155
MM
6092int
6093expand_block_move (operands)
6094 rtx operands[];
6095{
b6c9286a
MM
6096 rtx orig_dest = operands[0];
6097 rtx orig_src = operands[1];
7e69e155 6098 rtx bytes_rtx = operands[2];
7e69e155 6099 rtx align_rtx = operands[3];
3933e0e1 6100 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6101 int align;
3933e0e1
MM
6102 int bytes;
6103 int offset;
7e69e155
MM
6104 int move_bytes;
6105
3933e0e1 6106 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6107 if (! constp)
3933e0e1
MM
6108 return 0;
6109
5ee95df6
FS
6110 /* If this is not a fixed size alignment, abort */
6111 if (GET_CODE (align_rtx) != CONST_INT)
6112 abort ();
6113 align = INTVAL (align_rtx);
6114
7e69e155 6115 /* Anything to move? */
3933e0e1
MM
6116 bytes = INTVAL (bytes_rtx);
6117 if (bytes <= 0)
7e69e155
MM
6118 return 1;
6119
ea9982a8 6120 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6121 reg_parm_stack_space. */
ea9982a8 6122 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6123 return 0;
6124
3933e0e1 6125 if (TARGET_STRING) /* string instructions are available */
7e69e155 6126 {
35aff10b 6127 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6128 {
35aff10b
AM
6129 union {
6130 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
6131 rtx (*mov) PARAMS ((rtx, rtx));
6132 } gen_func;
6133 enum machine_mode mode = BLKmode;
6134 rtx src, dest;
6135
3933e0e1 6136 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6137 && ! fixed_regs[5]
6138 && ! fixed_regs[6]
6139 && ! fixed_regs[7]
6140 && ! fixed_regs[8]
6141 && ! fixed_regs[9]
6142 && ! fixed_regs[10]
6143 && ! fixed_regs[11]
6144 && ! fixed_regs[12])
3933e0e1
MM
6145 {
6146 move_bytes = (bytes > 32) ? 32 : bytes;
35aff10b 6147 gen_func.movstrsi = gen_movstrsi_8reg;
3933e0e1
MM
6148 }
6149 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6150 && ! fixed_regs[5]
6151 && ! fixed_regs[6]
cc0d9ba8
DE
6152 && ! fixed_regs[7]
6153 && ! fixed_regs[8]
6154 && ! fixed_regs[9]
f9562f27 6155 && ! fixed_regs[10])
3933e0e1
MM
6156 {
6157 move_bytes = (bytes > 24) ? 24 : bytes;
35aff10b 6158 gen_func.movstrsi = gen_movstrsi_6reg;
3933e0e1
MM
6159 }
6160 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6161 && ! fixed_regs[5]
6162 && ! fixed_regs[6]
6163 && ! fixed_regs[7]
6164 && ! fixed_regs[8])
3933e0e1
MM
6165 {
6166 move_bytes = (bytes > 16) ? 16 : bytes;
35aff10b 6167 gen_func.movstrsi = gen_movstrsi_4reg;
3933e0e1 6168 }
acad7ed3 6169 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6170 /* 64-bit loads and stores require word-aligned
82e41834 6171 displacements. */
a4f6c312 6172 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6173 {
6174 move_bytes = 8;
35aff10b
AM
6175 mode = DImode;
6176 gen_func.mov = gen_movdi;
acad7ed3 6177 }
09a625f7 6178 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6179 { /* move up to 8 bytes at a time */
6180 move_bytes = (bytes > 8) ? 8 : bytes;
35aff10b 6181 gen_func.movstrsi = gen_movstrsi_2reg;
3933e0e1 6182 }
cc0d9ba8 6183 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6184 { /* move 4 bytes */
6185 move_bytes = 4;
35aff10b
AM
6186 mode = SImode;
6187 gen_func.mov = gen_movsi;
3933e0e1 6188 }
cc0d9ba8 6189 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6190 { /* move 2 bytes */
6191 move_bytes = 2;
35aff10b
AM
6192 mode = HImode;
6193 gen_func.mov = gen_movhi;
3933e0e1
MM
6194 }
6195 else if (bytes == 1) /* move 1 byte */
6196 {
6197 move_bytes = 1;
35aff10b
AM
6198 mode = QImode;
6199 gen_func.mov = gen_movqi;
3933e0e1
MM
6200 }
6201 else
6202 { /* move up to 4 bytes at a time */
6203 move_bytes = (bytes > 4) ? 4 : bytes;
35aff10b 6204 gen_func.movstrsi = gen_movstrsi_1reg;
3933e0e1 6205 }
4c64a852 6206
35aff10b
AM
6207 src = adjust_address (orig_src, mode, offset);
6208 dest = adjust_address (orig_dest, mode, offset);
6209
6210 if (mode == BLKmode)
015892ee 6211 {
35aff10b
AM
6212 /* Move the address into scratch registers. The movstrsi
6213 patterns require zero offset. */
6214 if (!REG_P (XEXP (src, 0)))
cc0d9ba8 6215 {
35aff10b
AM
6216 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
6217 src = replace_equiv_address (src, src_reg);
cc0d9ba8 6218 }
35aff10b
AM
6219 set_mem_size (src, GEN_INT (move_bytes));
6220
6221 if (!REG_P (XEXP (dest, 0)))
cc0d9ba8 6222 {
35aff10b
AM
6223 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
6224 dest = replace_equiv_address (dest, dest_reg);
cc0d9ba8 6225 }
35aff10b
AM
6226 set_mem_size (dest, GEN_INT (move_bytes));
6227
6228 emit_insn ((*gen_func.movstrsi) (dest, src,
6229 GEN_INT (move_bytes & 31),
6230 align_rtx));
6231 }
6232 else
6233 {
6234 rtx tmp_reg = gen_reg_rtx (mode);
6235
6236 emit_insn ((*gen_func.mov) (tmp_reg, src));
6237 emit_insn ((*gen_func.mov) (dest, tmp_reg));
015892ee 6238 }
4c64a852 6239 }
3933e0e1
MM
6240 }
6241
6242 else /* string instructions not available */
6243 {
35aff10b
AM
6244 rtx stores[MAX_MOVE_REG];
6245 int num_reg = 0;
6246 int i;
6247
6248 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6249 {
35aff10b
AM
6250 rtx (*gen_mov_func) PARAMS ((rtx, rtx));
6251 enum machine_mode mode;
6252 rtx src, dest, tmp_reg;
3933e0e1 6253
cc0d9ba8
DE
6254 /* Generate the appropriate load and store, saving the stores
6255 for later. */
6256 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6257 /* 64-bit loads and stores require word-aligned
6258 displacements. */
cc0d9ba8 6259 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6260 {
6261 move_bytes = 8;
35aff10b
AM
6262 mode = DImode;
6263 gen_mov_func = gen_movdi;
b6c9286a 6264 }
cc0d9ba8 6265 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6266 {
6267 move_bytes = 4;
35aff10b
AM
6268 mode = SImode;
6269 gen_mov_func = gen_movsi;
3933e0e1 6270 }
cc0d9ba8 6271 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6272 {
6273 move_bytes = 2;
35aff10b
AM
6274 mode = HImode;
6275 gen_mov_func = gen_movhi;
3933e0e1
MM
6276 }
6277 else
6278 {
6279 move_bytes = 1;
35aff10b
AM
6280 mode = QImode;
6281 gen_mov_func = gen_movqi;
3933e0e1
MM
6282 }
6283
35aff10b
AM
6284 src = adjust_address (orig_src, mode, offset);
6285 dest = adjust_address (orig_dest, mode, offset);
6286 tmp_reg = gen_reg_rtx (mode);
6287
6288 emit_insn ((*gen_mov_func) (tmp_reg, src));
6289 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
6290
3933e0e1
MM
6291 if (num_reg >= MAX_MOVE_REG)
6292 {
6293 for (i = 0; i < num_reg; i++)
6294 emit_insn (stores[i]);
6295 num_reg = 0;
7e69e155
MM
6296 }
6297 }
3933e0e1 6298
b6c9286a
MM
6299 for (i = 0; i < num_reg; i++)
6300 emit_insn (stores[i]);
7e69e155
MM
6301 }
6302
6303 return 1;
6304}
6305
9878760c
RK
6306\f
6307/* Return 1 if OP is a load multiple operation. It is known to be a
6308 PARALLEL and the first section will be tested. */
6309
6310int
6311load_multiple_operation (op, mode)
6312 rtx op;
296b8152 6313 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6314{
6315 int count = XVECLEN (op, 0);
e2c953b6 6316 unsigned int dest_regno;
9878760c
RK
6317 rtx src_addr;
6318 int i;
6319
6320 /* Perform a quick check so we don't blow up below. */
6321 if (count <= 1
6322 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6323 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6324 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6325 return 0;
6326
6327 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6328 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6329
6330 for (i = 1; i < count; i++)
6331 {
6332 rtx elt = XVECEXP (op, 0, i);
6333
6334 if (GET_CODE (elt) != SET
6335 || GET_CODE (SET_DEST (elt)) != REG
6336 || GET_MODE (SET_DEST (elt)) != SImode
6337 || REGNO (SET_DEST (elt)) != dest_regno + i
6338 || GET_CODE (SET_SRC (elt)) != MEM
6339 || GET_MODE (SET_SRC (elt)) != SImode
6340 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6341 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6342 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6343 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6344 return 0;
6345 }
6346
6347 return 1;
6348}
6349
6350/* Similar, but tests for store multiple. Here, the second vector element
6351 is a CLOBBER. It will be tested later. */
6352
6353int
6354store_multiple_operation (op, mode)
6355 rtx op;
296b8152 6356 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6357{
6358 int count = XVECLEN (op, 0) - 1;
e2c953b6 6359 unsigned int src_regno;
9878760c
RK
6360 rtx dest_addr;
6361 int i;
6362
6363 /* Perform a quick check so we don't blow up below. */
6364 if (count <= 1
6365 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6366 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6367 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6368 return 0;
6369
6370 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6371 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6372
6373 for (i = 1; i < count; i++)
6374 {
6375 rtx elt = XVECEXP (op, 0, i + 1);
6376
6377 if (GET_CODE (elt) != SET
6378 || GET_CODE (SET_SRC (elt)) != REG
6379 || GET_MODE (SET_SRC (elt)) != SImode
6380 || REGNO (SET_SRC (elt)) != src_regno + i
6381 || GET_CODE (SET_DEST (elt)) != MEM
6382 || GET_MODE (SET_DEST (elt)) != SImode
6383 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6384 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6385 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6386 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6387 return 0;
6388 }
6389
6390 return 1;
6391}
9ebbca7d 6392
00b960c7
AH
6393/* Return 1 for a parallel vrsave operation. */
6394
6395int
6396vrsave_operation (op, mode)
6397 rtx op;
6398 enum machine_mode mode ATTRIBUTE_UNUSED;
6399{
6400 int count = XVECLEN (op, 0);
6401 unsigned int dest_regno, src_regno;
6402 int i;
6403
6404 if (count <= 1
6405 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6406 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6407 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6408 return 0;
6409
6410 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6411 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6412
6413 if (dest_regno != VRSAVE_REGNO
6414 && src_regno != VRSAVE_REGNO)
6415 return 0;
6416
6417 for (i = 1; i < count; i++)
6418 {
6419 rtx elt = XVECEXP (op, 0, i);
6420
9aa86737
AH
6421 if (GET_CODE (elt) != CLOBBER
6422 && GET_CODE (elt) != SET)
00b960c7
AH
6423 return 0;
6424 }
6425
6426 return 1;
6427}
6428
a4f6c312 6429/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6430
6431int
6432mtcrf_operation (op, mode)
6433 rtx op;
6434 enum machine_mode mode ATTRIBUTE_UNUSED;
6435{
6436 int count = XVECLEN (op, 0);
6437 int i;
9ebbca7d
GK
6438 rtx src_reg;
6439
6440 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6441 if (count < 1
6442 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6443 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6444 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6445 return 0;
e35b9579 6446 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6447
6448 if (GET_CODE (src_reg) != REG
6449 || GET_MODE (src_reg) != SImode
6450 || ! INT_REGNO_P (REGNO (src_reg)))
6451 return 0;
6452
e35b9579 6453 for (i = 0; i < count; i++)
9ebbca7d
GK
6454 {
6455 rtx exp = XVECEXP (op, 0, i);
6456 rtx unspec;
6457 int maskval;
6458
6459 if (GET_CODE (exp) != SET
6460 || GET_CODE (SET_DEST (exp)) != REG
6461 || GET_MODE (SET_DEST (exp)) != CCmode
6462 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6463 return 0;
6464 unspec = SET_SRC (exp);
6465 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6466
6467 if (GET_CODE (unspec) != UNSPEC
6468 || XINT (unspec, 1) != 20
6469 || XVECLEN (unspec, 0) != 2
6470 || XVECEXP (unspec, 0, 0) != src_reg
6471 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6472 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6473 return 0;
6474 }
e35b9579 6475 return 1;
9ebbca7d
GK
6476}
6477
a4f6c312 6478/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6479
6480int
6481lmw_operation (op, mode)
6482 rtx op;
6483 enum machine_mode mode ATTRIBUTE_UNUSED;
6484{
6485 int count = XVECLEN (op, 0);
e2c953b6 6486 unsigned int dest_regno;
9ebbca7d 6487 rtx src_addr;
e2c953b6 6488 unsigned int base_regno;
9ebbca7d
GK
6489 HOST_WIDE_INT offset;
6490 int i;
6491
6492 /* Perform a quick check so we don't blow up below. */
6493 if (count <= 1
6494 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6495 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6496 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6497 return 0;
6498
6499 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6500 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6501
6502 if (dest_regno > 31
e2c953b6 6503 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6504 return 0;
6505
258bfae2 6506 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6507 {
6508 offset = 0;
6509 base_regno = REGNO (src_addr);
6510 if (base_regno == 0)
6511 return 0;
6512 }
258bfae2 6513 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6514 {
6515 offset = INTVAL (XEXP (src_addr, 1));
6516 base_regno = REGNO (XEXP (src_addr, 0));
6517 }
6518 else
6519 return 0;
6520
6521 for (i = 0; i < count; i++)
6522 {
6523 rtx elt = XVECEXP (op, 0, i);
6524 rtx newaddr;
6525 rtx addr_reg;
6526 HOST_WIDE_INT newoffset;
6527
6528 if (GET_CODE (elt) != SET
6529 || GET_CODE (SET_DEST (elt)) != REG
6530 || GET_MODE (SET_DEST (elt)) != SImode
6531 || REGNO (SET_DEST (elt)) != dest_regno + i
6532 || GET_CODE (SET_SRC (elt)) != MEM
6533 || GET_MODE (SET_SRC (elt)) != SImode)
6534 return 0;
6535 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6536 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6537 {
6538 newoffset = 0;
6539 addr_reg = newaddr;
6540 }
258bfae2 6541 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6542 {
6543 addr_reg = XEXP (newaddr, 0);
6544 newoffset = INTVAL (XEXP (newaddr, 1));
6545 }
6546 else
6547 return 0;
6548 if (REGNO (addr_reg) != base_regno
6549 || newoffset != offset + 4 * i)
6550 return 0;
6551 }
6552
6553 return 1;
6554}
6555
a4f6c312 6556/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6557
6558int
6559stmw_operation (op, mode)
6560 rtx op;
6561 enum machine_mode mode ATTRIBUTE_UNUSED;
6562{
6563 int count = XVECLEN (op, 0);
e2c953b6 6564 unsigned int src_regno;
9ebbca7d 6565 rtx dest_addr;
e2c953b6 6566 unsigned int base_regno;
9ebbca7d
GK
6567 HOST_WIDE_INT offset;
6568 int i;
6569
6570 /* Perform a quick check so we don't blow up below. */
6571 if (count <= 1
6572 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6573 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6574 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6575 return 0;
6576
6577 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6578 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6579
6580 if (src_regno > 31
e2c953b6 6581 || count != 32 - (int) src_regno)
9ebbca7d
GK
6582 return 0;
6583
258bfae2 6584 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6585 {
6586 offset = 0;
6587 base_regno = REGNO (dest_addr);
6588 if (base_regno == 0)
6589 return 0;
6590 }
258bfae2 6591 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6592 {
6593 offset = INTVAL (XEXP (dest_addr, 1));
6594 base_regno = REGNO (XEXP (dest_addr, 0));
6595 }
6596 else
6597 return 0;
6598
6599 for (i = 0; i < count; i++)
6600 {
6601 rtx elt = XVECEXP (op, 0, i);
6602 rtx newaddr;
6603 rtx addr_reg;
6604 HOST_WIDE_INT newoffset;
6605
6606 if (GET_CODE (elt) != SET
6607 || GET_CODE (SET_SRC (elt)) != REG
6608 || GET_MODE (SET_SRC (elt)) != SImode
6609 || REGNO (SET_SRC (elt)) != src_regno + i
6610 || GET_CODE (SET_DEST (elt)) != MEM
6611 || GET_MODE (SET_DEST (elt)) != SImode)
6612 return 0;
6613 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6614 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6615 {
6616 newoffset = 0;
6617 addr_reg = newaddr;
6618 }
258bfae2 6619 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6620 {
6621 addr_reg = XEXP (newaddr, 0);
6622 newoffset = INTVAL (XEXP (newaddr, 1));
6623 }
6624 else
6625 return 0;
6626 if (REGNO (addr_reg) != base_regno
6627 || newoffset != offset + 4 * i)
6628 return 0;
6629 }
6630
6631 return 1;
6632}
9878760c 6633\f
a4f6c312
SS
6634/* A validation routine: say whether CODE, a condition code, and MODE
6635 match. The other alternatives either don't make sense or should
6636 never be generated. */
39a10a29 6637
39a10a29
GK
6638static void
6639validate_condition_mode (code, mode)
6640 enum rtx_code code;
6641 enum machine_mode mode;
6642{
6643 if (GET_RTX_CLASS (code) != '<'
6644 || GET_MODE_CLASS (mode) != MODE_CC)
6645 abort ();
6646
6647 /* These don't make sense. */
6648 if ((code == GT || code == LT || code == GE || code == LE)
6649 && mode == CCUNSmode)
6650 abort ();
6651
6652 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6653 && mode != CCUNSmode)
6654 abort ();
6655
6656 if (mode != CCFPmode
6657 && (code == ORDERED || code == UNORDERED
6658 || code == UNEQ || code == LTGT
6659 || code == UNGT || code == UNLT
6660 || code == UNGE || code == UNLE))
a4f6c312 6661 abort ();
39a10a29 6662
de6c5979 6663 /* These should never be generated except for
ad72b533 6664 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6665 if (mode == CCFPmode
de6c5979 6666 && ! flag_unsafe_math_optimizations
ad72b533 6667 && ! flag_finite_math_only
39a10a29
GK
6668 && (code == LE || code == GE
6669 || code == UNEQ || code == LTGT
6670 || code == UNGT || code == UNLT))
6671 abort ();
6672
6673 /* These are invalid; the information is not there. */
6674 if (mode == CCEQmode
6675 && code != EQ && code != NE)
6676 abort ();
6677}
6678
9878760c
RK
6679/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6680 We only check the opcode against the mode of the CC value here. */
6681
6682int
6683branch_comparison_operator (op, mode)
592696dd 6684 rtx op;
296b8152 6685 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6686{
6687 enum rtx_code code = GET_CODE (op);
6688 enum machine_mode cc_mode;
6689
6690 if (GET_RTX_CLASS (code) != '<')
6691 return 0;
6692
6693 cc_mode = GET_MODE (XEXP (op, 0));
6694 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6695 return 0;
6696
39a10a29 6697 validate_condition_mode (code, cc_mode);
9878760c 6698
39a10a29
GK
6699 return 1;
6700}
6701
6702/* Return 1 if OP is a comparison operation that is valid for a branch
6703 insn and which is true if the corresponding bit in the CC register
6704 is set. */
6705
6706int
6707branch_positive_comparison_operator (op, mode)
592696dd 6708 rtx op;
39a10a29
GK
6709 enum machine_mode mode;
6710{
6711 enum rtx_code code;
6712
6713 if (! branch_comparison_operator (op, mode))
9878760c
RK
6714 return 0;
6715
39a10a29
GK
6716 code = GET_CODE (op);
6717 return (code == EQ || code == LT || code == GT
a3170dc6 6718 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
6719 || code == LTU || code == GTU
6720 || code == UNORDERED);
9878760c
RK
6721}
6722
6723/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6724 We check the opcode against the mode of the CC value and disallow EQ or
6725 NE comparisons for integers. */
6726
6727int
6728scc_comparison_operator (op, mode)
592696dd 6729 rtx op;
9878760c
RK
6730 enum machine_mode mode;
6731{
6732 enum rtx_code code = GET_CODE (op);
6733 enum machine_mode cc_mode;
6734
6735 if (GET_MODE (op) != mode && mode != VOIDmode)
6736 return 0;
6737
6738 if (GET_RTX_CLASS (code) != '<')
6739 return 0;
6740
6741 cc_mode = GET_MODE (XEXP (op, 0));
6742 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6743 return 0;
6744
39a10a29 6745 validate_condition_mode (code, cc_mode);
9878760c 6746
39a10a29 6747 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
6748 return 0;
6749
9878760c
RK
6750 return 1;
6751}
e0cd0770
JC
6752
6753int
6754trap_comparison_operator (op, mode)
6755 rtx op;
6756 enum machine_mode mode;
6757{
6758 if (mode != VOIDmode && mode != GET_MODE (op))
6759 return 0;
39a10a29 6760 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 6761}
dfbdccdb
GK
6762
6763int
6764boolean_operator (op, mode)
6765 rtx op;
6766 enum machine_mode mode ATTRIBUTE_UNUSED;
6767{
6768 enum rtx_code code = GET_CODE (op);
6769 return (code == AND || code == IOR || code == XOR);
6770}
1d328b19
GK
6771
6772int
6773boolean_or_operator (op, mode)
6774 rtx op;
6775 enum machine_mode mode ATTRIBUTE_UNUSED;
6776{
6777 enum rtx_code code = GET_CODE (op);
6778 return (code == IOR || code == XOR);
6779}
50a0b056
GK
6780
6781int
6782min_max_operator (op, mode)
6783 rtx op;
6784 enum machine_mode mode ATTRIBUTE_UNUSED;
6785{
6786 enum rtx_code code = GET_CODE (op);
6787 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6788}
9878760c
RK
6789\f
6790/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6791 mask required to convert the result of a rotate insn into a shift
b1765bde 6792 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
6793
6794int
6795includes_lshift_p (shiftop, andop)
592696dd
SS
6796 rtx shiftop;
6797 rtx andop;
9878760c 6798{
e2c953b6
DE
6799 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6800
6801 shift_mask <<= INTVAL (shiftop);
9878760c 6802
b1765bde 6803 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
6804}
6805
6806/* Similar, but for right shift. */
6807
6808int
6809includes_rshift_p (shiftop, andop)
592696dd
SS
6810 rtx shiftop;
6811 rtx andop;
9878760c 6812{
a7653a2c 6813 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
6814
6815 shift_mask >>= INTVAL (shiftop);
6816
b1765bde 6817 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
6818}
6819
c5059423
AM
6820/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6821 to perform a left shift. It must have exactly SHIFTOP least
6822 signifigant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
6823
6824int
c5059423 6825includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
6826 rtx shiftop;
6827 rtx andop;
e2c953b6 6828{
c5059423
AM
6829 if (GET_CODE (andop) == CONST_INT)
6830 {
02071907 6831 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 6832
c5059423 6833 c = INTVAL (andop);
02071907 6834 if (c == 0 || c == ~0)
c5059423 6835 return 0;
e2c953b6 6836
02071907 6837 shift_mask = ~0;
c5059423
AM
6838 shift_mask <<= INTVAL (shiftop);
6839
6840 /* Find the least signifigant one bit. */
6841 lsb = c & -c;
6842
6843 /* It must coincide with the LSB of the shift mask. */
6844 if (-lsb != shift_mask)
6845 return 0;
e2c953b6 6846
c5059423
AM
6847 /* Invert to look for the next transition (if any). */
6848 c = ~c;
6849
6850 /* Remove the low group of ones (originally low group of zeros). */
6851 c &= -lsb;
6852
6853 /* Again find the lsb, and check we have all 1's above. */
6854 lsb = c & -c;
6855 return c == -lsb;
6856 }
6857 else if (GET_CODE (andop) == CONST_DOUBLE
6858 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6859 {
02071907
AM
6860 HOST_WIDE_INT low, high, lsb;
6861 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
6862
6863 low = CONST_DOUBLE_LOW (andop);
6864 if (HOST_BITS_PER_WIDE_INT < 64)
6865 high = CONST_DOUBLE_HIGH (andop);
6866
6867 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 6868 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
6869 return 0;
6870
6871 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6872 {
02071907 6873 shift_mask_high = ~0;
c5059423
AM
6874 if (INTVAL (shiftop) > 32)
6875 shift_mask_high <<= INTVAL (shiftop) - 32;
6876
6877 lsb = high & -high;
6878
6879 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
6880 return 0;
6881
6882 high = ~high;
6883 high &= -lsb;
6884
6885 lsb = high & -high;
6886 return high == -lsb;
6887 }
6888
02071907 6889 shift_mask_low = ~0;
c5059423
AM
6890 shift_mask_low <<= INTVAL (shiftop);
6891
6892 lsb = low & -low;
6893
6894 if (-lsb != shift_mask_low)
6895 return 0;
6896
6897 if (HOST_BITS_PER_WIDE_INT < 64)
6898 high = ~high;
6899 low = ~low;
6900 low &= -lsb;
6901
6902 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
6903 {
6904 lsb = high & -high;
6905 return high == -lsb;
6906 }
6907
6908 lsb = low & -low;
6909 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
6910 }
6911 else
6912 return 0;
6913}
e2c953b6 6914
c5059423
AM
6915/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
6916 to perform a left shift. It must have SHIFTOP or more least
6917 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 6918
c5059423
AM
6919int
6920includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
6921 rtx shiftop;
6922 rtx andop;
c5059423 6923{
e2c953b6 6924 if (GET_CODE (andop) == CONST_INT)
c5059423 6925 {
02071907 6926 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 6927
02071907 6928 shift_mask = ~0;
c5059423
AM
6929 shift_mask <<= INTVAL (shiftop);
6930 c = INTVAL (andop);
6931
6932 /* Find the least signifigant one bit. */
6933 lsb = c & -c;
6934
6935 /* It must be covered by the shift mask.
a4f6c312 6936 This test also rejects c == 0. */
c5059423
AM
6937 if ((lsb & shift_mask) == 0)
6938 return 0;
6939
6940 /* Check we have all 1's above the transition, and reject all 1's. */
6941 return c == -lsb && lsb != 1;
6942 }
6943 else if (GET_CODE (andop) == CONST_DOUBLE
6944 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
6945 {
02071907 6946 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
6947
6948 low = CONST_DOUBLE_LOW (andop);
6949
6950 if (HOST_BITS_PER_WIDE_INT < 64)
6951 {
02071907 6952 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
6953
6954 high = CONST_DOUBLE_HIGH (andop);
6955
6956 if (low == 0)
6957 {
02071907 6958 shift_mask_high = ~0;
c5059423
AM
6959 if (INTVAL (shiftop) > 32)
6960 shift_mask_high <<= INTVAL (shiftop) - 32;
6961
6962 lsb = high & -high;
6963
6964 if ((lsb & shift_mask_high) == 0)
6965 return 0;
6966
6967 return high == -lsb;
6968 }
6969 if (high != ~0)
6970 return 0;
6971 }
6972
02071907 6973 shift_mask_low = ~0;
c5059423
AM
6974 shift_mask_low <<= INTVAL (shiftop);
6975
6976 lsb = low & -low;
6977
6978 if ((lsb & shift_mask_low) == 0)
6979 return 0;
6980
6981 return low == -lsb && lsb != 1;
6982 }
e2c953b6 6983 else
c5059423 6984 return 0;
9878760c 6985}
35068b43
RK
6986
6987/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
6988 for lfq and stfq insns.
6989
6990 Note reg1 and reg2 *must* be hard registers. To be sure we will
6991 abort if we are passed pseudo registers. */
6992
6993int
6994registers_ok_for_quad_peep (reg1, reg2)
6995 rtx reg1, reg2;
6996{
6997 /* We might have been passed a SUBREG. */
6998 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
6999 return 0;
7000
7001 return (REGNO (reg1) == REGNO (reg2) - 1);
7002}
7003
a4f6c312
SS
7004/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
7005 addr1 and addr2 must be in consecutive memory locations
7006 (addr2 == addr1 + 8). */
35068b43
RK
7007
7008int
7009addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
7010 rtx addr1;
7011 rtx addr2;
35068b43 7012{
e2c953b6 7013 unsigned int reg1;
35068b43
RK
7014 int offset1;
7015
7016 /* Extract an offset (if used) from the first addr. */
7017 if (GET_CODE (addr1) == PLUS)
7018 {
7019 /* If not a REG, return zero. */
7020 if (GET_CODE (XEXP (addr1, 0)) != REG)
7021 return 0;
7022 else
7023 {
7024 reg1 = REGNO (XEXP (addr1, 0));
7025 /* The offset must be constant! */
7026 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7027 return 0;
7028 offset1 = INTVAL (XEXP (addr1, 1));
7029 }
7030 }
7031 else if (GET_CODE (addr1) != REG)
7032 return 0;
7033 else
7034 {
7035 reg1 = REGNO (addr1);
7036 /* This was a simple (mem (reg)) expression. Offset is 0. */
7037 offset1 = 0;
7038 }
7039
acad7ed3 7040 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
7041 if (GET_CODE (addr2) != PLUS)
7042 return 0;
7043
7044 if (GET_CODE (XEXP (addr2, 0)) != REG
7045 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7046 return 0;
7047
7048 if (reg1 != REGNO (XEXP (addr2, 0)))
7049 return 0;
7050
7051 /* The offset for the second addr must be 8 more than the first addr. */
7052 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7053 return 0;
7054
7055 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7056 instructions. */
7057 return 1;
7058}
9878760c
RK
7059\f
7060/* Return the register class of a scratch register needed to copy IN into
7061 or out of a register in CLASS in MODE. If it can be done directly,
7062 NO_REGS is returned. */
7063
7064enum reg_class
7065secondary_reload_class (class, mode, in)
7066 enum reg_class class;
296b8152 7067 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7068 rtx in;
7069{
5accd822 7070 int regno;
9878760c 7071
46fad5b7
DJ
7072 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN && flag_pic))
7073 {
7074 /* We cannot copy a symbolic operand directly into anything
7075 other than BASE_REGS for TARGET_ELF. So indicate that a
7076 register from BASE_REGS is needed as an intermediate
7077 register.
7078
7079 On Darwin, pic addresses require a load from memory, which
7080 needs a base register. */
7081 if (class != BASE_REGS
7082 && (GET_CODE (in) == SYMBOL_REF
7083 || GET_CODE (in) == HIGH
7084 || GET_CODE (in) == LABEL_REF
7085 || GET_CODE (in) == CONST))
7086 return BASE_REGS;
7087 }
e7b7998a 7088
5accd822
DE
7089 if (GET_CODE (in) == REG)
7090 {
7091 regno = REGNO (in);
7092 if (regno >= FIRST_PSEUDO_REGISTER)
7093 {
7094 regno = true_regnum (in);
7095 if (regno >= FIRST_PSEUDO_REGISTER)
7096 regno = -1;
7097 }
7098 }
7099 else if (GET_CODE (in) == SUBREG)
7100 {
7101 regno = true_regnum (in);
7102 if (regno >= FIRST_PSEUDO_REGISTER)
7103 regno = -1;
7104 }
7105 else
7106 regno = -1;
7107
9878760c
RK
7108 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7109 into anything. */
7110 if (class == GENERAL_REGS || class == BASE_REGS
7111 || (regno >= 0 && INT_REGNO_P (regno)))
7112 return NO_REGS;
7113
7114 /* Constants, memory, and FP registers can go into FP registers. */
7115 if ((regno == -1 || FP_REGNO_P (regno))
7116 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7117 return NO_REGS;
7118
0ac081f6
AH
7119 /* Memory, and AltiVec registers can go into AltiVec registers. */
7120 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7121 && class == ALTIVEC_REGS)
7122 return NO_REGS;
7123
9878760c
RK
7124 /* We can copy among the CR registers. */
7125 if ((class == CR_REGS || class == CR0_REGS)
7126 && regno >= 0 && CR_REGNO_P (regno))
7127 return NO_REGS;
7128
7129 /* Otherwise, we need GENERAL_REGS. */
7130 return GENERAL_REGS;
7131}
7132\f
7133/* Given a comparison operation, return the bit number in CCR to test. We
7134 know this is a valid comparison.
7135
7136 SCC_P is 1 if this is for an scc. That means that %D will have been
7137 used instead of %C, so the bits will be in different places.
7138
b4ac57ab 7139 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7140
7141int
7142ccr_bit (op, scc_p)
592696dd 7143 rtx op;
9878760c
RK
7144 int scc_p;
7145{
7146 enum rtx_code code = GET_CODE (op);
7147 enum machine_mode cc_mode;
7148 int cc_regnum;
7149 int base_bit;
9ebbca7d 7150 rtx reg;
9878760c
RK
7151
7152 if (GET_RTX_CLASS (code) != '<')
7153 return -1;
7154
9ebbca7d
GK
7155 reg = XEXP (op, 0);
7156
7157 if (GET_CODE (reg) != REG
7158 || ! CR_REGNO_P (REGNO (reg)))
7159 abort ();
7160
7161 cc_mode = GET_MODE (reg);
7162 cc_regnum = REGNO (reg);
7163 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7164
39a10a29 7165 validate_condition_mode (code, cc_mode);
c5defebb 7166
9878760c
RK
7167 switch (code)
7168 {
7169 case NE:
a3170dc6
AH
7170 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7171 return base_bit + 1;
9878760c
RK
7172 return scc_p ? base_bit + 3 : base_bit + 2;
7173 case EQ:
a3170dc6
AH
7174 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7175 return base_bit + 1;
9878760c 7176 return base_bit + 2;
1c882ea4 7177 case GT: case GTU: case UNLE:
9878760c 7178 return base_bit + 1;
1c882ea4 7179 case LT: case LTU: case UNGE:
9878760c 7180 return base_bit;
1c882ea4
GK
7181 case ORDERED: case UNORDERED:
7182 return base_bit + 3;
9878760c
RK
7183
7184 case GE: case GEU:
39a10a29 7185 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7186 unordered position. So test that bit. For integer, this is ! LT
7187 unless this is an scc insn. */
39a10a29 7188 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7189
7190 case LE: case LEU:
39a10a29 7191 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7192
9878760c
RK
7193 default:
7194 abort ();
7195 }
7196}
1ff7789b 7197\f
8d30c4ee 7198/* Return the GOT register. */
1ff7789b
MM
7199
7200struct rtx_def *
7201rs6000_got_register (value)
5f59ecb7 7202 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7203{
a4f6c312
SS
7204 /* The second flow pass currently (June 1999) can't update
7205 regs_ever_live without disturbing other parts of the compiler, so
7206 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7207 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7208 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7209
8d30c4ee 7210 current_function_uses_pic_offset_table = 1;
3cb999d8 7211
1ff7789b
MM
7212 return pic_offset_table_rtx;
7213}
a7df97e6 7214\f
e2500fed
GK
7215/* Function to init struct machine_function.
7216 This will be called, via a pointer variable,
7217 from push_function_context. */
a7df97e6 7218
e2500fed
GK
7219static struct machine_function *
7220rs6000_init_machine_status ()
a7df97e6 7221{
e2500fed 7222 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7223}
9878760c 7224\f
0ba1b2ff
AM
7225/* These macros test for integers and extract the low-order bits. */
7226#define INT_P(X) \
7227((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7228 && GET_MODE (X) == VOIDmode)
7229
7230#define INT_LOWPART(X) \
7231 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7232
7233int
7234extract_MB (op)
7235 rtx op;
7236{
7237 int i;
7238 unsigned long val = INT_LOWPART (op);
7239
7240 /* If the high bit is zero, the value is the first 1 bit we find
7241 from the left. */
7242 if ((val & 0x80000000) == 0)
7243 {
7244 if ((val & 0xffffffff) == 0)
7245 abort ();
7246
7247 i = 1;
7248 while (((val <<= 1) & 0x80000000) == 0)
7249 ++i;
7250 return i;
7251 }
7252
7253 /* If the high bit is set and the low bit is not, or the mask is all
7254 1's, the value is zero. */
7255 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7256 return 0;
7257
7258 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7259 from the right. */
7260 i = 31;
7261 while (((val >>= 1) & 1) != 0)
7262 --i;
7263
7264 return i;
7265}
7266
7267int
7268extract_ME (op)
7269 rtx op;
7270{
7271 int i;
7272 unsigned long val = INT_LOWPART (op);
7273
7274 /* If the low bit is zero, the value is the first 1 bit we find from
7275 the right. */
7276 if ((val & 1) == 0)
7277 {
7278 if ((val & 0xffffffff) == 0)
7279 abort ();
7280
7281 i = 30;
7282 while (((val >>= 1) & 1) == 0)
7283 --i;
7284
7285 return i;
7286 }
7287
7288 /* If the low bit is set and the high bit is not, or the mask is all
7289 1's, the value is 31. */
7290 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7291 return 31;
7292
7293 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7294 from the left. */
7295 i = 0;
7296 while (((val <<= 1) & 0x80000000) != 0)
7297 ++i;
7298
7299 return i;
7300}
7301
9878760c
RK
7302/* Print an operand. Recognize special options, documented below. */
7303
38c1f2d7 7304#if TARGET_ELF
d9407988 7305#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7306#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7307#else
7308#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7309#define SMALL_DATA_REG 0
ba5e43aa
MM
7310#endif
7311
9878760c
RK
7312void
7313print_operand (file, x, code)
7314 FILE *file;
7315 rtx x;
9ebbca7d 7316 int code;
9878760c
RK
7317{
7318 int i;
a260abc9 7319 HOST_WIDE_INT val;
0ba1b2ff 7320 unsigned HOST_WIDE_INT uval;
9878760c
RK
7321
7322 switch (code)
7323 {
a8b3aeda 7324 case '.':
a85d226b
RK
7325 /* Write out an instruction after the call which may be replaced
7326 with glue code by the loader. This depends on the AIX version. */
7327 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7328 return;
7329
81eace42
GK
7330 /* %a is output_address. */
7331
9854d9ed
RK
7332 case 'A':
7333 /* If X is a constant integer whose low-order 5 bits are zero,
7334 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7335 in the AIX assembler where "sri" with a zero shift count
20e26713 7336 writes a trash instruction. */
9854d9ed 7337 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7338 putc ('l', file);
9854d9ed 7339 else
76229ac8 7340 putc ('r', file);
9854d9ed
RK
7341 return;
7342
7343 case 'b':
e2c953b6
DE
7344 /* If constant, low-order 16 bits of constant, unsigned.
7345 Otherwise, write normally. */
7346 if (INT_P (x))
7347 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7348 else
7349 print_operand (file, x, 0);
cad12a8d
RK
7350 return;
7351
a260abc9
DE
7352 case 'B':
7353 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7354 for 64-bit mask direction. */
296b8152 7355 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7356 return;
a260abc9 7357
81eace42
GK
7358 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7359 output_operand. */
7360
9854d9ed 7361 case 'D':
39a10a29
GK
7362 /* There used to be a comment for 'C' reading "This is an
7363 optional cror needed for certain floating-point
7364 comparisons. Otherwise write nothing." */
7365
9854d9ed
RK
7366 /* Similar, except that this is for an scc, so we must be able to
7367 encode the test in a single bit that is one. We do the above
7368 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7369 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7370 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7371 {
9ebbca7d 7372 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7373
7374 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7375 base_bit + 2,
7376 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7377 }
7378
7379 else if (GET_CODE (x) == NE)
7380 {
9ebbca7d 7381 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7382
7383 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7384 base_bit + 2, base_bit + 2);
7385 }
a3170dc6
AH
7386 else if (TARGET_SPE && TARGET_HARD_FLOAT
7387 && GET_CODE (x) == EQ
7388 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7389 {
7390 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7391
7392 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7393 base_bit + 1, base_bit + 1);
7394 }
9854d9ed
RK
7395 return;
7396
7397 case 'E':
39a10a29 7398 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7399 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7400 output_operand_lossage ("invalid %%E value");
78fbdbf7 7401 else
39a10a29 7402 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7403 return;
9854d9ed
RK
7404
7405 case 'f':
7406 /* X is a CR register. Print the shift count needed to move it
7407 to the high-order four bits. */
7408 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7409 output_operand_lossage ("invalid %%f value");
7410 else
9ebbca7d 7411 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7412 return;
7413
7414 case 'F':
7415 /* Similar, but print the count for the rotate in the opposite
7416 direction. */
7417 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7418 output_operand_lossage ("invalid %%F value");
7419 else
9ebbca7d 7420 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7421 return;
7422
7423 case 'G':
7424 /* X is a constant integer. If it is negative, print "m",
43aa4e05 7425 otherwise print "z". This is to make an aze or ame insn. */
9854d9ed
RK
7426 if (GET_CODE (x) != CONST_INT)
7427 output_operand_lossage ("invalid %%G value");
7428 else if (INTVAL (x) >= 0)
76229ac8 7429 putc ('z', file);
9854d9ed 7430 else
76229ac8 7431 putc ('m', file);
9854d9ed 7432 return;
e2c953b6 7433
9878760c 7434 case 'h':
a4f6c312
SS
7435 /* If constant, output low-order five bits. Otherwise, write
7436 normally. */
9878760c 7437 if (INT_P (x))
5f59ecb7 7438 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7439 else
7440 print_operand (file, x, 0);
7441 return;
7442
64305719 7443 case 'H':
a4f6c312
SS
7444 /* If constant, output low-order six bits. Otherwise, write
7445 normally. */
64305719 7446 if (INT_P (x))
5f59ecb7 7447 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7448 else
7449 print_operand (file, x, 0);
7450 return;
7451
9854d9ed
RK
7452 case 'I':
7453 /* Print `i' if this is a constant, else nothing. */
9878760c 7454 if (INT_P (x))
76229ac8 7455 putc ('i', file);
9878760c
RK
7456 return;
7457
9854d9ed
RK
7458 case 'j':
7459 /* Write the bit number in CCR for jump. */
7460 i = ccr_bit (x, 0);
7461 if (i == -1)
7462 output_operand_lossage ("invalid %%j code");
9878760c 7463 else
9854d9ed 7464 fprintf (file, "%d", i);
9878760c
RK
7465 return;
7466
9854d9ed
RK
7467 case 'J':
7468 /* Similar, but add one for shift count in rlinm for scc and pass
7469 scc flag to `ccr_bit'. */
7470 i = ccr_bit (x, 1);
7471 if (i == -1)
7472 output_operand_lossage ("invalid %%J code");
7473 else
a0466a68
RK
7474 /* If we want bit 31, write a shift count of zero, not 32. */
7475 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7476 return;
7477
9854d9ed
RK
7478 case 'k':
7479 /* X must be a constant. Write the 1's complement of the
7480 constant. */
9878760c 7481 if (! INT_P (x))
9854d9ed 7482 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7483 else
7484 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7485 return;
7486
81eace42 7487 case 'K':
9ebbca7d
GK
7488 /* X must be a symbolic constant on ELF. Write an
7489 expression suitable for an 'addi' that adds in the low 16
7490 bits of the MEM. */
7491 if (GET_CODE (x) != CONST)
7492 {
7493 print_operand_address (file, x);
7494 fputs ("@l", file);
7495 }
7496 else
7497 {
7498 if (GET_CODE (XEXP (x, 0)) != PLUS
7499 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7500 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7501 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7502 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7503 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7504 fputs ("@l", file);
ed8d2920
MM
7505 /* For GNU as, there must be a non-alphanumeric character
7506 between 'l' and the number. The '-' is added by
7507 print_operand() already. */
7508 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7509 fputs ("+", file);
9ebbca7d
GK
7510 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7511 }
81eace42
GK
7512 return;
7513
7514 /* %l is output_asm_label. */
9ebbca7d 7515
9854d9ed
RK
7516 case 'L':
7517 /* Write second word of DImode or DFmode reference. Works on register
7518 or non-indexed memory only. */
7519 if (GET_CODE (x) == REG)
5ebfb2ba 7520 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7521 else if (GET_CODE (x) == MEM)
7522 {
7523 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7524 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7525 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7526 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7527 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7528 UNITS_PER_WORD));
9854d9ed 7529 else
d7624dc0
RK
7530 output_address (XEXP (adjust_address_nv (x, SImode,
7531 UNITS_PER_WORD),
7532 0));
ed8908e7 7533
ba5e43aa 7534 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7535 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7536 reg_names[SMALL_DATA_REG]);
9854d9ed 7537 }
9878760c 7538 return;
9854d9ed 7539
9878760c
RK
7540 case 'm':
7541 /* MB value for a mask operand. */
b1765bde 7542 if (! mask_operand (x, SImode))
9878760c
RK
7543 output_operand_lossage ("invalid %%m value");
7544
0ba1b2ff 7545 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7546 return;
7547
7548 case 'M':
7549 /* ME value for a mask operand. */
b1765bde 7550 if (! mask_operand (x, SImode))
a260abc9 7551 output_operand_lossage ("invalid %%M value");
9878760c 7552
0ba1b2ff 7553 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7554 return;
7555
81eace42
GK
7556 /* %n outputs the negative of its operand. */
7557
9878760c
RK
7558 case 'N':
7559 /* Write the number of elements in the vector times 4. */
7560 if (GET_CODE (x) != PARALLEL)
7561 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7562 else
7563 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7564 return;
7565
7566 case 'O':
7567 /* Similar, but subtract 1 first. */
7568 if (GET_CODE (x) != PARALLEL)
1427100a 7569 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7570 else
7571 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7572 return;
7573
9854d9ed
RK
7574 case 'p':
7575 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7576 if (! INT_P (x)
2bfcf297 7577 || INT_LOWPART (x) < 0
9854d9ed
RK
7578 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7579 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7580 else
7581 fprintf (file, "%d", i);
9854d9ed
RK
7582 return;
7583
9878760c
RK
7584 case 'P':
7585 /* The operand must be an indirect memory reference. The result
a4f6c312 7586 is the register number. */
9878760c
RK
7587 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7588 || REGNO (XEXP (x, 0)) >= 32)
7589 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7590 else
7591 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7592 return;
7593
dfbdccdb
GK
7594 case 'q':
7595 /* This outputs the logical code corresponding to a boolean
7596 expression. The expression may have one or both operands
39a10a29
GK
7597 negated (if one, only the first one). For condition register
7598 logical operations, it will also treat the negated
7599 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7600 {
63bc1d05 7601 const char *const *t = 0;
dfbdccdb
GK
7602 const char *s;
7603 enum rtx_code code = GET_CODE (x);
7604 static const char * const tbl[3][3] = {
7605 { "and", "andc", "nor" },
7606 { "or", "orc", "nand" },
7607 { "xor", "eqv", "xor" } };
7608
7609 if (code == AND)
7610 t = tbl[0];
7611 else if (code == IOR)
7612 t = tbl[1];
7613 else if (code == XOR)
7614 t = tbl[2];
7615 else
7616 output_operand_lossage ("invalid %%q value");
7617
7618 if (GET_CODE (XEXP (x, 0)) != NOT)
7619 s = t[0];
7620 else
7621 {
7622 if (GET_CODE (XEXP (x, 1)) == NOT)
7623 s = t[2];
7624 else
7625 s = t[1];
7626 }
7627
7628 fputs (s, file);
7629 }
7630 return;
7631
9854d9ed
RK
7632 case 'R':
7633 /* X is a CR register. Print the mask for `mtcrf'. */
7634 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7635 output_operand_lossage ("invalid %%R value");
7636 else
9ebbca7d 7637 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7638 return;
9854d9ed
RK
7639
7640 case 's':
7641 /* Low 5 bits of 32 - value */
7642 if (! INT_P (x))
7643 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7644 else
7645 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7646 return;
9854d9ed 7647
a260abc9 7648 case 'S':
0ba1b2ff 7649 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7650 CONST_INT 32-bit mask is considered sign-extended so any
7651 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7652 if (! mask64_operand (x, DImode))
a260abc9
DE
7653 output_operand_lossage ("invalid %%S value");
7654
0ba1b2ff 7655 uval = INT_LOWPART (x);
a260abc9 7656
0ba1b2ff 7657 if (uval & 1) /* Clear Left */
a260abc9 7658 {
0ba1b2ff
AM
7659 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7660 i = 64;
a260abc9 7661 }
0ba1b2ff 7662 else /* Clear Right */
a260abc9 7663 {
0ba1b2ff
AM
7664 uval = ~uval;
7665 uval &= ((unsigned HOST_WIDE_INT) 1 << 63 << 1) - 1;
7666 i = 63;
a260abc9 7667 }
0ba1b2ff
AM
7668 while (uval != 0)
7669 --i, uval >>= 1;
7670 if (i < 0)
7671 abort ();
7672 fprintf (file, "%d", i);
7673 return;
a260abc9 7674
a3170dc6
AH
7675 case 't':
7676 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7677 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7678 abort ();
7679
7680 /* Bit 3 is OV bit. */
7681 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7682
7683 /* If we want bit 31, write a shift count of zero, not 32. */
7684 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7685 return;
7686
cccf3bdc
DE
7687 case 'T':
7688 /* Print the symbolic name of a branch target register. */
7689 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7690 && REGNO (x) != COUNT_REGISTER_REGNUM))
7691 output_operand_lossage ("invalid %%T value");
e2c953b6 7692 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
7693 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7694 else
7695 fputs ("ctr", file);
7696 return;
7697
9854d9ed 7698 case 'u':
802a0058 7699 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
7700 if (! INT_P (x))
7701 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
7702 else
7703 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7704 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
7705 return;
7706
802a0058
MM
7707 case 'v':
7708 /* High-order 16 bits of constant for use in signed operand. */
7709 if (! INT_P (x))
7710 output_operand_lossage ("invalid %%v value");
e2c953b6 7711 else
134c32f6
DE
7712 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7713 (INT_LOWPART (x) >> 16) & 0xffff);
7714 return;
802a0058 7715
9854d9ed
RK
7716 case 'U':
7717 /* Print `u' if this has an auto-increment or auto-decrement. */
7718 if (GET_CODE (x) == MEM
7719 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7720 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 7721 putc ('u', file);
9854d9ed 7722 return;
9878760c 7723
e0cd0770
JC
7724 case 'V':
7725 /* Print the trap code for this operand. */
7726 switch (GET_CODE (x))
7727 {
7728 case EQ:
7729 fputs ("eq", file); /* 4 */
7730 break;
7731 case NE:
7732 fputs ("ne", file); /* 24 */
7733 break;
7734 case LT:
7735 fputs ("lt", file); /* 16 */
7736 break;
7737 case LE:
7738 fputs ("le", file); /* 20 */
7739 break;
7740 case GT:
7741 fputs ("gt", file); /* 8 */
7742 break;
7743 case GE:
7744 fputs ("ge", file); /* 12 */
7745 break;
7746 case LTU:
7747 fputs ("llt", file); /* 2 */
7748 break;
7749 case LEU:
7750 fputs ("lle", file); /* 6 */
7751 break;
7752 case GTU:
7753 fputs ("lgt", file); /* 1 */
7754 break;
7755 case GEU:
7756 fputs ("lge", file); /* 5 */
7757 break;
7758 default:
7759 abort ();
7760 }
7761 break;
7762
9854d9ed
RK
7763 case 'w':
7764 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7765 normally. */
7766 if (INT_P (x))
5f59ecb7
DE
7767 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7768 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
7769 else
7770 print_operand (file, x, 0);
9878760c
RK
7771 return;
7772
9854d9ed 7773 case 'W':
e2c953b6 7774 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
7775 val = (GET_CODE (x) == CONST_INT
7776 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7777
7778 if (val < 0)
7779 i = -1;
9854d9ed 7780 else
e2c953b6
DE
7781 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7782 if ((val <<= 1) < 0)
7783 break;
7784
7785#if HOST_BITS_PER_WIDE_INT == 32
7786 if (GET_CODE (x) == CONST_INT && i >= 0)
7787 i += 32; /* zero-extend high-part was all 0's */
7788 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7789 {
7790 val = CONST_DOUBLE_LOW (x);
7791
7792 if (val == 0)
a4f6c312 7793 abort ();
e2c953b6
DE
7794 else if (val < 0)
7795 --i;
7796 else
7797 for ( ; i < 64; i++)
7798 if ((val <<= 1) < 0)
7799 break;
7800 }
7801#endif
7802
7803 fprintf (file, "%d", i + 1);
9854d9ed 7804 return;
9878760c 7805
9854d9ed
RK
7806 case 'X':
7807 if (GET_CODE (x) == MEM
258bfae2 7808 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 7809 putc ('x', file);
9854d9ed 7810 return;
9878760c 7811
9854d9ed
RK
7812 case 'Y':
7813 /* Like 'L', for third word of TImode */
7814 if (GET_CODE (x) == REG)
5ebfb2ba 7815 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 7816 else if (GET_CODE (x) == MEM)
9878760c 7817 {
9854d9ed
RK
7818 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7819 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7820 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 7821 else
d7624dc0 7822 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 7823 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7824 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7825 reg_names[SMALL_DATA_REG]);
9878760c
RK
7826 }
7827 return;
9854d9ed 7828
9878760c 7829 case 'z':
b4ac57ab
RS
7830 /* X is a SYMBOL_REF. Write out the name preceded by a
7831 period and without any trailing data in brackets. Used for function
4d30c363
MM
7832 names. If we are configured for System V (or the embedded ABI) on
7833 the PowerPC, do not emit the period, since those systems do not use
7834 TOCs and the like. */
9878760c
RK
7835 if (GET_CODE (x) != SYMBOL_REF)
7836 abort ();
7837
b6c9286a
MM
7838 if (XSTR (x, 0)[0] != '.')
7839 {
7840 switch (DEFAULT_ABI)
7841 {
7842 default:
7843 abort ();
7844
7845 case ABI_AIX:
7846 putc ('.', file);
7847 break;
7848
7849 case ABI_V4:
7850 case ABI_AIX_NODESC:
ee890fe2 7851 case ABI_DARWIN:
b6c9286a 7852 break;
b6c9286a
MM
7853 }
7854 }
54ee9799
DE
7855#if TARGET_AIX
7856 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
7857#else
9ebbca7d 7858 assemble_name (file, XSTR (x, 0));
54ee9799 7859#endif
9878760c
RK
7860 return;
7861
9854d9ed
RK
7862 case 'Z':
7863 /* Like 'L', for last word of TImode. */
7864 if (GET_CODE (x) == REG)
5ebfb2ba 7865 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
7866 else if (GET_CODE (x) == MEM)
7867 {
7868 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7869 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7870 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 7871 else
d7624dc0 7872 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 7873 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7874 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7875 reg_names[SMALL_DATA_REG]);
9854d9ed 7876 }
5c23c401 7877 return;
0ac081f6 7878
a3170dc6 7879 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
7880 case 'y':
7881 {
7882 rtx tmp;
7883
7884 if (GET_CODE (x) != MEM)
7885 abort ();
7886
7887 tmp = XEXP (x, 0);
7888
a3170dc6
AH
7889 if (TARGET_SPE)
7890 {
7891 /* Handle [reg]. */
7892 if (GET_CODE (tmp) == REG)
7893 {
7894 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
7895 break;
7896 }
7897 /* Handle [reg+UIMM]. */
7898 else if (GET_CODE (tmp) == PLUS &&
7899 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
7900 {
7901 int x;
7902
7903 if (GET_CODE (XEXP (tmp, 0)) != REG)
7904 abort ();
7905
7906 x = INTVAL (XEXP (tmp, 1));
7907 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
7908 break;
7909 }
7910
7911 /* Fall through. Must be [reg+reg]. */
7912 }
0ac081f6 7913 if (GET_CODE (tmp) == REG)
c62f2db5 7914 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
7915 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
7916 {
7917 if (REGNO (XEXP (tmp, 0)) == 0)
7918 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
7919 reg_names[ REGNO (XEXP (tmp, 0)) ]);
7920 else
7921 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
7922 reg_names[ REGNO (XEXP (tmp, 1)) ]);
7923 }
7924 else
7925 abort ();
7926 break;
7927 }
9854d9ed 7928
9878760c
RK
7929 case 0:
7930 if (GET_CODE (x) == REG)
7931 fprintf (file, "%s", reg_names[REGNO (x)]);
7932 else if (GET_CODE (x) == MEM)
7933 {
7934 /* We need to handle PRE_INC and PRE_DEC here, since we need to
7935 know the width from the mode. */
7936 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
7937 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
7938 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7939 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
7940 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
7941 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 7942 else
a54d04b7 7943 output_address (XEXP (x, 0));
9878760c
RK
7944 }
7945 else
a54d04b7 7946 output_addr_const (file, x);
a85d226b 7947 return;
9878760c
RK
7948
7949 default:
7950 output_operand_lossage ("invalid %%xn code");
7951 }
7952}
7953\f
7954/* Print the address of an operand. */
7955
7956void
7957print_operand_address (file, x)
7958 FILE *file;
592696dd 7959 rtx x;
9878760c
RK
7960{
7961 if (GET_CODE (x) == REG)
4697a36c 7962 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
7963 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
7964 || GET_CODE (x) == LABEL_REF)
9878760c
RK
7965 {
7966 output_addr_const (file, x);
ba5e43aa 7967 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7968 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7969 reg_names[SMALL_DATA_REG]);
9ebbca7d 7970 else if (TARGET_TOC)
a4f6c312 7971 abort ();
9878760c
RK
7972 }
7973 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
7974 {
7975 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
7976 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
7977 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 7978 else
4697a36c
MM
7979 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
7980 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
7981 }
7982 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
7983 {
7984 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
7985 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7986 }
3cb999d8
DE
7987#if TARGET_ELF
7988 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
7989 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
7990 {
7991 output_addr_const (file, XEXP (x, 1));
7992 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
7993 }
c859cda6
DJ
7994#endif
7995#if TARGET_MACHO
7996 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
7997 && CONSTANT_P (XEXP (x, 1)))
7998 {
7999 fprintf (file, "lo16(");
8000 output_addr_const (file, XEXP (x, 1));
8001 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8002 }
3cb999d8 8003#endif
9ebbca7d
GK
8004 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
8005 {
2bfcf297 8006 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 8007 {
2bfcf297
DB
8008 rtx contains_minus = XEXP (x, 1);
8009 rtx minus, symref;
8010 const char *name;
9ebbca7d
GK
8011
8012 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 8013 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
8014 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8015 contains_minus = XEXP (contains_minus, 0);
8016
2bfcf297
DB
8017 minus = XEXP (contains_minus, 0);
8018 symref = XEXP (minus, 0);
8019 XEXP (contains_minus, 0) = symref;
8020 if (TARGET_ELF)
8021 {
8022 char *newname;
8023
8024 name = XSTR (symref, 0);
8025 newname = alloca (strlen (name) + sizeof ("@toc"));
8026 strcpy (newname, name);
8027 strcat (newname, "@toc");
8028 XSTR (symref, 0) = newname;
8029 }
8030 output_addr_const (file, XEXP (x, 1));
8031 if (TARGET_ELF)
8032 XSTR (symref, 0) = name;
9ebbca7d
GK
8033 XEXP (contains_minus, 0) = minus;
8034 }
8035 else
8036 output_addr_const (file, XEXP (x, 1));
8037
8038 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8039 }
9878760c
RK
8040 else
8041 abort ();
8042}
8043\f
88cad84b 8044/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
8045 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8046 is defined. It also needs to handle DI-mode objects on 64-bit
8047 targets. */
8048
8049static bool
8050rs6000_assemble_integer (x, size, aligned_p)
8051 rtx x;
8052 unsigned int size;
8053 int aligned_p;
8054{
8055#ifdef RELOCATABLE_NEEDS_FIXUP
8056 /* Special handling for SI values. */
8057 if (size == 4 && aligned_p)
8058 {
8059 extern int in_toc_section PARAMS ((void));
8060 static int recurse = 0;
8061
8062 /* For -mrelocatable, we mark all addresses that need to be fixed up
8063 in the .fixup section. */
8064 if (TARGET_RELOCATABLE
8065 && !in_toc_section ()
8066 && !in_text_section ()
8067 && !recurse
8068 && GET_CODE (x) != CONST_INT
8069 && GET_CODE (x) != CONST_DOUBLE
8070 && CONSTANT_P (x))
8071 {
8072 char buf[256];
8073
8074 recurse = 1;
8075 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8076 fixuplabelno++;
8077 ASM_OUTPUT_LABEL (asm_out_file, buf);
8078 fprintf (asm_out_file, "\t.long\t(");
8079 output_addr_const (asm_out_file, x);
8080 fprintf (asm_out_file, ")@fixup\n");
8081 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8082 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8083 fprintf (asm_out_file, "\t.long\t");
8084 assemble_name (asm_out_file, buf);
8085 fprintf (asm_out_file, "\n\t.previous\n");
8086 recurse = 0;
8087 return true;
8088 }
8089 /* Remove initial .'s to turn a -mcall-aixdesc function
8090 address into the address of the descriptor, not the function
8091 itself. */
8092 else if (GET_CODE (x) == SYMBOL_REF
8093 && XSTR (x, 0)[0] == '.'
8094 && DEFAULT_ABI == ABI_AIX)
8095 {
8096 const char *name = XSTR (x, 0);
8097 while (*name == '.')
8098 name++;
8099
8100 fprintf (asm_out_file, "\t.long\t%s\n", name);
8101 return true;
8102 }
8103 }
8104#endif /* RELOCATABLE_NEEDS_FIXUP */
8105 return default_assemble_integer (x, size, aligned_p);
8106}
93638d7a
AM
8107
8108#ifdef HAVE_GAS_HIDDEN
8109/* Emit an assembler directive to set symbol visibility for DECL to
8110 VISIBILITY_TYPE. */
8111
5add3202 8112static void
93638d7a
AM
8113rs6000_assemble_visibility (decl, visibility_type)
8114 tree decl;
8115 const char *visibility_type;
8116{
bd79540a 8117 default_assemble_visibility (decl, visibility_type);
93638d7a
AM
8118
8119 /* Functions need to have their entry point symbol visibility set as
8120 well as their descriptor symbol visibility. */
8121 if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
8122 {
8123 const char *name;
8124
8125 name = ((* targetm.strip_name_encoding)
8126 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
8127
8128 fprintf (asm_out_file, "\t.%s\t.%s\n", visibility_type, name);
8129 }
8130}
8131#endif
301d03af 8132\f
39a10a29
GK
8133enum rtx_code
8134rs6000_reverse_condition (mode, code)
8135 enum machine_mode mode;
8136 enum rtx_code code;
8137{
8138 /* Reversal of FP compares takes care -- an ordered compare
8139 becomes an unordered compare and vice versa. */
de40e1df 8140 if (mode == CCFPmode && !flag_unsafe_math_optimizations)
bab6226b 8141 return reverse_condition_maybe_unordered (code);
39a10a29 8142 else
bab6226b 8143 return reverse_condition (code);
39a10a29
GK
8144}
8145
39a10a29
GK
8146/* Generate a compare for CODE. Return a brand-new rtx that
8147 represents the result of the compare. */
a4f6c312 8148
39a10a29
GK
8149static rtx
8150rs6000_generate_compare (code)
8151 enum rtx_code code;
8152{
8153 enum machine_mode comp_mode;
8154 rtx compare_result;
8155
8156 if (rs6000_compare_fp_p)
8157 comp_mode = CCFPmode;
8158 else if (code == GTU || code == LTU
8159 || code == GEU || code == LEU)
8160 comp_mode = CCUNSmode;
8161 else
8162 comp_mode = CCmode;
8163
8164 /* First, the compare. */
8165 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
8166
8167 /* SPE FP compare instructions on the GPRs. Yuck! */
8168 if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
8169 {
8170 rtx cmp, or1, or2, or_result, compare_result2;
8171
8172 switch (code)
8173 {
8174 case EQ:
8175 case UNEQ:
8176 case NE:
8177 case LTGT:
8178 cmp = flag_unsafe_math_optimizations
8179 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8180 rs6000_compare_op1)
8181 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8182 rs6000_compare_op1);
8183 break;
8184 case GT:
8185 case GTU:
8186 case UNGT:
8187 case UNGE:
8188 case GE:
8189 case GEU:
8190 cmp = flag_unsafe_math_optimizations
8191 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8192 rs6000_compare_op1)
8193 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8194 rs6000_compare_op1);
8195 break;
8196 case LT:
8197 case LTU:
8198 case UNLT:
8199 case UNLE:
8200 case LE:
8201 case LEU:
8202 cmp = flag_unsafe_math_optimizations
8203 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8204 rs6000_compare_op1)
8205 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8206 rs6000_compare_op1);
8207 break;
8208 default:
8209 abort ();
8210 }
8211
8212 /* Synthesize LE and GE from LT/GT || EQ. */
8213 if (code == LE || code == GE || code == LEU || code == GEU)
8214 {
8215 /* Synthesize GE/LE frome GT/LT || EQ. */
8216
8217 emit_insn (cmp);
8218
8219 switch (code)
8220 {
8221 case LE: code = LT; break;
8222 case GE: code = GT; break;
8223 case LEU: code = LT; break;
8224 case GEU: code = GT; break;
8225 default: abort ();
8226 }
8227
8228 or1 = gen_reg_rtx (SImode);
8229 or2 = gen_reg_rtx (SImode);
8230 or_result = gen_reg_rtx (CCEQmode);
8231 compare_result2 = gen_reg_rtx (CCFPmode);
8232
8233 /* Do the EQ. */
8234 cmp = flag_unsafe_math_optimizations
8235 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8236 rs6000_compare_op1)
8237 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8238 rs6000_compare_op1);
8239 emit_insn (cmp);
8240
8241 /* The MC8540 FP compare instructions set the CR bits
8242 differently than other PPC compare instructions. For
8243 that matter, there is no generic test instruction, but a
8244 testgt, testlt, and testeq. For a true condition, bit 2
8245 is set (x1xx) in the CR. Following the traditional CR
8246 values:
8247
8248 LT GT EQ OV
8249 bit3 bit2 bit1 bit0
8250
8251 ... bit 2 would be a GT CR alias, so later on we
8252 look in the GT bits for the branch instructins.
8253 However, we must be careful to emit correct RTL in
8254 the meantime, so optimizations don't get confused. */
8255
8256 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8257 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8258
8259 /* OR them together. */
8260 cmp = gen_rtx_SET (VOIDmode, or_result,
8261 gen_rtx_COMPARE (CCEQmode,
8262 gen_rtx_IOR (SImode, or1, or2),
8263 const_true_rtx));
8264 compare_result = or_result;
8265 code = EQ;
8266 }
8267 else
8268 {
8269 /* We only care about 1 bit (x1xx), so map everything to NE to
8270 maintain rtl sanity. We'll get to the right bit (x1xx) at
8271 code output time. */
8272 if (code == NE || code == LTGT)
8273 /* Do the inverse here because we have no cmpne
8274 instruction. We use the cmpeq instruction and expect
8275 to get a 0 instead. */
8276 code = EQ;
8277 else
8278 code = NE;
8279 }
8280
8281 emit_insn (cmp);
8282 }
8283 else
8284 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8285 gen_rtx_COMPARE (comp_mode,
8286 rs6000_compare_op0,
8287 rs6000_compare_op1)));
39a10a29 8288
ca5adc63 8289 /* Some kinds of FP comparisons need an OR operation;
de6c5979 8290 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 8291 if (rs6000_compare_fp_p
de6c5979 8292 && ! flag_unsafe_math_optimizations
a3170dc6 8293 && ! (TARGET_HARD_FLOAT && TARGET_SPE)
39a10a29
GK
8294 && (code == LE || code == GE
8295 || code == UNEQ || code == LTGT
8296 || code == UNGT || code == UNLT))
8297 {
8298 enum rtx_code or1, or2;
8299 rtx or1_rtx, or2_rtx, compare2_rtx;
8300 rtx or_result = gen_reg_rtx (CCEQmode);
8301
8302 switch (code)
8303 {
8304 case LE: or1 = LT; or2 = EQ; break;
8305 case GE: or1 = GT; or2 = EQ; break;
8306 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8307 case LTGT: or1 = LT; or2 = GT; break;
8308 case UNGT: or1 = UNORDERED; or2 = GT; break;
8309 case UNLT: or1 = UNORDERED; or2 = LT; break;
8310 default: abort ();
8311 }
8312 validate_condition_mode (or1, comp_mode);
8313 validate_condition_mode (or2, comp_mode);
8314 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8315 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8316 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8317 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8318 const_true_rtx);
8319 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8320
8321 compare_result = or_result;
8322 code = EQ;
8323 }
8324
8325 validate_condition_mode (code, GET_MODE (compare_result));
8326
8327 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8328}
8329
8330
8331/* Emit the RTL for an sCOND pattern. */
8332
8333void
8334rs6000_emit_sCOND (code, result)
8335 enum rtx_code code;
8336 rtx result;
8337{
8338 rtx condition_rtx;
8339 enum machine_mode op_mode;
8340
8341 condition_rtx = rs6000_generate_compare (code);
8342
8343 op_mode = GET_MODE (rs6000_compare_op0);
8344 if (op_mode == VOIDmode)
8345 op_mode = GET_MODE (rs6000_compare_op1);
8346
8347 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8348 {
8349 PUT_MODE (condition_rtx, DImode);
8350 convert_move (result, condition_rtx, 0);
8351 }
8352 else
8353 {
8354 PUT_MODE (condition_rtx, SImode);
8355 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8356 }
8357}
8358
39a10a29
GK
8359/* Emit a branch of kind CODE to location LOC. */
8360
8361void
8362rs6000_emit_cbranch (code, loc)
8363 enum rtx_code code;
8364 rtx loc;
8365{
8366 rtx condition_rtx, loc_ref;
8367
8368 condition_rtx = rs6000_generate_compare (code);
8369 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8370 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8371 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8372 loc_ref, pc_rtx)));
8373}
8374
12a4e8c5
GK
8375/* Return the string to output a conditional branch to LABEL, which is
8376 the operand number of the label, or -1 if the branch is really a
8377 conditional return.
8378
8379 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8380 condition code register and its mode specifies what kind of
8381 comparison we made.
8382
a0ab749a 8383 REVERSED is nonzero if we should reverse the sense of the comparison.
12a4e8c5
GK
8384
8385 INSN is the insn. */
8386
8387char *
8388output_cbranch (op, label, reversed, insn)
8389 rtx op;
8390 const char * label;
8391 int reversed;
8392 rtx insn;
8393{
8394 static char string[64];
8395 enum rtx_code code = GET_CODE (op);
8396 rtx cc_reg = XEXP (op, 0);
8397 enum machine_mode mode = GET_MODE (cc_reg);
8398 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 8399 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
8400 int really_reversed = reversed ^ need_longbranch;
8401 char *s = string;
8402 const char *ccode;
8403 const char *pred;
8404 rtx note;
8405
39a10a29
GK
8406 validate_condition_mode (code, mode);
8407
8408 /* Work out which way this really branches. We could use
8409 reverse_condition_maybe_unordered here always but this
8410 makes the resulting assembler clearer. */
12a4e8c5 8411 if (really_reversed)
de40e1df
DJ
8412 {
8413 /* Reversal of FP compares takes care -- an ordered compare
8414 becomes an unordered compare and vice versa. */
8415 if (mode == CCFPmode)
8416 code = reverse_condition_maybe_unordered (code);
8417 else
8418 code = reverse_condition (code);
8419 }
12a4e8c5 8420
a3170dc6
AH
8421 if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
8422 {
8423 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8424 to the GT bit. */
8425 if (code == EQ)
8426 /* Opposite of GT. */
8427 code = UNLE;
8428 else if (code == NE)
8429 code = GT;
8430 else
8431 abort ();
8432 }
8433
39a10a29 8434 switch (code)
12a4e8c5
GK
8435 {
8436 /* Not all of these are actually distinct opcodes, but
8437 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
8438 case NE: case LTGT:
8439 ccode = "ne"; break;
8440 case EQ: case UNEQ:
8441 ccode = "eq"; break;
8442 case GE: case GEU:
8443 ccode = "ge"; break;
8444 case GT: case GTU: case UNGT:
8445 ccode = "gt"; break;
8446 case LE: case LEU:
8447 ccode = "le"; break;
8448 case LT: case LTU: case UNLT:
8449 ccode = "lt"; break;
12a4e8c5
GK
8450 case UNORDERED: ccode = "un"; break;
8451 case ORDERED: ccode = "nu"; break;
8452 case UNGE: ccode = "nl"; break;
8453 case UNLE: ccode = "ng"; break;
8454 default:
a4f6c312 8455 abort ();
12a4e8c5
GK
8456 }
8457
94a54f47
GK
8458 /* Maybe we have a guess as to how likely the branch is.
8459 The old mnemonics don't have a way to specify this information. */
f4857b9b 8460 pred = "";
12a4e8c5
GK
8461 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8462 if (note != NULL_RTX)
8463 {
8464 /* PROB is the difference from 50%. */
8465 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
8466 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8467
8468 /* Only hint for highly probable/improbable branches on newer
8469 cpus as static prediction overrides processor dynamic
8470 prediction. For older cpus we may as well always hint, but
8471 assume not taken for branches that are very close to 50% as a
8472 mispredicted taken branch is more expensive than a
8473 mispredicted not-taken branch. */
8474 if (always_hint
8475 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8476 {
8477 if (abs (prob) > REG_BR_PROB_BASE / 20
8478 && ((prob > 0) ^ need_longbranch))
8479 pred = "+";
8480 else
8481 pred = "-";
8482 }
12a4e8c5 8483 }
12a4e8c5
GK
8484
8485 if (label == NULL)
94a54f47 8486 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 8487 else
94a54f47 8488 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 8489
37c67319
GK
8490 /* We need to escape any '%' characters in the reg_names string.
8491 Assume they'd only be the first character... */
8492 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8493 *s++ = '%';
94a54f47 8494 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
8495
8496 if (label != NULL)
8497 {
8498 /* If the branch distance was too far, we may have to use an
8499 unconditional branch to go the distance. */
8500 if (need_longbranch)
44518ddd 8501 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
8502 else
8503 s += sprintf (s, ",%s", label);
8504 }
8505
8506 return string;
8507}
50a0b056
GK
8508
8509/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8510 operands of the last comparison is nonzero/true, FALSE_COND if it
8511 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 8512
50a0b056
GK
8513int
8514rs6000_emit_cmove (dest, op, true_cond, false_cond)
8515 rtx dest;
8516 rtx op;
8517 rtx true_cond;
8518 rtx false_cond;
8519{
8520 enum rtx_code code = GET_CODE (op);
8521 rtx op0 = rs6000_compare_op0;
8522 rtx op1 = rs6000_compare_op1;
8523 REAL_VALUE_TYPE c1;
3148ad6d
DJ
8524 enum machine_mode compare_mode = GET_MODE (op0);
8525 enum machine_mode result_mode = GET_MODE (dest);
50a0b056
GK
8526 rtx temp;
8527
3148ad6d 8528 /* These modes should always match. */
a3170dc6
AH
8529 if (GET_MODE (op1) != compare_mode
8530 /* In the isel case however, we can use a compare immediate, so
8531 op1 may be a small constant. */
8532 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 8533 return 0;
178c3eff 8534 if (GET_MODE (true_cond) != result_mode)
3148ad6d 8535 return 0;
178c3eff 8536 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
8537 return 0;
8538
50a0b056
GK
8539 /* First, work out if the hardware can do this at all, or
8540 if it's too slow... */
50a0b056 8541 if (! rs6000_compare_fp_p)
a3170dc6
AH
8542 {
8543 if (TARGET_ISEL)
8544 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8545 return 0;
8546 }
50a0b056
GK
8547
8548 /* Eliminate half of the comparisons by switching operands, this
8549 makes the remaining code simpler. */
8550 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8551 || code == LTGT || code == LT)
8552 {
8553 code = reverse_condition_maybe_unordered (code);
8554 temp = true_cond;
8555 true_cond = false_cond;
8556 false_cond = temp;
8557 }
8558
8559 /* UNEQ and LTGT take four instructions for a comparison with zero,
8560 it'll probably be faster to use a branch here too. */
8561 if (code == UNEQ)
8562 return 0;
8563
8564 if (GET_CODE (op1) == CONST_DOUBLE)
8565 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8566
8567 /* We're going to try to implement comparions by performing
8568 a subtract, then comparing against zero. Unfortunately,
8569 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 8570 know that the operand is finite and the comparison
50a0b056
GK
8571 would treat EQ different to UNORDERED, we can't do it. */
8572 if (! flag_unsafe_math_optimizations
8573 && code != GT && code != UNGE
045572c7 8574 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
8575 /* Constructs of the form (a OP b ? a : b) are safe. */
8576 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8577 || (! rtx_equal_p (op0, true_cond)
8578 && ! rtx_equal_p (op1, true_cond))))
8579 return 0;
8580 /* At this point we know we can use fsel. */
8581
8582 /* Reduce the comparison to a comparison against zero. */
3148ad6d 8583 temp = gen_reg_rtx (compare_mode);
50a0b056 8584 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8585 gen_rtx_MINUS (compare_mode, op0, op1)));
50a0b056 8586 op0 = temp;
3148ad6d 8587 op1 = CONST0_RTX (compare_mode);
50a0b056
GK
8588
8589 /* If we don't care about NaNs we can reduce some of the comparisons
8590 down to faster ones. */
8591 if (flag_unsafe_math_optimizations)
8592 switch (code)
8593 {
8594 case GT:
8595 code = LE;
8596 temp = true_cond;
8597 true_cond = false_cond;
8598 false_cond = temp;
8599 break;
8600 case UNGE:
8601 code = GE;
8602 break;
8603 case UNEQ:
8604 code = EQ;
8605 break;
8606 default:
8607 break;
8608 }
8609
8610 /* Now, reduce everything down to a GE. */
8611 switch (code)
8612 {
8613 case GE:
8614 break;
8615
8616 case LE:
3148ad6d
DJ
8617 temp = gen_reg_rtx (compare_mode);
8618 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8619 op0 = temp;
8620 break;
8621
8622 case ORDERED:
3148ad6d
DJ
8623 temp = gen_reg_rtx (compare_mode);
8624 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
8625 op0 = temp;
8626 break;
8627
8628 case EQ:
3148ad6d 8629 temp = gen_reg_rtx (compare_mode);
50a0b056 8630 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
8631 gen_rtx_NEG (compare_mode,
8632 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
8633 op0 = temp;
8634 break;
8635
8636 case UNGE:
3148ad6d 8637 temp = gen_reg_rtx (result_mode);
50a0b056 8638 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8639 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8640 gen_rtx_GE (VOIDmode,
8641 op0, op1),
8642 true_cond, false_cond)));
8643 false_cond = temp;
8644 true_cond = false_cond;
8645
3148ad6d
DJ
8646 temp = gen_reg_rtx (compare_mode);
8647 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8648 op0 = temp;
8649 break;
8650
8651 case GT:
3148ad6d 8652 temp = gen_reg_rtx (result_mode);
50a0b056 8653 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8654 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8655 gen_rtx_GE (VOIDmode,
8656 op0, op1),
8657 true_cond, false_cond)));
8658 true_cond = temp;
8659 false_cond = true_cond;
8660
3148ad6d
DJ
8661 temp = gen_reg_rtx (compare_mode);
8662 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8663 op0 = temp;
8664 break;
8665
8666 default:
8667 abort ();
8668 }
8669
8670 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 8671 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8672 gen_rtx_GE (VOIDmode,
8673 op0, op1),
8674 true_cond, false_cond)));
8675 return 1;
8676}
8677
a3170dc6
AH
8678/* Same as above, but for ints (isel). */
8679
8680static int
8681rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
8682 rtx dest;
8683 rtx op;
8684 rtx true_cond;
8685 rtx false_cond;
8686{
8687 rtx condition_rtx, cr;
8688
8689 /* All isel implementations thus far are 32-bits. */
8690 if (GET_MODE (rs6000_compare_op0) != SImode)
8691 return 0;
8692
8693 /* We still have to do the compare, because isel doesn't do a
8694 compare, it just looks at the CRx bits set by a previous compare
8695 instruction. */
8696 condition_rtx = rs6000_generate_compare (GET_CODE (op));
8697 cr = XEXP (condition_rtx, 0);
8698
8699 if (GET_MODE (cr) == CCmode)
8700 emit_insn (gen_isel_signed (dest, condition_rtx,
8701 true_cond, false_cond, cr));
8702 else
8703 emit_insn (gen_isel_unsigned (dest, condition_rtx,
8704 true_cond, false_cond, cr));
8705
8706 return 1;
8707}
8708
8709const char *
8710output_isel (operands)
8711 rtx *operands;
8712{
8713 enum rtx_code code;
8714
8715 code = GET_CODE (operands[1]);
8716 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
8717 {
8718 PUT_CODE (operands[1], reverse_condition (code));
8719 return "isel %0,%3,%2,%j1";
8720 }
8721 else
8722 return "isel %0,%2,%3,%j1";
8723}
8724
50a0b056
GK
8725void
8726rs6000_emit_minmax (dest, code, op0, op1)
8727 rtx dest;
8728 enum rtx_code code;
8729 rtx op0;
8730 rtx op1;
8731{
8732 enum machine_mode mode = GET_MODE (op0);
5dc8d536 8733 enum rtx_code c;
50a0b056 8734 rtx target;
5dc8d536
AH
8735
8736 if (code == SMAX || code == SMIN)
8737 c = GE;
8738 else
8739 c = GEU;
8740
50a0b056 8741 if (code == SMAX || code == UMAX)
5dc8d536 8742 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8743 op0, op1, mode, 0);
8744 else
5dc8d536 8745 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8746 op1, op0, mode, 0);
8747 if (target == NULL_RTX)
8748 abort ();
8749 if (target != dest)
8750 emit_move_insn (dest, target);
8751}
12a4e8c5 8752\f
a4f6c312
SS
8753/* This page contains routines that are used to determine what the
8754 function prologue and epilogue code will do and write them out. */
9878760c 8755
a4f6c312
SS
8756/* Return the first fixed-point register that is required to be
8757 saved. 32 if none. */
9878760c
RK
8758
8759int
8760first_reg_to_save ()
8761{
8762 int first_reg;
8763
8764 /* Find lowest numbered live register. */
8765 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
8766 if (regs_ever_live[first_reg]
8767 && (! call_used_regs[first_reg]
1db02437 8768 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
8769 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
8770 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
8771 break;
8772
ee890fe2 8773#if TARGET_MACHO
93638d7a
AM
8774 if (flag_pic
8775 && current_function_uses_pic_offset_table
8776 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 8777 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
8778#endif
8779
9878760c
RK
8780 return first_reg;
8781}
8782
8783/* Similar, for FP regs. */
8784
8785int
8786first_fp_reg_to_save ()
8787{
8788 int first_reg;
8789
8790 /* Find lowest numbered live register. */
8791 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8792 if (regs_ever_live[first_reg])
8793 break;
8794
8795 return first_reg;
8796}
00b960c7
AH
8797
8798/* Similar, for AltiVec regs. */
8799
8800static int
8801first_altivec_reg_to_save ()
8802{
8803 int i;
8804
8805 /* Stack frame remains as is unless we are in AltiVec ABI. */
8806 if (! TARGET_ALTIVEC_ABI)
8807 return LAST_ALTIVEC_REGNO + 1;
8808
8809 /* Find lowest numbered live register. */
8810 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8811 if (regs_ever_live[i])
8812 break;
8813
8814 return i;
8815}
8816
8817/* Return a 32-bit mask of the AltiVec registers we need to set in
8818 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
8819 the 32-bit word is 0. */
8820
8821static unsigned int
8822compute_vrsave_mask ()
8823{
8824 unsigned int i, mask = 0;
8825
8826 /* First, find out if we use _any_ altivec registers. */
8827 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8828 if (regs_ever_live[i])
8829 mask |= ALTIVEC_REG_BIT (i);
8830
8831 if (mask == 0)
8832 return mask;
8833
8834 /* Next, add all registers that are call-clobbered. We do this
8835 because post-reload register optimizers such as regrename_optimize
8836 may choose to use them. They never change the register class
8837 chosen by reload, so cannot create new uses of altivec registers
8838 if there were none before, so the early exit above is safe. */
8839 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
8840 altivec registers not saved in the mask, which might well make the
8841 adjustments below more effective in eliding the save/restore of
8842 VRSAVE in small functions. */
8843 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
8844 if (call_used_regs[i])
8845 mask |= ALTIVEC_REG_BIT (i);
8846
8847 /* Next, remove the argument registers from the set. These must
8848 be in the VRSAVE mask set by the caller, so we don't need to add
8849 them in again. More importantly, the mask we compute here is
8850 used to generate CLOBBERs in the set_vrsave insn, and we do not
8851 wish the argument registers to die. */
8852 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
8853 mask &= ~ALTIVEC_REG_BIT (i);
8854
8855 /* Similarly, remove the return value from the set. */
8856 {
8857 bool yes = false;
8858 diddle_return_value (is_altivec_return_reg, &yes);
8859 if (yes)
8860 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
8861 }
8862
8863 return mask;
8864}
8865
8866static void
8867is_altivec_return_reg (reg, xyes)
8868 rtx reg;
8869 void *xyes;
8870{
8871 bool *yes = (bool *) xyes;
8872 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
8873 *yes = true;
8874}
8875
4697a36c
MM
8876\f
8877/* Calculate the stack information for the current function. This is
8878 complicated by having two separate calling sequences, the AIX calling
8879 sequence and the V.4 calling sequence.
8880
592696dd 8881 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 8882 32-bit 64-bit
4697a36c 8883 SP----> +---------------------------------------+
a260abc9 8884 | back chain to caller | 0 0
4697a36c 8885 +---------------------------------------+
a260abc9 8886 | saved CR | 4 8 (8-11)
4697a36c 8887 +---------------------------------------+
a260abc9 8888 | saved LR | 8 16
4697a36c 8889 +---------------------------------------+
a260abc9 8890 | reserved for compilers | 12 24
4697a36c 8891 +---------------------------------------+
a260abc9 8892 | reserved for binders | 16 32
4697a36c 8893 +---------------------------------------+
a260abc9 8894 | saved TOC pointer | 20 40
4697a36c 8895 +---------------------------------------+
a260abc9 8896 | Parameter save area (P) | 24 48
4697a36c 8897 +---------------------------------------+
a260abc9 8898 | Alloca space (A) | 24+P etc.
802a0058 8899 +---------------------------------------+
a7df97e6 8900 | Local variable space (L) | 24+P+A
4697a36c 8901 +---------------------------------------+
a7df97e6 8902 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 8903 +---------------------------------------+
00b960c7
AH
8904 | Save area for AltiVec registers (W) | 24+P+A+L+X
8905 +---------------------------------------+
8906 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
8907 +---------------------------------------+
8908 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 8909 +---------------------------------------+
00b960c7
AH
8910 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
8911 +---------------------------------------+
8912 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
8913 +---------------------------------------+
8914 old SP->| back chain to caller's caller |
8915 +---------------------------------------+
8916
5376a30c
KR
8917 The required alignment for AIX configurations is two words (i.e., 8
8918 or 16 bytes).
8919
8920
4697a36c
MM
8921 V.4 stack frames look like:
8922
8923 SP----> +---------------------------------------+
8924 | back chain to caller | 0
8925 +---------------------------------------+
5eb387b8 8926 | caller's saved LR | 4
4697a36c
MM
8927 +---------------------------------------+
8928 | Parameter save area (P) | 8
8929 +---------------------------------------+
a7df97e6
MM
8930 | Alloca space (A) | 8+P
8931 +---------------------------------------+
8932 | Varargs save area (V) | 8+P+A
8933 +---------------------------------------+
8934 | Local variable space (L) | 8+P+A+V
8935 +---------------------------------------+
8936 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 8937 +---------------------------------------+
00b960c7
AH
8938 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
8939 +---------------------------------------+
8940 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
8941 +---------------------------------------+
8942 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
8943 +---------------------------------------+
a3170dc6
AH
8944 | SPE: area for 64-bit GP registers |
8945 +---------------------------------------+
8946 | SPE alignment padding |
8947 +---------------------------------------+
00b960c7 8948 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 8949 +---------------------------------------+
00b960c7 8950 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 8951 +---------------------------------------+
00b960c7 8952 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
8953 +---------------------------------------+
8954 old SP->| back chain to caller's caller |
8955 +---------------------------------------+
b6c9286a 8956
5376a30c
KR
8957 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
8958 given. (But note below and in sysv4.h that we require only 8 and
8959 may round up the size of our stack frame anyways. The historical
8960 reason is early versions of powerpc-linux which didn't properly
8961 align the stack at program startup. A happy side-effect is that
8962 -mno-eabi libraries can be used with -meabi programs.)
8963
5376a30c
KR
8964 The EABI configuration defaults to the V.4 layout, unless
8965 -mcall-aix is used, in which case the AIX layout is used. However,
8966 the stack alignment requirements may differ. If -mno-eabi is not
8967 given, the required stack alignment is 8 bytes; if -mno-eabi is
8968 given, the required alignment is 16 bytes. (But see V.4 comment
8969 above.) */
4697a36c 8970
61b2fbe7
MM
8971#ifndef ABI_STACK_BOUNDARY
8972#define ABI_STACK_BOUNDARY STACK_BOUNDARY
8973#endif
8974
4697a36c
MM
8975rs6000_stack_t *
8976rs6000_stack_info ()
8977{
8978 static rs6000_stack_t info, zero_info;
8979 rs6000_stack_t *info_ptr = &info;
9ebbca7d 8980 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 8981 enum rs6000_abi abi;
83720594 8982 int ehrd_size;
b6c9286a 8983 int total_raw_size;
4697a36c 8984
a4f6c312 8985 /* Zero all fields portably. */
4697a36c
MM
8986 info = zero_info;
8987
a4f6c312 8988 /* Select which calling sequence. */
b6c9286a 8989 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 8990
a4f6c312 8991 /* Calculate which registers need to be saved & save area size. */
4697a36c 8992 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 8993 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 8994 even if it currently looks like we won't. */
2bfcf297 8995 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
8996 || (flag_pic == 1 && abi == ABI_V4)
8997 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
8998 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
8999 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
9000 else
9001 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 9002
a3170dc6
AH
9003 /* For the SPE, we have an additional upper 32-bits on each GPR.
9004 Ideally we should save the entire 64-bits only when the upper
9005 half is used in SIMD instructions. Since we only record
9006 registers live (not the size they are used in), this proves
9007 difficult because we'd have to traverse the instruction chain at
9008 the right time, taking reload into account. This is a real pain,
9009 so we opt to save the GPRs in 64-bits always. Anyone overly
9010 concerned with frame size can fix this. ;-).
9011
9012 So... since we save all GPRs (except the SP) in 64-bits, the
9013 traditional GP save area will be empty. */
9014 if (TARGET_SPE_ABI)
9015 info_ptr->gp_size = 0;
9016
4697a36c
MM
9017 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
9018 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
9019
00b960c7
AH
9020 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9021 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9022 - info_ptr->first_altivec_reg_save);
9023
592696dd 9024 /* Does this function call anything? */
71f123ca
FS
9025 info_ptr->calls_p = (! current_function_is_leaf
9026 || cfun->machine->ra_needs_full_frame);
b6c9286a 9027
a4f6c312 9028 /* Determine if we need to save the link register. */
71f123ca 9029 if (rs6000_ra_ever_killed ()
70f4f91c 9030 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
9031#ifdef TARGET_RELOCATABLE
9032 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9033#endif
9034 || (info_ptr->first_fp_reg_save != 64
9035 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 9036 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 9037 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
9038 || (DEFAULT_ABI == ABI_DARWIN
9039 && flag_pic
9040 && current_function_uses_pic_offset_table)
4697a36c
MM
9041 || info_ptr->calls_p)
9042 {
9043 info_ptr->lr_save_p = 1;
9ebbca7d 9044 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9045 }
9046
9ebbca7d
GK
9047 /* Determine if we need to save the condition code registers. */
9048 if (regs_ever_live[CR2_REGNO]
9049 || regs_ever_live[CR3_REGNO]
9050 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9051 {
9052 info_ptr->cr_save_p = 1;
f607bc57 9053 if (abi == ABI_V4)
4697a36c
MM
9054 info_ptr->cr_size = reg_size;
9055 }
9056
83720594
RH
9057 /* If the current function calls __builtin_eh_return, then we need
9058 to allocate stack space for registers that will hold data for
9059 the exception handler. */
9060 if (current_function_calls_eh_return)
9061 {
9062 unsigned int i;
9063 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9064 continue;
a3170dc6
AH
9065
9066 /* SPE saves EH registers in 64-bits. */
9067 ehrd_size = i * (TARGET_SPE_ABI ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9068 }
9069 else
9070 ehrd_size = 0;
9071
592696dd 9072 /* Determine various sizes. */
4697a36c
MM
9073 info_ptr->reg_size = reg_size;
9074 info_ptr->fixed_size = RS6000_SAVE_AREA;
9075 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9076 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9077 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9078 8);
00b960c7 9079
a3170dc6
AH
9080 if (TARGET_SPE_ABI)
9081 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9082 else
9083 info_ptr->spe_gp_size = 0;
9084
08b57fb3 9085 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9086 {
9087 info_ptr->vrsave_mask = compute_vrsave_mask ();
9088 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9089 }
9090 else
9091 {
9092 info_ptr->vrsave_mask = 0;
9093 info_ptr->vrsave_size = 0;
9094 }
b6c9286a 9095
592696dd 9096 /* Calculate the offsets. */
24d304eb 9097 switch (abi)
4697a36c 9098 {
b6c9286a 9099 case ABI_NONE:
24d304eb 9100 default:
b6c9286a
MM
9101 abort ();
9102
9103 case ABI_AIX:
9104 case ABI_AIX_NODESC:
ee890fe2 9105 case ABI_DARWIN:
b6c9286a
MM
9106 info_ptr->fp_save_offset = - info_ptr->fp_size;
9107 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9108
9109 if (TARGET_ALTIVEC_ABI)
9110 {
9111 info_ptr->vrsave_save_offset
9112 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9113
9114 /* Align stack so vector save area is on a quadword boundary. */
9115 if (info_ptr->altivec_size != 0)
9116 info_ptr->altivec_padding_size
9117 = 16 - (-info_ptr->vrsave_save_offset % 16);
9118 else
9119 info_ptr->altivec_padding_size = 0;
9120
9121 info_ptr->altivec_save_offset
9122 = info_ptr->vrsave_save_offset
9123 - info_ptr->altivec_padding_size
9124 - info_ptr->altivec_size;
9125
9126 /* Adjust for AltiVec case. */
9127 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9128 }
9129 else
9130 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9131 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9132 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9133 break;
9134
9135 case ABI_V4:
b6c9286a
MM
9136 info_ptr->fp_save_offset = - info_ptr->fp_size;
9137 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9138 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9139
a3170dc6
AH
9140 if (TARGET_SPE_ABI)
9141 {
9142 /* Align stack so SPE GPR save area is aligned on a
9143 double-word boundary. */
9144 if (info_ptr->spe_gp_size != 0)
9145 info_ptr->spe_padding_size
9146 = 8 - (-info_ptr->cr_save_offset % 8);
9147 else
9148 info_ptr->spe_padding_size = 0;
9149
9150 info_ptr->spe_gp_save_offset
9151 = info_ptr->cr_save_offset
9152 - info_ptr->spe_padding_size
9153 - info_ptr->spe_gp_size;
9154
9155 /* Adjust for SPE case. */
9156 info_ptr->toc_save_offset
9157 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9158 }
9159 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9160 {
9161 info_ptr->vrsave_save_offset
9162 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9163
9164 /* Align stack so vector save area is on a quadword boundary. */
9165 if (info_ptr->altivec_size != 0)
9166 info_ptr->altivec_padding_size
9167 = 16 - (-info_ptr->vrsave_save_offset % 16);
9168 else
9169 info_ptr->altivec_padding_size = 0;
9170
9171 info_ptr->altivec_save_offset
9172 = info_ptr->vrsave_save_offset
9173 - info_ptr->altivec_padding_size
9174 - info_ptr->altivec_size;
9175
9176 /* Adjust for AltiVec case. */
9177 info_ptr->toc_save_offset
9178 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9179 }
9180 else
9181 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9182 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9183 info_ptr->lr_save_offset = reg_size;
9184 break;
4697a36c
MM
9185 }
9186
00b960c7
AH
9187 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9188 + info_ptr->gp_size
9189 + info_ptr->altivec_size
9190 + info_ptr->altivec_padding_size
9191 + info_ptr->vrsave_size
a3170dc6
AH
9192 + info_ptr->spe_gp_size
9193 + info_ptr->spe_padding_size
00b960c7
AH
9194 + ehrd_size
9195 + info_ptr->cr_size
9196 + info_ptr->lr_size
9197 + info_ptr->vrsave_size
9198 + info_ptr->toc_size,
9199 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9200 ? 16 : 8);
9201
ff381587
MM
9202 total_raw_size = (info_ptr->vars_size
9203 + info_ptr->parm_size
ff381587
MM
9204 + info_ptr->save_size
9205 + info_ptr->varargs_size
9206 + info_ptr->fixed_size);
9207
a4f6c312
SS
9208 info_ptr->total_size =
9209 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9210
9211 /* Determine if we need to allocate any stack frame:
9212
a4f6c312
SS
9213 For AIX we need to push the stack if a frame pointer is needed
9214 (because the stack might be dynamically adjusted), if we are
9215 debugging, if we make calls, or if the sum of fp_save, gp_save,
9216 and local variables are more than the space needed to save all
9217 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9218 + 18*8 = 288 (GPR13 reserved).
ff381587 9219
a4f6c312
SS
9220 For V.4 we don't have the stack cushion that AIX uses, but assume
9221 that the debugger can handle stackless frames. */
ff381587
MM
9222
9223 if (info_ptr->calls_p)
9224 info_ptr->push_p = 1;
9225
f607bc57 9226 else if (abi == ABI_V4)
e72247f4 9227 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
9228
9229 else
9230 info_ptr->push_p = (frame_pointer_needed
ee890fe2 9231 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 9232 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 9233 > (TARGET_32BIT ? 220 : 288)));
ff381587 9234
a4f6c312 9235 /* Zero offsets if we're not saving those registers. */
8dda1a21 9236 if (info_ptr->fp_size == 0)
4697a36c
MM
9237 info_ptr->fp_save_offset = 0;
9238
8dda1a21 9239 if (info_ptr->gp_size == 0)
4697a36c
MM
9240 info_ptr->gp_save_offset = 0;
9241
00b960c7
AH
9242 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9243 info_ptr->altivec_save_offset = 0;
9244
9245 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9246 info_ptr->vrsave_save_offset = 0;
9247
a3170dc6
AH
9248 if (! TARGET_SPE_ABI || info_ptr->spe_gp_size == 0)
9249 info_ptr->spe_gp_save_offset = 0;
9250
c81fc13e 9251 if (! info_ptr->lr_save_p)
4697a36c
MM
9252 info_ptr->lr_save_offset = 0;
9253
c81fc13e 9254 if (! info_ptr->cr_save_p)
4697a36c
MM
9255 info_ptr->cr_save_offset = 0;
9256
c81fc13e 9257 if (! info_ptr->toc_save_p)
b6c9286a
MM
9258 info_ptr->toc_save_offset = 0;
9259
4697a36c
MM
9260 return info_ptr;
9261}
9262
9263void
9264debug_stack_info (info)
9265 rs6000_stack_t *info;
9878760c 9266{
d330fd93 9267 const char *abi_string;
24d304eb 9268
c81fc13e 9269 if (! info)
4697a36c
MM
9270 info = rs6000_stack_info ();
9271
9272 fprintf (stderr, "\nStack information for function %s:\n",
9273 ((current_function_decl && DECL_NAME (current_function_decl))
9274 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9275 : "<unknown>"));
9276
24d304eb
RK
9277 switch (info->abi)
9278 {
b6c9286a
MM
9279 default: abi_string = "Unknown"; break;
9280 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9281 case ABI_AIX:
b6c9286a 9282 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9283 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9284 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9285 }
9286
9287 fprintf (stderr, "\tABI = %5s\n", abi_string);
9288
00b960c7
AH
9289 if (TARGET_ALTIVEC_ABI)
9290 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9291
a3170dc6
AH
9292 if (TARGET_SPE_ABI)
9293 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9294
4697a36c
MM
9295 if (info->first_gp_reg_save != 32)
9296 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9297
9298 if (info->first_fp_reg_save != 64)
9299 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9300
00b960c7
AH
9301 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9302 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9303 info->first_altivec_reg_save);
9304
4697a36c
MM
9305 if (info->lr_save_p)
9306 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9307
4697a36c
MM
9308 if (info->cr_save_p)
9309 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9310
b6c9286a
MM
9311 if (info->toc_save_p)
9312 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9313
00b960c7
AH
9314 if (info->vrsave_mask)
9315 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9316
4697a36c
MM
9317 if (info->push_p)
9318 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9319
9320 if (info->calls_p)
9321 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9322
4697a36c
MM
9323 if (info->gp_save_offset)
9324 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9325
9326 if (info->fp_save_offset)
9327 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9328
00b960c7
AH
9329 if (info->altivec_save_offset)
9330 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9331 info->altivec_save_offset);
9332
a3170dc6
AH
9333 if (info->spe_gp_save_offset)
9334 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9335 info->spe_gp_save_offset);
9336
00b960c7
AH
9337 if (info->vrsave_save_offset)
9338 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9339 info->vrsave_save_offset);
9340
4697a36c
MM
9341 if (info->lr_save_offset)
9342 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9343
9344 if (info->cr_save_offset)
9345 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9346
b6c9286a
MM
9347 if (info->toc_save_offset)
9348 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9349
4697a36c
MM
9350 if (info->varargs_save_offset)
9351 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9352
9353 if (info->total_size)
9354 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9355
9356 if (info->varargs_size)
9357 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9358
9359 if (info->vars_size)
9360 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9361
9362 if (info->parm_size)
9363 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9364
9365 if (info->fixed_size)
9366 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9367
9368 if (info->gp_size)
9369 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9370
a3170dc6
AH
9371 if (info->spe_gp_size)
9372 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9373
4697a36c
MM
9374 if (info->fp_size)
9375 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9376
00b960c7
AH
9377 if (info->altivec_size)
9378 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9379
9380 if (info->vrsave_size)
9381 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9382
9383 if (info->altivec_padding_size)
9384 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9385 info->altivec_padding_size);
9386
a3170dc6
AH
9387 if (info->spe_padding_size)
9388 fprintf (stderr, "\tspe_padding_size = %5d\n",
9389 info->spe_padding_size);
9390
a4f6c312 9391 if (info->lr_size)
ed947a96 9392 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9393
4697a36c
MM
9394 if (info->cr_size)
9395 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9396
a4f6c312 9397 if (info->toc_size)
b6c9286a
MM
9398 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9399
4697a36c
MM
9400 if (info->save_size)
9401 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9402
9403 if (info->reg_size != 4)
9404 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9405
9406 fprintf (stderr, "\n");
9878760c 9407}
71f123ca
FS
9408
9409rtx
9410rs6000_return_addr (count, frame)
9411 int count;
9412 rtx frame;
9413{
a4f6c312
SS
9414 /* Currently we don't optimize very well between prolog and body
9415 code and for PIC code the code can be actually quite bad, so
9416 don't try to be too clever here. */
f585a356 9417 if (count != 0 || flag_pic != 0)
71f123ca
FS
9418 {
9419 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9420
9421 return
9422 gen_rtx_MEM
9423 (Pmode,
9424 memory_address
9425 (Pmode,
9426 plus_constant (copy_to_reg
9427 (gen_rtx_MEM (Pmode,
9428 memory_address (Pmode, frame))),
9429 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9430 }
9431
9e2f7ec7 9432 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9433}
9434
5e1bf043
DJ
9435/* Say whether a function is a candidate for sibcall handling or not.
9436 We do not allow indirect calls to be optimized into sibling calls.
9437 Also, we can't do it if there are any vector parameters; there's
9438 nowhere to put the VRsave code so it works; note that functions with
9439 vector parameters are required to have a prototype, so the argument
9440 type info must be available here. (The tail recursion case can work
9441 with vector parameters, but there's no way to distinguish here.) */
9442int
9443function_ok_for_sibcall (fndecl)
9444 tree fndecl;
9445{
9446 tree type;
9447 if (fndecl)
9448 {
9449 if (TARGET_ALTIVEC_VRSAVE)
9450 {
9451 for (type = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
9452 type; type = TREE_CHAIN (type))
9453 {
c15b529f 9454 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
5e1bf043
DJ
9455 return 0;
9456 }
9457 }
9458 if (DEFAULT_ABI == ABI_DARWIN
2bcc50d0
AM
9459 || (*targetm.binds_local_p) (fndecl))
9460 {
9461 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
9462
9463 if (!lookup_attribute ("longcall", attr_list)
9464 || lookup_attribute ("shortcall", attr_list))
9465 return 1;
9466 }
5e1bf043
DJ
9467 }
9468 return 0;
9469}
9470
71f123ca
FS
9471static int
9472rs6000_ra_ever_killed ()
9473{
9474 rtx top;
5e1bf043
DJ
9475 rtx reg;
9476 rtx insn;
71f123ca 9477
3961e8fe
RH
9478 /* Irritatingly, there are two kinds of thunks -- those created with
9479 TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
9480 through the regular part of the compiler. This is a very hacky
9481 way to tell them apart. */
9482 if (current_function_is_thunk && !no_new_pseudos)
71f123ca 9483 return 0;
eb0424da 9484
36f7e964
AH
9485 /* regs_ever_live has LR marked as used if any sibcalls are present,
9486 but this should not force saving and restoring in the
9487 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
9488 clobbers LR, so that is inappropriate. */
9489
5e1bf043
DJ
9490 /* Also, the prologue can generate a store into LR that
9491 doesn't really count, like this:
36f7e964 9492
5e1bf043
DJ
9493 move LR->R0
9494 bcl to set PIC register
9495 move LR->R31
9496 move R0->LR
36f7e964
AH
9497
9498 When we're called from the epilogue, we need to avoid counting
9499 this as a store. */
5e1bf043 9500
71f123ca
FS
9501 push_topmost_sequence ();
9502 top = get_insns ();
9503 pop_topmost_sequence ();
5e1bf043 9504 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9505
5e1bf043
DJ
9506 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9507 {
9508 if (INSN_P (insn))
9509 {
9510 if (FIND_REG_INC_NOTE (insn, reg))
9511 return 1;
9512 else if (GET_CODE (insn) == CALL_INSN
c15b529f 9513 && !SIBLING_CALL_P (insn))
5e1bf043 9514 return 1;
36f7e964
AH
9515 else if (set_of (reg, insn) != NULL_RTX
9516 && !prologue_epilogue_contains (insn))
5e1bf043
DJ
9517 return 1;
9518 }
9519 }
9520 return 0;
71f123ca 9521}
4697a36c 9522\f
8cd8f856
GK
9523/* Add a REG_MAYBE_DEAD note to the insn. */
9524static void
9525rs6000_maybe_dead (insn)
9526 rtx insn;
9527{
9528 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9529 const0_rtx,
9530 REG_NOTES (insn));
9531}
9532
9ebbca7d 9533/* Emit instructions needed to load the TOC register.
c7ca610e 9534 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9535 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9536
9537void
9ebbca7d
GK
9538rs6000_emit_load_toc_table (fromprolog)
9539 int fromprolog;
c7ca610e 9540{
9ebbca7d 9541 rtx dest;
1db02437 9542 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9543
20b71b17
AM
9544 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9545 {
9546 rtx temp = (fromprolog
9547 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9548 : gen_reg_rtx (Pmode));
9549 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
9550 rs6000_maybe_dead (emit_move_insn (dest, temp));
9551 }
9552 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
9553 {
9554 char buf[30];
9555 rtx tempLR = (fromprolog
9556 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9557 : gen_reg_rtx (Pmode));
9558 rtx temp0 = (fromprolog
9559 ? gen_rtx_REG (Pmode, 0)
9560 : gen_reg_rtx (Pmode));
9561 rtx symF;
9562
9563 /* possibly create the toc section */
9564 if (! toc_initialized)
38c1f2d7 9565 {
20b71b17
AM
9566 toc_section ();
9567 function_section (current_function_decl);
38c1f2d7 9568 }
9ebbca7d 9569
20b71b17
AM
9570 if (fromprolog)
9571 {
9572 rtx symL;
38c1f2d7 9573
20b71b17
AM
9574 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
9575 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9576
20b71b17
AM
9577 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
9578 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9579
9580 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9581 symF)));
9582 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9583 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9584 symL,
9585 symF)));
9ebbca7d
GK
9586 }
9587 else
20b71b17
AM
9588 {
9589 rtx tocsym;
9590 static int reload_toc_labelno = 0;
9591
9592 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
9593
9594 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
9595 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9596
9597 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9598 symF,
9599 tocsym)));
9600 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9601 rs6000_maybe_dead (emit_move_insn (temp0,
9602 gen_rtx_MEM (Pmode, dest)));
9603 }
9604 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d 9605 }
20b71b17
AM
9606 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
9607 {
9608 /* This is for AIX code running in non-PIC ELF32. */
9609 char buf[30];
9610 rtx realsym;
9611 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9612 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9613
9614 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9615 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9616 }
9617 else if (DEFAULT_ABI == ABI_AIX)
9ebbca7d
GK
9618 {
9619 if (TARGET_32BIT)
20b71b17 9620 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 9621 else
20b71b17 9622 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d 9623 }
20b71b17
AM
9624 else
9625 abort ();
9ebbca7d
GK
9626}
9627
9628int
9629get_TOC_alias_set ()
9630{
9631 static int set = -1;
9632 if (set == -1)
9633 set = new_alias_set ();
9634 return set;
9635}
9636
9637/* This retuns nonzero if the current function uses the TOC. This is
9638 determined by the presence of (unspec ... 7), which is generated by
9639 the various load_toc_* patterns. */
a4f6c312 9640
9ebbca7d
GK
9641int
9642uses_TOC ()
9643{
9644 rtx insn;
38c1f2d7 9645
9ebbca7d 9646 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 9647 if (INSN_P (insn))
9ebbca7d
GK
9648 {
9649 rtx pat = PATTERN (insn);
9650 int i;
9651
8cd8f856 9652 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
9653 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9654 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9655 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9656 return 1;
38c1f2d7 9657 }
9ebbca7d
GK
9658 return 0;
9659}
38c1f2d7 9660
9ebbca7d 9661rtx
a4f6c312 9662create_TOC_reference (symbol)
9ebbca7d
GK
9663 rtx symbol;
9664{
a8a05998
ZW
9665 return gen_rtx_PLUS (Pmode,
9666 gen_rtx_REG (Pmode, TOC_REGISTER),
9667 gen_rtx_CONST (Pmode,
9668 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 9669 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 9670}
38c1f2d7 9671
9ebbca7d
GK
9672#if TARGET_AIX
9673/* __throw will restore its own return address to be the same as the
9674 return address of the function that the throw is being made to.
9675 This is unfortunate, because we want to check the original
9676 return address to see if we need to restore the TOC.
9677 So we have to squirrel it away here.
9678 This is used only in compiling __throw and __rethrow.
c7ca610e 9679
9ebbca7d
GK
9680 Most of this code should be removed by CSE. */
9681static rtx insn_after_throw;
c7ca610e 9682
a4f6c312 9683/* This does the saving... */
9ebbca7d
GK
9684void
9685rs6000_aix_emit_builtin_unwind_init ()
9686{
9687 rtx mem;
9688 rtx stack_top = gen_reg_rtx (Pmode);
9689 rtx opcode_addr = gen_reg_rtx (Pmode);
9690
9691 insn_after_throw = gen_reg_rtx (SImode);
9692
9693 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9694 emit_move_insn (stack_top, mem);
9695
9696 mem = gen_rtx_MEM (Pmode,
9697 gen_rtx_PLUS (Pmode, stack_top,
9698 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9699 emit_move_insn (opcode_addr, mem);
9700 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
9701}
9702
a4f6c312
SS
9703/* Emit insns to _restore_ the TOC register, at runtime (specifically
9704 in _eh.o). Only used on AIX.
9ebbca7d
GK
9705
9706 The idea is that on AIX, function calls look like this:
9707 bl somefunction-trampoline
9708 lwz r2,20(sp)
9709
a4f6c312 9710 and later,
9ebbca7d
GK
9711 somefunction-trampoline:
9712 stw r2,20(sp)
9713 ... load function address in the count register ...
9714 bctr
9715 or like this, if the linker determines that this is not a cross-module call
9716 and so the TOC need not be restored:
9717 bl somefunction
9718 nop
9719 or like this, if the compiler could determine that this is not a
9720 cross-module call:
9721 bl somefunction
9722 now, the tricky bit here is that register 2 is saved and restored
9723 by the _linker_, so we can't readily generate debugging information
9724 for it. So we need to go back up the call chain looking at the
9725 insns at return addresses to see which calls saved the TOC register
9726 and so see where it gets restored from.
9727
9728 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9729 just before the actual epilogue.
9730
9731 On the bright side, this incurs no space or time overhead unless an
9732 exception is thrown, except for the extra code in libgcc.a.
9733
9734 The parameter STACKSIZE is a register containing (at runtime)
9735 the amount to be popped off the stack in addition to the stack frame
9736 of this routine (which will be __throw or __rethrow, and so is
9737 guaranteed to have a stack frame). */
a4f6c312 9738
9ebbca7d
GK
9739void
9740rs6000_emit_eh_toc_restore (stacksize)
9741 rtx stacksize;
9742{
9743 rtx top_of_stack;
9744 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9745 rtx tocompare = gen_reg_rtx (SImode);
9746 rtx opcode = gen_reg_rtx (SImode);
9747 rtx opcode_addr = gen_reg_rtx (Pmode);
9748 rtx mem;
9749 rtx loop_start = gen_label_rtx ();
9750 rtx no_toc_restore_needed = gen_label_rtx ();
9751 rtx loop_exit = gen_label_rtx ();
9752
9753 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 9754 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9755 emit_move_insn (bottom_of_stack, mem);
9756
9757 top_of_stack = expand_binop (Pmode, add_optab,
9758 bottom_of_stack, stacksize,
9759 NULL_RTX, 1, OPTAB_WIDEN);
9760
2496c7bd
LB
9761 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9762 : 0xE8410028, SImode));
9ebbca7d
GK
9763
9764 if (insn_after_throw == NULL_RTX)
a4f6c312 9765 abort ();
9ebbca7d
GK
9766 emit_move_insn (opcode, insn_after_throw);
9767
6496a589 9768 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
9769 emit_label (loop_start);
9770
9771 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 9772 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9773 no_toc_restore_needed);
9774
9775 mem = gen_rtx_MEM (Pmode,
9776 gen_rtx_PLUS (Pmode, bottom_of_stack,
9777 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
9778 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
9779
9780 emit_label (no_toc_restore_needed);
9781 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 9782 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
9783 loop_exit);
9784
9785 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 9786 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9787 emit_move_insn (bottom_of_stack, mem);
9788
9789 mem = gen_rtx_MEM (Pmode,
9790 gen_rtx_PLUS (Pmode, bottom_of_stack,
9791 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9792 emit_move_insn (opcode_addr, mem);
9793 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
9794
6496a589 9795 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 9796 emit_jump (loop_start);
6496a589 9797 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
9798 emit_label (loop_exit);
9799}
9800#endif /* TARGET_AIX */
38c1f2d7 9801\f
ba4828e0
RK
9802/* This ties together stack memory (MEM with an alias set of
9803 rs6000_sr_alias_set) and the change to the stack pointer. */
9804
9ebbca7d
GK
9805static void
9806rs6000_emit_stack_tie ()
9807{
ba4828e0
RK
9808 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
9809
9810 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9811 emit_insn (gen_stack_tie (mem));
9812}
38c1f2d7 9813
9ebbca7d
GK
9814/* Emit the correct code for allocating stack space, as insns.
9815 If COPY_R12, make sure a copy of the old frame is left in r12.
9816 The generated code may use hard register 0 as a temporary. */
9817
9818static void
9819rs6000_emit_allocate_stack (size, copy_r12)
9820 HOST_WIDE_INT size;
38c1f2d7
MM
9821 int copy_r12;
9822{
9ebbca7d
GK
9823 rtx insn;
9824 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
9825 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
9826 rtx todec = GEN_INT (-size);
a157febd
GK
9827
9828 if (current_function_limit_stack)
9829 {
9830 if (REG_P (stack_limit_rtx)
9831 && REGNO (stack_limit_rtx) > 1
9832 && REGNO (stack_limit_rtx) <= 31)
9833 {
9ebbca7d
GK
9834 emit_insn (Pmode == SImode
9835 ? gen_addsi3 (tmp_reg,
9836 stack_limit_rtx,
9837 GEN_INT (size))
9838 : gen_adddi3 (tmp_reg,
9839 stack_limit_rtx,
9840 GEN_INT (size)));
9841
9842 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9843 const0_rtx));
a157febd
GK
9844 }
9845 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 9846 && TARGET_32BIT
f607bc57 9847 && DEFAULT_ABI == ABI_V4)
a157febd 9848 {
9ebbca7d
GK
9849 rtx toload = gen_rtx_CONST (VOIDmode,
9850 gen_rtx_PLUS (Pmode,
9851 stack_limit_rtx,
9852 GEN_INT (size)));
9853
9854 emit_insn (gen_elf_high (tmp_reg, toload));
9855 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
9856 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
9857 const0_rtx));
a157febd
GK
9858 }
9859 else
9860 warning ("stack limit expression is not supported");
9861 }
9862
9ebbca7d
GK
9863 if (copy_r12 || ! TARGET_UPDATE)
9864 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
9865
38c1f2d7
MM
9866 if (TARGET_UPDATE)
9867 {
9ebbca7d 9868 if (size > 32767)
38c1f2d7 9869 {
9ebbca7d
GK
9870 /* Need a note here so that try_split doesn't get confused. */
9871 if (get_last_insn() == NULL_RTX)
9872 emit_note (0, NOTE_INSN_DELETED);
9873 insn = emit_move_insn (tmp_reg, todec);
9874 try_split (PATTERN (insn), insn, 0);
9875 todec = tmp_reg;
38c1f2d7 9876 }
9ebbca7d
GK
9877
9878 if (Pmode == SImode)
9879 insn = emit_insn (gen_movsi_update (stack_reg, stack_reg,
9880 todec, stack_reg));
9881 else
9882 insn = emit_insn (gen_movdi_update (stack_reg, stack_reg,
9883 todec, stack_reg));
38c1f2d7
MM
9884 }
9885 else
9886 {
9ebbca7d
GK
9887 if (Pmode == SImode)
9888 insn = emit_insn (gen_addsi3 (stack_reg, stack_reg, todec));
38c1f2d7 9889 else
9ebbca7d
GK
9890 insn = emit_insn (gen_adddi3 (stack_reg, stack_reg, todec));
9891 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
9892 gen_rtx_REG (Pmode, 12));
9893 }
9894
9895 RTX_FRAME_RELATED_P (insn) = 1;
9896 REG_NOTES (insn) =
9897 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9898 gen_rtx_SET (VOIDmode, stack_reg,
9899 gen_rtx_PLUS (Pmode, stack_reg,
9900 GEN_INT (-size))),
9901 REG_NOTES (insn));
9902}
9903
9aa86737
AH
9904/* Add a RTX_FRAME_RELATED note so that dwarf2out_frame_debug_expr
9905 knows that:
9906
9907 (mem (plus (blah) (regXX)))
9908
9909 is really:
9910
9911 (mem (plus (blah) (const VALUE_OF_REGXX))). */
9912
9913static void
9914altivec_frame_fixup (insn, reg, val)
9915 rtx insn, reg;
9916 HOST_WIDE_INT val;
9917{
9918 rtx real;
9919
9920 real = copy_rtx (PATTERN (insn));
9921
9922 real = replace_rtx (real, reg, GEN_INT (val));
9923
9924 RTX_FRAME_RELATED_P (insn) = 1;
9925 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
9926 real,
9927 REG_NOTES (insn));
9928}
9929
a4f6c312
SS
9930/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
9931 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
9932 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
9933 deduce these equivalences by itself so it wasn't necessary to hold
9934 its hand so much. */
9ebbca7d
GK
9935
9936static void
9937rs6000_frame_related (insn, reg, val, reg2, rreg)
9938 rtx insn;
9939 rtx reg;
9940 HOST_WIDE_INT val;
9941 rtx reg2;
9942 rtx rreg;
9943{
9944 rtx real, temp;
9945
e56c4463
JL
9946 /* copy_rtx will not make unique copies of registers, so we need to
9947 ensure we don't have unwanted sharing here. */
9948 if (reg == reg2)
9949 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9950
9951 if (reg == rreg)
9952 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
9953
9ebbca7d
GK
9954 real = copy_rtx (PATTERN (insn));
9955
89e7058f
AH
9956 if (reg2 != NULL_RTX)
9957 real = replace_rtx (real, reg2, rreg);
9958
9ebbca7d
GK
9959 real = replace_rtx (real, reg,
9960 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
9961 STACK_POINTER_REGNUM),
9962 GEN_INT (val)));
9963
9964 /* We expect that 'real' is either a SET or a PARALLEL containing
9965 SETs (and possibly other stuff). In a PARALLEL, all the SETs
9966 are important so they all have to be marked RTX_FRAME_RELATED_P. */
9967
9968 if (GET_CODE (real) == SET)
9969 {
9970 rtx set = real;
9971
9972 temp = simplify_rtx (SET_SRC (set));
9973 if (temp)
9974 SET_SRC (set) = temp;
9975 temp = simplify_rtx (SET_DEST (set));
9976 if (temp)
9977 SET_DEST (set) = temp;
9978 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 9979 {
9ebbca7d
GK
9980 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
9981 if (temp)
9982 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 9983 }
38c1f2d7 9984 }
9ebbca7d
GK
9985 else if (GET_CODE (real) == PARALLEL)
9986 {
9987 int i;
9988 for (i = 0; i < XVECLEN (real, 0); i++)
9989 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
9990 {
9991 rtx set = XVECEXP (real, 0, i);
9992
9993 temp = simplify_rtx (SET_SRC (set));
9994 if (temp)
9995 SET_SRC (set) = temp;
9996 temp = simplify_rtx (SET_DEST (set));
9997 if (temp)
9998 SET_DEST (set) = temp;
9999 if (GET_CODE (SET_DEST (set)) == MEM)
10000 {
10001 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10002 if (temp)
10003 XEXP (SET_DEST (set), 0) = temp;
10004 }
10005 RTX_FRAME_RELATED_P (set) = 1;
10006 }
10007 }
10008 else
a4f6c312 10009 abort ();
9ebbca7d 10010
9ebbca7d
GK
10011 RTX_FRAME_RELATED_P (insn) = 1;
10012 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10013 real,
10014 REG_NOTES (insn));
38c1f2d7
MM
10015}
10016
00b960c7
AH
10017/* Returns an insn that has a vrsave set operation with the
10018 appropriate CLOBBERs. */
10019
10020static rtx
9aa86737 10021generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
10022 rtx reg;
10023 rs6000_stack_t *info;
9aa86737 10024 int epiloguep;
00b960c7
AH
10025{
10026 int nclobs, i;
10027 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 10028 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 10029
a004eb82
AH
10030 clobs[0]
10031 = gen_rtx_SET (VOIDmode,
10032 vrsave,
10033 gen_rtx_UNSPEC_VOLATILE (SImode,
10034 gen_rtvec (2, reg, vrsave),
10035 30));
00b960c7
AH
10036
10037 nclobs = 1;
10038
9aa86737
AH
10039 /* We need to clobber the registers in the mask so the scheduler
10040 does not move sets to VRSAVE before sets of AltiVec registers.
10041
10042 However, if the function receives nonlocal gotos, reload will set
10043 all call saved registers live. We will end up with:
10044
10045 (set (reg 999) (mem))
10046 (parallel [ (set (reg vrsave) (unspec blah))
10047 (clobber (reg 999))])
10048
10049 The clobber will cause the store into reg 999 to be dead, and
10050 flow will attempt to delete an epilogue insn. In this case, we
10051 need an unspec use/set of the register. */
00b960c7
AH
10052
10053 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10054 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10055 {
10056 if (!epiloguep || call_used_regs [i])
10057 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10058 gen_rtx_REG (V4SImode, i));
10059 else
10060 {
10061 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10062
10063 clobs[nclobs++]
a004eb82
AH
10064 = gen_rtx_SET (VOIDmode,
10065 reg,
10066 gen_rtx_UNSPEC (V4SImode,
10067 gen_rtvec (1, reg), 27));
9aa86737
AH
10068 }
10069 }
00b960c7
AH
10070
10071 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10072
10073 for (i = 0; i < nclobs; ++i)
10074 XVECEXP (insn, 0, i) = clobs[i];
10075
10076 return insn;
10077}
10078
89e7058f
AH
10079/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10080 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10081
10082static void
10083emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10084 rtx frame_reg;
10085 rtx frame_ptr;
10086 enum machine_mode mode;
10087 unsigned int regno;
10088 int offset;
10089 int total_size;
10090{
10091 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10092 rtx replacea, replaceb;
10093
10094 int_rtx = GEN_INT (offset);
10095
10096 /* Some cases that need register indexed addressing. */
10097 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10098 || (TARGET_SPE_ABI
10099 && SPE_VECTOR_MODE (mode)
10100 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10101 {
10102 /* Whomever calls us must make sure r11 is available in the
10103 flow path of instructions in the prologue. */
10104 offset_rtx = gen_rtx_REG (Pmode, 11);
10105 emit_move_insn (offset_rtx, int_rtx);
10106
10107 replacea = offset_rtx;
10108 replaceb = int_rtx;
10109 }
10110 else
10111 {
10112 offset_rtx = int_rtx;
10113 replacea = NULL_RTX;
10114 replaceb = NULL_RTX;
10115 }
10116
10117 reg = gen_rtx_REG (mode, regno);
10118 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10119 mem = gen_rtx_MEM (mode, addr);
10120 set_mem_alias_set (mem, rs6000_sr_alias_set);
10121
10122 insn = emit_move_insn (mem, reg);
10123
10124 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10125}
10126
a3170dc6
AH
10127/* Emit an offset memory reference suitable for a frame store, while
10128 converting to a valid addressing mode. */
10129
10130static rtx
10131gen_frame_mem_offset (mode, reg, offset)
10132 enum machine_mode mode;
10133 rtx reg;
10134 int offset;
10135{
10136 rtx int_rtx, offset_rtx;
10137
10138 int_rtx = GEN_INT (offset);
10139
10140 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10141 {
10142 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10143 emit_move_insn (offset_rtx, int_rtx);
10144 }
10145 else
10146 offset_rtx = int_rtx;
10147
10148 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10149}
10150
9ebbca7d
GK
10151/* Emit function prologue as insns. */
10152
9878760c 10153void
83720594 10154rs6000_emit_prologue ()
9878760c 10155{
4697a36c 10156 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10157 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10158 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10159 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10160 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10161 rtx frame_reg_rtx = sp_reg_rtx;
10162 rtx cr_save_rtx = NULL;
10163 rtx insn;
10164 int saving_FPRs_inline;
10165 int using_store_multiple;
10166 HOST_WIDE_INT sp_offset = 0;
10167
a3170dc6
AH
10168 if (TARGET_SPE_ABI)
10169 {
10170 reg_mode = V2SImode;
10171 reg_size = 8;
10172 }
10173
9ebbca7d 10174 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10175 && !TARGET_SPE_ABI
9ebbca7d
GK
10176 && info->first_gp_reg_save < 31);
10177 saving_FPRs_inline = (info->first_fp_reg_save == 64
10178 || FP_SAVE_INLINE (info->first_fp_reg_save));
10179
10180 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10181 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10182 {
10183 if (info->total_size < 32767)
10184 sp_offset = info->total_size;
10185 else
10186 frame_reg_rtx = frame_ptr_rtx;
10187 rs6000_emit_allocate_stack (info->total_size,
10188 (frame_reg_rtx != sp_reg_rtx
10189 && (info->cr_save_p
10190 || info->lr_save_p
10191 || info->first_fp_reg_save < 64
10192 || info->first_gp_reg_save < 32
10193 )));
10194 if (frame_reg_rtx != sp_reg_rtx)
10195 rs6000_emit_stack_tie ();
10196 }
10197
9aa86737
AH
10198 /* Save AltiVec registers if needed. */
10199 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10200 {
10201 int i;
10202
10203 /* There should be a non inline version of this, for when we
10204 are saving lots of vector registers. */
10205 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10206 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10207 {
10208 rtx areg, savereg, mem;
10209 int offset;
10210
10211 offset = info->altivec_save_offset + sp_offset
10212 + 16 * (i - info->first_altivec_reg_save);
10213
10214 savereg = gen_rtx_REG (V4SImode, i);
10215
10216 areg = gen_rtx_REG (Pmode, 0);
10217 emit_move_insn (areg, GEN_INT (offset));
10218
10219 /* AltiVec addressing mode is [reg+reg]. */
10220 mem = gen_rtx_MEM (V4SImode,
10221 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10222
10223 set_mem_alias_set (mem, rs6000_sr_alias_set);
10224
10225 insn = emit_move_insn (mem, savereg);
10226
10227 altivec_frame_fixup (insn, areg, offset);
10228 }
10229 }
10230
10231 /* VRSAVE is a bit vector representing which AltiVec registers
10232 are used. The OS uses this to determine which vector
10233 registers to save on a context switch. We need to save
10234 VRSAVE on the stack frame, add whatever AltiVec registers we
10235 used in this function, and do the corresponding magic in the
10236 epilogue. */
10237
10238 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10239 {
a004eb82 10240 rtx reg, mem, vrsave;
9aa86737
AH
10241 int offset;
10242
10243 /* Get VRSAVE onto a GPR. */
10244 reg = gen_rtx_REG (SImode, 12);
a004eb82 10245 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10246 if (TARGET_MACHO)
10247 emit_insn (gen_get_vrsave_internal (reg));
10248 else
10249 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10250
10251 /* Save VRSAVE. */
10252 offset = info->vrsave_save_offset + sp_offset;
10253 mem
10254 = gen_rtx_MEM (SImode,
10255 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10256 set_mem_alias_set (mem, rs6000_sr_alias_set);
10257 insn = emit_move_insn (mem, reg);
10258
10259 /* Include the registers in the mask. */
10260 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10261
10262 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10263 }
10264
9ebbca7d
GK
10265 /* If we use the link register, get it into r0. */
10266 if (info->lr_save_p)
71f123ca 10267 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10268 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10269
10270 /* If we need to save CR, put it into r12. */
10271 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10272 {
10273 cr_save_rtx = gen_rtx_REG (SImode, 12);
10274 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10275 }
10276
a4f6c312
SS
10277 /* Do any required saving of fpr's. If only one or two to save, do
10278 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10279 if (saving_FPRs_inline)
10280 {
10281 int i;
10282 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10283 if ((regs_ever_live[info->first_fp_reg_save+i]
10284 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10285 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10286 info->first_fp_reg_save + i,
10287 info->fp_save_offset + sp_offset + 8 * i,
10288 info->total_size);
9ebbca7d
GK
10289 }
10290 else if (info->first_fp_reg_save != 64)
10291 {
10292 int i;
10293 char rname[30];
520a57c8 10294 const char *alloc_rname;
9ebbca7d
GK
10295 rtvec p;
10296 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10297
10298 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10299 gen_rtx_REG (Pmode,
10300 LINK_REGISTER_REGNUM));
10301 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10302 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10303 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10304 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10305 gen_rtx_SYMBOL_REF (Pmode,
10306 alloc_rname));
10307 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10308 {
10309 rtx addr, reg, mem;
10310 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10311 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10312 GEN_INT (info->fp_save_offset
10313 + sp_offset + 8*i));
10314 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10315 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10316
10317 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10318 }
10319 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10320 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10321 NULL_RTX, NULL_RTX);
10322 }
b6c9286a 10323
9ebbca7d
GK
10324 /* Save GPRs. This is done as a PARALLEL if we are using
10325 the store-multiple instructions. */
10326 if (using_store_multiple)
b6c9286a 10327 {
308c142a 10328 rtvec p;
9ebbca7d
GK
10329 int i;
10330 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10331 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10332 {
10333 rtx addr, reg, mem;
10334 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10335 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10336 GEN_INT (info->gp_save_offset
10337 + sp_offset
10338 + reg_size * i));
10339 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10340 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10341
10342 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10343 }
10344 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10345 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10346 NULL_RTX, NULL_RTX);
b6c9286a
MM
10347 }
10348 else
10349 {
9ebbca7d
GK
10350 int i;
10351 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10352 if ((regs_ever_live[info->first_gp_reg_save+i]
10353 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10354 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10355 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10356 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10357 {
10358 rtx addr, reg, mem;
10359 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10360
10361 if (TARGET_SPE_ABI)
10362 {
10363 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10364 rtx b;
10365
10366 if (!SPE_CONST_OFFSET_OK (offset))
10367 {
10368 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10369 emit_move_insn (b, GEN_INT (offset));
10370 }
10371 else
10372 b = GEN_INT (offset);
10373
10374 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10375 mem = gen_rtx_MEM (V2SImode, addr);
10376 set_mem_alias_set (mem, rs6000_sr_alias_set);
10377 insn = emit_move_insn (mem, reg);
10378
10379 if (GET_CODE (b) == CONST_INT)
10380 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10381 NULL_RTX, NULL_RTX);
10382 else
10383 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10384 b, GEN_INT (offset));
10385 }
10386 else
10387 {
10388 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10389 GEN_INT (info->gp_save_offset
10390 + sp_offset
10391 + reg_size * i));
10392 mem = gen_rtx_MEM (reg_mode, addr);
10393 set_mem_alias_set (mem, rs6000_sr_alias_set);
10394
10395 insn = emit_move_insn (mem, reg);
10396 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10397 NULL_RTX, NULL_RTX);
10398 }
10399 }
9ebbca7d
GK
10400 }
10401
83720594
RH
10402 /* ??? There's no need to emit actual instructions here, but it's the
10403 easiest way to get the frame unwind information emitted. */
10404 if (current_function_calls_eh_return)
10405 {
78e1b90d
DE
10406 unsigned int i, regno;
10407
83720594
RH
10408 for (i = 0; ; ++i)
10409 {
83720594
RH
10410 regno = EH_RETURN_DATA_REGNO (i);
10411 if (regno == INVALID_REGNUM)
10412 break;
10413
89e7058f
AH
10414 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10415 info->ehrd_offset + sp_offset
10416 + reg_size * (int) i,
10417 info->total_size);
83720594
RH
10418 }
10419 }
10420
9ebbca7d
GK
10421 /* Save lr if we used it. */
10422 if (info->lr_save_p)
10423 {
10424 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10425 GEN_INT (info->lr_save_offset + sp_offset));
10426 rtx reg = gen_rtx_REG (Pmode, 0);
10427 rtx mem = gen_rtx_MEM (Pmode, addr);
10428 /* This should not be of rs6000_sr_alias_set, because of
10429 __builtin_return_address. */
10430
10431 insn = emit_move_insn (mem, reg);
10432 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10433 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10434 }
10435
10436 /* Save CR if we use any that must be preserved. */
10437 if (info->cr_save_p)
10438 {
10439 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10440 GEN_INT (info->cr_save_offset + sp_offset));
10441 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10442
10443 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10444
10445 /* If r12 was used to hold the original sp, copy cr into r0 now
10446 that it's free. */
10447 if (REGNO (frame_reg_rtx) == 12)
10448 {
10449 cr_save_rtx = gen_rtx_REG (SImode, 0);
10450 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10451 }
10452 insn = emit_move_insn (mem, cr_save_rtx);
10453
10454 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10455 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10456 OK. All we have to do is specify that _one_ condition code
10457 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10458 will then restore all the call-saved registers.
10459 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10460 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10461 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10462 }
10463
10464 /* Update stack and set back pointer unless this is V.4,
10465 for which it was done previously. */
f607bc57 10466 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10467 rs6000_emit_allocate_stack (info->total_size, FALSE);
10468
10469 /* Set frame pointer, if needed. */
10470 if (frame_pointer_needed)
10471 {
a3170dc6 10472 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10473 sp_reg_rtx);
10474 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10475 }
9878760c 10476
1db02437 10477 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10478 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10479 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10480 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10481 {
10482 /* If emit_load_toc_table will use the link register, we need to save
10483 it. We use R11 for this purpose because emit_load_toc_table
10484 can use register 0. This allows us to use a plain 'blr' to return
10485 from the procedure more often. */
d5fa86ba
GK
10486 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10487 && ! info->lr_save_p
10488 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10489 if (save_LR_around_toc_setup)
10490 emit_move_insn (gen_rtx_REG (Pmode, 11),
10491 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10492
10493 rs6000_emit_load_toc_table (TRUE);
10494
10495 if (save_LR_around_toc_setup)
10496 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10497 gen_rtx_REG (Pmode, 11));
10498 }
ee890fe2 10499
fcce224d 10500#if TARGET_MACHO
ee890fe2
SS
10501 if (DEFAULT_ABI == ABI_DARWIN
10502 && flag_pic && current_function_uses_pic_offset_table)
10503 {
10504 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
f51eee6a
GK
10505 char *picbase = machopic_function_base_name ();
10506 rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
ee890fe2 10507
f51eee6a 10508 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
ee890fe2
SS
10509
10510 rs6000_maybe_dead (
1db02437 10511 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10512 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10513 }
fcce224d 10514#endif
9ebbca7d
GK
10515}
10516
9ebbca7d 10517/* Write function prologue. */
a4f6c312 10518
08c148a8
NB
10519static void
10520rs6000_output_function_prologue (file, size)
9ebbca7d 10521 FILE *file;
08c148a8 10522 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10523{
10524 rs6000_stack_t *info = rs6000_stack_info ();
10525
4697a36c
MM
10526 if (TARGET_DEBUG_STACK)
10527 debug_stack_info (info);
9878760c 10528
a4f6c312
SS
10529 /* Write .extern for any function we will call to save and restore
10530 fp values. */
10531 if (info->first_fp_reg_save < 64
10532 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10533 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10534 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10535 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10536 RESTORE_FP_SUFFIX);
9878760c 10537
c764f757
RK
10538 /* Write .extern for AIX common mode routines, if needed. */
10539 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10540 {
f6709c70
JW
10541 fputs ("\t.extern __mulh\n", file);
10542 fputs ("\t.extern __mull\n", file);
10543 fputs ("\t.extern __divss\n", file);
10544 fputs ("\t.extern __divus\n", file);
10545 fputs ("\t.extern __quoss\n", file);
10546 fputs ("\t.extern __quous\n", file);
c764f757
RK
10547 common_mode_defined = 1;
10548 }
9878760c 10549
9ebbca7d 10550 if (! HAVE_prologue)
979721f8 10551 {
9ebbca7d 10552 start_sequence ();
9dda4cc8 10553
a4f6c312
SS
10554 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10555 the "toplevel" insn chain. */
9ebbca7d
GK
10556 emit_note (0, NOTE_INSN_DELETED);
10557 rs6000_emit_prologue ();
10558 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10559
10560 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10561 {
10562 rtx insn;
10563 unsigned addr = 0;
10564 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10565 {
10566 INSN_ADDRESSES_NEW (insn, addr);
10567 addr += 4;
10568 }
10569 }
9dda4cc8 10570
9ebbca7d 10571 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10572 debug_rtx_list (get_insns (), 100);
10573 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10574 end_sequence ();
979721f8
MM
10575 }
10576
9ebbca7d
GK
10577 rs6000_pic_labelno++;
10578}
10579
10580/* Emit function epilogue as insns.
9878760c 10581
9ebbca7d
GK
10582 At present, dwarf2out_frame_debug_expr doesn't understand
10583 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10584 anywhere in the epilogue. Most of the insns below would in any case
10585 need special notes to explain where r11 is in relation to the stack. */
9878760c 10586
9ebbca7d 10587void
83720594 10588rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
10589 int sibcall;
10590{
10591 rs6000_stack_t *info;
10592 int restoring_FPRs_inline;
10593 int using_load_multiple;
10594 int using_mfcr_multiple;
10595 int use_backchain_to_restore_sp;
10596 int sp_offset = 0;
10597 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10598 rtx frame_reg_rtx = sp_reg_rtx;
10599 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10600 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10601 int i;
10602
a3170dc6
AH
10603 if (TARGET_SPE_ABI)
10604 {
10605 reg_mode = V2SImode;
10606 reg_size = 8;
10607 }
10608
9ebbca7d
GK
10609 info = rs6000_stack_info ();
10610 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
a3170dc6 10611 && !TARGET_SPE_ABI
9ebbca7d
GK
10612 && info->first_gp_reg_save < 31);
10613 restoring_FPRs_inline = (sibcall
83720594 10614 || current_function_calls_eh_return
9ebbca7d
GK
10615 || info->first_fp_reg_save == 64
10616 || FP_SAVE_INLINE (info->first_fp_reg_save));
10617 use_backchain_to_restore_sp = (frame_pointer_needed
10618 || current_function_calls_alloca
10619 || info->total_size > 32767);
10620 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10621 || rs6000_cpu == PROCESSOR_PPC603
10622 || rs6000_cpu == PROCESSOR_PPC750
10623 || optimize_size);
10624
10625 /* If we have a frame pointer, a call to alloca, or a large stack
10626 frame, restore the old stack pointer using the backchain. Otherwise,
10627 we know what size to update it with. */
10628 if (use_backchain_to_restore_sp)
bacbde18 10629 {
9ebbca7d
GK
10630 /* Under V.4, don't reset the stack pointer until after we're done
10631 loading the saved registers. */
f607bc57 10632 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 10633 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 10634
9ebbca7d
GK
10635 emit_move_insn (frame_reg_rtx,
10636 gen_rtx_MEM (Pmode, sp_reg_rtx));
10637
bacbde18 10638 }
9ebbca7d 10639 else if (info->push_p)
85638c0d 10640 {
f607bc57 10641 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10642 sp_offset = info->total_size;
10643 else
10644 {
10645 emit_insn (TARGET_32BIT
10646 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10647 GEN_INT (info->total_size))
10648 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10649 GEN_INT (info->total_size)));
10650 }
85638c0d 10651 }
9ebbca7d 10652
9aa86737
AH
10653 /* Restore AltiVec registers if needed. */
10654 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10655 {
10656 int i;
10657
10658 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10659 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10660 {
10661 rtx addr, areg, mem;
10662
10663 areg = gen_rtx_REG (Pmode, 0);
10664 emit_move_insn
10665 (areg, GEN_INT (info->altivec_save_offset
10666 + sp_offset
10667 + 16 * (i - info->first_altivec_reg_save)));
10668
10669 /* AltiVec addressing mode is [reg+reg]. */
10670 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10671 mem = gen_rtx_MEM (V4SImode, addr);
10672 set_mem_alias_set (mem, rs6000_sr_alias_set);
10673
10674 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10675 }
10676 }
10677
10678 /* Restore VRSAVE if needed. */
10679 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10680 {
10681 rtx addr, mem, reg;
10682
10683 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10684 GEN_INT (info->vrsave_save_offset + sp_offset));
10685 mem = gen_rtx_MEM (SImode, addr);
10686 set_mem_alias_set (mem, rs6000_sr_alias_set);
10687 reg = gen_rtx_REG (SImode, 12);
10688 emit_move_insn (reg, mem);
10689
10690 emit_insn (generate_set_vrsave (reg, info, 1));
10691 }
10692
9ebbca7d
GK
10693 /* Get the old lr if we saved it. */
10694 if (info->lr_save_p)
b6c9286a 10695 {
a3170dc6
AH
10696 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10697 info->lr_save_offset + sp_offset);
ba4828e0
RK
10698
10699 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10700
9ebbca7d 10701 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 10702 }
9ebbca7d
GK
10703
10704 /* Get the old cr if we saved it. */
10705 if (info->cr_save_p)
10706 {
10707 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10708 GEN_INT (info->cr_save_offset + sp_offset));
10709 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10710
10711 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10712
9ebbca7d
GK
10713 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10714 }
10715
10716 /* Set LR here to try to overlap restores below. */
4697a36c 10717 if (info->lr_save_p)
9ebbca7d
GK
10718 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10719 gen_rtx_REG (Pmode, 0));
10720
83720594
RH
10721 /* Load exception handler data registers, if needed. */
10722 if (current_function_calls_eh_return)
10723 {
78e1b90d
DE
10724 unsigned int i, regno;
10725
83720594
RH
10726 for (i = 0; ; ++i)
10727 {
a3170dc6 10728 rtx mem;
83720594
RH
10729
10730 regno = EH_RETURN_DATA_REGNO (i);
10731 if (regno == INVALID_REGNUM)
10732 break;
10733
a3170dc6
AH
10734 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
10735 info->ehrd_offset + sp_offset
10736 + reg_size * (int) i);
ba4828e0 10737 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
10738
10739 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
10740 }
10741 }
9ebbca7d
GK
10742
10743 /* Restore GPRs. This is done as a PARALLEL if we are using
10744 the load-multiple instructions. */
10745 if (using_load_multiple)
979721f8 10746 {
9ebbca7d
GK
10747 rtvec p;
10748 p = rtvec_alloc (32 - info->first_gp_reg_save);
10749 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 10750 {
9ebbca7d
GK
10751 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10752 GEN_INT (info->gp_save_offset
10753 + sp_offset
10754 + reg_size * i));
10755 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
10756
10757 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10758
10759 RTVEC_ELT (p, i) =
10760 gen_rtx_SET (VOIDmode,
10761 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
10762 mem);
979721f8 10763 }
9ebbca7d 10764 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 10765 }
9ebbca7d
GK
10766 else
10767 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10768 if ((regs_ever_live[info->first_gp_reg_save+i]
10769 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10770 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
f607bc57
ZW
10771 && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10772 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
10773 {
10774 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10775 GEN_INT (info->gp_save_offset
10776 + sp_offset
10777 + reg_size * i));
10778 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10779
a3170dc6
AH
10780 /* Restore 64-bit quantities for SPE. */
10781 if (TARGET_SPE_ABI)
10782 {
10783 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10784 rtx b;
10785
10786 if (!SPE_CONST_OFFSET_OK (offset))
10787 {
10788 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10789 emit_move_insn (b, GEN_INT (offset));
10790 }
10791 else
10792 b = GEN_INT (offset);
10793
10794 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10795 mem = gen_rtx_MEM (V2SImode, addr);
10796 }
10797
ba4828e0 10798 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10799
10800 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 10801 info->first_gp_reg_save + i), mem);
9ebbca7d 10802 }
9878760c 10803
9ebbca7d
GK
10804 /* Restore fpr's if we need to do it without calling a function. */
10805 if (restoring_FPRs_inline)
10806 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10807 if ((regs_ever_live[info->first_fp_reg_save+i]
10808 && ! call_used_regs[info->first_fp_reg_save+i]))
10809 {
10810 rtx addr, mem;
10811 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10812 GEN_INT (info->fp_save_offset
10813 + sp_offset
a4f6c312 10814 + 8 * i));
9ebbca7d 10815 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10816 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10817
10818 emit_move_insn (gen_rtx_REG (DFmode,
10819 info->first_fp_reg_save + i),
10820 mem);
10821 }
8d30c4ee 10822
9ebbca7d
GK
10823 /* If we saved cr, restore it here. Just those that were used. */
10824 if (info->cr_save_p)
979721f8 10825 {
9ebbca7d 10826 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 10827 int count = 0;
9ebbca7d
GK
10828
10829 if (using_mfcr_multiple)
979721f8 10830 {
9ebbca7d
GK
10831 for (i = 0; i < 8; i++)
10832 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 10833 count++;
9ebbca7d 10834 if (count == 0)
e35b9579
GK
10835 abort ();
10836 }
10837
10838 if (using_mfcr_multiple && count > 1)
10839 {
10840 rtvec p;
10841 int ndx;
9ebbca7d 10842
e35b9579 10843 p = rtvec_alloc (count);
9ebbca7d 10844
e35b9579 10845 ndx = 0;
9ebbca7d
GK
10846 for (i = 0; i < 8; i++)
10847 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
10848 {
10849 rtvec r = rtvec_alloc (2);
10850 RTVEC_ELT (r, 0) = r12_rtx;
10851 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 10852 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
10853 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
10854 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 10855 ndx++;
9ebbca7d
GK
10856 }
10857 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
10858 if (ndx != count)
10859 abort ();
979721f8
MM
10860 }
10861 else
9ebbca7d
GK
10862 for (i = 0; i < 8; i++)
10863 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 10864 {
9ebbca7d
GK
10865 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
10866 CR0_REGNO+i),
10867 r12_rtx));
979721f8 10868 }
979721f8
MM
10869 }
10870
9ebbca7d
GK
10871 /* If this is V.4, unwind the stack pointer after all of the loads
10872 have been done. We need to emit a block here so that sched
10873 doesn't decide to move the sp change before the register restores
10874 (which may not have any obvious dependency on the stack). This
10875 doesn't hurt performance, because there is no scheduling that can
10876 be done after this point. */
f607bc57 10877 if (DEFAULT_ABI == ABI_V4)
b6c9286a 10878 {
9ebbca7d
GK
10879 if (frame_reg_rtx != sp_reg_rtx)
10880 rs6000_emit_stack_tie ();
b6c9286a 10881
9ebbca7d 10882 if (use_backchain_to_restore_sp)
b6c9286a 10883 {
9ebbca7d 10884 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 10885 }
9ebbca7d 10886 else if (sp_offset != 0)
13f1623b 10887 {
9ebbca7d
GK
10888 emit_insn (Pmode == SImode
10889 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10890 GEN_INT (sp_offset))
10891 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10892 GEN_INT (sp_offset)));
13f1623b 10893 }
9ebbca7d 10894 }
b6c9286a 10895
83720594
RH
10896 if (current_function_calls_eh_return)
10897 {
10898 rtx sa = EH_RETURN_STACKADJ_RTX;
10899 emit_insn (Pmode == SImode
10900 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
10901 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
10902 }
10903
9ebbca7d
GK
10904 if (!sibcall)
10905 {
10906 rtvec p;
10907 if (! restoring_FPRs_inline)
10908 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
10909 else
10910 p = rtvec_alloc (2);
b6c9286a 10911
e35b9579
GK
10912 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
10913 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
10914 gen_rtx_REG (Pmode,
10915 LINK_REGISTER_REGNUM));
9ebbca7d
GK
10916
10917 /* If we have to restore more than two FP registers, branch to the
10918 restore function. It will return to our caller. */
10919 if (! restoring_FPRs_inline)
10920 {
10921 int i;
10922 char rname[30];
520a57c8 10923 const char *alloc_rname;
979721f8 10924
9ebbca7d
GK
10925 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
10926 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 10927 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10928 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
10929 gen_rtx_SYMBOL_REF (Pmode,
10930 alloc_rname));
b6c9286a 10931
9ebbca7d
GK
10932 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10933 {
10934 rtx addr, mem;
10935 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
10936 GEN_INT (info->fp_save_offset + 8*i));
10937 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10938 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10939
10940 RTVEC_ELT (p, i+3) =
10941 gen_rtx_SET (VOIDmode,
10942 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
10943 mem);
b6c9286a
MM
10944 }
10945 }
9ebbca7d
GK
10946
10947 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 10948 }
9878760c
RK
10949}
10950
10951/* Write function epilogue. */
10952
08c148a8
NB
10953static void
10954rs6000_output_function_epilogue (file, size)
9878760c 10955 FILE *file;
08c148a8 10956 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 10957{
4697a36c 10958 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 10959
9ebbca7d 10960 if (! HAVE_epilogue)
9878760c 10961 {
9ebbca7d
GK
10962 rtx insn = get_last_insn ();
10963 /* If the last insn was a BARRIER, we don't have to write anything except
10964 the trace table. */
10965 if (GET_CODE (insn) == NOTE)
10966 insn = prev_nonnote_insn (insn);
10967 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 10968 {
9ebbca7d
GK
10969 /* This is slightly ugly, but at least we don't have two
10970 copies of the epilogue-emitting code. */
10971 start_sequence ();
10972
10973 /* A NOTE_INSN_DELETED is supposed to be at the start
10974 and end of the "toplevel" insn chain. */
10975 emit_note (0, NOTE_INSN_DELETED);
10976 rs6000_emit_epilogue (FALSE);
10977 emit_note (0, NOTE_INSN_DELETED);
10978
178c3eff
DJ
10979 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10980 {
10981 rtx insn;
10982 unsigned addr = 0;
10983 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10984 {
10985 INSN_ADDRESSES_NEW (insn, addr);
10986 addr += 4;
10987 }
10988 }
10989
9ebbca7d 10990 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10991 debug_rtx_list (get_insns (), 100);
10992 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10993 end_sequence ();
4697a36c 10994 }
9878760c 10995 }
b4ac57ab 10996
9b30bae2 10997 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
10998 on its format.
10999
11000 We don't output a traceback table if -finhibit-size-directive was
11001 used. The documentation for -finhibit-size-directive reads
11002 ``don't output a @code{.size} assembler directive, or anything
11003 else that would cause trouble if the function is split in the
11004 middle, and the two halves are placed at locations far apart in
11005 memory.'' The traceback table has this property, since it
11006 includes the offset from the start of the function to the
4d30c363
MM
11007 traceback table itself.
11008
11009 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 11010 different traceback table. */
57ac7be9
AM
11011 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
11012 && rs6000_traceback != traceback_none)
9b30bae2 11013 {
69c75916 11014 const char *fname = NULL;
3ac88239 11015 const char *language_string = lang_hooks.name;
6041bf2f 11016 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 11017 int i;
57ac7be9
AM
11018 int optional_tbtab;
11019
11020 if (rs6000_traceback == traceback_full)
11021 optional_tbtab = 1;
11022 else if (rs6000_traceback == traceback_part)
11023 optional_tbtab = 0;
11024 else
11025 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 11026
69c75916
AM
11027 if (optional_tbtab)
11028 {
11029 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
11030 while (*fname == '.') /* V.4 encodes . in the name */
11031 fname++;
11032
11033 /* Need label immediately before tbtab, so we can compute
11034 its offset from the function start. */
11035 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11036 ASM_OUTPUT_LABEL (file, fname);
11037 }
314fc5a9
ILT
11038
11039 /* The .tbtab pseudo-op can only be used for the first eight
11040 expressions, since it can't handle the possibly variable
11041 length fields that follow. However, if you omit the optional
11042 fields, the assembler outputs zeros for all optional fields
11043 anyways, giving each variable length field is minimum length
11044 (as defined in sys/debug.h). Thus we can not use the .tbtab
11045 pseudo-op at all. */
11046
11047 /* An all-zero word flags the start of the tbtab, for debuggers
11048 that have to find it by searching forward from the entry
11049 point or from the current pc. */
19d2d16f 11050 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11051
11052 /* Tbtab format type. Use format type 0. */
19d2d16f 11053 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11054
11055 /* Language type. Unfortunately, there doesn't seem to be any
11056 official way to get this info, so we use language_string. C
11057 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11058 value for C for now. There is no official value for Java,
6f573ff9 11059 although IBM appears to be using 13. There is no official value
f710504c 11060 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11061 if (! strcmp (language_string, "GNU C")
e2c953b6 11062 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11063 i = 0;
11064 else if (! strcmp (language_string, "GNU F77"))
11065 i = 1;
11066 else if (! strcmp (language_string, "GNU Ada"))
11067 i = 3;
8b83775b 11068 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11069 i = 2;
11070 else if (! strcmp (language_string, "GNU C++"))
11071 i = 9;
9517ead8
AG
11072 else if (! strcmp (language_string, "GNU Java"))
11073 i = 13;
6f573ff9
JL
11074 else if (! strcmp (language_string, "GNU CHILL"))
11075 i = 44;
314fc5a9
ILT
11076 else
11077 abort ();
11078 fprintf (file, "%d,", i);
11079
11080 /* 8 single bit fields: global linkage (not set for C extern linkage,
11081 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11082 from start of procedure stored in tbtab, internal function, function
11083 has controlled storage, function has no toc, function uses fp,
11084 function logs/aborts fp operations. */
11085 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11086 fprintf (file, "%d,",
11087 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11088
11089 /* 6 bitfields: function is interrupt handler, name present in
11090 proc table, function calls alloca, on condition directives
11091 (controls stack walks, 3 bits), saves condition reg, saves
11092 link reg. */
11093 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11094 set up as a frame pointer, even when there is no alloca call. */
11095 fprintf (file, "%d,",
6041bf2f
DE
11096 ((optional_tbtab << 6)
11097 | ((optional_tbtab & frame_pointer_needed) << 5)
11098 | (info->cr_save_p << 1)
11099 | (info->lr_save_p)));
314fc5a9 11100
6041bf2f 11101 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11102 (6 bits). */
11103 fprintf (file, "%d,",
4697a36c 11104 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11105
11106 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11107 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11108
6041bf2f
DE
11109 if (optional_tbtab)
11110 {
11111 /* Compute the parameter info from the function decl argument
11112 list. */
11113 tree decl;
11114 int next_parm_info_bit = 31;
314fc5a9 11115
6041bf2f
DE
11116 for (decl = DECL_ARGUMENTS (current_function_decl);
11117 decl; decl = TREE_CHAIN (decl))
11118 {
11119 rtx parameter = DECL_INCOMING_RTL (decl);
11120 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11121
6041bf2f
DE
11122 if (GET_CODE (parameter) == REG)
11123 {
11124 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11125 {
11126 int bits;
11127
11128 float_parms++;
11129
11130 if (mode == SFmode)
11131 bits = 0x2;
fcce224d 11132 else if (mode == DFmode || mode == TFmode)
6041bf2f
DE
11133 bits = 0x3;
11134 else
11135 abort ();
11136
11137 /* If only one bit will fit, don't or in this entry. */
11138 if (next_parm_info_bit > 0)
11139 parm_info |= (bits << (next_parm_info_bit - 1));
11140 next_parm_info_bit -= 2;
11141 }
11142 else
11143 {
11144 fixed_parms += ((GET_MODE_SIZE (mode)
11145 + (UNITS_PER_WORD - 1))
11146 / UNITS_PER_WORD);
11147 next_parm_info_bit -= 1;
11148 }
11149 }
11150 }
11151 }
314fc5a9
ILT
11152
11153 /* Number of fixed point parameters. */
11154 /* This is actually the number of words of fixed point parameters; thus
11155 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11156 fprintf (file, "%d,", fixed_parms);
11157
11158 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11159 all on stack. */
11160 /* This is actually the number of fp registers that hold parameters;
11161 and thus the maximum value is 13. */
11162 /* Set parameters on stack bit if parameters are not in their original
11163 registers, regardless of whether they are on the stack? Xlc
11164 seems to set the bit when not optimizing. */
11165 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11166
6041bf2f
DE
11167 if (! optional_tbtab)
11168 return;
11169
314fc5a9
ILT
11170 /* Optional fields follow. Some are variable length. */
11171
11172 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11173 11 double float. */
11174 /* There is an entry for each parameter in a register, in the order that
11175 they occur in the parameter list. Any intervening arguments on the
11176 stack are ignored. If the list overflows a long (max possible length
11177 34 bits) then completely leave off all elements that don't fit. */
11178 /* Only emit this long if there was at least one parameter. */
11179 if (fixed_parms || float_parms)
11180 fprintf (file, "\t.long %d\n", parm_info);
11181
11182 /* Offset from start of code to tb table. */
19d2d16f 11183 fputs ("\t.long ", file);
314fc5a9 11184 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11185#if TARGET_AIX
11186 RS6000_OUTPUT_BASENAME (file, fname);
11187#else
9ebbca7d 11188 assemble_name (file, fname);
54ee9799 11189#endif
19d2d16f 11190 fputs ("-.", file);
54ee9799
DE
11191#if TARGET_AIX
11192 RS6000_OUTPUT_BASENAME (file, fname);
11193#else
9ebbca7d 11194 assemble_name (file, fname);
54ee9799 11195#endif
19d2d16f 11196 putc ('\n', file);
314fc5a9
ILT
11197
11198 /* Interrupt handler mask. */
11199 /* Omit this long, since we never set the interrupt handler bit
11200 above. */
11201
11202 /* Number of CTL (controlled storage) anchors. */
11203 /* Omit this long, since the has_ctl bit is never set above. */
11204
11205 /* Displacement into stack of each CTL anchor. */
11206 /* Omit this list of longs, because there are no CTL anchors. */
11207
11208 /* Length of function name. */
69c75916
AM
11209 if (*fname == '*')
11210 ++fname;
296b8152 11211 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11212
11213 /* Function name. */
11214 assemble_string (fname, strlen (fname));
11215
11216 /* Register for alloca automatic storage; this is always reg 31.
11217 Only emit this if the alloca bit was set above. */
11218 if (frame_pointer_needed)
19d2d16f 11219 fputs ("\t.byte 31\n", file);
b1765bde
DE
11220
11221 fputs ("\t.align 2\n", file);
9b30bae2 11222 }
9878760c 11223}
17167fd8 11224\f
a4f6c312
SS
11225/* A C compound statement that outputs the assembler code for a thunk
11226 function, used to implement C++ virtual function calls with
11227 multiple inheritance. The thunk acts as a wrapper around a virtual
11228 function, adjusting the implicit object parameter before handing
11229 control off to the real function.
11230
11231 First, emit code to add the integer DELTA to the location that
11232 contains the incoming first argument. Assume that this argument
11233 contains a pointer, and is the one used to pass the `this' pointer
11234 in C++. This is the incoming argument *before* the function
11235 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11236 values of all other incoming arguments.
17167fd8
MM
11237
11238 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11239 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11240 not touch the return address. Hence returning from FUNCTION will
11241 return to whoever called the current `thunk'.
17167fd8 11242
a4f6c312
SS
11243 The effect must be as if FUNCTION had been called directly with the
11244 adjusted first argument. This macro is responsible for emitting
11245 all of the code for a thunk function; output_function_prologue()
11246 and output_function_epilogue() are not invoked.
17167fd8 11247
a4f6c312
SS
11248 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11249 been extracted from it.) It might possibly be useful on some
11250 targets, but probably not.
17167fd8 11251
a4f6c312
SS
11252 If you do not define this macro, the target-independent code in the
11253 C++ frontend will generate a less efficient heavyweight thunk that
11254 calls FUNCTION instead of jumping to it. The generic approach does
11255 not support varargs. */
17167fd8 11256
3961e8fe
RH
11257static void
11258rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
17167fd8 11259 FILE *file;
d330fd93 11260 tree thunk_fndecl ATTRIBUTE_UNUSED;
eb0424da 11261 HOST_WIDE_INT delta;
3961e8fe 11262 HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;
17167fd8
MM
11263 tree function;
11264{
a4f6c312
SS
11265 const char *this_reg =
11266 reg_names[ aggregate_value_p (TREE_TYPE (TREE_TYPE (function))) ? 4 : 3 ];
d330fd93 11267 const char *prefix;
3cce094d 11268 const char *fname;
d330fd93 11269 const char *r0 = reg_names[0];
d330fd93
KG
11270 const char *toc = reg_names[2];
11271 const char *schain = reg_names[11];
11272 const char *r12 = reg_names[12];
17167fd8
MM
11273 char buf[512];
11274 static int labelno = 0;
11275
a4f6c312 11276 /* Small constants that can be done by one add instruction. */
17167fd8
MM
11277 if (delta >= -32768 && delta <= 32767)
11278 {
22b4a3b0 11279 if (! TARGET_NEW_MNEMONICS)
eb0424da 11280 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, (int) delta, this_reg);
17167fd8 11281 else
eb0424da 11282 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, (int) delta);
17167fd8
MM
11283 }
11284
56a7189a
AM
11285 /* 64-bit constants. If "int" is 32 bits, we'll never hit this abort. */
11286 else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
11287 abort ();
11288
a4f6c312 11289 /* Large constants that can be done by one addis instruction. */
56a7189a 11290 else if ((delta & 0xffff) == 0)
17167fd8 11291 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
eb0424da 11292 (int) (delta >> 16));
17167fd8
MM
11293
11294 /* 32-bit constants that can be done by an add and addis instruction. */
56a7189a 11295 else
17167fd8 11296 {
a4f6c312
SS
11297 /* Break into two pieces, propagating the sign bit from the low
11298 word to the upper word. */
56a7189a
AM
11299 int delta_low = ((delta & 0xffff) ^ 0x8000) - 0x8000;
11300 int delta_high = (delta - delta_low) >> 16;
17167fd8
MM
11301
11302 asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
11303 delta_high);
11304
22b4a3b0 11305 if (! TARGET_NEW_MNEMONICS)
17167fd8
MM
11306 fprintf (file, "\tcal %s,%d(%s)\n", this_reg, delta_low, this_reg);
11307 else
11308 fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
11309 }
11310
17167fd8
MM
11311 /* Get the prefix in front of the names. */
11312 switch (DEFAULT_ABI)
11313 {
11314 default:
11315 abort ();
11316
11317 case ABI_AIX:
11318 prefix = ".";
11319 break;
11320
11321 case ABI_V4:
11322 case ABI_AIX_NODESC:
2d173d20 11323 case ABI_DARWIN:
17167fd8
MM
11324 prefix = "";
11325 break;
17167fd8
MM
11326 }
11327
11328 /* If the function is compiled in this module, jump to it directly.
11329 Otherwise, load up its address and jump to it. */
11330
11331 fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
42820a49 11332
9ebbca7d 11333 if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
a5c76ee6
ZW
11334 && (! lookup_attribute ("longcall",
11335 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11336 || lookup_attribute ("shortcall",
11337 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
17167fd8
MM
11338 {
11339 fprintf (file, "\tb %s", prefix);
11340 assemble_name (file, fname);
22b4a3b0 11341 if (DEFAULT_ABI == ABI_V4 && flag_pic) fputs ("@local", file);
949ea356 11342 putc ('\n', file);
17167fd8
MM
11343 }
11344
11345 else
11346 {
11347 switch (DEFAULT_ABI)
11348 {
11349 default:
17167fd8
MM
11350 abort ();
11351
11352 case ABI_AIX:
11353 /* Set up a TOC entry for the function. */
11354 ASM_GENERATE_INTERNAL_LABEL (buf, "Lthunk", labelno);
11355 toc_section ();
11356 ASM_OUTPUT_INTERNAL_LABEL (file, "Lthunk", labelno);
11357 labelno++;
11358
fa9b5c6b
DE
11359 if (TARGET_MINIMAL_TOC)
11360 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
11361 else
11362 {
11363 fputs ("\t.tc ", file);
11364 assemble_name (file, fname);
11365 fputs ("[TC],", file);
11366 }
11367 assemble_name (file, fname);
17167fd8 11368 putc ('\n', file);
3961e8fe 11369 function_section (current_function_decl);
468e8dba
DE
11370 if (TARGET_MINIMAL_TOC)
11371 asm_fprintf (file, (TARGET_32BIT)
11372 ? "\t{l|lwz} %s,%s(%s)\n" : "\tld %s,%s(%s)\n", r12,
11373 TARGET_ELF ? ".LCTOC0@toc" : ".LCTOC..1", toc);
d2574c50 11374 asm_fprintf (file, (TARGET_32BIT) ? "\t{l|lwz} %s," : "\tld %s,", r12);
17167fd8 11375 assemble_name (file, buf);
468e8dba
DE
11376 if (TARGET_ELF && TARGET_MINIMAL_TOC)
11377 fputs ("-(.LCTOC1)", file);
11378 asm_fprintf (file, "(%s)\n", TARGET_MINIMAL_TOC ? r12 : toc);
17167fd8
MM
11379 asm_fprintf (file,
11380 (TARGET_32BIT) ? "\t{l|lwz} %s,0(%s)\n" : "\tld %s,0(%s)\n",
11381 r0, r12);
11382
11383 asm_fprintf (file,
11384 (TARGET_32BIT) ? "\t{l|lwz} %s,4(%s)\n" : "\tld %s,8(%s)\n",
11385 toc, r12);
11386
11387 asm_fprintf (file, "\tmtctr %s\n", r0);
11388 asm_fprintf (file,
11389 (TARGET_32BIT) ? "\t{l|lwz} %s,8(%s)\n" : "\tld %s,16(%s)\n",
11390 schain, r12);
11391
11392 asm_fprintf (file, "\tbctr\n");
11393 break;
11394
9ebbca7d 11395 case ABI_AIX_NODESC:
17167fd8 11396 case ABI_V4:
22b4a3b0
FS
11397 fprintf (file, "\tb %s", prefix);
11398 assemble_name (file, fname);
11399 if (flag_pic) fputs ("@plt", file);
949ea356 11400 putc ('\n', file);
22b4a3b0 11401 break;
ee890fe2
SS
11402
11403#if TARGET_MACHO
11404 case ABI_DARWIN:
11405 fprintf (file, "\tb %s", prefix);
11406 if (flag_pic && !machopic_name_defined_p (fname))
11407 assemble_name (file, machopic_stub_name (fname));
11408 else
11409 assemble_name (file, fname);
11410 putc ('\n', file);
11411 break;
11412#endif
9ebbca7d
GK
11413 }
11414 }
11415}
9ebbca7d
GK
11416\f
11417/* A quick summary of the various types of 'constant-pool tables'
11418 under PowerPC:
11419
11420 Target Flags Name One table per
11421 AIX (none) AIX TOC object file
11422 AIX -mfull-toc AIX TOC object file
11423 AIX -mminimal-toc AIX minimal TOC translation unit
11424 SVR4/EABI (none) SVR4 SDATA object file
11425 SVR4/EABI -fpic SVR4 pic object file
11426 SVR4/EABI -fPIC SVR4 PIC translation unit
11427 SVR4/EABI -mrelocatable EABI TOC function
11428 SVR4/EABI -maix AIX TOC object file
11429 SVR4/EABI -maix -mminimal-toc
11430 AIX minimal TOC translation unit
11431
11432 Name Reg. Set by entries contains:
11433 made by addrs? fp? sum?
11434
11435 AIX TOC 2 crt0 as Y option option
11436 AIX minimal TOC 30 prolog gcc Y Y option
11437 SVR4 SDATA 13 crt0 gcc N Y N
11438 SVR4 pic 30 prolog ld Y not yet N
11439 SVR4 PIC 30 prolog gcc Y option option
11440 EABI TOC 30 prolog gcc Y option option
11441
11442*/
11443
11444/* Hash table stuff for keeping track of TOC entries. */
11445
11446struct toc_hash_struct
11447{
11448 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
11449 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
11450 rtx key;
a9098fd0 11451 enum machine_mode key_mode;
9ebbca7d
GK
11452 int labelno;
11453};
17167fd8 11454
9ebbca7d
GK
11455static htab_t toc_hash_table;
11456
11457/* Hash functions for the hash table. */
11458
11459static unsigned
11460rs6000_hash_constant (k)
11461 rtx k;
11462{
46b33600
RH
11463 enum rtx_code code = GET_CODE (k);
11464 enum machine_mode mode = GET_MODE (k);
11465 unsigned result = (code << 3) ^ mode;
11466 const char *format;
11467 int flen, fidx;
9ebbca7d 11468
46b33600
RH
11469 format = GET_RTX_FORMAT (code);
11470 flen = strlen (format);
11471 fidx = 0;
9ebbca7d 11472
46b33600
RH
11473 switch (code)
11474 {
11475 case LABEL_REF:
11476 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
11477
11478 case CONST_DOUBLE:
11479 if (mode != VOIDmode)
11480 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
11481 flen = 2;
11482 break;
11483
11484 case CODE_LABEL:
11485 fidx = 3;
11486 break;
11487
11488 default:
11489 break;
11490 }
9ebbca7d
GK
11491
11492 for (; fidx < flen; fidx++)
11493 switch (format[fidx])
11494 {
11495 case 's':
11496 {
11497 unsigned i, len;
11498 const char *str = XSTR (k, fidx);
11499 len = strlen (str);
11500 result = result * 613 + len;
11501 for (i = 0; i < len; i++)
11502 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11503 break;
11504 }
9ebbca7d
GK
11505 case 'u':
11506 case 'e':
11507 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11508 break;
11509 case 'i':
11510 case 'n':
11511 result = result * 613 + (unsigned) XINT (k, fidx);
11512 break;
11513 case 'w':
11514 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11515 result = result * 613 + (unsigned) XWINT (k, fidx);
11516 else
11517 {
11518 size_t i;
11519 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11520 result = result * 613 + (unsigned) (XWINT (k, fidx)
11521 >> CHAR_BIT * i);
11522 }
11523 break;
11524 default:
a4f6c312 11525 abort ();
9ebbca7d 11526 }
46b33600 11527
9ebbca7d
GK
11528 return result;
11529}
11530
11531static unsigned
11532toc_hash_function (hash_entry)
11533 const void * hash_entry;
11534{
a9098fd0
GK
11535 const struct toc_hash_struct *thc =
11536 (const struct toc_hash_struct *) hash_entry;
11537 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11538}
11539
11540/* Compare H1 and H2 for equivalence. */
11541
11542static int
11543toc_hash_eq (h1, h2)
11544 const void * h1;
11545 const void * h2;
11546{
11547 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11548 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11549
a9098fd0
GK
11550 if (((const struct toc_hash_struct *) h1)->key_mode
11551 != ((const struct toc_hash_struct *) h2)->key_mode)
11552 return 0;
11553
5692c7bc 11554 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11555}
11556
11557/* Mark the hash table-entry HASH_ENTRY. */
11558
11559static int
11560toc_hash_mark_entry (hash_slot, unused)
2eba1afa 11561 void ** hash_slot;
9ebbca7d
GK
11562 void * unused ATTRIBUTE_UNUSED;
11563{
11564 const struct toc_hash_struct * hash_entry =
11565 *(const struct toc_hash_struct **) hash_slot;
11566 rtx r = hash_entry->key;
11567 ggc_set_mark (hash_entry);
a4f6c312 11568 /* For CODE_LABELS, we don't want to drag in the whole insn chain... */
9ebbca7d
GK
11569 if (GET_CODE (r) == LABEL_REF)
11570 {
11571 ggc_set_mark (r);
11572 ggc_set_mark (XEXP (r, 0));
11573 }
11574 else
11575 ggc_mark_rtx (r);
11576 return 1;
11577}
11578
11579/* Mark all the elements of the TOC hash-table *HT. */
11580
11581static void
11582toc_hash_mark_table (vht)
11583 void *vht;
11584{
11585 htab_t *ht = vht;
11586
11587 htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
17167fd8
MM
11588}
11589
28e510bd
MM
11590/* These are the names given by the C++ front-end to vtables, and
11591 vtable-like objects. Ideally, this logic should not be here;
11592 instead, there should be some programmatic way of inquiring as
11593 to whether or not an object is a vtable. */
11594
11595#define VTABLE_NAME_P(NAME) \
11596 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11597 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11598 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11599 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11600
11601void
11602rs6000_output_symbol_ref (file, x)
11603 FILE *file;
11604 rtx x;
11605{
11606 /* Currently C++ toc references to vtables can be emitted before it
11607 is decided whether the vtable is public or private. If this is
11608 the case, then the linker will eventually complain that there is
11609 a reference to an unknown section. Thus, for vtables only,
11610 we emit the TOC reference to reference the symbol and not the
11611 section. */
11612 const char *name = XSTR (x, 0);
54ee9799
DE
11613
11614 if (VTABLE_NAME_P (name))
11615 {
11616 RS6000_OUTPUT_BASENAME (file, name);
11617 }
11618 else
11619 assemble_name (file, name);
28e510bd
MM
11620}
11621
a4f6c312
SS
11622/* Output a TOC entry. We derive the entry name from what is being
11623 written. */
9878760c
RK
11624
11625void
a9098fd0 11626output_toc (file, x, labelno, mode)
9878760c
RK
11627 FILE *file;
11628 rtx x;
11629 int labelno;
a9098fd0 11630 enum machine_mode mode;
9878760c
RK
11631{
11632 char buf[256];
3cce094d 11633 const char *name = buf;
ec940faa 11634 const char *real_name;
9878760c
RK
11635 rtx base = x;
11636 int offset = 0;
11637
4697a36c
MM
11638 if (TARGET_NO_TOC)
11639 abort ();
11640
9ebbca7d
GK
11641 /* When the linker won't eliminate them, don't output duplicate
11642 TOC entries (this happens on AIX if there is any kind of TOC,
1f8f4a0b
MM
11643 and on SVR4 under -fPIC or -mrelocatable). */
11644 if (TARGET_TOC)
9ebbca7d
GK
11645 {
11646 struct toc_hash_struct *h;
11647 void * * found;
11648
11649 h = ggc_alloc (sizeof (*h));
11650 h->key = x;
a9098fd0 11651 h->key_mode = mode;
9ebbca7d
GK
11652 h->labelno = labelno;
11653
11654 found = htab_find_slot (toc_hash_table, h, 1);
11655 if (*found == NULL)
11656 *found = h;
11657 else /* This is indeed a duplicate.
11658 Set this label equal to that label. */
11659 {
11660 fputs ("\t.set ", file);
11661 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11662 fprintf (file, "%d,", labelno);
11663 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11664 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11665 found)->labelno));
11666 return;
11667 }
11668 }
11669
11670 /* If we're going to put a double constant in the TOC, make sure it's
11671 aligned properly when strict alignment is on. */
ff1720ed
RK
11672 if (GET_CODE (x) == CONST_DOUBLE
11673 && STRICT_ALIGNMENT
a9098fd0 11674 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
11675 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11676 ASM_OUTPUT_ALIGN (file, 3);
11677 }
11678
9ebbca7d 11679 ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
9878760c 11680
37c37a57
RK
11681 /* Handle FP constants specially. Note that if we have a minimal
11682 TOC, things we put here aren't actually in the TOC, so we can allow
11683 FP constants. */
fcce224d
DE
11684 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
11685 {
11686 REAL_VALUE_TYPE rv;
11687 long k[4];
11688
11689 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11690 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
11691
11692 if (TARGET_64BIT)
11693 {
11694 if (TARGET_MINIMAL_TOC)
11695 fputs (DOUBLE_INT_ASM_OP, file);
11696 else
11697 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11698 k[0] & 0xffffffff, k[1] & 0xffffffff,
11699 k[2] & 0xffffffff, k[3] & 0xffffffff);
11700 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
11701 k[0] & 0xffffffff, k[1] & 0xffffffff,
11702 k[2] & 0xffffffff, k[3] & 0xffffffff);
11703 return;
11704 }
11705 else
11706 {
11707 if (TARGET_MINIMAL_TOC)
11708 fputs ("\t.long ", file);
11709 else
11710 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11711 k[0] & 0xffffffff, k[1] & 0xffffffff,
11712 k[2] & 0xffffffff, k[3] & 0xffffffff);
11713 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
11714 k[0] & 0xffffffff, k[1] & 0xffffffff,
11715 k[2] & 0xffffffff, k[3] & 0xffffffff);
11716 return;
11717 }
11718 }
11719 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 11720 {
042259f2
DE
11721 REAL_VALUE_TYPE rv;
11722 long k[2];
0adc764e 11723
042259f2
DE
11724 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11725 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 11726
13ded975
DE
11727 if (TARGET_64BIT)
11728 {
11729 if (TARGET_MINIMAL_TOC)
2bfcf297 11730 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11731 else
2f0552b6
AM
11732 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11733 k[0] & 0xffffffff, k[1] & 0xffffffff);
11734 fprintf (file, "0x%lx%08lx\n",
11735 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11736 return;
11737 }
1875cc88 11738 else
13ded975
DE
11739 {
11740 if (TARGET_MINIMAL_TOC)
2bfcf297 11741 fputs ("\t.long ", file);
13ded975 11742 else
2f0552b6
AM
11743 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11744 k[0] & 0xffffffff, k[1] & 0xffffffff);
11745 fprintf (file, "0x%lx,0x%lx\n",
11746 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11747 return;
11748 }
9878760c 11749 }
a9098fd0 11750 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 11751 {
042259f2
DE
11752 REAL_VALUE_TYPE rv;
11753 long l;
9878760c 11754
042259f2
DE
11755 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11756 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11757
31bfaa0b
DE
11758 if (TARGET_64BIT)
11759 {
11760 if (TARGET_MINIMAL_TOC)
2bfcf297 11761 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 11762 else
2f0552b6
AM
11763 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11764 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
11765 return;
11766 }
042259f2 11767 else
31bfaa0b
DE
11768 {
11769 if (TARGET_MINIMAL_TOC)
2bfcf297 11770 fputs ("\t.long ", file);
31bfaa0b 11771 else
2f0552b6
AM
11772 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11773 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
11774 return;
11775 }
042259f2 11776 }
f176e826 11777 else if (GET_MODE (x) == VOIDmode
a9098fd0 11778 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 11779 {
e2c953b6 11780 unsigned HOST_WIDE_INT low;
042259f2
DE
11781 HOST_WIDE_INT high;
11782
11783 if (GET_CODE (x) == CONST_DOUBLE)
11784 {
11785 low = CONST_DOUBLE_LOW (x);
11786 high = CONST_DOUBLE_HIGH (x);
11787 }
11788 else
11789#if HOST_BITS_PER_WIDE_INT == 32
11790 {
11791 low = INTVAL (x);
0858c623 11792 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
11793 }
11794#else
11795 {
0858c623 11796 low = INTVAL (x) & 0xffffffff;
042259f2
DE
11797 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11798 }
11799#endif
9878760c 11800
a9098fd0
GK
11801 /* TOC entries are always Pmode-sized, but since this
11802 is a bigendian machine then if we're putting smaller
11803 integer constants in the TOC we have to pad them.
11804 (This is still a win over putting the constants in
11805 a separate constant pool, because then we'd have
02a4ec28
FS
11806 to have both a TOC entry _and_ the actual constant.)
11807
11808 For a 32-bit target, CONST_INT values are loaded and shifted
11809 entirely within `low' and can be stored in one TOC entry. */
11810
11811 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 11812 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
11813
11814 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
11815 {
11816#if HOST_BITS_PER_WIDE_INT == 32
11817 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11818 POINTER_SIZE, &low, &high, 0);
11819#else
11820 low |= high << 32;
11821 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11822 high = (HOST_WIDE_INT) low >> 32;
11823 low &= 0xffffffff;
11824#endif
11825 }
a9098fd0 11826
13ded975
DE
11827 if (TARGET_64BIT)
11828 {
11829 if (TARGET_MINIMAL_TOC)
2bfcf297 11830 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11831 else
2f0552b6
AM
11832 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
11833 (long) high & 0xffffffff, (long) low & 0xffffffff);
11834 fprintf (file, "0x%lx%08lx\n",
11835 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
11836 return;
11837 }
1875cc88 11838 else
13ded975 11839 {
02a4ec28
FS
11840 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
11841 {
11842 if (TARGET_MINIMAL_TOC)
2bfcf297 11843 fputs ("\t.long ", file);
02a4ec28 11844 else
2bfcf297 11845 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
11846 (long) high & 0xffffffff, (long) low & 0xffffffff);
11847 fprintf (file, "0x%lx,0x%lx\n",
11848 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 11849 }
13ded975 11850 else
02a4ec28
FS
11851 {
11852 if (TARGET_MINIMAL_TOC)
2bfcf297 11853 fputs ("\t.long ", file);
02a4ec28 11854 else
2f0552b6
AM
11855 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
11856 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 11857 }
13ded975
DE
11858 return;
11859 }
9878760c
RK
11860 }
11861
11862 if (GET_CODE (x) == CONST)
11863 {
2bfcf297
DB
11864 if (GET_CODE (XEXP (x, 0)) != PLUS)
11865 abort ();
11866
9878760c
RK
11867 base = XEXP (XEXP (x, 0), 0);
11868 offset = INTVAL (XEXP (XEXP (x, 0), 1));
11869 }
11870
11871 if (GET_CODE (base) == SYMBOL_REF)
11872 name = XSTR (base, 0);
11873 else if (GET_CODE (base) == LABEL_REF)
11874 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
11875 else if (GET_CODE (base) == CODE_LABEL)
11876 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
11877 else
11878 abort ();
11879
772c5265 11880 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 11881 if (TARGET_MINIMAL_TOC)
2bfcf297 11882 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
11883 else
11884 {
b6c9286a 11885 fprintf (file, "\t.tc %s", real_name);
9878760c 11886
1875cc88
JW
11887 if (offset < 0)
11888 fprintf (file, ".N%d", - offset);
11889 else if (offset)
11890 fprintf (file, ".P%d", offset);
9878760c 11891
19d2d16f 11892 fputs ("[TC],", file);
1875cc88 11893 }
581bc4de
MM
11894
11895 /* Currently C++ toc references to vtables can be emitted before it
11896 is decided whether the vtable is public or private. If this is
11897 the case, then the linker will eventually complain that there is
11898 a TOC reference to an unknown section. Thus, for vtables only,
11899 we emit the TOC reference to reference the symbol and not the
11900 section. */
28e510bd 11901 if (VTABLE_NAME_P (name))
581bc4de 11902 {
54ee9799 11903 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
11904 if (offset < 0)
11905 fprintf (file, "%d", offset);
11906 else if (offset > 0)
11907 fprintf (file, "+%d", offset);
11908 }
11909 else
11910 output_addr_const (file, x);
19d2d16f 11911 putc ('\n', file);
9878760c
RK
11912}
11913\f
11914/* Output an assembler pseudo-op to write an ASCII string of N characters
11915 starting at P to FILE.
11916
11917 On the RS/6000, we have to do this using the .byte operation and
11918 write out special characters outside the quoted string.
11919 Also, the assembler is broken; very long strings are truncated,
a4f6c312 11920 so we must artificially break them up early. */
9878760c
RK
11921
11922void
11923output_ascii (file, p, n)
11924 FILE *file;
d330fd93 11925 const char *p;
9878760c
RK
11926 int n;
11927{
11928 char c;
11929 int i, count_string;
d330fd93
KG
11930 const char *for_string = "\t.byte \"";
11931 const char *for_decimal = "\t.byte ";
11932 const char *to_close = NULL;
9878760c
RK
11933
11934 count_string = 0;
11935 for (i = 0; i < n; i++)
11936 {
11937 c = *p++;
11938 if (c >= ' ' && c < 0177)
11939 {
11940 if (for_string)
11941 fputs (for_string, file);
11942 putc (c, file);
11943
11944 /* Write two quotes to get one. */
11945 if (c == '"')
11946 {
11947 putc (c, file);
11948 ++count_string;
11949 }
11950
11951 for_string = NULL;
11952 for_decimal = "\"\n\t.byte ";
11953 to_close = "\"\n";
11954 ++count_string;
11955
11956 if (count_string >= 512)
11957 {
11958 fputs (to_close, file);
11959
11960 for_string = "\t.byte \"";
11961 for_decimal = "\t.byte ";
11962 to_close = NULL;
11963 count_string = 0;
11964 }
11965 }
11966 else
11967 {
11968 if (for_decimal)
11969 fputs (for_decimal, file);
11970 fprintf (file, "%d", c);
11971
11972 for_string = "\n\t.byte \"";
11973 for_decimal = ", ";
11974 to_close = "\n";
11975 count_string = 0;
11976 }
11977 }
11978
11979 /* Now close the string if we have written one. Then end the line. */
11980 if (to_close)
9ebbca7d 11981 fputs (to_close, file);
9878760c
RK
11982}
11983\f
11984/* Generate a unique section name for FILENAME for a section type
11985 represented by SECTION_DESC. Output goes into BUF.
11986
11987 SECTION_DESC can be any string, as long as it is different for each
11988 possible section type.
11989
11990 We name the section in the same manner as xlc. The name begins with an
11991 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
11992 names) with the last period replaced by the string SECTION_DESC. If
11993 FILENAME does not contain a period, SECTION_DESC is appended to the end of
11994 the name. */
9878760c
RK
11995
11996void
11997rs6000_gen_section_name (buf, filename, section_desc)
11998 char **buf;
9ebbca7d
GK
11999 const char *filename;
12000 const char *section_desc;
9878760c 12001{
9ebbca7d 12002 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
12003 char *p;
12004 int len;
9878760c
RK
12005
12006 after_last_slash = filename;
12007 for (q = filename; *q; q++)
11e5fe42
RK
12008 {
12009 if (*q == '/')
12010 after_last_slash = q + 1;
12011 else if (*q == '.')
12012 last_period = q;
12013 }
9878760c 12014
11e5fe42 12015 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 12016 *buf = (char *) xmalloc (len);
9878760c
RK
12017
12018 p = *buf;
12019 *p++ = '_';
12020
12021 for (q = after_last_slash; *q; q++)
12022 {
11e5fe42 12023 if (q == last_period)
9878760c
RK
12024 {
12025 strcpy (p, section_desc);
12026 p += strlen (section_desc);
9878760c
RK
12027 }
12028
e9a780ec 12029 else if (ISALNUM (*q))
9878760c
RK
12030 *p++ = *q;
12031 }
12032
11e5fe42 12033 if (last_period == 0)
9878760c
RK
12034 strcpy (p, section_desc);
12035 else
12036 *p = '\0';
12037}
e165f3f0 12038\f
a4f6c312 12039/* Emit profile function. */
411707f4 12040
411707f4
CC
12041void
12042output_profile_hook (labelno)
57ac7be9 12043 int labelno ATTRIBUTE_UNUSED;
411707f4 12044{
8480e480
CC
12045 if (DEFAULT_ABI == ABI_AIX)
12046 {
57ac7be9
AM
12047#ifdef NO_PROFILE_COUNTERS
12048 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
12049#else
8480e480 12050 char buf[30];
40501e5f 12051 const char *label_name;
8480e480 12052 rtx fun;
411707f4 12053
8480e480 12054 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 12055 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 12056 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 12057
8480e480
CC
12058 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
12059 fun, Pmode);
57ac7be9 12060#endif
8480e480 12061 }
ee890fe2
SS
12062 else if (DEFAULT_ABI == ABI_DARWIN)
12063 {
d5fa86ba 12064 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
12065 int caller_addr_regno = LINK_REGISTER_REGNUM;
12066
12067 /* Be conservative and always set this, at least for now. */
12068 current_function_uses_pic_offset_table = 1;
12069
12070#if TARGET_MACHO
12071 /* For PIC code, set up a stub and collect the caller's address
12072 from r0, which is where the prologue puts it. */
12073 if (flag_pic)
12074 {
12075 mcount_name = machopic_stub_name (mcount_name);
12076 if (current_function_uses_pic_offset_table)
12077 caller_addr_regno = 0;
12078 }
12079#endif
12080 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
12081 0, VOIDmode, 1,
12082 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12083 }
411707f4
CC
12084}
12085
a4f6c312 12086/* Write function profiler code. */
e165f3f0
RK
12087
12088void
12089output_function_profiler (file, labelno)
12090 FILE *file;
12091 int labelno;
12092{
3daf36a4 12093 char buf[100];
09eeeacb 12094 int save_lr = 8;
e165f3f0 12095
3daf36a4 12096 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 12097 switch (DEFAULT_ABI)
3daf36a4 12098 {
38c1f2d7
MM
12099 default:
12100 abort ();
12101
12102 case ABI_V4:
09eeeacb
AM
12103 save_lr = 4;
12104 /* Fall through. */
12105
38c1f2d7 12106 case ABI_AIX_NODESC:
09eeeacb
AM
12107 if (!TARGET_32BIT)
12108 {
12109 warning ("no profiling of 64-bit code for this ABI");
12110 return;
12111 }
38c1f2d7
MM
12112 fprintf (file, "\tmflr %s\n", reg_names[0]);
12113 if (flag_pic == 1)
12114 {
dfdfa60f 12115 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12116 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12117 reg_names[0], save_lr, reg_names[1]);
17167fd8 12118 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12119 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12120 assemble_name (file, buf);
17167fd8 12121 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12122 }
9ebbca7d 12123 else if (flag_pic > 1)
38c1f2d7 12124 {
09eeeacb
AM
12125 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12126 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12127 /* Now, we need to get the address of the label. */
12128 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12129 assemble_name (file, buf);
9ebbca7d
GK
12130 fputs ("-.\n1:", file);
12131 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12132 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12133 reg_names[0], reg_names[11]);
12134 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12135 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12136 }
38c1f2d7
MM
12137 else
12138 {
17167fd8 12139 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12140 assemble_name (file, buf);
dfdfa60f 12141 fputs ("@ha\n", file);
09eeeacb
AM
12142 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12143 reg_names[0], save_lr, reg_names[1]);
a260abc9 12144 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12145 assemble_name (file, buf);
17167fd8 12146 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12147 }
12148
09eeeacb
AM
12149 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12150 {
12151 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12152 reg_names[STATIC_CHAIN_REGNUM],
12153 12, reg_names[1]);
12154 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12155 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12156 reg_names[STATIC_CHAIN_REGNUM],
12157 12, reg_names[1]);
12158 }
12159 else
12160 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12161 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12162 break;
12163
12164 case ABI_AIX:
ee890fe2 12165 case ABI_DARWIN:
a4f6c312 12166 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7
MM
12167 break;
12168 }
e165f3f0 12169}
a251ffd0
TG
12170
12171/* Adjust the cost of a scheduling dependency. Return the new cost of
12172 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12173
c237e94a 12174static int
a06faf84 12175rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12176 rtx insn;
12177 rtx link;
296b8152 12178 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12179 int cost;
12180{
12181 if (! recog_memoized (insn))
12182 return 0;
12183
12184 if (REG_NOTE_KIND (link) != 0)
12185 return 0;
12186
12187 if (REG_NOTE_KIND (link) == 0)
12188 {
ed947a96
DJ
12189 /* Data dependency; DEP_INSN writes a register that INSN reads
12190 some cycles later. */
12191 switch (get_attr_type (insn))
12192 {
12193 case TYPE_JMPREG:
309323c2 12194 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12195 a mtctr and bctr (and mtlr and br/blr). The first
12196 scheduling pass will not know about this latency since
12197 the mtctr instruction, which has the latency associated
12198 to it, will be generated by reload. */
309323c2 12199 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12200 case TYPE_BRANCH:
12201 /* Leave some extra cycles between a compare and its
12202 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12203 if ((rs6000_cpu_attr == CPU_PPC603
12204 || rs6000_cpu_attr == CPU_PPC604
12205 || rs6000_cpu_attr == CPU_PPC604E
12206 || rs6000_cpu_attr == CPU_PPC620
12207 || rs6000_cpu_attr == CPU_PPC630
12208 || rs6000_cpu_attr == CPU_PPC750
12209 || rs6000_cpu_attr == CPU_PPC7400
12210 || rs6000_cpu_attr == CPU_PPC7450
12211 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12212 && recog_memoized (dep_insn)
12213 && (INSN_CODE (dep_insn) >= 0)
12214 && (get_attr_type (dep_insn) == TYPE_COMPARE
12215 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12216 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
12217 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL))
12218 return cost + 2;
12219 default:
12220 break;
12221 }
a251ffd0
TG
12222 /* Fall out to return default cost. */
12223 }
12224
12225 return cost;
12226}
b6c9286a 12227
a4f6c312
SS
12228/* A C statement (sans semicolon) to update the integer scheduling
12229 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12230 INSN earlier, increase the priority to execute INSN later. Do not
12231 define this macro if you do not need to adjust the scheduling
12232 priorities of insns. */
bef84347 12233
c237e94a 12234static int
bef84347 12235rs6000_adjust_priority (insn, priority)
d330fd93 12236 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12237 int priority;
12238{
a4f6c312
SS
12239 /* On machines (like the 750) which have asymmetric integer units,
12240 where one integer unit can do multiply and divides and the other
12241 can't, reduce the priority of multiply/divide so it is scheduled
12242 before other integer operations. */
bef84347
VM
12243
12244#if 0
2c3c49de 12245 if (! INSN_P (insn))
bef84347
VM
12246 return priority;
12247
12248 if (GET_CODE (PATTERN (insn)) == USE)
12249 return priority;
12250
12251 switch (rs6000_cpu_attr) {
12252 case CPU_PPC750:
12253 switch (get_attr_type (insn))
12254 {
12255 default:
12256 break;
12257
12258 case TYPE_IMUL:
12259 case TYPE_IDIV:
3cb999d8
DE
12260 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12261 priority, priority);
bef84347
VM
12262 if (priority >= 0 && priority < 0x01000000)
12263 priority >>= 3;
12264 break;
12265 }
12266 }
12267#endif
12268
12269 return priority;
12270}
12271
a4f6c312
SS
12272/* Return how many instructions the machine can issue per cycle. */
12273
c237e94a
ZW
12274static int
12275rs6000_issue_rate ()
b6c9286a
MM
12276{
12277 switch (rs6000_cpu_attr) {
3cb999d8
DE
12278 case CPU_RIOS1: /* ? */
12279 case CPU_RS64A:
12280 case CPU_PPC601: /* ? */
ed947a96 12281 case CPU_PPC7450:
3cb999d8 12282 return 3;
b6c9286a 12283 case CPU_PPC603:
bef84347 12284 case CPU_PPC750:
ed947a96 12285 case CPU_PPC7400:
bef84347 12286 return 2;
3cb999d8 12287 case CPU_RIOS2:
b6c9286a 12288 case CPU_PPC604:
19684119 12289 case CPU_PPC604E:
b6c9286a 12290 case CPU_PPC620:
3cb999d8 12291 case CPU_PPC630:
309323c2 12292 case CPU_POWER4:
b6c9286a
MM
12293 return 4;
12294 default:
12295 return 1;
12296 }
12297}
12298
b6c9286a 12299\f
b6c9286a
MM
12300/* Length in units of the trampoline for entering a nested function. */
12301
12302int
12303rs6000_trampoline_size ()
12304{
12305 int ret = 0;
12306
12307 switch (DEFAULT_ABI)
12308 {
12309 default:
12310 abort ();
12311
12312 case ABI_AIX:
8f802bfb 12313 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12314 break;
12315
4dabc42d 12316 case ABI_DARWIN:
b6c9286a
MM
12317 case ABI_V4:
12318 case ABI_AIX_NODESC:
03a7e1a5 12319 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12320 break;
b6c9286a
MM
12321 }
12322
12323 return ret;
12324}
12325
12326/* Emit RTL insns to initialize the variable parts of a trampoline.
12327 FNADDR is an RTX for the address of the function's pure code.
12328 CXT is an RTX for the static chain value for the function. */
12329
12330void
12331rs6000_initialize_trampoline (addr, fnaddr, cxt)
12332 rtx addr;
12333 rtx fnaddr;
12334 rtx cxt;
12335{
ac2a93a1 12336 enum machine_mode pmode = Pmode;
8bd04c56
MM
12337 int regsize = (TARGET_32BIT) ? 4 : 8;
12338 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12339
12340 switch (DEFAULT_ABI)
12341 {
12342 default:
12343 abort ();
12344
8bd04c56 12345/* Macros to shorten the code expansions below. */
39403d82 12346#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12347#define MEM_PLUS(addr,offset) \
12348 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12349
b6c9286a
MM
12350 /* Under AIX, just build the 3 word function descriptor */
12351 case ABI_AIX:
8bd04c56
MM
12352 {
12353 rtx fn_reg = gen_reg_rtx (pmode);
12354 rtx toc_reg = gen_reg_rtx (pmode);
12355 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12356 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12357 emit_move_insn (MEM_DEREF (addr), fn_reg);
12358 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12359 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12360 }
b6c9286a
MM
12361 break;
12362
4dabc42d
TC
12363 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12364 case ABI_DARWIN:
b6c9286a
MM
12365 case ABI_V4:
12366 case ABI_AIX_NODESC:
39403d82 12367 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12368 FALSE, VOIDmode, 4,
12369 addr, pmode,
12370 GEN_INT (rs6000_trampoline_size ()), SImode,
12371 fnaddr, pmode,
12372 ctx_reg, pmode);
b6c9286a 12373 break;
b6c9286a
MM
12374 }
12375
12376 return;
12377}
7509c759
MM
12378
12379\f
91d231cb 12380/* Table of valid machine attributes. */
a4f6c312 12381
91d231cb 12382const struct attribute_spec rs6000_attribute_table[] =
7509c759 12383{
91d231cb 12384 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12385 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12386 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12387 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12388};
7509c759 12389
a5c76ee6
ZW
12390/* Handle a "longcall" or "shortcall" attribute; arguments as in
12391 struct attribute_spec.handler. */
a4f6c312 12392
91d231cb
JM
12393static tree
12394rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12395 tree *node;
12396 tree name;
12397 tree args ATTRIBUTE_UNUSED;
12398 int flags ATTRIBUTE_UNUSED;
12399 bool *no_add_attrs;
12400{
12401 if (TREE_CODE (*node) != FUNCTION_TYPE
12402 && TREE_CODE (*node) != FIELD_DECL
12403 && TREE_CODE (*node) != TYPE_DECL)
12404 {
12405 warning ("`%s' attribute only applies to functions",
12406 IDENTIFIER_POINTER (name));
12407 *no_add_attrs = true;
12408 }
6a4cee5f 12409
91d231cb 12410 return NULL_TREE;
7509c759
MM
12411}
12412
a5c76ee6
ZW
12413/* Set longcall attributes on all functions declared when
12414 rs6000_default_long_calls is true. */
12415static void
12416rs6000_set_default_type_attributes (type)
12417 tree type;
12418{
12419 if (rs6000_default_long_calls
12420 && (TREE_CODE (type) == FUNCTION_TYPE
12421 || TREE_CODE (type) == METHOD_TYPE))
12422 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12423 NULL_TREE,
12424 TYPE_ATTRIBUTES (type));
12425}
12426
3cb999d8
DE
12427/* Return a reference suitable for calling a function with the
12428 longcall attribute. */
a4f6c312 12429
6a4cee5f
MM
12430struct rtx_def *
12431rs6000_longcall_ref (call_ref)
12432 rtx call_ref;
12433{
d330fd93 12434 const char *call_name;
6a4cee5f
MM
12435 tree node;
12436
12437 if (GET_CODE (call_ref) != SYMBOL_REF)
12438 return call_ref;
12439
12440 /* System V adds '.' to the internal name, so skip them. */
12441 call_name = XSTR (call_ref, 0);
12442 if (*call_name == '.')
12443 {
12444 while (*call_name == '.')
12445 call_name++;
12446
12447 node = get_identifier (call_name);
39403d82 12448 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12449 }
12450
12451 return force_reg (Pmode, call_ref);
12452}
12453
7509c759 12454\f
b64a1b53
RH
12455#ifdef USING_ELFOS_H
12456
7509c759
MM
12457/* A C statement or statements to switch to the appropriate section
12458 for output of RTX in mode MODE. You can assume that RTX is some
12459 kind of constant in RTL. The argument MODE is redundant except in
12460 the case of a `const_int' rtx. Select the section by calling
12461 `text_section' or one of the alternatives for other sections.
12462
12463 Do not define this macro if you put all constants in the read-only
12464 data section. */
12465
b64a1b53
RH
12466static void
12467rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12468 enum machine_mode mode;
7509c759 12469 rtx x;
b64a1b53 12470 unsigned HOST_WIDE_INT align;
7509c759 12471{
a9098fd0 12472 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12473 toc_section ();
7509c759 12474 else
b64a1b53 12475 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12476}
12477
12478/* A C statement or statements to switch to the appropriate
12479 section for output of DECL. DECL is either a `VAR_DECL' node
12480 or a constant of some sort. RELOC indicates whether forming
12481 the initial value of DECL requires link-time relocations. */
12482
ae46c4e0
RH
12483static void
12484rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12485 tree decl;
12486 int reloc;
0e5dbd9b 12487 unsigned HOST_WIDE_INT align;
7509c759 12488{
0e5dbd9b
DE
12489 default_elf_select_section_1 (decl, reloc, align,
12490 flag_pic || DEFAULT_ABI == ABI_AIX);
63019373
GK
12491}
12492
12493/* A C statement to build up a unique section name, expressed as a
12494 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12495 RELOC indicates whether the initial value of EXP requires
12496 link-time relocations. If you do not define this macro, GCC will use
12497 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12498 macro can now be called for uninitialized data items as well as
4912a07c 12499 initialized data and functions. */
63019373 12500
ae46c4e0
RH
12501static void
12502rs6000_elf_unique_section (decl, reloc)
63019373
GK
12503 tree decl;
12504 int reloc;
12505{
0e5dbd9b
DE
12506 default_unique_section_1 (decl, reloc,
12507 flag_pic || DEFAULT_ABI == ABI_AIX);
7509c759 12508}
d9407988
MM
12509
12510\f
d9407988
MM
12511/* If we are referencing a function that is static or is known to be
12512 in this file, make the SYMBOL_REF special. We can use this to indicate
12513 that we can branch to this function without emitting a no-op after the
9ebbca7d 12514 call. For real AIX calling sequences, we also replace the
d9407988
MM
12515 function name with the real name (1 or 2 leading .'s), rather than
12516 the function descriptor name. This saves a lot of overriding code
a260abc9 12517 to read the prefixes. */
d9407988 12518
fb49053f
RH
12519static void
12520rs6000_elf_encode_section_info (decl, first)
d9407988 12521 tree decl;
b2003250 12522 int first;
d9407988 12523{
b2003250
RH
12524 if (!first)
12525 return;
12526
d9407988
MM
12527 if (TREE_CODE (decl) == FUNCTION_DECL)
12528 {
12529 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
b629ba0c 12530 if ((*targetm.binds_local_p) (decl))
d9407988
MM
12531 SYMBOL_REF_FLAG (sym_ref) = 1;
12532
9ebbca7d 12533 if (DEFAULT_ABI == ABI_AIX)
d9407988 12534 {
ff669a6c
RH
12535 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12536 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12537 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12538 str[0] = '.';
12539 str[1] = '.';
12540 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12541
520a57c8 12542 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12543 }
12544 }
12545 else if (rs6000_sdata != SDATA_NONE
f607bc57 12546 && DEFAULT_ABI == ABI_V4
d9407988
MM
12547 && TREE_CODE (decl) == VAR_DECL)
12548 {
12549 int size = int_size_in_bytes (TREE_TYPE (decl));
12550 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12551 const char *name = (char *)0;
d9407988
MM
12552 int len = 0;
12553
12554 if (section_name)
12555 {
12556 if (TREE_CODE (section_name) == STRING_CST)
12557 {
12558 name = TREE_STRING_POINTER (section_name);
12559 len = TREE_STRING_LENGTH (section_name);
12560 }
12561 else
12562 abort ();
12563 }
12564
12565 if ((size > 0 && size <= g_switch_value)
12566 || (name
5f59ecb7 12567 && ((len == sizeof (".sdata") - 1
3cb999d8 12568 && strcmp (name, ".sdata") == 0)
5f59ecb7 12569 || (len == sizeof (".sdata2") - 1
3cb999d8 12570 && strcmp (name, ".sdata2") == 0)
5f59ecb7 12571 || (len == sizeof (".sbss") - 1
3cb999d8 12572 && strcmp (name, ".sbss") == 0)
5f59ecb7 12573 || (len == sizeof (".sbss2") - 1
3cb999d8 12574 && strcmp (name, ".sbss2") == 0)
5f59ecb7 12575 || (len == sizeof (".PPC.EMB.sdata0") - 1
3cb999d8 12576 && strcmp (name, ".PPC.EMB.sdata0") == 0)
5f59ecb7 12577 || (len == sizeof (".PPC.EMB.sbss0") - 1
3cb999d8 12578 && strcmp (name, ".PPC.EMB.sbss0") == 0))))
d9407988
MM
12579 {
12580 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
ff669a6c 12581 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 12582 char *str = alloca (len + 2);
ff669a6c 12583
ff669a6c
RH
12584 str[0] = '@';
12585 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 12586 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
12587 }
12588 }
12589}
12590
772c5265
RH
12591static const char *
12592rs6000_elf_strip_name_encoding (str)
12593 const char *str;
12594{
12595 while (*str == '*' || *str == '@')
12596 str++;
12597 return str;
12598}
12599
0e5dbd9b
DE
12600static bool
12601rs6000_elf_in_small_data_p (decl)
12602 tree decl;
12603{
12604 if (rs6000_sdata == SDATA_NONE)
12605 return false;
12606
12607 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
12608 {
12609 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
12610 if (strcmp (section, ".sdata") == 0
12611 || strcmp (section, ".sdata2") == 0
12612 || strcmp (section, ".sbss") == 0)
12613 return true;
12614 }
12615 else
12616 {
12617 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
12618
12619 if (size > 0
12620 && size <= g_switch_value
12621 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
12622 return true;
12623 }
12624
12625 return false;
12626}
12627
b91da81f 12628#endif /* USING_ELFOS_H */
000034eb 12629
a6c2a102 12630\f
000034eb 12631/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
12632 ADDR can be effectively incremented by incrementing REG.
12633
12634 r0 is special and we must not select it as an address
12635 register by this routine since our caller will try to
12636 increment the returned register via an "la" instruction. */
000034eb
DE
12637
12638struct rtx_def *
12639find_addr_reg (addr)
12640 rtx addr;
12641{
12642 while (GET_CODE (addr) == PLUS)
12643 {
02441cd6
JL
12644 if (GET_CODE (XEXP (addr, 0)) == REG
12645 && REGNO (XEXP (addr, 0)) != 0)
000034eb 12646 addr = XEXP (addr, 0);
02441cd6
JL
12647 else if (GET_CODE (XEXP (addr, 1)) == REG
12648 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
12649 addr = XEXP (addr, 1);
12650 else if (CONSTANT_P (XEXP (addr, 0)))
12651 addr = XEXP (addr, 1);
12652 else if (CONSTANT_P (XEXP (addr, 1)))
12653 addr = XEXP (addr, 0);
12654 else
12655 abort ();
12656 }
02441cd6 12657 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
12658 return addr;
12659 abort ();
12660}
12661
a6c2a102
DE
12662void
12663rs6000_fatal_bad_address (op)
12664 rtx op;
12665{
12666 fatal_insn ("bad address", op);
12667}
c8023011
MM
12668
12669/* Called to register all of our global variables with the garbage
12670 collector. */
12671
12672static void
12673rs6000_add_gc_roots ()
12674{
9ebbca7d
GK
12675 toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
12676 ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
12677 toc_hash_mark_table);
ee890fe2
SS
12678}
12679
12680#if TARGET_MACHO
12681
12682#if 0
12683/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12684 reference and a constant. */
12685
12686int
12687symbolic_operand (op)
592696dd 12688 rtx op;
ee890fe2
SS
12689{
12690 switch (GET_CODE (op))
12691 {
12692 case SYMBOL_REF:
12693 case LABEL_REF:
12694 return 1;
12695 case CONST:
12696 op = XEXP (op, 0);
12697 return (GET_CODE (op) == SYMBOL_REF ||
12698 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12699 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12700 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12701 default:
12702 return 0;
12703 }
c8023011 12704}
ee890fe2
SS
12705#endif
12706
12707#ifdef RS6000_LONG_BRANCH
12708
12709static tree stub_list = 0;
12710
12711/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12712 procedure calls to the linked list. */
12713
12714void
12715add_compiler_stub (label_name, function_name, line_number)
12716 tree label_name;
12717 tree function_name;
12718 int line_number;
12719{
12720 tree stub = build_tree_list (function_name, label_name);
12721 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12722 TREE_CHAIN (stub) = stub_list;
12723 stub_list = stub;
12724}
12725
12726#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12727#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12728#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12729
a4f6c312
SS
12730/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12731 handling procedure calls from the linked list and initializes the
12732 linked list. */
ee890fe2 12733
a4f6c312
SS
12734void
12735output_compiler_stub ()
ee890fe2
SS
12736{
12737 char tmp_buf[256];
12738 char label_buf[256];
308c142a 12739 tree stub;
ee890fe2
SS
12740
12741 if (!flag_pic)
12742 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12743 {
12744 fprintf (asm_out_file,
12745 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12746
12747#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12748 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12749 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12750#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12751
12752 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12753 strcpy (label_buf,
12754 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12755 else
12756 {
12757 label_buf[0] = '_';
12758 strcpy (label_buf+1,
12759 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12760 }
12761
12762 strcpy (tmp_buf, "lis r12,hi16(");
12763 strcat (tmp_buf, label_buf);
12764 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12765 strcat (tmp_buf, label_buf);
12766 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12767 output_asm_insn (tmp_buf, 0);
12768
12769#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12770 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12771 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12772#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12773 }
12774
12775 stub_list = 0;
12776}
12777
12778/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12779 already there or not. */
12780
a4f6c312
SS
12781int
12782no_previous_def (function_name)
ee890fe2
SS
12783 tree function_name;
12784{
12785 tree stub;
12786 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12787 if (function_name == STUB_FUNCTION_NAME (stub))
12788 return 0;
12789 return 1;
12790}
12791
12792/* GET_PREV_LABEL gets the label name from the previous definition of
12793 the function. */
12794
a4f6c312
SS
12795tree
12796get_prev_label (function_name)
ee890fe2
SS
12797 tree function_name;
12798{
12799 tree stub;
12800 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12801 if (function_name == STUB_FUNCTION_NAME (stub))
12802 return STUB_LABEL_NAME (stub);
12803 return 0;
12804}
12805
12806/* INSN is either a function call or a millicode call. It may have an
12807 unconditional jump in its delay slot.
12808
12809 CALL_DEST is the routine we are calling. */
12810
12811char *
12812output_call (insn, call_dest, operand_number)
12813 rtx insn;
12814 rtx call_dest;
12815 int operand_number;
12816{
12817 static char buf[256];
12818 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
12819 {
12820 tree labelname;
12821 tree funname = get_identifier (XSTR (call_dest, 0));
12822
12823 if (no_previous_def (funname))
12824 {
308c142a 12825 int line_number = 0;
ee890fe2
SS
12826 rtx label_rtx = gen_label_rtx ();
12827 char *label_buf, temp_buf[256];
12828 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
12829 CODE_LABEL_NUMBER (label_rtx));
12830 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
12831 labelname = get_identifier (label_buf);
12832 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
12833 if (insn)
12834 line_number = NOTE_LINE_NUMBER (insn);
12835 add_compiler_stub (labelname, funname, line_number);
12836 }
12837 else
12838 labelname = get_prev_label (funname);
12839
12840 sprintf (buf, "jbsr %%z%d,%.246s",
12841 operand_number, IDENTIFIER_POINTER (labelname));
12842 return buf;
12843 }
12844 else
12845 {
12846 sprintf (buf, "bl %%z%d", operand_number);
12847 return buf;
12848 }
12849}
12850
12851#endif /* RS6000_LONG_BRANCH */
12852
12853#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
12854 do { \
83182544 12855 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
12856 char *buffer_ = (BUF); \
12857 if (symbol_[0] == '"') \
12858 { \
12859 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
12860 } \
12861 else if (name_needs_quotes(symbol_)) \
12862 { \
12863 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
12864 } \
12865 else \
12866 { \
12867 sprintf(buffer_, "L%d$%s", (N), symbol_); \
12868 } \
12869 } while (0)
12870
12871
12872/* Generate PIC and indirect symbol stubs. */
12873
12874void
12875machopic_output_stub (file, symb, stub)
12876 FILE *file;
12877 const char *symb, *stub;
12878{
12879 unsigned int length;
a4f6c312
SS
12880 char *symbol_name, *lazy_ptr_name;
12881 char *local_label_0;
ee890fe2
SS
12882 static int label = 0;
12883
df56a27f 12884 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 12885 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 12886
ee890fe2
SS
12887 label += 1;
12888
ee890fe2
SS
12889 length = strlen (symb);
12890 symbol_name = alloca (length + 32);
12891 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
12892
12893 lazy_ptr_name = alloca (length + 32);
12894 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
12895
12896 local_label_0 = alloca (length + 32);
12897 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
12898
ee890fe2
SS
12899 if (flag_pic == 2)
12900 machopic_picsymbol_stub_section ();
12901 else
12902 machopic_symbol_stub_section ();
12903
12904 fprintf (file, "%s:\n", stub);
12905 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12906
12907 if (flag_pic == 2)
12908 {
12909 fprintf (file, "\tmflr r0\n");
12910 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
12911 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
12912 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
12913 lazy_ptr_name, local_label_0);
12914 fprintf (file, "\tmtlr r0\n");
12915 fprintf (file, "\tlwz r12,lo16(%s-%s)(r11)\n",
12916 lazy_ptr_name, local_label_0);
12917 fprintf (file, "\tmtctr r12\n");
12918 fprintf (file, "\taddi r11,r11,lo16(%s-%s)\n",
12919 lazy_ptr_name, local_label_0);
12920 fprintf (file, "\tbctr\n");
12921 }
12922 else
12923 fprintf (file, "non-pure not supported\n");
12924
12925 machopic_lazy_symbol_ptr_section ();
12926 fprintf (file, "%s:\n", lazy_ptr_name);
12927 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
12928 fprintf (file, "\t.long dyld_stub_binding_helper\n");
12929}
12930
12931/* Legitimize PIC addresses. If the address is already
12932 position-independent, we return ORIG. Newly generated
12933 position-independent addresses go into a reg. This is REG if non
12934 zero, otherwise we allocate register(s) as necessary. */
12935
c859cda6 12936#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
12937
12938rtx
12939rs6000_machopic_legitimize_pic_address (orig, mode, reg)
12940 rtx orig;
12941 enum machine_mode mode;
12942 rtx reg;
12943{
12944 rtx base, offset;
12945
12946 if (reg == NULL && ! reload_in_progress && ! reload_completed)
12947 reg = gen_reg_rtx (Pmode);
12948
12949 if (GET_CODE (orig) == CONST)
12950 {
12951 if (GET_CODE (XEXP (orig, 0)) == PLUS
12952 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
12953 return orig;
12954
12955 if (GET_CODE (XEXP (orig, 0)) == PLUS)
12956 {
a4f6c312
SS
12957 base =
12958 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
12959 Pmode, reg);
12960 offset =
12961 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
12962 Pmode, reg);
ee890fe2
SS
12963 }
12964 else
12965 abort ();
12966
12967 if (GET_CODE (offset) == CONST_INT)
12968 {
12969 if (SMALL_INT (offset))
ed8908e7 12970 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
12971 else if (! reload_in_progress && ! reload_completed)
12972 offset = force_reg (Pmode, offset);
12973 else
c859cda6
DJ
12974 {
12975 rtx mem = force_const_mem (Pmode, orig);
12976 return machopic_legitimize_pic_address (mem, Pmode, reg);
12977 }
ee890fe2
SS
12978 }
12979 return gen_rtx (PLUS, Pmode, base, offset);
12980 }
12981
12982 /* Fall back on generic machopic code. */
12983 return machopic_legitimize_pic_address (orig, mode, reg);
12984}
12985
12986/* This is just a placeholder to make linking work without having to
12987 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
12988 ever needed for Darwin (not too likely!) this would have to get a
12989 real definition. */
12990
12991void
12992toc_section ()
12993{
12994}
12995
12996#endif /* TARGET_MACHO */
7c262518
RH
12997
12998#if TARGET_ELF
12999static unsigned int
13000rs6000_elf_section_type_flags (decl, name, reloc)
13001 tree decl;
13002 const char *name;
13003 int reloc;
13004{
5add3202
DE
13005 unsigned int flags
13006 = default_section_type_flags_1 (decl, name, reloc,
13007 flag_pic || DEFAULT_ABI == ABI_AIX);
7c262518 13008
270fc29b
RH
13009 if (TARGET_RELOCATABLE)
13010 flags |= SECTION_WRITE;
7c262518 13011
d0101753 13012 return flags;
7c262518 13013}
d9f6800d
RH
13014
13015/* Record an element in the table of global constructors. SYMBOL is
13016 a SYMBOL_REF of the function to be called; PRIORITY is a number
13017 between 0 and MAX_INIT_PRIORITY.
13018
13019 This differs from default_named_section_asm_out_constructor in
13020 that we have special handling for -mrelocatable. */
13021
13022static void
13023rs6000_elf_asm_out_constructor (symbol, priority)
13024 rtx symbol;
13025 int priority;
13026{
13027 const char *section = ".ctors";
13028 char buf[16];
13029
13030 if (priority != DEFAULT_INIT_PRIORITY)
13031 {
13032 sprintf (buf, ".ctors.%.5u",
13033 /* Invert the numbering so the linker puts us in the proper
13034 order; constructors are run from right to left, and the
13035 linker sorts in increasing order. */
13036 MAX_INIT_PRIORITY - priority);
13037 section = buf;
13038 }
13039
715bdd29
RH
13040 named_section_flags (section, SECTION_WRITE);
13041 assemble_align (POINTER_SIZE);
d9f6800d
RH
13042
13043 if (TARGET_RELOCATABLE)
13044 {
13045 fputs ("\t.long (", asm_out_file);
13046 output_addr_const (asm_out_file, symbol);
13047 fputs (")@fixup\n", asm_out_file);
13048 }
13049 else
c8af3574 13050 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
13051}
13052
13053static void
13054rs6000_elf_asm_out_destructor (symbol, priority)
13055 rtx symbol;
13056 int priority;
13057{
13058 const char *section = ".dtors";
13059 char buf[16];
13060
13061 if (priority != DEFAULT_INIT_PRIORITY)
13062 {
13063 sprintf (buf, ".dtors.%.5u",
13064 /* Invert the numbering so the linker puts us in the proper
13065 order; constructors are run from right to left, and the
13066 linker sorts in increasing order. */
13067 MAX_INIT_PRIORITY - priority);
13068 section = buf;
13069 }
13070
715bdd29
RH
13071 named_section_flags (section, SECTION_WRITE);
13072 assemble_align (POINTER_SIZE);
d9f6800d
RH
13073
13074 if (TARGET_RELOCATABLE)
13075 {
13076 fputs ("\t.long (", asm_out_file);
13077 output_addr_const (asm_out_file, symbol);
13078 fputs (")@fixup\n", asm_out_file);
13079 }
13080 else
c8af3574 13081 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 13082}
7c262518
RH
13083#endif
13084
cbaaba19 13085#if TARGET_XCOFF
7c262518 13086static void
b275d088
DE
13087rs6000_xcoff_asm_globalize_label (stream, name)
13088 FILE *stream;
13089 const char *name;
13090{
13091 fputs (GLOBAL_ASM_OP, stream);
13092 RS6000_OUTPUT_BASENAME (stream, name);
13093 putc ('\n', stream);
13094}
13095
13096static void
13097rs6000_xcoff_asm_named_section (name, flags)
7c262518 13098 const char *name;
0e5dbd9b 13099 unsigned int flags;
7c262518 13100{
0e5dbd9b
DE
13101 int smclass;
13102 static const char * const suffix[3] = { "PR", "RO", "RW" };
13103
13104 if (flags & SECTION_CODE)
13105 smclass = 0;
13106 else if (flags & SECTION_WRITE)
13107 smclass = 2;
13108 else
13109 smclass = 1;
13110
5b5198f7 13111 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 13112 (flags & SECTION_CODE) ? "." : "",
5b5198f7 13113 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 13114}
ae46c4e0
RH
13115
13116static void
0e5dbd9b
DE
13117rs6000_xcoff_select_section (decl, reloc, align)
13118 tree decl;
ae46c4e0
RH
13119 int reloc;
13120 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13121{
5add3202 13122 if (decl_readonly_section_1 (decl, reloc, 1))
ae46c4e0 13123 {
0e5dbd9b 13124 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13125 read_only_data_section ();
13126 else
13127 read_only_private_data_section ();
13128 }
13129 else
13130 {
0e5dbd9b 13131 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13132 data_section ();
13133 else
13134 private_data_section ();
13135 }
13136}
13137
13138static void
13139rs6000_xcoff_unique_section (decl, reloc)
13140 tree decl;
772c5265 13141 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13142{
13143 const char *name;
ae46c4e0 13144
5b5198f7
DE
13145 /* Use select_section for private and uninitialized data. */
13146 if (!TREE_PUBLIC (decl)
13147 || DECL_COMMON (decl)
0e5dbd9b
DE
13148 || DECL_INITIAL (decl) == NULL_TREE
13149 || DECL_INITIAL (decl) == error_mark_node
13150 || (flag_zero_initialized_in_bss
13151 && initializer_zerop (DECL_INITIAL (decl))))
13152 return;
13153
13154 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13155 name = (*targetm.strip_name_encoding) (name);
13156 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 13157}
b64a1b53 13158
fb49053f
RH
13159/* Select section for constant in constant pool.
13160
13161 On RS/6000, all constants are in the private read-only data area.
13162 However, if this is being placed in the TOC it must be output as a
13163 toc entry. */
13164
b64a1b53
RH
13165static void
13166rs6000_xcoff_select_rtx_section (mode, x, align)
13167 enum machine_mode mode;
13168 rtx x;
13169 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13170{
13171 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13172 toc_section ();
13173 else
13174 read_only_private_data_section ();
13175}
772c5265
RH
13176
13177/* Remove any trailing [DS] or the like from the symbol name. */
13178
13179static const char *
13180rs6000_xcoff_strip_name_encoding (name)
13181 const char *name;
13182{
13183 size_t len;
13184 if (*name == '*')
13185 name++;
13186 len = strlen (name);
13187 if (name[len - 1] == ']')
13188 return ggc_alloc_string (name, len - 4);
13189 else
13190 return name;
13191}
13192
5add3202
DE
13193/* Section attributes. AIX is always PIC. */
13194
13195static unsigned int
13196rs6000_xcoff_section_type_flags (decl, name, reloc)
13197 tree decl;
13198 const char *name;
13199 int reloc;
13200{
5b5198f7
DE
13201 unsigned int align;
13202 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
13203
13204 /* Align to at least UNIT size. */
13205 if (flags & SECTION_CODE)
13206 align = MIN_UNITS_PER_WORD;
13207 else
13208 /* Increase alignment of large objects if not already stricter. */
13209 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
13210 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
13211 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
13212
13213 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202
DE
13214}
13215
cbaaba19 13216#endif /* TARGET_XCOFF */
fb49053f 13217
0e5dbd9b 13218/* Note that this is also used for PPC64 Linux. */
fb49053f
RH
13219
13220static void
13221rs6000_xcoff_encode_section_info (decl, first)
13222 tree decl;
13223 int first ATTRIBUTE_UNUSED;
13224{
13225 if (TREE_CODE (decl) == FUNCTION_DECL
b629ba0c 13226 && (*targetm.binds_local_p) (decl))
fb49053f
RH
13227 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13228}
0e5dbd9b
DE
13229
13230/* Cross-module name binding. For AIX and PPC64 Linux, which always are
13231 PIC, use private copy of flag_pic. */
13232
2bcc50d0 13233static bool
0e5dbd9b
DE
13234rs6000_binds_local_p (decl)
13235 tree decl;
13236{
5add3202 13237 return default_binds_local_p_1 (decl, flag_pic || rs6000_flag_pic);
0e5dbd9b 13238}