]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
Makefile.in: Update.
[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,
d3c300d2 3 2000, 2001, 2002, 2003 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"
4977bab6
ZW
25#include "coretypes.h"
26#include "tm.h"
9878760c
RK
27#include "rtl.h"
28#include "regs.h"
29#include "hard-reg-set.h"
30#include "real.h"
31#include "insn-config.h"
32#include "conditions.h"
9878760c
RK
33#include "insn-attr.h"
34#include "flags.h"
35#include "recog.h"
9878760c 36#include "obstack.h"
9b30bae2 37#include "tree.h"
dfafc897 38#include "expr.h"
2fc1c679 39#include "optabs.h"
2a430ec1 40#include "except.h"
a7df97e6 41#include "function.h"
296b8152 42#include "output.h"
d5fa86ba 43#include "basic-block.h"
d0101753 44#include "integrate.h"
296b8152 45#include "toplev.h"
c8023011 46#include "ggc.h"
9ebbca7d
GK
47#include "hashtab.h"
48#include "tm_p.h"
672a6f42
NB
49#include "target.h"
50#include "target-def.h"
3ac88239 51#include "langhooks.h"
24ea750e 52#include "reload.h"
9b30bae2 53
7509c759
MM
54#ifndef TARGET_NO_PROTOTYPE
55#define TARGET_NO_PROTOTYPE 0
56#endif
57
9878760c
RK
58#define min(A,B) ((A) < (B) ? (A) : (B))
59#define max(A,B) ((A) > (B) ? (A) : (B))
60
5248c961
RK
61/* Target cpu type */
62
63enum processor_type rs6000_cpu;
8e3f41e7
MM
64struct rs6000_cpu_select rs6000_select[3] =
65{
815cdc52
MM
66 /* switch name, tune arch */
67 { (const char *)0, "--with-cpu=", 1, 1 },
68 { (const char *)0, "-mcpu=", 1, 1 },
69 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 70};
5248c961 71
6fa3f289
ZW
72/* Size of long double */
73const char *rs6000_long_double_size_string;
74int rs6000_long_double_type_size;
75
76/* Whether -mabi=altivec has appeared */
77int rs6000_altivec_abi;
78
08b57fb3
AH
79/* Whether VRSAVE instructions should be generated. */
80int rs6000_altivec_vrsave;
81
82/* String from -mvrsave= option. */
83const char *rs6000_altivec_vrsave_string;
84
a3170dc6
AH
85/* Nonzero if we want SPE ABI extensions. */
86int rs6000_spe_abi;
87
88/* Whether isel instructions should be generated. */
89int rs6000_isel;
90
91/* Nonzero if we have FPRs. */
92int rs6000_fprs = 1;
93
94/* String from -misel=. */
95const char *rs6000_isel_string;
96
a0ab749a 97/* Set to nonzero once AIX common-mode calls have been defined. */
bbfb86aa 98static GTY(()) int common_mode_defined;
c81bebd7 99
0e5dbd9b
DE
100/* Private copy of original value of flag_pic for ABI_AIX. */
101static int rs6000_flag_pic;
102
9878760c
RK
103/* Save information from a "cmpxx" operation until the branch or scc is
104 emitted. */
9878760c
RK
105rtx rs6000_compare_op0, rs6000_compare_op1;
106int rs6000_compare_fp_p;
874a0744 107
874a0744
MM
108/* Label number of label created for -mrelocatable, to call to so we can
109 get the address of the GOT section */
110int rs6000_pic_labelno;
c81bebd7 111
b91da81f 112#ifdef USING_ELFOS_H
c81bebd7 113/* Which abi to adhere to */
815cdc52 114const char *rs6000_abi_name = RS6000_ABI_NAME;
d9407988
MM
115
116/* Semantics of the small data area */
117enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
118
119/* Which small data model to use */
815cdc52 120const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
121
122/* Counter for labels which are to be placed in .fixup. */
123int fixuplabelno = 0;
874a0744 124#endif
4697a36c 125
b6c9286a
MM
126/* ABI enumeration available for subtarget to use. */
127enum rs6000_abi rs6000_current_abi;
128
0ac081f6
AH
129/* ABI string from -mabi= option. */
130const char *rs6000_abi_string;
131
38c1f2d7 132/* Debug flags */
815cdc52 133const char *rs6000_debug_name;
38c1f2d7
MM
134int rs6000_debug_stack; /* debug stack applications */
135int rs6000_debug_arg; /* debug argument handling */
136
57ac7be9
AM
137const char *rs6000_traceback_name;
138static enum {
139 traceback_default = 0,
140 traceback_none,
141 traceback_part,
142 traceback_full
143} rs6000_traceback;
144
38c1f2d7
MM
145/* Flag to say the TOC is initialized */
146int toc_initialized;
9ebbca7d 147char toc_label_name[10];
38c1f2d7 148
9ebbca7d
GK
149/* Alias set for saves and restores from the rs6000 stack. */
150static int rs6000_sr_alias_set;
c8023011 151
a5c76ee6
ZW
152/* Call distance, overridden by -mlongcall and #pragma longcall(1).
153 The only place that looks at this is rs6000_set_default_type_attributes;
154 everywhere else should rely on the presence or absence of a longcall
155 attribute on the function declaration. */
156int rs6000_default_long_calls;
157const char *rs6000_longcall_switch;
158
a3170dc6
AH
159struct builtin_description
160{
161 /* mask is not const because we're going to alter it below. This
162 nonsense will go away when we rewrite the -march infrastructure
163 to give us more target flag bits. */
164 unsigned int mask;
165 const enum insn_code icode;
166 const char *const name;
167 const enum rs6000_builtins code;
168};
169
4977bab6 170static bool rs6000_function_ok_for_sibcall PARAMS ((tree, tree));
9ebbca7d 171static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
39a10a29
GK
172static void validate_condition_mode
173 PARAMS ((enum rtx_code, enum machine_mode));
174static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
e50f5f3d 175static void rs6000_maybe_dead PARAMS ((rtx));
9ebbca7d
GK
176static void rs6000_emit_stack_tie PARAMS ((void));
177static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
c19de7aa
AH
178static rtx spe_synthesize_frame_save PARAMS ((rtx));
179static bool spe_func_has_64bit_regs_p PARAMS ((void));
89e7058f
AH
180static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
181 unsigned int, int, int));
a3170dc6 182static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
9ebbca7d
GK
183static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
184static unsigned rs6000_hash_constant PARAMS ((rtx));
185static unsigned toc_hash_function PARAMS ((const void *));
186static int toc_hash_eq PARAMS ((const void *, const void *));
9ebbca7d 187static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
e2500fed 188static struct machine_function * rs6000_init_machine_status PARAMS ((void));
301d03af 189static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
5add3202 190#ifdef HAVE_GAS_HIDDEN
25fdb4dc 191static void rs6000_assemble_visibility PARAMS ((tree, int));
5add3202 192#endif
71f123ca 193static int rs6000_ra_ever_killed PARAMS ((void));
91d231cb
JM
194static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
195const struct attribute_spec rs6000_attribute_table[];
a5c76ee6 196static void rs6000_set_default_type_attributes PARAMS ((tree));
08c148a8
NB
197static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
198static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
3961e8fe
RH
199static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
200 HOST_WIDE_INT, tree));
2bfcf297
DB
201static rtx rs6000_emit_set_long_const PARAMS ((rtx,
202 HOST_WIDE_INT, HOST_WIDE_INT));
7c262518
RH
203#if TARGET_ELF
204static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
205 int));
d9f6800d
RH
206static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
207static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
ae46c4e0 208static void rs6000_elf_select_section PARAMS ((tree, int,
5b71a4e7 209 unsigned HOST_WIDE_INT));
ae46c4e0 210static void rs6000_elf_unique_section PARAMS ((tree, int));
b64a1b53
RH
211static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
212 unsigned HOST_WIDE_INT));
0e5dbd9b
DE
213static void rs6000_elf_encode_section_info PARAMS ((tree, int))
214 ATTRIBUTE_UNUSED;
772c5265 215static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
0e5dbd9b 216static bool rs6000_elf_in_small_data_p PARAMS ((tree));
7c262518 217#endif
cbaaba19 218#if TARGET_XCOFF
b275d088
DE
219static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
220static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
ae46c4e0
RH
221static void rs6000_xcoff_select_section PARAMS ((tree, int,
222 unsigned HOST_WIDE_INT));
223static void rs6000_xcoff_unique_section PARAMS ((tree, int));
b64a1b53
RH
224static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
225 unsigned HOST_WIDE_INT));
772c5265 226static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
5add3202 227static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
7c262518 228#endif
fb49053f
RH
229static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
230 ATTRIBUTE_UNUSED;
2bcc50d0 231static bool rs6000_binds_local_p PARAMS ((tree));
b54cf83a 232static int rs6000_use_dfa_pipeline_interface PARAMS ((void));
b54cf83a 233static int rs6000_variable_issue PARAMS ((FILE *, int, rtx, int));
3c50106f 234static bool rs6000_rtx_costs PARAMS ((rtx, int, int, int *));
c237e94a
ZW
235static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
236static int rs6000_adjust_priority PARAMS ((rtx, int));
237static int rs6000_issue_rate PARAMS ((void));
238
6fa3f289 239static void rs6000_init_builtins PARAMS ((void));
92898235
AH
240static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
241static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
242static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 243static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
92898235 244static void altivec_init_builtins PARAMS ((void));
a3170dc6
AH
245static void rs6000_common_init_builtins PARAMS ((void));
246
247static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
248 int, enum rs6000_builtins,
249 enum rs6000_builtins));
250static void spe_init_builtins PARAMS ((void));
251static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
252static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
253static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
254static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
255
92898235 256static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
3a9b8c7e
AH
257static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
258static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
259static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
100c4561 260static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 261static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
6525c0e7 262static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 263static void rs6000_parse_abi_options PARAMS ((void));
08b57fb3 264static void rs6000_parse_vrsave_option PARAMS ((void));
a3170dc6 265static void rs6000_parse_isel_option PARAMS ((void));
00b960c7
AH
266static int first_altivec_reg_to_save PARAMS ((void));
267static unsigned int compute_vrsave_mask PARAMS ((void));
268static void is_altivec_return_reg PARAMS ((rtx, void *));
9aa86737 269static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
69ef87e2 270static int easy_vector_constant PARAMS ((rtx));
c8e4f0e9 271static bool is_ev64_opaque_type PARAMS ((tree));
96714395 272static rtx rs6000_dwarf_register_span PARAMS ((rtx));
17211ab5
GK
273
274/* Hash table stuff for keeping track of TOC entries. */
275
276struct toc_hash_struct GTY(())
277{
278 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
279 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
280 rtx key;
281 enum machine_mode key_mode;
282 int labelno;
283};
284
285static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
c81bebd7
MM
286\f
287/* Default register names. */
288char rs6000_reg_names[][8] =
289{
802a0058
MM
290 "0", "1", "2", "3", "4", "5", "6", "7",
291 "8", "9", "10", "11", "12", "13", "14", "15",
292 "16", "17", "18", "19", "20", "21", "22", "23",
293 "24", "25", "26", "27", "28", "29", "30", "31",
294 "0", "1", "2", "3", "4", "5", "6", "7",
295 "8", "9", "10", "11", "12", "13", "14", "15",
296 "16", "17", "18", "19", "20", "21", "22", "23",
297 "24", "25", "26", "27", "28", "29", "30", "31",
298 "mq", "lr", "ctr","ap",
299 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
300 "xer",
301 /* AltiVec registers. */
0cd5e3a1
AH
302 "0", "1", "2", "3", "4", "5", "6", "7",
303 "8", "9", "10", "11", "12", "13", "14", "15",
304 "16", "17", "18", "19", "20", "21", "22", "23",
305 "24", "25", "26", "27", "28", "29", "30", "31",
59a4c851
AH
306 "vrsave", "vscr",
307 /* SPE registers. */
308 "spe_acc", "spefscr"
c81bebd7
MM
309};
310
311#ifdef TARGET_REGNAMES
8b60264b 312static const char alt_reg_names[][8] =
c81bebd7 313{
802a0058
MM
314 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
315 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
316 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
317 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
318 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
319 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
320 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
321 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
322 "mq", "lr", "ctr", "ap",
323 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6 324 "xer",
59a4c851 325 /* AltiVec registers. */
0ac081f6 326 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
59a4c851
AH
327 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
328 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
329 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
330 "vrsave", "vscr",
331 /* SPE registers. */
332 "spe_acc", "spefscr"
c81bebd7
MM
333};
334#endif
9878760c 335\f
daf11973
MM
336#ifndef MASK_STRICT_ALIGN
337#define MASK_STRICT_ALIGN 0
338#endif
3961e8fe
RH
339
340/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
341#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
672a6f42
NB
342\f
343/* Initialize the GCC target structure. */
91d231cb
JM
344#undef TARGET_ATTRIBUTE_TABLE
345#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
346#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
347#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 348
301d03af
RS
349#undef TARGET_ASM_ALIGNED_DI_OP
350#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
351
352/* Default unaligned ops are only provided for ELF. Find the ops needed
353 for non-ELF systems. */
354#ifndef OBJECT_FORMAT_ELF
cbaaba19 355#if TARGET_XCOFF
ae6c1efd 356/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
357 64-bit targets. */
358#undef TARGET_ASM_UNALIGNED_HI_OP
359#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
360#undef TARGET_ASM_UNALIGNED_SI_OP
361#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
362#undef TARGET_ASM_UNALIGNED_DI_OP
363#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
364#else
365/* For Darwin. */
366#undef TARGET_ASM_UNALIGNED_HI_OP
367#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
368#undef TARGET_ASM_UNALIGNED_SI_OP
369#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
370#endif
371#endif
372
373/* This hook deals with fixups for relocatable code and DI-mode objects
374 in 64-bit code. */
375#undef TARGET_ASM_INTEGER
376#define TARGET_ASM_INTEGER rs6000_assemble_integer
377
93638d7a
AM
378#ifdef HAVE_GAS_HIDDEN
379#undef TARGET_ASM_ASSEMBLE_VISIBILITY
380#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
381#endif
382
08c148a8
NB
383#undef TARGET_ASM_FUNCTION_PROLOGUE
384#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
385#undef TARGET_ASM_FUNCTION_EPILOGUE
386#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
387
b54cf83a
DE
388#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
389#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE rs6000_use_dfa_pipeline_interface
b54cf83a
DE
390#undef TARGET_SCHED_VARIABLE_ISSUE
391#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
392
c237e94a
ZW
393#undef TARGET_SCHED_ISSUE_RATE
394#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
395#undef TARGET_SCHED_ADJUST_COST
396#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
397#undef TARGET_SCHED_ADJUST_PRIORITY
398#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
399
0ac081f6
AH
400#undef TARGET_INIT_BUILTINS
401#define TARGET_INIT_BUILTINS rs6000_init_builtins
402
403#undef TARGET_EXPAND_BUILTIN
404#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
405
0e5dbd9b
DE
406#undef TARGET_BINDS_LOCAL_P
407#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
408
3961e8fe
RH
409#undef TARGET_ASM_OUTPUT_MI_THUNK
410#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
411
3961e8fe 412#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5b71a4e7 413#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
00b960c7 414
4977bab6
ZW
415#undef TARGET_FUNCTION_OK_FOR_SIBCALL
416#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
417
3c50106f
RH
418#undef TARGET_RTX_COSTS
419#define TARGET_RTX_COSTS rs6000_rtx_costs
dcefdf67
RH
420#undef TARGET_ADDRESS_COST
421#define TARGET_ADDRESS_COST hook_int_rtx_0
3c50106f 422
c8e4f0e9
AH
423#undef TARGET_VECTOR_OPAQUE_P
424#define TARGET_VECTOR_OPAQUE_P is_ev64_opaque_type
62e1dfcf 425
96714395
AH
426#undef TARGET_DWARF_REGISTER_SPAN
427#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
428
f6897b10 429struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 430\f
5248c961
RK
431/* Override command line options. Mostly we process the processor
432 type and sometimes adjust other TARGET_ options. */
433
434void
8e3f41e7 435rs6000_override_options (default_cpu)
d330fd93 436 const char *default_cpu;
5248c961 437{
c4d38ccb 438 size_t i, j;
8e3f41e7 439 struct rs6000_cpu_select *ptr;
5248c961 440
85638c0d
RK
441 /* Simplify the entries below by making a mask for any POWER
442 variant and any PowerPC variant. */
443
938937d8 444#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
445#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
446 | MASK_PPC_GFXOPT | MASK_POWERPC64)
447#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 448
5248c961
RK
449 static struct ptt
450 {
8b60264b
KG
451 const char *const name; /* Canonical processor name. */
452 const enum processor_type processor; /* Processor type enum value. */
453 const int target_enable; /* Target flags to enable. */
454 const int target_disable; /* Target flags to disable. */
455 } const processor_target_table[]
cf27b467
MM
456 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
457 POWER_MASKS | POWERPC_MASKS},
db7f1e43 458 {"power", PROCESSOR_POWER,
938937d8 459 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 460 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
461 {"power2", PROCESSOR_POWER,
462 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
463 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
464 {"power3", PROCESSOR_PPC630,
465 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
d7b53ca4 466 POWER_MASKS},
309323c2 467 {"power4", PROCESSOR_POWER4,
7f3d8013
DJ
468 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
469 POWER_MASKS | MASK_PPC_GPOPT},
db7f1e43
RK
470 {"powerpc", PROCESSOR_POWERPC,
471 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 472 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
473 {"powerpc64", PROCESSOR_POWERPC64,
474 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
475 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 476 {"rios", PROCESSOR_RIOS1,
938937d8 477 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
478 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
479 {"rios1", PROCESSOR_RIOS1,
938937d8 480 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
481 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
482 {"rsc", PROCESSOR_PPC601,
938937d8 483 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
484 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
485 {"rsc1", PROCESSOR_PPC601,
938937d8 486 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
487 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
488 {"rios2", PROCESSOR_RIOS2,
938937d8 489 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 490 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
491 {"rs64a", PROCESSOR_RS64A,
492 MASK_POWERPC | MASK_NEW_MNEMONICS,
493 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
494 {"401", PROCESSOR_PPC403,
495 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
496 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 497 {"403", PROCESSOR_PPC403,
daf11973 498 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 499 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
500 {"405", PROCESSOR_PPC405,
501 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
502 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
4977bab6
ZW
503 {"405f", PROCESSOR_PPC405,
504 MASK_POWERPC | MASK_NEW_MNEMONICS,
505 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
506 {"505", PROCESSOR_MPCCORE,
507 MASK_POWERPC | MASK_NEW_MNEMONICS,
508 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 509 {"601", PROCESSOR_PPC601,
938937d8 510 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 511 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 512 {"602", PROCESSOR_PPC603,
cf27b467
MM
513 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
514 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 515 {"603", PROCESSOR_PPC603,
68c49ffa
RK
516 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
517 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
518 {"603e", PROCESSOR_PPC603,
519 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
520 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 521 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
522 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
523 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 524 {"604", PROCESSOR_PPC604,
b6c9286a
MM
525 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
526 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 527 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
528 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
529 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 530 {"620", PROCESSOR_PPC620,
68c49ffa 531 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
d7b53ca4 532 POWER_MASKS},
3cb999d8
DE
533 {"630", PROCESSOR_PPC630,
534 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
d7b53ca4 535 POWER_MASKS},
bef84347
VM
536 {"740", PROCESSOR_PPC750,
537 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
538 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
539 {"750", PROCESSOR_PPC750,
540 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
541 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
542 {"7400", PROCESSOR_PPC7400,
543 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
544 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
545 {"7450", PROCESSOR_PPC7450,
546 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
547 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a3170dc6
AH
548 {"8540", PROCESSOR_PPC8540,
549 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
550 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
551 {"801", PROCESSOR_MPCCORE,
552 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
553 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
554 {"821", PROCESSOR_MPCCORE,
555 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
556 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
557 {"823", PROCESSOR_MPCCORE,
558 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
559 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
560 {"860", PROCESSOR_MPCCORE,
561 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
562 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 563
ca7558fc 564 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 565
a4f6c312
SS
566 /* Save current -mmultiple/-mno-multiple status. */
567 int multiple = TARGET_MULTIPLE;
568 /* Save current -mstring/-mno-string status. */
569 int string = TARGET_STRING;
8a61d227 570
a4f6c312 571 /* Identify the processor type. */
8e3f41e7 572 rs6000_select[0].string = default_cpu;
3cb999d8 573 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 574
b6a1cbae 575 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 576 {
8e3f41e7
MM
577 ptr = &rs6000_select[i];
578 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 579 {
8e3f41e7
MM
580 for (j = 0; j < ptt_size; j++)
581 if (! strcmp (ptr->string, processor_target_table[j].name))
582 {
583 if (ptr->set_tune_p)
584 rs6000_cpu = processor_target_table[j].processor;
585
586 if (ptr->set_arch_p)
587 {
588 target_flags |= processor_target_table[j].target_enable;
589 target_flags &= ~processor_target_table[j].target_disable;
590 }
591 break;
592 }
593
4406229e 594 if (j == ptt_size)
8e3f41e7 595 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
596 }
597 }
8a61d227 598
a3170dc6
AH
599 if (rs6000_cpu == PROCESSOR_PPC8540)
600 rs6000_isel = 1;
601
dff9f1b6
DE
602 /* If we are optimizing big endian systems for space, use the load/store
603 multiple and string instructions. */
ef792183 604 if (BYTES_BIG_ENDIAN && optimize_size)
dff9f1b6 605 target_flags |= MASK_MULTIPLE | MASK_STRING;
ef792183 606
8a61d227
MM
607 /* If -mmultiple or -mno-multiple was explicitly used, don't
608 override with the processor default */
b21fb038 609 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
8a61d227 610 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 611
a4f6c312
SS
612 /* If -mstring or -mno-string was explicitly used, don't override
613 with the processor default. */
b21fb038 614 if ((target_flags_explicit & MASK_STRING) != 0)
1f5515bf 615 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 616
a4f6c312
SS
617 /* Don't allow -mmultiple or -mstring on little endian systems
618 unless the cpu is a 750, because the hardware doesn't support the
619 instructions used in little endian mode, and causes an alignment
620 trap. The 750 does not cause an alignment trap (except when the
621 target is unaligned). */
bef84347 622
b21fb038 623 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
624 {
625 if (TARGET_MULTIPLE)
626 {
627 target_flags &= ~MASK_MULTIPLE;
b21fb038 628 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
7e69e155
MM
629 warning ("-mmultiple is not supported on little endian systems");
630 }
631
632 if (TARGET_STRING)
633 {
634 target_flags &= ~MASK_STRING;
b21fb038 635 if ((target_flags_explicit & MASK_STRING) != 0)
938937d8 636 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
637 }
638 }
3933e0e1 639
ee2ca2a2 640 if (flag_pic != 0 && DEFAULT_ABI == ABI_AIX)
a260abc9 641 {
0e5dbd9b 642 rs6000_flag_pic = flag_pic;
ee2ca2a2 643 flag_pic = 0;
a260abc9
DE
644 }
645
38c1f2d7
MM
646 /* Set debug flags */
647 if (rs6000_debug_name)
648 {
bfc79d3b 649 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 650 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 651 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 652 rs6000_debug_stack = 1;
bfc79d3b 653 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
654 rs6000_debug_arg = 1;
655 else
c725bd79 656 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
657 }
658
57ac7be9
AM
659 if (rs6000_traceback_name)
660 {
661 if (! strncmp (rs6000_traceback_name, "full", 4))
662 rs6000_traceback = traceback_full;
663 else if (! strncmp (rs6000_traceback_name, "part", 4))
664 rs6000_traceback = traceback_part;
665 else if (! strncmp (rs6000_traceback_name, "no", 2))
666 rs6000_traceback = traceback_none;
667 else
668 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
669 rs6000_traceback_name);
670 }
671
6fa3f289
ZW
672 /* Set size of long double */
673 rs6000_long_double_type_size = 64;
674 if (rs6000_long_double_size_string)
675 {
676 char *tail;
677 int size = strtol (rs6000_long_double_size_string, &tail, 10);
678 if (*tail != '\0' || (size != 64 && size != 128))
679 error ("Unknown switch -mlong-double-%s",
680 rs6000_long_double_size_string);
681 else
682 rs6000_long_double_type_size = size;
683 }
684
0ac081f6
AH
685 /* Handle -mabi= options. */
686 rs6000_parse_abi_options ();
687
08b57fb3
AH
688 /* Handle -mvrsave= option. */
689 rs6000_parse_vrsave_option ();
690
a3170dc6
AH
691 /* Handle -misel= option. */
692 rs6000_parse_isel_option ();
693
a7ae18e2
AH
694#ifdef SUBTARGET_OVERRIDE_OPTIONS
695 SUBTARGET_OVERRIDE_OPTIONS;
696#endif
697#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
698 SUBSUBTARGET_OVERRIDE_OPTIONS;
699#endif
700
a5c76ee6
ZW
701 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
702 using TARGET_OPTIONS to handle a toggle switch, but we're out of
703 bits in target_flags so TARGET_SWITCHES cannot be used.
704 Assumption here is that rs6000_longcall_switch points into the
705 text of the complete option, rather than being a copy, so we can
706 scan back for the presence or absence of the no- modifier. */
707 if (rs6000_longcall_switch)
708 {
709 const char *base = rs6000_longcall_switch;
710 while (base[-1] != 'm') base--;
711
712 if (*rs6000_longcall_switch != '\0')
713 error ("invalid option `%s'", base);
714 rs6000_default_long_calls = (base[0] != 'n');
715 }
716
c81bebd7 717#ifdef TARGET_REGNAMES
a4f6c312
SS
718 /* If the user desires alternate register names, copy in the
719 alternate names now. */
c81bebd7 720 if (TARGET_REGNAMES)
4e135bdd 721 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
722#endif
723
6fa3f289
ZW
724 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
725 If -maix-struct-return or -msvr4-struct-return was explicitly
726 used, don't override with the ABI default. */
b21fb038 727 if ((target_flags_explicit & MASK_AIX_STRUCT_RET) == 0)
6fa3f289
ZW
728 {
729 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
730 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
731 else
732 target_flags |= MASK_AIX_STRUCT_RET;
733 }
734
fcce224d
DE
735 if (TARGET_LONG_DOUBLE_128
736 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
737 real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
738
9ebbca7d
GK
739 /* Allocate an alias set for register saves & restores from stack. */
740 rs6000_sr_alias_set = new_alias_set ();
741
742 if (TARGET_TOC)
743 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 744
301d03af
RS
745 /* We can only guarantee the availability of DI pseudo-ops when
746 assembling for 64-bit targets. */
ae6c1efd 747 if (!TARGET_64BIT)
301d03af
RS
748 {
749 targetm.asm_out.aligned_op.di = NULL;
750 targetm.asm_out.unaligned_op.di = NULL;
751 }
752
2792d578
DE
753 /* Set maximum branch target alignment at two instructions, eight bytes. */
754 align_jumps_max_skip = 8;
755 align_loops_max_skip = 8;
756
71f123ca
FS
757 /* Arrange to save and restore machine status around nested functions. */
758 init_machine_status = rs6000_init_machine_status;
5248c961 759}
5accd822 760
a3170dc6
AH
761/* Handle -misel= option. */
762static void
763rs6000_parse_isel_option ()
764{
765 if (rs6000_isel_string == 0)
766 return;
767 else if (! strcmp (rs6000_isel_string, "yes"))
768 rs6000_isel = 1;
769 else if (! strcmp (rs6000_isel_string, "no"))
770 rs6000_isel = 0;
771 else
772 error ("unknown -misel= option specified: '%s'",
773 rs6000_isel_string);
774}
775
08b57fb3
AH
776/* Handle -mvrsave= options. */
777static void
778rs6000_parse_vrsave_option ()
779{
780 /* Generate VRSAVE instructions by default. */
781 if (rs6000_altivec_vrsave_string == 0
782 || ! strcmp (rs6000_altivec_vrsave_string, "yes"))
783 rs6000_altivec_vrsave = 1;
784 else if (! strcmp (rs6000_altivec_vrsave_string, "no"))
785 rs6000_altivec_vrsave = 0;
786 else
787 error ("unknown -mvrsave= option specified: '%s'",
788 rs6000_altivec_vrsave_string);
789}
790
0ac081f6 791/* Handle -mabi= options. */
00b960c7
AH
792static void
793rs6000_parse_abi_options ()
0ac081f6
AH
794{
795 if (rs6000_abi_string == 0)
796 return;
797 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 798 rs6000_altivec_abi = 1;
76a773f3
AH
799 else if (! strcmp (rs6000_abi_string, "no-altivec"))
800 rs6000_altivec_abi = 0;
a3170dc6 801 else if (! strcmp (rs6000_abi_string, "spe"))
01f4962d
NS
802 {
803 rs6000_spe_abi = 1;
804 if (!TARGET_SPE_ABI)
805 error ("not configured for ABI: '%s'", rs6000_abi_string);
806 }
807
a3170dc6
AH
808 else if (! strcmp (rs6000_abi_string, "no-spe"))
809 rs6000_spe_abi = 0;
0ac081f6 810 else
c725bd79 811 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
812}
813
5accd822
DE
814void
815optimization_options (level, size)
e2c953b6 816 int level ATTRIBUTE_UNUSED;
5accd822
DE
817 int size ATTRIBUTE_UNUSED;
818{
5accd822 819}
3cfa4909
MM
820\f
821/* Do anything needed at the start of the asm file. */
822
823void
824rs6000_file_start (file, default_cpu)
825 FILE *file;
d330fd93 826 const char *default_cpu;
3cfa4909 827{
c4d38ccb 828 size_t i;
3cfa4909 829 char buffer[80];
d330fd93 830 const char *start = buffer;
3cfa4909
MM
831 struct rs6000_cpu_select *ptr;
832
833 if (flag_verbose_asm)
834 {
835 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
836 rs6000_select[0].string = default_cpu;
837
b6a1cbae 838 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
839 {
840 ptr = &rs6000_select[i];
841 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
842 {
843 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
844 start = "";
845 }
846 }
847
b91da81f 848#ifdef USING_ELFOS_H
3cfa4909
MM
849 switch (rs6000_sdata)
850 {
851 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
852 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
853 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
854 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
855 }
856
857 if (rs6000_sdata && g_switch_value)
858 {
859 fprintf (file, "%s -G %d", start, g_switch_value);
860 start = "";
861 }
862#endif
863
864 if (*start == '\0')
949ea356 865 putc ('\n', file);
3cfa4909
MM
866 }
867}
5248c961 868\f
a0ab749a 869/* Return nonzero if this function is known to have a null epilogue. */
9878760c
RK
870
871int
872direct_return ()
873{
4697a36c
MM
874 if (reload_completed)
875 {
876 rs6000_stack_t *info = rs6000_stack_info ();
877
878 if (info->first_gp_reg_save == 32
879 && info->first_fp_reg_save == 64
00b960c7 880 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
881 && ! info->lr_save_p
882 && ! info->cr_save_p
00b960c7 883 && info->vrsave_mask == 0
c81fc13e 884 && ! info->push_p)
4697a36c
MM
885 return 1;
886 }
887
888 return 0;
9878760c
RK
889}
890
891/* Returns 1 always. */
892
893int
894any_operand (op, mode)
592696dd 895 rtx op ATTRIBUTE_UNUSED;
296b8152 896 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
897{
898 return 1;
899}
900
a4f6c312 901/* Returns 1 if op is the count register. */
38c1f2d7 902int
a4f6c312 903count_register_operand (op, mode)
592696dd 904 rtx op;
296b8152 905 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
906{
907 if (GET_CODE (op) != REG)
908 return 0;
909
910 if (REGNO (op) == COUNT_REGISTER_REGNUM)
911 return 1;
912
913 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
914 return 1;
915
916 return 0;
917}
918
0ec4e2a8
AH
919/* Returns 1 if op is an altivec register. */
920int
921altivec_register_operand (op, mode)
922 rtx op;
923 enum machine_mode mode ATTRIBUTE_UNUSED;
924{
925
926 return (register_operand (op, mode)
927 && (GET_CODE (op) != REG
928 || REGNO (op) > FIRST_PSEUDO_REGISTER
929 || ALTIVEC_REGNO_P (REGNO (op))));
930}
931
38c1f2d7 932int
a4f6c312 933xer_operand (op, mode)
592696dd 934 rtx op;
296b8152 935 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
936{
937 if (GET_CODE (op) != REG)
938 return 0;
939
9ebbca7d 940 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
941 return 1;
942
802a0058
MM
943 return 0;
944}
945
c859cda6 946/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 947 by such constants completes more quickly. */
c859cda6
DJ
948
949int
950s8bit_cint_operand (op, mode)
951 rtx op;
952 enum machine_mode mode ATTRIBUTE_UNUSED;
953{
954 return ( GET_CODE (op) == CONST_INT
955 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
956}
957
9878760c
RK
958/* Return 1 if OP is a constant that can fit in a D field. */
959
960int
961short_cint_operand (op, mode)
592696dd 962 rtx op;
296b8152 963 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 964{
5f59ecb7
DE
965 return (GET_CODE (op) == CONST_INT
966 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
967}
968
5519a4f9 969/* Similar for an unsigned D field. */
9878760c
RK
970
971int
972u_short_cint_operand (op, mode)
592696dd 973 rtx op;
296b8152 974 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 975{
19684119 976 return (GET_CODE (op) == CONST_INT
c1f11548 977 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
978}
979
dcfedcd0
RK
980/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
981
982int
983non_short_cint_operand (op, mode)
592696dd 984 rtx op;
296b8152 985 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
986{
987 return (GET_CODE (op) == CONST_INT
a7653a2c 988 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
989}
990
2bfcf297
DB
991/* Returns 1 if OP is a CONST_INT that is a positive value
992 and an exact power of 2. */
993
994int
995exact_log2_cint_operand (op, mode)
592696dd 996 rtx op;
2bfcf297
DB
997 enum machine_mode mode ATTRIBUTE_UNUSED;
998{
999 return (GET_CODE (op) == CONST_INT
1000 && INTVAL (op) > 0
1001 && exact_log2 (INTVAL (op)) >= 0);
1002}
1003
9878760c
RK
1004/* Returns 1 if OP is a register that is not special (i.e., not MQ,
1005 ctr, or lr). */
1006
1007int
cd2b37d9 1008gpc_reg_operand (op, mode)
592696dd 1009 rtx op;
9878760c
RK
1010 enum machine_mode mode;
1011{
1012 return (register_operand (op, mode)
802a0058 1013 && (GET_CODE (op) != REG
9ebbca7d
GK
1014 || (REGNO (op) >= ARG_POINTER_REGNUM
1015 && !XER_REGNO_P (REGNO (op)))
1016 || REGNO (op) < MQ_REGNO));
9878760c
RK
1017}
1018
1019/* Returns 1 if OP is either a pseudo-register or a register denoting a
1020 CR field. */
1021
1022int
1023cc_reg_operand (op, mode)
592696dd 1024 rtx op;
9878760c
RK
1025 enum machine_mode mode;
1026{
1027 return (register_operand (op, mode)
1028 && (GET_CODE (op) != REG
1029 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1030 || CR_REGNO_P (REGNO (op))));
1031}
1032
815cdc52
MM
1033/* Returns 1 if OP is either a pseudo-register or a register denoting a
1034 CR field that isn't CR0. */
1035
1036int
1037cc_reg_not_cr0_operand (op, mode)
592696dd 1038 rtx op;
815cdc52
MM
1039 enum machine_mode mode;
1040{
1041 return (register_operand (op, mode)
1042 && (GET_CODE (op) != REG
1043 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1044 || CR_REGNO_NOT_CR0_P (REGNO (op))));
1045}
1046
a4f6c312
SS
1047/* Returns 1 if OP is either a constant integer valid for a D-field or
1048 a non-special register. If a register, it must be in the proper
1049 mode unless MODE is VOIDmode. */
9878760c
RK
1050
1051int
1052reg_or_short_operand (op, mode)
592696dd 1053 rtx op;
9878760c
RK
1054 enum machine_mode mode;
1055{
f5a28898 1056 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1057}
1058
a4f6c312
SS
1059/* Similar, except check if the negation of the constant would be
1060 valid for a D-field. */
9878760c
RK
1061
1062int
1063reg_or_neg_short_operand (op, mode)
592696dd 1064 rtx op;
9878760c
RK
1065 enum machine_mode mode;
1066{
1067 if (GET_CODE (op) == CONST_INT)
1068 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1069
cd2b37d9 1070 return gpc_reg_operand (op, mode);
9878760c
RK
1071}
1072
768070a0
TR
1073/* Returns 1 if OP is either a constant integer valid for a DS-field or
1074 a non-special register. If a register, it must be in the proper
1075 mode unless MODE is VOIDmode. */
1076
1077int
1078reg_or_aligned_short_operand (op, mode)
1079 rtx op;
1080 enum machine_mode mode;
1081{
1082 if (gpc_reg_operand (op, mode))
1083 return 1;
1084 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1085 return 1;
1086
1087 return 0;
1088}
1089
1090
a4f6c312
SS
1091/* Return 1 if the operand is either a register or an integer whose
1092 high-order 16 bits are zero. */
9878760c
RK
1093
1094int
1095reg_or_u_short_operand (op, mode)
592696dd 1096 rtx op;
9878760c
RK
1097 enum machine_mode mode;
1098{
e675f625 1099 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1100}
1101
1102/* Return 1 is the operand is either a non-special register or ANY
1103 constant integer. */
1104
1105int
1106reg_or_cint_operand (op, mode)
592696dd 1107 rtx op;
9878760c
RK
1108 enum machine_mode mode;
1109{
a4f6c312 1110 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1111}
1112
1113/* Return 1 is the operand is either a non-special register or ANY
1114 32-bit signed constant integer. */
1115
1116int
1117reg_or_arith_cint_operand (op, mode)
592696dd 1118 rtx op;
f6bf7de2
DE
1119 enum machine_mode mode;
1120{
a4f6c312
SS
1121 return (gpc_reg_operand (op, mode)
1122 || (GET_CODE (op) == CONST_INT
f6bf7de2 1123#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1124 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1125 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1126#endif
a4f6c312 1127 ));
9878760c
RK
1128}
1129
2bfcf297
DB
1130/* Return 1 is the operand is either a non-special register or a 32-bit
1131 signed constant integer valid for 64-bit addition. */
1132
1133int
1134reg_or_add_cint64_operand (op, mode)
592696dd 1135 rtx op;
2bfcf297
DB
1136 enum machine_mode mode;
1137{
a4f6c312
SS
1138 return (gpc_reg_operand (op, mode)
1139 || (GET_CODE (op) == CONST_INT
a65c591c 1140#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1141 && INTVAL (op) < 0x7fff8000
a65c591c 1142#else
a4f6c312
SS
1143 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1144 < 0x100000000ll)
2bfcf297 1145#endif
a4f6c312 1146 ));
2bfcf297
DB
1147}
1148
1149/* Return 1 is the operand is either a non-special register or a 32-bit
1150 signed constant integer valid for 64-bit subtraction. */
1151
1152int
1153reg_or_sub_cint64_operand (op, mode)
592696dd 1154 rtx op;
2bfcf297
DB
1155 enum machine_mode mode;
1156{
a4f6c312
SS
1157 return (gpc_reg_operand (op, mode)
1158 || (GET_CODE (op) == CONST_INT
a65c591c 1159#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1160 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1161#else
a4f6c312
SS
1162 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1163 < 0x100000000ll)
2bfcf297 1164#endif
a4f6c312 1165 ));
2bfcf297
DB
1166}
1167
9ebbca7d
GK
1168/* Return 1 is the operand is either a non-special register or ANY
1169 32-bit unsigned constant integer. */
1170
1171int
1d328b19 1172reg_or_logical_cint_operand (op, mode)
592696dd 1173 rtx op;
9ebbca7d
GK
1174 enum machine_mode mode;
1175{
1d328b19
GK
1176 if (GET_CODE (op) == CONST_INT)
1177 {
1178 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1179 {
1180 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1181 abort ();
1d328b19
GK
1182
1183 if (INTVAL (op) < 0)
1184 return 0;
1185 }
1186
1187 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1188 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1189 }
1190 else if (GET_CODE (op) == CONST_DOUBLE)
1191 {
1192 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1193 || mode != DImode)
a4f6c312 1194 abort ();
1d328b19
GK
1195
1196 return CONST_DOUBLE_HIGH (op) == 0;
1197 }
1198 else
1199 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1200}
1201
51d3e7d6 1202/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1203
1204int
1205got_operand (op, mode)
592696dd 1206 rtx op;
296b8152 1207 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1208{
1209 return (GET_CODE (op) == SYMBOL_REF
1210 || GET_CODE (op) == CONST
1211 || GET_CODE (op) == LABEL_REF);
1212}
1213
38c1f2d7
MM
1214/* Return 1 if the operand is a simple references that can be loaded via
1215 the GOT (labels involving addition aren't allowed). */
1216
1217int
1218got_no_const_operand (op, mode)
592696dd 1219 rtx op;
296b8152 1220 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1221{
1222 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1223}
1224
4e74d8ec
MM
1225/* Return the number of instructions it takes to form a constant in an
1226 integer register. */
1227
1228static int
1229num_insns_constant_wide (value)
1230 HOST_WIDE_INT value;
1231{
1232 /* signed constant loadable with {cal|addi} */
5f59ecb7 1233 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1234 return 1;
1235
4e74d8ec 1236 /* constant loadable with {cau|addis} */
5f59ecb7 1237 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1238 return 1;
1239
5f59ecb7 1240#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1241 else if (TARGET_POWERPC64)
4e74d8ec 1242 {
a65c591c
DE
1243 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1244 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1245
a65c591c 1246 if (high == 0 || high == -1)
4e74d8ec
MM
1247 return 2;
1248
a65c591c 1249 high >>= 1;
4e74d8ec 1250
a65c591c 1251 if (low == 0)
4e74d8ec 1252 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1253 else
1254 return (num_insns_constant_wide (high)
e396202a 1255 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1256 }
1257#endif
1258
1259 else
1260 return 2;
1261}
1262
1263int
1264num_insns_constant (op, mode)
1265 rtx op;
1266 enum machine_mode mode;
1267{
4e74d8ec 1268 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1269 {
1270#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1271 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1272 && mask64_operand (op, mode))
0d30d435
DE
1273 return 2;
1274 else
1275#endif
1276 return num_insns_constant_wide (INTVAL (op));
1277 }
4e74d8ec 1278
6fc48950
MM
1279 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1280 {
1281 long l;
1282 REAL_VALUE_TYPE rv;
1283
1284 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1285 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1286 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1287 }
1288
47ad8c61 1289 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1290 {
47ad8c61
MM
1291 HOST_WIDE_INT low;
1292 HOST_WIDE_INT high;
1293 long l[2];
1294 REAL_VALUE_TYPE rv;
1295 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1296
47ad8c61
MM
1297 if (mode == VOIDmode || mode == DImode)
1298 {
1299 high = CONST_DOUBLE_HIGH (op);
1300 low = CONST_DOUBLE_LOW (op);
1301 }
1302 else
1303 {
1304 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1305 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1306 high = l[endian];
1307 low = l[1 - endian];
1308 }
4e74d8ec 1309
47ad8c61
MM
1310 if (TARGET_32BIT)
1311 return (num_insns_constant_wide (low)
1312 + num_insns_constant_wide (high));
4e74d8ec
MM
1313
1314 else
47ad8c61 1315 {
e72247f4 1316 if (high == 0 && low >= 0)
47ad8c61
MM
1317 return num_insns_constant_wide (low);
1318
e72247f4 1319 else if (high == -1 && low < 0)
47ad8c61
MM
1320 return num_insns_constant_wide (low);
1321
a260abc9
DE
1322 else if (mask64_operand (op, mode))
1323 return 2;
1324
47ad8c61
MM
1325 else if (low == 0)
1326 return num_insns_constant_wide (high) + 1;
1327
1328 else
1329 return (num_insns_constant_wide (high)
1330 + num_insns_constant_wide (low) + 1);
1331 }
4e74d8ec
MM
1332 }
1333
1334 else
1335 abort ();
1336}
1337
a4f6c312
SS
1338/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1339 register with one instruction per word. We only do this if we can
1340 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1341
1342int
1343easy_fp_constant (op, mode)
592696dd
SS
1344 rtx op;
1345 enum machine_mode mode;
9878760c 1346{
9878760c
RK
1347 if (GET_CODE (op) != CONST_DOUBLE
1348 || GET_MODE (op) != mode
4e74d8ec 1349 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1350 return 0;
1351
a4f6c312 1352 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1353 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1354 && mode != DImode)
b6c9286a
MM
1355 return 1;
1356
a4f6c312 1357 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1358 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1359 return 0;
1360
5ae4759c 1361#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1362 /* Similarly if we are using -mrelocatable, consider all constants
1363 to be hard. */
5ae4759c
MM
1364 if (TARGET_RELOCATABLE)
1365 return 0;
1366#endif
1367
fcce224d
DE
1368 if (mode == TFmode)
1369 {
1370 long k[4];
1371 REAL_VALUE_TYPE rv;
1372
1373 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1374 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
1375
1376 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1377 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
1378 && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
1379 && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
1380 }
1381
1382 else if (mode == DFmode)
042259f2
DE
1383 {
1384 long k[2];
1385 REAL_VALUE_TYPE rv;
1386
1387 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1388 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1389
a65c591c
DE
1390 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1391 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1392 }
4e74d8ec
MM
1393
1394 else if (mode == SFmode)
042259f2
DE
1395 {
1396 long l;
1397 REAL_VALUE_TYPE rv;
1398
1399 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1400 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1401
4e74d8ec 1402 return num_insns_constant_wide (l) == 1;
042259f2 1403 }
4e74d8ec 1404
a260abc9 1405 else if (mode == DImode)
c81fc13e 1406 return ((TARGET_POWERPC64
a260abc9
DE
1407 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1408 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1409
a9098fd0
GK
1410 else if (mode == SImode)
1411 return 1;
4e74d8ec
MM
1412 else
1413 abort ();
9878760c 1414}
8f75773e 1415
69ef87e2
AH
1416/* Return 1 if the operand is a CONST_INT and can be put into a
1417 register with one instruction. */
1418
1419static int
1420easy_vector_constant (op)
1421 rtx op;
1422{
1423 rtx elt;
1424 int units, i;
1425
1426 if (GET_CODE (op) != CONST_VECTOR)
1427 return 0;
1428
1429 units = CONST_VECTOR_NUNITS (op);
1430
1431 /* We can generate 0 easily. Look for that. */
1432 for (i = 0; i < units; ++i)
1433 {
1434 elt = CONST_VECTOR_ELT (op, i);
1435
1436 /* We could probably simplify this by just checking for equality
1437 with CONST0_RTX for the current mode, but let's be safe
1438 instead. */
1439
98ef3137
JJ
1440 switch (GET_CODE (elt))
1441 {
1442 case CONST_INT:
1443 if (INTVAL (elt) != 0)
1444 return 0;
1445 break;
1446 case CONST_DOUBLE:
1447 if (CONST_DOUBLE_LOW (elt) != 0 || CONST_DOUBLE_HIGH (elt) != 0)
1448 return 0;
1449 break;
1450 default:
1451 return 0;
1452 }
69ef87e2
AH
1453 }
1454
1455 /* We could probably generate a few other constants trivially, but
1456 gcc doesn't generate them yet. FIXME later. */
98ef3137 1457 return 1;
69ef87e2
AH
1458}
1459
1460/* Return 1 if the operand is the constant 0. This works for scalars
1461 as well as vectors. */
1462int
1463zero_constant (op, mode)
1464 rtx op;
1465 enum machine_mode mode;
1466{
1467 return op == CONST0_RTX (mode);
1468}
1469
50a0b056
GK
1470/* Return 1 if the operand is 0.0. */
1471int
1472zero_fp_constant (op, mode)
592696dd
SS
1473 rtx op;
1474 enum machine_mode mode;
50a0b056
GK
1475{
1476 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1477}
1478
a4f6c312
SS
1479/* Return 1 if the operand is in volatile memory. Note that during
1480 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1481 volatile memory references. So this function allows us to
1482 recognize volatile references where its safe. */
1483
1484int
1485volatile_mem_operand (op, mode)
592696dd 1486 rtx op;
b6c9286a
MM
1487 enum machine_mode mode;
1488{
1489 if (GET_CODE (op) != MEM)
1490 return 0;
1491
1492 if (!MEM_VOLATILE_P (op))
1493 return 0;
1494
1495 if (mode != GET_MODE (op))
1496 return 0;
1497
1498 if (reload_completed)
1499 return memory_operand (op, mode);
1500
1501 if (reload_in_progress)
1502 return strict_memory_address_p (mode, XEXP (op, 0));
1503
1504 return memory_address_p (mode, XEXP (op, 0));
1505}
1506
97f6e72f 1507/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1508
1509int
97f6e72f 1510offsettable_mem_operand (op, mode)
592696dd 1511 rtx op;
914c2e77
RK
1512 enum machine_mode mode;
1513{
97f6e72f 1514 return ((GET_CODE (op) == MEM)
677a9668 1515 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1516 mode, XEXP (op, 0)));
914c2e77
RK
1517}
1518
9878760c
RK
1519/* Return 1 if the operand is either an easy FP constant (see above) or
1520 memory. */
1521
1522int
1523mem_or_easy_const_operand (op, mode)
592696dd 1524 rtx op;
9878760c
RK
1525 enum machine_mode mode;
1526{
1527 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1528}
1529
1530/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1531 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1532
1533int
1534add_operand (op, mode)
592696dd 1535 rtx op;
9878760c
RK
1536 enum machine_mode mode;
1537{
2bfcf297 1538 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1539 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1540 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1541
1542 return gpc_reg_operand (op, mode);
9878760c
RK
1543}
1544
dcfedcd0
RK
1545/* Return 1 if OP is a constant but not a valid add_operand. */
1546
1547int
1548non_add_cint_operand (op, mode)
592696dd 1549 rtx op;
296b8152 1550 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1551{
1552 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1553 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1554 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1555}
1556
9878760c
RK
1557/* Return 1 if the operand is a non-special register or a constant that
1558 can be used as the operand of an OR or XOR insn on the RS/6000. */
1559
1560int
1561logical_operand (op, mode)
592696dd 1562 rtx op;
9878760c
RK
1563 enum machine_mode mode;
1564{
40501e5f 1565 HOST_WIDE_INT opl, oph;
1d328b19 1566
dfbdccdb
GK
1567 if (gpc_reg_operand (op, mode))
1568 return 1;
1d328b19 1569
dfbdccdb 1570 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1571 {
1572 opl = INTVAL (op) & GET_MODE_MASK (mode);
1573
1574#if HOST_BITS_PER_WIDE_INT <= 32
1575 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1576 return 0;
1577#endif
1578 }
dfbdccdb
GK
1579 else if (GET_CODE (op) == CONST_DOUBLE)
1580 {
1d328b19 1581 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1582 abort ();
1d328b19
GK
1583
1584 opl = CONST_DOUBLE_LOW (op);
1585 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1586 if (oph != 0)
38886f37 1587 return 0;
dfbdccdb
GK
1588 }
1589 else
1590 return 0;
1d328b19 1591
40501e5f
AM
1592 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1593 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1594}
1595
dcfedcd0 1596/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1597 above), but could be split into one. */
dcfedcd0
RK
1598
1599int
1600non_logical_cint_operand (op, mode)
592696dd 1601 rtx op;
5f59ecb7 1602 enum machine_mode mode;
dcfedcd0 1603{
dfbdccdb 1604 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1605 && ! logical_operand (op, mode)
1606 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1607}
1608
19ba8161 1609/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1610 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1611 Reject all ones and all zeros, since these should have been optimized
1612 away and confuse the making of MB and ME. */
1613
1614int
19ba8161 1615mask_operand (op, mode)
592696dd 1616 rtx op;
19ba8161 1617 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1618{
02071907 1619 HOST_WIDE_INT c, lsb;
9878760c 1620
19ba8161
DE
1621 if (GET_CODE (op) != CONST_INT)
1622 return 0;
1623
1624 c = INTVAL (op);
1625
57deb3a1
AM
1626 /* Fail in 64-bit mode if the mask wraps around because the upper
1627 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1628 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1629 return 0;
1630
c5059423
AM
1631 /* We don't change the number of transitions by inverting,
1632 so make sure we start with the LS bit zero. */
1633 if (c & 1)
1634 c = ~c;
1635
1636 /* Reject all zeros or all ones. */
1637 if (c == 0)
9878760c
RK
1638 return 0;
1639
c5059423
AM
1640 /* Find the first transition. */
1641 lsb = c & -c;
1642
1643 /* Invert to look for a second transition. */
1644 c = ~c;
9878760c 1645
c5059423
AM
1646 /* Erase first transition. */
1647 c &= -lsb;
9878760c 1648
c5059423
AM
1649 /* Find the second transition (if any). */
1650 lsb = c & -c;
1651
1652 /* Match if all the bits above are 1's (or c is zero). */
1653 return c == -lsb;
9878760c
RK
1654}
1655
0ba1b2ff
AM
1656/* Return 1 for the PowerPC64 rlwinm corner case. */
1657
1658int
1659mask_operand_wrap (op, mode)
1660 rtx op;
1661 enum machine_mode mode ATTRIBUTE_UNUSED;
1662{
1663 HOST_WIDE_INT c, lsb;
1664
1665 if (GET_CODE (op) != CONST_INT)
1666 return 0;
1667
1668 c = INTVAL (op);
1669
1670 if ((c & 0x80000001) != 0x80000001)
1671 return 0;
1672
1673 c = ~c;
1674 if (c == 0)
1675 return 0;
1676
1677 lsb = c & -c;
1678 c = ~c;
1679 c &= -lsb;
1680 lsb = c & -c;
1681 return c == -lsb;
1682}
1683
a260abc9
DE
1684/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1685 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1686 Reject all zeros, since zero should have been optimized away and
1687 confuses the making of MB and ME. */
9878760c
RK
1688
1689int
a260abc9 1690mask64_operand (op, mode)
592696dd 1691 rtx op;
0ba1b2ff 1692 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1693{
1694 if (GET_CODE (op) == CONST_INT)
1695 {
02071907 1696 HOST_WIDE_INT c, lsb;
a260abc9 1697
c5059423 1698 c = INTVAL (op);
a260abc9 1699
0ba1b2ff 1700 /* Reject all zeros. */
c5059423 1701 if (c == 0)
e2c953b6
DE
1702 return 0;
1703
0ba1b2ff
AM
1704 /* We don't change the number of transitions by inverting,
1705 so make sure we start with the LS bit zero. */
1706 if (c & 1)
1707 c = ~c;
1708
c5059423
AM
1709 /* Find the transition, and check that all bits above are 1's. */
1710 lsb = c & -c;
e3981aab
DE
1711
1712 /* Match if all the bits above are 1's (or c is zero). */
c5059423 1713 return c == -lsb;
e2c953b6 1714 }
0ba1b2ff
AM
1715 return 0;
1716}
1717
1718/* Like mask64_operand, but allow up to three transitions. This
1719 predicate is used by insn patterns that generate two rldicl or
1720 rldicr machine insns. */
1721
1722int
1723mask64_2_operand (op, mode)
1724 rtx op;
1725 enum machine_mode mode ATTRIBUTE_UNUSED;
1726{
1727 if (GET_CODE (op) == CONST_INT)
a260abc9 1728 {
0ba1b2ff 1729 HOST_WIDE_INT c, lsb;
a260abc9 1730
0ba1b2ff 1731 c = INTVAL (op);
a260abc9 1732
0ba1b2ff
AM
1733 /* Disallow all zeros. */
1734 if (c == 0)
1735 return 0;
a260abc9 1736
0ba1b2ff
AM
1737 /* We don't change the number of transitions by inverting,
1738 so make sure we start with the LS bit zero. */
1739 if (c & 1)
1740 c = ~c;
a260abc9 1741
0ba1b2ff
AM
1742 /* Find the first transition. */
1743 lsb = c & -c;
a260abc9 1744
0ba1b2ff
AM
1745 /* Invert to look for a second transition. */
1746 c = ~c;
1747
1748 /* Erase first transition. */
1749 c &= -lsb;
1750
1751 /* Find the second transition. */
1752 lsb = c & -c;
1753
1754 /* Invert to look for a third transition. */
1755 c = ~c;
1756
1757 /* Erase second transition. */
1758 c &= -lsb;
1759
1760 /* Find the third transition (if any). */
1761 lsb = c & -c;
1762
1763 /* Match if all the bits above are 1's (or c is zero). */
1764 return c == -lsb;
1765 }
1766 return 0;
1767}
1768
1769/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1770 implement ANDing by the mask IN. */
1771void
1772build_mask64_2_operands (in, out)
1773 rtx in;
1774 rtx *out;
1775{
1776#if HOST_BITS_PER_WIDE_INT >= 64
1777 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1778 int shift;
1779
1780 if (GET_CODE (in) != CONST_INT)
1781 abort ();
1782
1783 c = INTVAL (in);
1784 if (c & 1)
1785 {
1786 /* Assume c initially something like 0x00fff000000fffff. The idea
1787 is to rotate the word so that the middle ^^^^^^ group of zeros
1788 is at the MS end and can be cleared with an rldicl mask. We then
1789 rotate back and clear off the MS ^^ group of zeros with a
1790 second rldicl. */
1791 c = ~c; /* c == 0xff000ffffff00000 */
1792 lsb = c & -c; /* lsb == 0x0000000000100000 */
1793 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1794 c = ~c; /* c == 0x00fff000000fffff */
1795 c &= -lsb; /* c == 0x00fff00000000000 */
1796 lsb = c & -c; /* lsb == 0x0000100000000000 */
1797 c = ~c; /* c == 0xff000fffffffffff */
1798 c &= -lsb; /* c == 0xff00000000000000 */
1799 shift = 0;
1800 while ((lsb >>= 1) != 0)
1801 shift++; /* shift == 44 on exit from loop */
1802 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1803 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1804 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1805 }
1806 else
0ba1b2ff
AM
1807 {
1808 /* Assume c initially something like 0xff000f0000000000. The idea
1809 is to rotate the word so that the ^^^ middle group of zeros
1810 is at the LS end and can be cleared with an rldicr mask. We then
1811 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1812 a second rldicr. */
1813 lsb = c & -c; /* lsb == 0x0000010000000000 */
1814 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1815 c = ~c; /* c == 0x00fff0ffffffffff */
1816 c &= -lsb; /* c == 0x00fff00000000000 */
1817 lsb = c & -c; /* lsb == 0x0000100000000000 */
1818 c = ~c; /* c == 0xff000fffffffffff */
1819 c &= -lsb; /* c == 0xff00000000000000 */
1820 shift = 0;
1821 while ((lsb >>= 1) != 0)
1822 shift++; /* shift == 44 on exit from loop */
1823 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1824 m1 >>= shift; /* m1 == 0x0000000000000fff */
1825 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1826 }
1827
1828 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1829 masks will be all 1's. We are guaranteed more than one transition. */
1830 out[0] = GEN_INT (64 - shift);
1831 out[1] = GEN_INT (m1);
1832 out[2] = GEN_INT (shift);
1833 out[3] = GEN_INT (m2);
1834#else
045572c7
GK
1835 (void)in;
1836 (void)out;
0ba1b2ff
AM
1837 abort ();
1838#endif
a260abc9
DE
1839}
1840
1841/* Return 1 if the operand is either a non-special register or a constant
1842 that can be used as the operand of a PowerPC64 logical AND insn. */
1843
1844int
1845and64_operand (op, mode)
592696dd 1846 rtx op;
9878760c
RK
1847 enum machine_mode mode;
1848{
a4f6c312 1849 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1850 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1851
1852 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1853}
1854
0ba1b2ff
AM
1855/* Like the above, but also match constants that can be implemented
1856 with two rldicl or rldicr insns. */
1857
1858int
1859and64_2_operand (op, mode)
1860 rtx op;
1861 enum machine_mode mode;
1862{
1863 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1864 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1865
1866 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1867}
1868
a260abc9
DE
1869/* Return 1 if the operand is either a non-special register or a
1870 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
1871
1872int
a260abc9 1873and_operand (op, mode)
592696dd 1874 rtx op;
a260abc9 1875 enum machine_mode mode;
dcfedcd0 1876{
a4f6c312 1877 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1878 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
1879
1880 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
1881}
1882
9878760c
RK
1883/* Return 1 if the operand is a general register or memory operand. */
1884
1885int
1886reg_or_mem_operand (op, mode)
592696dd
SS
1887 rtx op;
1888 enum machine_mode mode;
9878760c 1889{
b6c9286a
MM
1890 return (gpc_reg_operand (op, mode)
1891 || memory_operand (op, mode)
1892 || volatile_mem_operand (op, mode));
9878760c
RK
1893}
1894
a7a813f7 1895/* Return 1 if the operand is a general register or memory operand without
3cb999d8 1896 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
1897 instruction. */
1898
1899int
1900lwa_operand (op, mode)
592696dd
SS
1901 rtx op;
1902 enum machine_mode mode;
a7a813f7
RK
1903{
1904 rtx inner = op;
1905
1906 if (reload_completed && GET_CODE (inner) == SUBREG)
1907 inner = SUBREG_REG (inner);
1908
1909 return gpc_reg_operand (inner, mode)
1910 || (memory_operand (inner, mode)
1911 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
1912 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
1913 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
1914 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
1915 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
1916}
1917
cc4d5fec
JH
1918/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
1919
1920int
1921symbol_ref_operand (op, mode)
1922 rtx op;
1923 enum machine_mode mode;
1924{
1925 if (mode != VOIDmode && GET_MODE (op) != mode)
1926 return 0;
1927
1928 return (GET_CODE (op) == SYMBOL_REF);
1929}
1930
9878760c 1931/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 1932 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
1933
1934int
1935call_operand (op, mode)
592696dd 1936 rtx op;
9878760c
RK
1937 enum machine_mode mode;
1938{
1939 if (mode != VOIDmode && GET_MODE (op) != mode)
1940 return 0;
1941
1942 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
1943 || (GET_CODE (op) == REG
1944 && (REGNO (op) == LINK_REGISTER_REGNUM
1945 || REGNO (op) == COUNT_REGISTER_REGNUM
1946 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
1947}
1948
2af3d377 1949/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 1950 this file and the function is not weakly defined. */
2af3d377
RK
1951
1952int
1953current_file_function_operand (op, mode)
592696dd 1954 rtx op;
296b8152 1955 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
1956{
1957 return (GET_CODE (op) == SYMBOL_REF
1958 && (SYMBOL_REF_FLAG (op)
8f1b829e 1959 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 1960 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
1961}
1962
9878760c
RK
1963/* Return 1 if this operand is a valid input for a move insn. */
1964
1965int
1966input_operand (op, mode)
592696dd 1967 rtx op;
9878760c
RK
1968 enum machine_mode mode;
1969{
eb4e8003 1970 /* Memory is always valid. */
9878760c
RK
1971 if (memory_operand (op, mode))
1972 return 1;
1973
34792e82 1974 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 1975 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
1976 return 1;
1977
eb4e8003
RK
1978 /* For floating-point, easy constants are valid. */
1979 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1980 && CONSTANT_P (op)
1981 && easy_fp_constant (op, mode))
1982 return 1;
1983
4e74d8ec
MM
1984 /* Allow any integer constant. */
1985 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 1986 && (GET_CODE (op) == CONST_INT
e675f625 1987 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
1988 return 1;
1989
eb4e8003
RK
1990 /* For floating-point or multi-word mode, the only remaining valid type
1991 is a register. */
9878760c
RK
1992 if (GET_MODE_CLASS (mode) == MODE_FLOAT
1993 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 1994 return register_operand (op, mode);
9878760c 1995
88fe15a1
RK
1996 /* The only cases left are integral modes one word or smaller (we
1997 do not get called for MODE_CC values). These can be in any
1998 register. */
1999 if (register_operand (op, mode))
a8b3aeda 2000 return 1;
88fe15a1 2001
84cf9dda 2002 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 2003 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
2004 return 1;
2005
9ebbca7d
GK
2006 /* A constant pool expression (relative to the TOC) is valid */
2007 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
2008 return 1;
2009
88228c4b
MM
2010 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
2011 to be valid. */
f607bc57 2012 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
2013 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
2014 && small_data_operand (op, Pmode))
2015 return 1;
2016
042259f2 2017 return 0;
9878760c 2018}
7509c759 2019
a4f6c312 2020/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
2021
2022int
2023small_data_operand (op, mode)
296b8152
KG
2024 rtx op ATTRIBUTE_UNUSED;
2025 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 2026{
38c1f2d7 2027#if TARGET_ELF
5f59ecb7 2028 rtx sym_ref;
7509c759 2029
d9407988 2030 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 2031 return 0;
a54d04b7 2032
f607bc57 2033 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
2034 return 0;
2035
88228c4b
MM
2036 if (GET_CODE (op) == SYMBOL_REF)
2037 sym_ref = op;
2038
2039 else if (GET_CODE (op) != CONST
2040 || GET_CODE (XEXP (op, 0)) != PLUS
2041 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2042 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
2043 return 0;
2044
88228c4b 2045 else
dbf55e53
MM
2046 {
2047 rtx sum = XEXP (op, 0);
2048 HOST_WIDE_INT summand;
2049
2050 /* We have to be careful here, because it is the referenced address
2051 that must be 32k from _SDA_BASE_, not just the symbol. */
2052 summand = INTVAL (XEXP (sum, 1));
2053 if (summand < 0 || summand > g_switch_value)
2054 return 0;
2055
2056 sym_ref = XEXP (sum, 0);
2057 }
88228c4b
MM
2058
2059 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
2060 return 0;
2061
2062 return 1;
d9407988
MM
2063
2064#else
2065 return 0;
2066#endif
7509c759 2067}
9ebbca7d
GK
2068\f
2069static int
2070constant_pool_expr_1 (op, have_sym, have_toc)
2071 rtx op;
2072 int *have_sym;
2073 int *have_toc;
2074{
2075 switch (GET_CODE(op))
2076 {
2077 case SYMBOL_REF:
a4f6c312
SS
2078 if (CONSTANT_POOL_ADDRESS_P (op))
2079 {
2080 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2081 {
2082 *have_sym = 1;
2083 return 1;
2084 }
2085 else
2086 return 0;
2087 }
2088 else if (! strcmp (XSTR (op, 0), toc_label_name))
2089 {
2090 *have_toc = 1;
2091 return 1;
2092 }
2093 else
2094 return 0;
9ebbca7d
GK
2095 case PLUS:
2096 case MINUS:
c1f11548
DE
2097 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2098 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2099 case CONST:
a4f6c312 2100 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2101 case CONST_INT:
a4f6c312 2102 return 1;
9ebbca7d 2103 default:
a4f6c312 2104 return 0;
9ebbca7d
GK
2105 }
2106}
2107
2108int
2109constant_pool_expr_p (op)
2110 rtx op;
2111{
2112 int have_sym = 0;
2113 int have_toc = 0;
2114 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2115}
2116
2117int
2118toc_relative_expr_p (op)
2119 rtx op;
2120{
2121 int have_sym = 0;
2122 int have_toc = 0;
2123 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2124}
2125
2126/* Try machine-dependent ways of modifying an illegitimate address
2127 to be legitimate. If we find one, return the new, valid address.
2128 This is used from only one place: `memory_address' in explow.c.
2129
a4f6c312
SS
2130 OLDX is the address as it was before break_out_memory_refs was
2131 called. In some cases it is useful to look at this to decide what
2132 needs to be done.
9ebbca7d 2133
a4f6c312 2134 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2135
a4f6c312
SS
2136 It is always safe for this function to do nothing. It exists to
2137 recognize opportunities to optimize the output.
9ebbca7d
GK
2138
2139 On RS/6000, first check for the sum of a register with a constant
2140 integer that is out of range. If so, generate code to add the
2141 constant with the low-order 16 bits masked to the register and force
2142 this result into another register (this can be done with `cau').
2143 Then generate an address of REG+(CONST&0xffff), allowing for the
2144 possibility of bit 16 being a one.
2145
2146 Then check for the sum of a register and something not constant, try to
2147 load the other things into a register and return the sum. */
2148rtx
2149rs6000_legitimize_address (x, oldx, mode)
2150 rtx x;
2151 rtx oldx ATTRIBUTE_UNUSED;
2152 enum machine_mode mode;
0ac081f6 2153{
9ebbca7d
GK
2154 if (GET_CODE (x) == PLUS
2155 && GET_CODE (XEXP (x, 0)) == REG
2156 && GET_CODE (XEXP (x, 1)) == CONST_INT
2157 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2158 {
2159 HOST_WIDE_INT high_int, low_int;
2160 rtx sum;
a65c591c
DE
2161 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2162 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2163 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2164 GEN_INT (high_int)), 0);
2165 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2166 }
2167 else if (GET_CODE (x) == PLUS
2168 && GET_CODE (XEXP (x, 0)) == REG
2169 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2170 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2171 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2172 || TARGET_POWERPC64
fcce224d 2173 || (mode != DFmode && mode != TFmode))
9ebbca7d
GK
2174 && (TARGET_POWERPC64 || mode != DImode)
2175 && mode != TImode)
2176 {
2177 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2178 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2179 }
0ac081f6
AH
2180 else if (ALTIVEC_VECTOR_MODE (mode))
2181 {
2182 rtx reg;
2183
2184 /* Make sure both operands are registers. */
2185 if (GET_CODE (x) == PLUS)
9f85ed45 2186 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2187 force_reg (Pmode, XEXP (x, 1)));
2188
2189 reg = force_reg (Pmode, x);
2190 return reg;
2191 }
a3170dc6
AH
2192 else if (SPE_VECTOR_MODE (mode))
2193 {
2194 /* We accept [reg + reg] and [reg + OFFSET]. */
2195
2196 if (GET_CODE (x) == PLUS)
2197 {
2198 rtx op1 = XEXP (x, 0);
2199 rtx op2 = XEXP (x, 1);
2200
2201 op1 = force_reg (Pmode, op1);
2202
2203 if (GET_CODE (op2) != REG
2204 && (GET_CODE (op2) != CONST_INT
2205 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2206 op2 = force_reg (Pmode, op2);
2207
2208 return gen_rtx_PLUS (Pmode, op1, op2);
2209 }
2210
2211 return force_reg (Pmode, x);
2212 }
9ebbca7d
GK
2213 else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
2214 && GET_CODE (x) != CONST_INT
2215 && GET_CODE (x) != CONST_DOUBLE
2216 && CONSTANT_P (x)
6ac7bf2c
GK
2217 && GET_MODE_NUNITS (mode) == 1
2218 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2219 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2220 {
2221 rtx reg = gen_reg_rtx (Pmode);
2222 emit_insn (gen_elf_high (reg, (x)));
2223 return gen_rtx_LO_SUM (Pmode, reg, (x));
2224 }
ee890fe2
SS
2225 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2226 && ! flag_pic
ab82a49f
AP
2227#if TARGET_MACHO
2228 && ! MACHO_DYNAMIC_NO_PIC_P
2229#endif
ee890fe2
SS
2230 && GET_CODE (x) != CONST_INT
2231 && GET_CODE (x) != CONST_DOUBLE
2232 && CONSTANT_P (x)
a3170dc6 2233 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2234 && mode != DImode
2235 && mode != TImode)
2236 {
2237 rtx reg = gen_reg_rtx (Pmode);
2238 emit_insn (gen_macho_high (reg, (x)));
2239 return gen_rtx_LO_SUM (Pmode, reg, (x));
2240 }
9ebbca7d
GK
2241 else if (TARGET_TOC
2242 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2243 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2244 {
2245 return create_TOC_reference (x);
2246 }
2247 else
2248 return NULL_RTX;
2249}
258bfae2 2250
24ea750e
DJ
2251/* The convention appears to be to define this wherever it is used.
2252 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2253 is now used here. */
2254#ifndef REG_MODE_OK_FOR_BASE_P
2255#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2256#endif
2257
2258/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2259 replace the input X, or the original X if no replacement is called for.
2260 The output parameter *WIN is 1 if the calling macro should goto WIN,
2261 0 if it should not.
2262
2263 For RS/6000, we wish to handle large displacements off a base
2264 register by splitting the addend across an addiu/addis and the mem insn.
2265 This cuts number of extra insns needed from 3 to 1.
2266
2267 On Darwin, we use this to generate code for floating point constants.
2268 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2269 The Darwin code is inside #if TARGET_MACHO because only then is
2270 machopic_function_base_name() defined. */
2271rtx
2272rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2273 rtx x;
2274 enum machine_mode mode;
2275 int opnum;
2276 int type;
2277 int ind_levels ATTRIBUTE_UNUSED;
2278 int *win;
2279{
2280 /* We must recognize output that we have already generated ourselves. */
2281 if (GET_CODE (x) == PLUS
2282 && GET_CODE (XEXP (x, 0)) == PLUS
2283 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2284 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2285 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2286 {
2287 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2288 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2289 opnum, (enum reload_type)type);
2290 *win = 1;
2291 return x;
2292 }
3deb2758 2293
24ea750e
DJ
2294#if TARGET_MACHO
2295 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2296 && GET_CODE (x) == LO_SUM
2297 && GET_CODE (XEXP (x, 0)) == PLUS
2298 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2299 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2300 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2301 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2302 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2303 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2304 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2305 {
2306 /* Result of previous invocation of this function on Darwin
6f317ef3 2307 floating point constant. */
24ea750e
DJ
2308 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2309 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2310 opnum, (enum reload_type)type);
2311 *win = 1;
2312 return x;
2313 }
2314#endif
2315 if (GET_CODE (x) == PLUS
2316 && GET_CODE (XEXP (x, 0)) == REG
2317 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2318 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2319 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 2320 && !SPE_VECTOR_MODE (mode)
78c875e8 2321 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2322 {
2323 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2324 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2325 HOST_WIDE_INT high
2326 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2327
2328 /* Check for 32-bit overflow. */
2329 if (high + low != val)
2330 {
2331 *win = 0;
2332 return x;
2333 }
2334
2335 /* Reload the high part into a base reg; leave the low part
2336 in the mem directly. */
2337
2338 x = gen_rtx_PLUS (GET_MODE (x),
2339 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2340 GEN_INT (high)),
2341 GEN_INT (low));
2342
2343 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2344 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2345 opnum, (enum reload_type)type);
2346 *win = 1;
2347 return x;
2348 }
2349#if TARGET_MACHO
2350 if (GET_CODE (x) == SYMBOL_REF
2351 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2352 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2353 && flag_pic)
2354 {
2355 /* Darwin load of floating point constant. */
2356 rtx offset = gen_rtx (CONST, Pmode,
2357 gen_rtx (MINUS, Pmode, x,
2358 gen_rtx (SYMBOL_REF, Pmode,
2359 machopic_function_base_name ())));
2360 x = gen_rtx (LO_SUM, GET_MODE (x),
2361 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2362 gen_rtx (HIGH, Pmode, offset)), offset);
2363 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2364 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2365 opnum, (enum reload_type)type);
2366 *win = 1;
2367 return x;
2368 }
ab82a49f
AP
2369 if (GET_CODE (x) == SYMBOL_REF
2370 && DEFAULT_ABI == ABI_DARWIN
2371 && !ALTIVEC_VECTOR_MODE (mode)
2372 && MACHO_DYNAMIC_NO_PIC_P)
2373 {
2374 /* Darwin load of floating point constant. */
2375 x = gen_rtx (LO_SUM, GET_MODE (x),
2376 gen_rtx (HIGH, Pmode, x), x);
2377 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2378 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2379 opnum, (enum reload_type)type);
2380 *win = 1;
2381 return x;
2382 }
24ea750e
DJ
2383#endif
2384 if (TARGET_TOC
c1f11548
DE
2385 && CONSTANT_POOL_EXPR_P (x)
2386 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2387 {
2388 (x) = create_TOC_reference (x);
2389 *win = 1;
2390 return x;
2391 }
2392 *win = 0;
2393 return x;
2394}
2395
258bfae2
FS
2396/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2397 that is a valid memory address for an instruction.
2398 The MODE argument is the machine mode for the MEM expression
2399 that wants to use this address.
2400
2401 On the RS/6000, there are four valid address: a SYMBOL_REF that
2402 refers to a constant pool entry of an address (or the sum of it
2403 plus a constant), a short (16-bit signed) constant plus a register,
2404 the sum of two registers, or a register indirect, possibly with an
5bdc5878 2405 auto-increment. For DFmode and DImode with a constant plus register,
258bfae2
FS
2406 we must ensure that both words are addressable or PowerPC64 with offset
2407 word aligned.
2408
2409 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2410 32-bit DImode, TImode), indexed addressing cannot be used because
2411 adjacent memory cells are accessed by adding word-sized offsets
2412 during assembly output. */
2413int
2414rs6000_legitimate_address (mode, x, reg_ok_strict)
2415 enum machine_mode mode;
2416 rtx x;
2417 int reg_ok_strict;
2418{
2419 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2420 return 1;
2421 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2422 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2423 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2424 && TARGET_UPDATE
2425 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2426 return 1;
2427 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2428 return 1;
2429 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2430 return 1;
2431 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2432 if (! reg_ok_strict
2433 && GET_CODE (x) == PLUS
2434 && GET_CODE (XEXP (x, 0)) == REG
2435 && XEXP (x, 0) == virtual_stack_vars_rtx
2436 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2437 return 1;
2438 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2439 return 1;
2440 if (mode != TImode
a3170dc6
AH
2441 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2442 || TARGET_POWERPC64
fcce224d 2443 || (mode != DFmode && mode != TFmode))
258bfae2
FS
2444 && (TARGET_POWERPC64 || mode != DImode)
2445 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2446 return 1;
2447 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2448 return 1;
2449 return 0;
2450}
fb4d4348 2451\f
a4f6c312
SS
2452/* Try to output insns to set TARGET equal to the constant C if it can
2453 be done in less than N insns. Do all computations in MODE.
2454 Returns the place where the output has been placed if it can be
2455 done and the insns have been emitted. If it would take more than N
2456 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2457
2458rtx
2459rs6000_emit_set_const (dest, mode, source, n)
2460 rtx dest, source;
2461 enum machine_mode mode;
2462 int n ATTRIBUTE_UNUSED;
2463{
af8cb5c5 2464 rtx result, insn, set;
2bfcf297
DB
2465 HOST_WIDE_INT c0, c1;
2466
af8cb5c5 2467 if (mode == QImode || mode == HImode)
2bfcf297
DB
2468 {
2469 if (dest == NULL)
2470 dest = gen_reg_rtx (mode);
2471 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2472 return dest;
2473 }
af8cb5c5 2474 else if (mode == SImode)
2bfcf297 2475 {
af8cb5c5
DE
2476 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2477
2478 emit_insn (gen_rtx_SET (VOIDmode, result,
2479 GEN_INT (INTVAL (source)
2480 & (~ (HOST_WIDE_INT) 0xffff))));
2481 emit_insn (gen_rtx_SET (VOIDmode, dest,
2482 gen_rtx_IOR (SImode, result,
2483 GEN_INT (INTVAL (source) & 0xffff))));
2484 result = dest;
2bfcf297 2485 }
af8cb5c5 2486 else if (mode == DImode)
2bfcf297 2487 {
af8cb5c5
DE
2488 if (GET_CODE (source) == CONST_INT)
2489 {
2490 c0 = INTVAL (source);
2491 c1 = -(c0 < 0);
2492 }
2493 else if (GET_CODE (source) == CONST_DOUBLE)
2494 {
2bfcf297 2495#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
2496 c0 = CONST_DOUBLE_LOW (source);
2497 c1 = -(c0 < 0);
2bfcf297 2498#else
af8cb5c5
DE
2499 c0 = CONST_DOUBLE_LOW (source);
2500 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 2501#endif
af8cb5c5
DE
2502 }
2503 else
2504 abort ();
2505
2506 result = rs6000_emit_set_long_const (dest, c0, c1);
2bfcf297
DB
2507 }
2508 else
a4f6c312 2509 abort ();
2bfcf297 2510
af8cb5c5
DE
2511 insn = get_last_insn ();
2512 set = single_set (insn);
2513 if (! CONSTANT_P (SET_SRC (set)))
2514 set_unique_reg_note (insn, REG_EQUAL, source);
2515
2516 return result;
2bfcf297
DB
2517}
2518
2519/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2520 fall back to a straight forward decomposition. We do this to avoid
2521 exponential run times encountered when looking for longer sequences
2522 with rs6000_emit_set_const. */
2523static rtx
2524rs6000_emit_set_long_const (dest, c1, c2)
2525 rtx dest;
2526 HOST_WIDE_INT c1, c2;
2527{
2528 if (!TARGET_POWERPC64)
2529 {
2530 rtx operand1, operand2;
2531
2532 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2533 DImode);
2534 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2535 DImode);
2536 emit_move_insn (operand1, GEN_INT (c1));
2537 emit_move_insn (operand2, GEN_INT (c2));
2538 }
2539 else
2540 {
bc06712d 2541 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2542
bc06712d
TR
2543 ud1 = c1 & 0xffff;
2544 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2545#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2546 c2 = c1 >> 32;
2bfcf297 2547#endif
bc06712d
TR
2548 ud3 = c2 & 0xffff;
2549 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2550
bc06712d
TR
2551 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2552 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2553 {
bc06712d
TR
2554 if (ud1 & 0x8000)
2555 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2556 else
2557 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2558 }
2bfcf297 2559
bc06712d
TR
2560 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2561 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2562 {
bc06712d
TR
2563 if (ud2 & 0x8000)
2564 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2565 - 0x80000000));
252b88f7 2566 else
bc06712d
TR
2567 emit_move_insn (dest, GEN_INT (ud2 << 16));
2568 if (ud1 != 0)
2569 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2570 }
bc06712d
TR
2571 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2572 || (ud4 == 0 && ! (ud3 & 0x8000)))
2573 {
2574 if (ud3 & 0x8000)
2575 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2576 - 0x80000000));
2577 else
2578 emit_move_insn (dest, GEN_INT (ud3 << 16));
2579
2580 if (ud2 != 0)
2581 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2582 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2583 if (ud1 != 0)
2584 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2585 }
2586 else
2587 {
2588 if (ud4 & 0x8000)
2589 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2590 - 0x80000000));
2591 else
2592 emit_move_insn (dest, GEN_INT (ud4 << 16));
2593
2594 if (ud3 != 0)
2595 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2596
bc06712d
TR
2597 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2598 if (ud2 != 0)
2599 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2600 GEN_INT (ud2 << 16)));
2601 if (ud1 != 0)
2602 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2603 }
2604 }
2bfcf297
DB
2605 return dest;
2606}
2607
fb4d4348
GK
2608/* Emit a move from SOURCE to DEST in mode MODE. */
2609void
2610rs6000_emit_move (dest, source, mode)
2611 rtx dest;
2612 rtx source;
2613 enum machine_mode mode;
2614{
2615 rtx operands[2];
2616 operands[0] = dest;
2617 operands[1] = source;
2618
2619 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2620 if (GET_CODE (operands[1]) == CONST_DOUBLE
2621 && ! FLOAT_MODE_P (mode)
2622 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2623 {
2624 /* FIXME. This should never happen. */
2625 /* Since it seems that it does, do the safe thing and convert
2626 to a CONST_INT. */
2496c7bd 2627 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2628 }
2629 if (GET_CODE (operands[1]) == CONST_DOUBLE
2630 && ! FLOAT_MODE_P (mode)
2631 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2632 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2633 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2634 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2635 abort ();
c9e8cb32
DD
2636
2637 /* Check if GCC is setting up a block move that will end up using FP
2638 registers as temporaries. We must make sure this is acceptable. */
2639 if (GET_CODE (operands[0]) == MEM
2640 && GET_CODE (operands[1]) == MEM
2641 && mode == DImode
41543739
GK
2642 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2643 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2644 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2645 ? 32 : MEM_ALIGN (operands[0])))
2646 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2647 ? 32
2648 : MEM_ALIGN (operands[1]))))
2649 && ! MEM_VOLATILE_P (operands [0])
2650 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2651 {
41543739
GK
2652 emit_move_insn (adjust_address (operands[0], SImode, 0),
2653 adjust_address (operands[1], SImode, 0));
2654 emit_move_insn (adjust_address (operands[0], SImode, 4),
2655 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2656 return;
2657 }
fb4d4348 2658
67cef334
DE
2659 if (!no_new_pseudos)
2660 {
2661 if (GET_CODE (operands[1]) == MEM && optimize > 0
2662 && (mode == QImode || mode == HImode || mode == SImode)
2663 && GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
2664 {
2665 rtx reg = gen_reg_rtx (word_mode);
2666
2667 emit_insn (gen_rtx_SET (word_mode, reg,
2668 gen_rtx_ZERO_EXTEND (word_mode,
2669 operands[1])));
2670 operands[1] = gen_lowpart (mode, reg);
2671 }
2672 if (GET_CODE (operands[0]) != REG)
2673 operands[1] = force_reg (mode, operands[1]);
2674 }
a9098fd0 2675
a3170dc6
AH
2676 if (mode == SFmode && ! TARGET_POWERPC
2677 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2678 && GET_CODE (operands[0]) == MEM)
fb4d4348 2679 {
ffc14f31
GK
2680 int regnum;
2681
2682 if (reload_in_progress || reload_completed)
2683 regnum = true_regnum (operands[1]);
2684 else if (GET_CODE (operands[1]) == REG)
2685 regnum = REGNO (operands[1]);
2686 else
2687 regnum = -1;
fb4d4348
GK
2688
2689 /* If operands[1] is a register, on POWER it may have
2690 double-precision data in it, so truncate it to single
2691 precision. */
2692 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2693 {
2694 rtx newreg;
2695 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2696 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2697 operands[1] = newreg;
2698 }
2699 }
2700
a9098fd0
GK
2701 /* Handle the case where reload calls us with an invalid address;
2702 and the case of CONSTANT_P_RTX. */
16861f33 2703 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2704 && (! general_operand (operands[1], mode)
2705 || ! nonimmediate_operand (operands[0], mode)
2706 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2707 {
2708 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2709 return;
2710 }
a9098fd0 2711
fb4d4348
GK
2712 /* FIXME: In the long term, this switch statement should go away
2713 and be replaced by a sequence of tests based on things like
2714 mode == Pmode. */
2715 switch (mode)
2716 {
2717 case HImode:
2718 case QImode:
2719 if (CONSTANT_P (operands[1])
2720 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2721 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2722 break;
2723
06f4e019 2724 case TFmode:
fb4d4348
GK
2725 case DFmode:
2726 case SFmode:
2727 if (CONSTANT_P (operands[1])
2728 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2729 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2730 break;
2731
0ac081f6
AH
2732 case V16QImode:
2733 case V8HImode:
2734 case V4SFmode:
2735 case V4SImode:
a3170dc6
AH
2736 case V4HImode:
2737 case V2SFmode:
2738 case V2SImode:
00a892b8 2739 case V1DImode:
69ef87e2
AH
2740 if (CONSTANT_P (operands[1])
2741 && !easy_vector_constant (operands[1]))
0ac081f6
AH
2742 operands[1] = force_const_mem (mode, operands[1]);
2743 break;
2744
fb4d4348 2745 case SImode:
a9098fd0 2746 case DImode:
fb4d4348
GK
2747 /* Use default pattern for address of ELF small data */
2748 if (TARGET_ELF
a9098fd0 2749 && mode == Pmode
f607bc57 2750 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2751 && (GET_CODE (operands[1]) == SYMBOL_REF
2752 || GET_CODE (operands[1]) == CONST)
2753 && small_data_operand (operands[1], mode))
fb4d4348
GK
2754 {
2755 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2756 return;
2757 }
2758
f607bc57 2759 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2760 && mode == Pmode && mode == SImode
2761 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2762 {
2763 emit_insn (gen_movsi_got (operands[0], operands[1]));
2764 return;
2765 }
2766
ee890fe2
SS
2767 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
2768 && TARGET_NO_TOC && ! flag_pic
a9098fd0 2769 && mode == Pmode
fb4d4348
GK
2770 && CONSTANT_P (operands[1])
2771 && GET_CODE (operands[1]) != HIGH
2772 && GET_CODE (operands[1]) != CONST_INT)
2773 {
a9098fd0 2774 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2775
2776 /* If this is a function address on -mcall-aixdesc,
2777 convert it to the address of the descriptor. */
2778 if (DEFAULT_ABI == ABI_AIX
2779 && GET_CODE (operands[1]) == SYMBOL_REF
2780 && XSTR (operands[1], 0)[0] == '.')
2781 {
2782 const char *name = XSTR (operands[1], 0);
2783 rtx new_ref;
2784 while (*name == '.')
2785 name++;
2786 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2787 CONSTANT_POOL_ADDRESS_P (new_ref)
2788 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2789 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2790 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2791 operands[1] = new_ref;
2792 }
7509c759 2793
ee890fe2
SS
2794 if (DEFAULT_ABI == ABI_DARWIN)
2795 {
ab82a49f
AP
2796#if TARGET_MACHO
2797 if (MACHO_DYNAMIC_NO_PIC_P)
2798 {
2799 /* Take care of any required data indirection. */
2800 operands[1] = rs6000_machopic_legitimize_pic_address (
2801 operands[1], mode, operands[0]);
2802 if (operands[0] != operands[1])
2803 emit_insn (gen_rtx_SET (VOIDmode,
2804 operands[0], operands[1]));
2805 return;
2806 }
2807#endif
ee890fe2
SS
2808 emit_insn (gen_macho_high (target, operands[1]));
2809 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2810 return;
2811 }
2812
fb4d4348
GK
2813 emit_insn (gen_elf_high (target, operands[1]));
2814 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2815 return;
2816 }
2817
a9098fd0
GK
2818 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2819 and we have put it in the TOC, we just need to make a TOC-relative
2820 reference to it. */
2821 if (TARGET_TOC
2822 && GET_CODE (operands[1]) == SYMBOL_REF
2823 && CONSTANT_POOL_EXPR_P (operands[1])
2824 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2825 get_pool_mode (operands[1])))
fb4d4348 2826 {
a9098fd0 2827 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2828 }
a9098fd0
GK
2829 else if (mode == Pmode
2830 && CONSTANT_P (operands[1])
38886f37
AO
2831 && ((GET_CODE (operands[1]) != CONST_INT
2832 && ! easy_fp_constant (operands[1], mode))
2833 || (GET_CODE (operands[1]) == CONST_INT
2834 && num_insns_constant (operands[1], mode) > 2)
2835 || (GET_CODE (operands[0]) == REG
2836 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2837 && GET_CODE (operands[1]) != HIGH
2838 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2839 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2840 {
2841 /* Emit a USE operation so that the constant isn't deleted if
2842 expensive optimizations are turned on because nobody
2843 references it. This should only be done for operands that
2844 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2845 This should not be done for operands that contain LABEL_REFs.
2846 For now, we just handle the obvious case. */
2847 if (GET_CODE (operands[1]) != LABEL_REF)
2848 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2849
c859cda6 2850#if TARGET_MACHO
ee890fe2 2851 /* Darwin uses a special PIC legitimizer. */
ab82a49f 2852 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
ee890fe2 2853 {
ee890fe2
SS
2854 operands[1] =
2855 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2856 operands[0]);
2857 if (operands[0] != operands[1])
2858 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
2859 return;
2860 }
c859cda6 2861#endif
ee890fe2 2862
fb4d4348
GK
2863 /* If we are to limit the number of things we put in the TOC and
2864 this is a symbol plus a constant we can add in one insn,
2865 just put the symbol in the TOC and add the constant. Don't do
2866 this if reload is in progress. */
2867 if (GET_CODE (operands[1]) == CONST
2868 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
2869 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 2870 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
2871 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
2872 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
2873 && ! side_effects_p (operands[0]))
2874 {
a4f6c312
SS
2875 rtx sym =
2876 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
2877 rtx other = XEXP (XEXP (operands[1], 0), 1);
2878
a9098fd0
GK
2879 sym = force_reg (mode, sym);
2880 if (mode == SImode)
2881 emit_insn (gen_addsi3 (operands[0], sym, other));
2882 else
2883 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
2884 return;
2885 }
2886
a9098fd0 2887 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2888
2889 if (TARGET_TOC
d34c5b80
DE
2890 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
2891 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
2892 get_pool_constant (XEXP (operands[1], 0)),
2893 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 2894 {
ba4828e0
RK
2895 operands[1]
2896 = gen_rtx_MEM (mode,
2897 create_TOC_reference (XEXP (operands[1], 0)));
2898 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 2899 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 2900 }
fb4d4348
GK
2901 }
2902 break;
a9098fd0 2903
fb4d4348
GK
2904 case TImode:
2905 if (GET_CODE (operands[0]) == MEM
2906 && GET_CODE (XEXP (operands[0], 0)) != REG
2907 && ! reload_in_progress)
792760b9
RK
2908 operands[0]
2909 = replace_equiv_address (operands[0],
2910 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
2911
2912 if (GET_CODE (operands[1]) == MEM
2913 && GET_CODE (XEXP (operands[1], 0)) != REG
2914 && ! reload_in_progress)
792760b9
RK
2915 operands[1]
2916 = replace_equiv_address (operands[1],
2917 copy_addr_to_reg (XEXP (operands[1], 0)));
27dc0551
DE
2918 if (TARGET_POWER)
2919 {
2920 emit_insn (gen_rtx_PARALLEL (VOIDmode,
2921 gen_rtvec (2,
2922 gen_rtx_SET (VOIDmode,
2923 operands[0], operands[1]),
2924 gen_rtx_CLOBBER (VOIDmode,
2925 gen_rtx_SCRATCH (SImode)))));
2926 return;
2927 }
fb4d4348
GK
2928 break;
2929
2930 default:
2931 abort ();
2932 }
2933
a9098fd0
GK
2934 /* Above, we may have called force_const_mem which may have returned
2935 an invalid address. If we can, fix this up; otherwise, reload will
2936 have to deal with it. */
2937 if (GET_CODE (operands[1]) == MEM
2938 && ! memory_address_p (mode, XEXP (operands[1], 0))
2939 && ! reload_in_progress)
f4ef873c 2940 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 2941
fb4d4348 2942 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 2943 return;
fb4d4348 2944}
4697a36c
MM
2945\f
2946/* Initialize a variable CUM of type CUMULATIVE_ARGS
2947 for a call to a function whose data type is FNTYPE.
2948 For a library call, FNTYPE is 0.
2949
2950 For incoming args we set the number of arguments in the prototype large
1c20ae99 2951 so we never return a PARALLEL. */
4697a36c
MM
2952
2953void
2954init_cumulative_args (cum, fntype, libname, incoming)
2955 CUMULATIVE_ARGS *cum;
2956 tree fntype;
296b8152 2957 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
2958 int incoming;
2959{
2960 static CUMULATIVE_ARGS zero_cumulative;
2961
2962 *cum = zero_cumulative;
2963 cum->words = 0;
2964 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 2965 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 2966 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 2967 cum->call_cookie = CALL_NORMAL;
4cc833b7 2968 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
2969
2970 if (incoming)
bd227acc 2971 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
2972
2973 else if (cum->prototype)
2974 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
2975 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
2976 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
2977
2978 else
2979 cum->nargs_prototype = 0;
2980
2981 cum->orig_nargs = cum->nargs_prototype;
7509c759 2982
a5c76ee6
ZW
2983 /* Check for a longcall attribute. */
2984 if (fntype
2985 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
2986 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
2987 cum->call_cookie = CALL_LONG;
2988
4697a36c
MM
2989 if (TARGET_DEBUG_ARG)
2990 {
2991 fprintf (stderr, "\ninit_cumulative_args:");
2992 if (fntype)
2993 {
2994 tree ret_type = TREE_TYPE (fntype);
2995 fprintf (stderr, " ret code = %s,",
2996 tree_code_name[ (int)TREE_CODE (ret_type) ]);
2997 }
2998
6a4cee5f
MM
2999 if (cum->call_cookie & CALL_LONG)
3000 fprintf (stderr, " longcall,");
3001
4697a36c
MM
3002 fprintf (stderr, " proto = %d, nargs = %d\n",
3003 cum->prototype, cum->nargs_prototype);
3004 }
3005}
3006\f
c229cba9
DE
3007/* If defined, a C expression which determines whether, and in which
3008 direction, to pad out an argument with extra space. The value
3009 should be of type `enum direction': either `upward' to pad above
3010 the argument, `downward' to pad below, or `none' to inhibit
3011 padding.
3012
3013 For the AIX ABI structs are always stored left shifted in their
3014 argument slot. */
3015
9ebbca7d 3016enum direction
c229cba9
DE
3017function_arg_padding (mode, type)
3018 enum machine_mode mode;
3019 tree type;
3020{
c85f7c16 3021 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 3022 return upward;
c229cba9
DE
3023
3024 /* This is the default definition. */
3025 return (! BYTES_BIG_ENDIAN
9ebbca7d 3026 ? upward
c229cba9
DE
3027 : ((mode == BLKmode
3028 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
3029 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
3030 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 3031 ? downward : upward));
c229cba9
DE
3032}
3033
b6c9286a
MM
3034/* If defined, a C expression that gives the alignment boundary, in bits,
3035 of an argument with the specified mode and type. If it is not defined,
3036 PARM_BOUNDARY is used for all arguments.
3037
2310f99a 3038 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
3039
3040int
3041function_arg_boundary (mode, type)
3042 enum machine_mode mode;
9ebbca7d 3043 tree type ATTRIBUTE_UNUSED;
b6c9286a 3044{
f607bc57 3045 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 3046 return 64;
a3170dc6
AH
3047 else if (SPE_VECTOR_MODE (mode))
3048 return 64;
0ac081f6
AH
3049 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3050 return 128;
9ebbca7d 3051 else
b6c9286a 3052 return PARM_BOUNDARY;
b6c9286a
MM
3053}
3054\f
4697a36c
MM
3055/* Update the data in CUM to advance over an argument
3056 of mode MODE and data type TYPE.
3057 (TYPE is null for libcalls where that information may not be available.) */
3058
3059void
3060function_arg_advance (cum, mode, type, named)
3061 CUMULATIVE_ARGS *cum;
3062 enum machine_mode mode;
3063 tree type;
3064 int named;
3065{
3066 cum->nargs_prototype--;
3067
0ac081f6
AH
3068 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3069 {
3070 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
3071 cum->vregno++;
3072 else
3073 cum->words += RS6000_ARG_SIZE (mode, type);
3074 }
a4b0320c
AH
3075 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
3076 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
3077 cum->sysv_gregno++;
f607bc57 3078 else if (DEFAULT_ABI == ABI_V4)
4697a36c 3079 {
a3170dc6 3080 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 3081 && (mode == SFmode || mode == DFmode))
4697a36c 3082 {
4cc833b7
RH
3083 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3084 cum->fregno++;
3085 else
3086 {
3087 if (mode == DFmode)
3088 cum->words += cum->words & 1;
d34c5b80 3089 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 3090 }
4697a36c 3091 }
4cc833b7
RH
3092 else
3093 {
3094 int n_words;
3095 int gregno = cum->sysv_gregno;
3096
3097 /* Aggregates and IEEE quad get passed by reference. */
3098 if ((type && AGGREGATE_TYPE_P (type))
3099 || mode == TFmode)
3100 n_words = 1;
3101 else
d34c5b80 3102 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3103
a4b0320c 3104 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3105 if (n_words == 2 && (gregno & 1) == 0)
3106 gregno += 1;
3107
a4b0320c
AH
3108 /* Long long and SPE vectors are not split between registers
3109 and stack. */
4cc833b7
RH
3110 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
3111 {
3112 /* Long long is aligned on the stack. */
3113 if (n_words == 2)
3114 cum->words += cum->words & 1;
3115 cum->words += n_words;
3116 }
4697a36c 3117
4cc833b7
RH
3118 /* Note: continuing to accumulate gregno past when we've started
3119 spilling to the stack indicates the fact that we've started
3120 spilling to the stack to expand_builtin_saveregs. */
3121 cum->sysv_gregno = gregno + n_words;
3122 }
4697a36c 3123
4cc833b7
RH
3124 if (TARGET_DEBUG_ARG)
3125 {
3126 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3127 cum->words, cum->fregno);
3128 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3129 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3130 fprintf (stderr, "mode = %4s, named = %d\n",
3131 GET_MODE_NAME (mode), named);
3132 }
4697a36c
MM
3133 }
3134 else
4cc833b7
RH
3135 {
3136 int align = (TARGET_32BIT && (cum->words & 1) != 0
3137 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 3138
d34c5b80 3139 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 3140
a3170dc6
AH
3141 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3142 && TARGET_HARD_FLOAT && TARGET_FPRS)
fcce224d 3143 cum->fregno += (mode == TFmode ? 2 : 1);
4cc833b7
RH
3144
3145 if (TARGET_DEBUG_ARG)
3146 {
3147 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3148 cum->words, cum->fregno);
3149 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3150 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3151 fprintf (stderr, "named = %d, align = %d\n", named, align);
3152 }
3153 }
4697a36c
MM
3154}
3155\f
3156/* Determine where to put an argument to a function.
3157 Value is zero to push the argument on the stack,
3158 or a hard register in which to store the argument.
3159
3160 MODE is the argument's machine mode.
3161 TYPE is the data type of the argument (as a tree).
3162 This is null for libcalls where that information may
3163 not be available.
3164 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3165 the preceding args and about the function being called.
3166 NAMED is nonzero if this argument is a named parameter
3167 (otherwise it is an extra parameter matching an ellipsis).
3168
3169 On RS/6000 the first eight words of non-FP are normally in registers
3170 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3171 Under V.4, the first 8 FP args are in registers.
3172
3173 If this is floating-point and no prototype is specified, we use
3174 both an FP and integer register (or possibly FP reg and stack). Library
3175 functions (when TYPE is zero) always have the proper types for args,
3176 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3177 doesn't support PARALLEL anyway. */
4697a36c
MM
3178
3179struct rtx_def *
3180function_arg (cum, mode, type, named)
3181 CUMULATIVE_ARGS *cum;
3182 enum machine_mode mode;
3183 tree type;
20c29ebe 3184 int named;
4697a36c 3185{
4cc833b7 3186 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3187
a4f6c312
SS
3188 /* Return a marker to indicate whether CR1 needs to set or clear the
3189 bit that V.4 uses to say fp args were passed in registers.
3190 Assume that we don't need the marker for software floating point,
3191 or compiler generated library calls. */
4697a36c
MM
3192 if (mode == VOIDmode)
3193 {
f607bc57 3194 if (abi == ABI_V4
7509c759 3195 && cum->nargs_prototype < 0
4697a36c 3196 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3197 {
a3170dc6
AH
3198 /* For the SPE, we need to crxor CR6 always. */
3199 if (TARGET_SPE_ABI)
3200 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3201 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3202 return GEN_INT (cum->call_cookie
3203 | ((cum->fregno == FP_ARG_MIN_REG)
3204 ? CALL_V4_SET_FP_ARGS
3205 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3206 }
4697a36c 3207
7509c759 3208 return GEN_INT (cum->call_cookie);
4697a36c
MM
3209 }
3210
0ac081f6
AH
3211 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3212 {
20c29ebe 3213 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3214 return gen_rtx_REG (mode, cum->vregno);
3215 else
3216 return NULL;
3217 }
a4b0320c 3218 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3219 {
a4b0320c 3220 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3221 return gen_rtx_REG (mode, cum->sysv_gregno);
3222 else
3223 return NULL;
3224 }
f607bc57 3225 else if (abi == ABI_V4)
4697a36c 3226 {
a3170dc6 3227 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3228 && (mode == SFmode || mode == DFmode))
3229 {
3230 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3231 return gen_rtx_REG (mode, cum->fregno);
3232 else
3233 return NULL;
3234 }
3235 else
3236 {
3237 int n_words;
3238 int gregno = cum->sysv_gregno;
3239
3240 /* Aggregates and IEEE quad get passed by reference. */
3241 if ((type && AGGREGATE_TYPE_P (type))
3242 || mode == TFmode)
3243 n_words = 1;
3244 else
d34c5b80 3245 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3246
a4b0320c 3247 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3248 if (n_words == 2 && (gregno & 1) == 0)
3249 gregno += 1;
3250
a4b0320c
AH
3251 /* Long long and SPE vectors are not split between registers
3252 and stack. */
4cc833b7 3253 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3254 {
3255 /* SPE vectors in ... get split into 2 registers. */
3256 if (TARGET_SPE && TARGET_SPE_ABI
3257 && SPE_VECTOR_MODE (mode) && !named)
3258 {
3259 rtx r1, r2;
57de2c8f 3260 enum machine_mode m = SImode;
f9dd72da 3261
a4b0320c
AH
3262 r1 = gen_rtx_REG (m, gregno);
3263 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3264 r2 = gen_rtx_REG (m, gregno + 1);
3265 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3266 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3267 }
3268 return gen_rtx_REG (mode, gregno);
3269 }
4cc833b7
RH
3270 else
3271 return NULL;
3272 }
4697a36c 3273 }
4cc833b7
RH
3274 else
3275 {
3276 int align = (TARGET_32BIT && (cum->words & 1) != 0
3277 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3278 int align_words = cum->words + align;
4697a36c 3279
4cc833b7
RH
3280 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3281 return NULL_RTX;
3282
3283 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3284 {
3285 if (! type
3286 || ((cum->nargs_prototype > 0)
3287 /* IBM AIX extended its linkage convention definition always
3288 to require FP args after register save area hole on the
3289 stack. */
3290 && (DEFAULT_ABI != ABI_AIX
3291 || ! TARGET_XL_CALL
3292 || (align_words < GP_ARG_NUM_REG))))
3293 return gen_rtx_REG (mode, cum->fregno);
3294
3295 return gen_rtx_PARALLEL (mode,
3296 gen_rtvec (2,
39403d82 3297 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3298 ((align_words >= GP_ARG_NUM_REG)
3299 ? NULL_RTX
3300 : (align_words
d34c5b80 3301 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3302 > GP_ARG_NUM_REG
3303 /* If this is partially on the stack, then
3304 we only include the portion actually
3305 in registers here. */
39403d82 3306 ? gen_rtx_REG (SImode,
1c20ae99 3307 GP_ARG_MIN_REG + align_words)
39403d82 3308 : gen_rtx_REG (mode,
1c20ae99
JW
3309 GP_ARG_MIN_REG + align_words))),
3310 const0_rtx),
39403d82
DE
3311 gen_rtx_EXPR_LIST (VOIDmode,
3312 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3313 const0_rtx)));
4cc833b7
RH
3314 }
3315 else if (align_words < GP_ARG_NUM_REG)
3316 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3317 else
3318 return NULL_RTX;
4697a36c 3319 }
4697a36c
MM
3320}
3321\f
3322/* For an arg passed partly in registers and partly in memory,
3323 this is the number of registers used.
3324 For args passed entirely in registers or entirely in memory, zero. */
3325
3326int
3327function_arg_partial_nregs (cum, mode, type, named)
3328 CUMULATIVE_ARGS *cum;
3329 enum machine_mode mode;
3330 tree type;
d34c5b80 3331 int named ATTRIBUTE_UNUSED;
4697a36c 3332{
f607bc57 3333 if (DEFAULT_ABI == ABI_V4)
4697a36c 3334 return 0;
4697a36c 3335
0ac081f6
AH
3336 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3337 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3338 {
3339 if (cum->nargs_prototype >= 0)
3340 return 0;
3341 }
3342
3343 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3344 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3345 {
3346 int ret = GP_ARG_NUM_REG - cum->words;
3347 if (ret && TARGET_DEBUG_ARG)
3348 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3349
3350 return ret;
3351 }
3352
3353 return 0;
3354}
3355\f
3356/* A C expression that indicates when an argument must be passed by
3357 reference. If nonzero for an argument, a copy of that argument is
3358 made in memory and a pointer to the argument is passed instead of
3359 the argument itself. The pointer is passed in whatever way is
3360 appropriate for passing a pointer to that type.
3361
c8c99a68
DE
3362 Under V.4, structures and unions are passed by reference.
3363
3364 As an extension to all ABIs, variable sized types are passed by
3365 reference. */
4697a36c
MM
3366
3367int
3368function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3369 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3370 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3371 tree type;
296b8152 3372 int named ATTRIBUTE_UNUSED;
4697a36c 3373{
f607bc57 3374 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3375 && ((type && AGGREGATE_TYPE_P (type))
3376 || mode == TFmode))
4697a36c
MM
3377 {
3378 if (TARGET_DEBUG_ARG)
3379 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3380
3381 return 1;
3382 }
c8c99a68 3383 return type && int_size_in_bytes (type) <= 0;
4697a36c 3384}
4697a36c
MM
3385\f
3386/* Perform any needed actions needed for a function that is receiving a
3387 variable number of arguments.
3388
3389 CUM is as above.
3390
3391 MODE and TYPE are the mode and type of the current parameter.
3392
3393 PRETEND_SIZE is a variable that should be set to the amount of stack
3394 that must be pushed by the prolog to pretend that our caller pushed
3395 it.
3396
3397 Normally, this macro will push all remaining incoming registers on the
3398 stack and set PRETEND_SIZE to the length of the registers pushed. */
3399
3400void
3401setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3402 CUMULATIVE_ARGS *cum;
3403 enum machine_mode mode;
3404 tree type;
de62b72c 3405 int *pretend_size ATTRIBUTE_UNUSED;
4697a36c
MM
3406 int no_rtl;
3407
3408{
4cc833b7
RH
3409 CUMULATIVE_ARGS next_cum;
3410 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3411 rtx save_area = NULL_RTX, mem;
dfafc897 3412 int first_reg_offset, set;
d34c5b80
DE
3413 tree fntype;
3414 int stdarg_p;
4697a36c 3415
d34c5b80
DE
3416 fntype = TREE_TYPE (current_function_decl);
3417 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3418 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3419 != void_type_node));
4cc833b7 3420
d34c5b80
DE
3421 /* For varargs, we do not want to skip the dummy va_dcl argument.
3422 For stdargs, we do want to skip the last named argument. */
3423 next_cum = *cum;
3424 if (stdarg_p)
3425 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3426
f607bc57 3427 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3428 {
4cc833b7 3429 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3430 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3431 if (! no_rtl)
2c4974b7 3432 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3433 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3434
3435 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3436 }
60e2d0ca 3437 else
4697a36c 3438 {
d34c5b80 3439 first_reg_offset = next_cum.words;
4cc833b7 3440 save_area = virtual_incoming_args_rtx;
00dba523 3441 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3442
3443 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3444 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3445 }
4697a36c 3446
dfafc897 3447 set = get_varargs_alias_set ();
c81fc13e 3448 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3449 {
dfafc897
FS
3450 mem = gen_rtx_MEM (BLKmode,
3451 plus_constant (save_area,
3452 first_reg_offset * reg_size)),
ba4828e0 3453 set_mem_alias_set (mem, set);
8ac61af7 3454 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3455
4cc833b7 3456 move_block_from_reg
dfafc897 3457 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3458 GP_ARG_NUM_REG - first_reg_offset,
3459 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
4697a36c
MM
3460 }
3461
4697a36c 3462 /* Save FP registers if needed. */
f607bc57 3463 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3464 && TARGET_HARD_FLOAT && TARGET_FPRS
3465 && ! no_rtl
4cc833b7 3466 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3467 {
4cc833b7 3468 int fregno = next_cum.fregno;
9ebbca7d 3469 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3470 rtx lab = gen_label_rtx ();
3471 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3472
4cc833b7 3473 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3474 pc_rtx,
39403d82 3475 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3476 gen_rtx_NE (VOIDmode, cr1,
3477 const0_rtx),
39403d82 3478 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3479 pc_rtx)));
3480
4cc833b7
RH
3481 while (fregno <= FP_ARG_V4_MAX_REG)
3482 {
dfafc897 3483 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3484 set_mem_alias_set (mem, set);
dfafc897 3485 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3486 fregno++;
3487 off += 8;
4697a36c 3488 }
4cc833b7
RH
3489
3490 emit_label (lab);
4697a36c 3491 }
4697a36c 3492}
4697a36c 3493
dfafc897 3494/* Create the va_list data type. */
2c4974b7 3495
dfafc897
FS
3496tree
3497rs6000_build_va_list ()
3498{
bab45a51 3499 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3500
9ebbca7d
GK
3501 /* For AIX, prefer 'char *' because that's what the system
3502 header files like. */
f607bc57 3503 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3504 return build_pointer_type (char_type_node);
dfafc897 3505
f1e639b1 3506 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3507 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3508
9ebbca7d
GK
3509 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3510 unsigned_char_type_node);
3511 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3512 unsigned_char_type_node);
dfafc897
FS
3513 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3514 ptr_type_node);
3515 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3516 ptr_type_node);
3517
3518 DECL_FIELD_CONTEXT (f_gpr) = record;
3519 DECL_FIELD_CONTEXT (f_fpr) = record;
3520 DECL_FIELD_CONTEXT (f_ovf) = record;
3521 DECL_FIELD_CONTEXT (f_sav) = record;
3522
bab45a51
FS
3523 TREE_CHAIN (record) = type_decl;
3524 TYPE_NAME (record) = type_decl;
dfafc897
FS
3525 TYPE_FIELDS (record) = f_gpr;
3526 TREE_CHAIN (f_gpr) = f_fpr;
3527 TREE_CHAIN (f_fpr) = f_ovf;
3528 TREE_CHAIN (f_ovf) = f_sav;
3529
3530 layout_type (record);
3531
3532 /* The correct type is an array type of one element. */
3533 return build_array_type (record, build_index_type (size_zero_node));
3534}
3535
3536/* Implement va_start. */
3537
3538void
e5faf155 3539rs6000_va_start (valist, nextarg)
dfafc897
FS
3540 tree valist;
3541 rtx nextarg;
4697a36c 3542{
dfafc897
FS
3543 HOST_WIDE_INT words, n_gpr, n_fpr;
3544 tree f_gpr, f_fpr, f_ovf, f_sav;
3545 tree gpr, fpr, ovf, sav, t;
2c4974b7 3546
dfafc897 3547 /* Only SVR4 needs something special. */
f607bc57 3548 if (DEFAULT_ABI != ABI_V4)
dfafc897 3549 {
e5faf155 3550 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3551 return;
3552 }
3553
973a648b 3554 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3555 f_fpr = TREE_CHAIN (f_gpr);
3556 f_ovf = TREE_CHAIN (f_fpr);
3557 f_sav = TREE_CHAIN (f_ovf);
3558
8ebecc3b 3559 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3560 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3561 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3562 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3563 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3564
3565 /* Count number of gp and fp argument registers used. */
4cc833b7 3566 words = current_function_args_info.words;
dfafc897
FS
3567 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3568 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3569
3570 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3571 {
3572 fputs ("va_start: words = ", stderr);
3573 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3574 fputs (", n_gpr = ", stderr);
3575 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3576 fputs (", n_fpr = ", stderr);
3577 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3578 putc ('\n', stderr);
3579 }
dfafc897
FS
3580
3581 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3582 TREE_SIDE_EFFECTS (t) = 1;
3583 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3584
3585 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3586 TREE_SIDE_EFFECTS (t) = 1;
3587 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3588
3589 /* Find the overflow area. */
3590 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3591 if (words != 0)
3592 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3593 build_int_2 (words * UNITS_PER_WORD, 0));
3594 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3595 TREE_SIDE_EFFECTS (t) = 1;
3596 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3597
3598 /* Find the register save area. */
3599 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3600 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3601 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3602 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3603 TREE_SIDE_EFFECTS (t) = 1;
3604 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3605}
3606
3607/* Implement va_arg. */
3608
3609rtx
3610rs6000_va_arg (valist, type)
3611 tree valist, type;
3612{
3613 tree f_gpr, f_fpr, f_ovf, f_sav;
3614 tree gpr, fpr, ovf, sav, reg, t, u;
3615 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3616 rtx lab_false, lab_over, addr_rtx, r;
3617
f607bc57 3618 if (DEFAULT_ABI != ABI_V4)
c8c99a68
DE
3619 {
3620 /* Variable sized types are passed by reference. */
3621 if (int_size_in_bytes (type) <= 0)
3622 {
3623 u = build_pointer_type (type);
3624
3625 /* Args grow upward. */
3626 t = build (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist,
3627 build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0));
3628 TREE_SIDE_EFFECTS (t) = 1;
3629
3630 t = build1 (NOP_EXPR, build_pointer_type (u), t);
3631 TREE_SIDE_EFFECTS (t) = 1;
3632
3633 t = build1 (INDIRECT_REF, u, t);
3634 TREE_SIDE_EFFECTS (t) = 1;
3635
3636 return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL);
3637 }
3638 else
3639 return std_expand_builtin_va_arg (valist, type);
3640 }
dfafc897 3641
973a648b 3642 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3643 f_fpr = TREE_CHAIN (f_gpr);
3644 f_ovf = TREE_CHAIN (f_fpr);
3645 f_sav = TREE_CHAIN (f_ovf);
3646
8ebecc3b 3647 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3648 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3649 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3650 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3651 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3652
3653 size = int_size_in_bytes (type);
3654 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3655
dfafc897 3656 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3657 {
dfafc897
FS
3658 /* Aggregates and long doubles are passed by reference. */
3659 indirect_p = 1;
3660 reg = gpr;
3661 n_reg = 1;
3662 sav_ofs = 0;
3663 sav_scale = 4;
d3294cd9
FS
3664 size = UNITS_PER_WORD;
3665 rsize = 1;
dfafc897 3666 }
a3170dc6 3667 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3668 {
3669 /* FP args go in FP registers, if present. */
3670 indirect_p = 0;
3671 reg = fpr;
3672 n_reg = 1;
3673 sav_ofs = 8*4;
3674 sav_scale = 8;
4cc833b7 3675 }
dfafc897
FS
3676 else
3677 {
3678 /* Otherwise into GP registers. */
3679 indirect_p = 0;
3680 reg = gpr;
3681 n_reg = rsize;
3682 sav_ofs = 0;
3683 sav_scale = 4;
3684 }
3685
a4f6c312 3686 /* Pull the value out of the saved registers ... */
dfafc897
FS
3687
3688 lab_false = gen_label_rtx ();
3689 lab_over = gen_label_rtx ();
3690 addr_rtx = gen_reg_rtx (Pmode);
3691
16861f33
AH
3692 /* AltiVec vectors never go in registers. */
3693 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3694 {
41daaf0e
AH
3695 TREE_THIS_VOLATILE (reg) = 1;
3696 emit_cmp_and_jump_insns
3697 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3698 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3699 lab_false);
dfafc897 3700
41daaf0e
AH
3701 /* Long long is aligned in the registers. */
3702 if (n_reg > 1)
3703 {
3704 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3705 build_int_2 (n_reg - 1, 0));
3706 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3707 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3708 TREE_SIDE_EFFECTS (u) = 1;
3709 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3710 }
2c4974b7 3711
41daaf0e
AH
3712 if (sav_ofs)
3713 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3714 else
3715 t = sav;
2c4974b7 3716
41daaf0e
AH
3717 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3718 build_int_2 (n_reg, 0));
3719 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3720
41daaf0e
AH
3721 u = build1 (CONVERT_EXPR, integer_type_node, u);
3722 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3723
41daaf0e
AH
3724 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3725 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3726
41daaf0e
AH
3727 t = build (PLUS_EXPR, ptr_type_node, t, u);
3728 TREE_SIDE_EFFECTS (t) = 1;
3729
3730 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3731 if (r != addr_rtx)
3732 emit_move_insn (addr_rtx, r);
3733
3734 emit_jump_insn (gen_jump (lab_over));
3735 emit_barrier ();
3736 }
dfafc897 3737
dfafc897
FS
3738 emit_label (lab_false);
3739
a4f6c312 3740 /* ... otherwise out of the overflow area. */
dfafc897 3741
41daaf0e
AH
3742 /* Make sure we don't find reg 7 for the next int arg.
3743
3744 All AltiVec vectors go in the overflow area. So in the AltiVec
3745 case we need to get the vectors from the overflow area, but
3746 remember where the GPRs and FPRs are. */
16861f33
AH
3747 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3748 || !TARGET_ALTIVEC))
dfafc897
FS
3749 {
3750 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3751 TREE_SIDE_EFFECTS (t) = 1;
3752 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3753 }
3754
3755 /* Care for on-stack alignment if needed. */
3756 if (rsize <= 1)
3757 t = ovf;
3758 else
3759 {
41daaf0e
AH
3760 int align;
3761
16861f33
AH
3762 /* AltiVec vectors are 16 byte aligned. */
3763 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3764 align = 15;
3765 else
3766 align = 7;
3767
3768 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3769 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3770 }
3771 t = save_expr (t);
3772
3773 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3774 if (r != addr_rtx)
3775 emit_move_insn (addr_rtx, r);
3776
3777 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3778 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3779 TREE_SIDE_EFFECTS (t) = 1;
3780 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3781
3782 emit_label (lab_over);
3783
3784 if (indirect_p)
3785 {
3786 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3787 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3788 emit_move_insn (addr_rtx, r);
3789 }
3790
3791 return addr_rtx;
4697a36c 3792}
0ac081f6
AH
3793
3794/* Builtins. */
3795
6a2dd09a
RS
3796#define def_builtin(MASK, NAME, TYPE, CODE) \
3797do { \
3798 if ((MASK) & target_flags) \
3799 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3800 NULL, NULL_TREE); \
0ac081f6
AH
3801} while (0)
3802
24408032
AH
3803/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3804
2212663f 3805static const struct builtin_description bdesc_3arg[] =
24408032
AH
3806{
3807 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3808 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3809 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3810 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3811 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3812 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3813 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3814 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3815 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3816 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3817 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3818 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3819 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3820 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3821 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3822 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3823 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3824 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3825 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3826 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3827 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3828 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3829 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3830};
2212663f 3831
95385cbb
AH
3832/* DST operations: void foo (void *, const int, const char). */
3833
3834static const struct builtin_description bdesc_dst[] =
3835{
3836 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3837 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3838 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3839 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3840};
3841
2212663f 3842/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3843
a3170dc6 3844static struct builtin_description bdesc_2arg[] =
0ac081f6 3845{
f18c054f
DB
3846 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3847 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3848 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3849 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3850 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3851 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3852 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3853 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3854 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3855 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3856 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3857 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3858 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
3859 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
3860 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
3861 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
3862 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
3863 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
3864 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
3865 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
3866 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
3867 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
3868 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
3869 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
3870 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
3871 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
3872 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
3873 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
3874 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
3875 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
3876 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
3877 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
3878 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
3879 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
3880 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
3881 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
3882 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
3883 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
3884 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
3885 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
3886 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
3887 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
3888 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
3889 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
3890 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
3891 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
3892 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
3893 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
3894 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
3895 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
3896 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
3897 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
3898 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
3899 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
3900 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
3901 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
3902 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
3903 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
3904 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
3905 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
3906 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
3907 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
3908 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
3909 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
3910 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 3911 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
3912 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
3913 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
3914 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
3915 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
3916 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
3917 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
3918 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
3919 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
3920 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
3921 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
3922 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
3923 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
3924 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
3925 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
3926 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
3927 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
3928 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
3929 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
3930 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
3931 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
3932 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
3933 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 3934 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
3935 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
3936 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
3937 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
3938 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
3939 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
3940 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
3941 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
3942 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
3943 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
3944 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
3945 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
3946 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
3947 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
3948 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
3949 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
3950 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
3951 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
3952 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
3953 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
3954 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
3955 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
3956 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
3957 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 3958 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
3959
3960 /* Place holder, leave as first spe builtin. */
3961 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
3962 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
3963 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
3964 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
3965 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
3966 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
3967 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
3968 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
3969 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
3970 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
3971 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
3972 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
3973 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
3974 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
3975 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
3976 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
3977 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
3978 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
3979 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
3980 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
3981 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
3982 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
3983 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
3984 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
3985 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
3986 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
3987 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
3988 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
3989 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
3990 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
3991 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
3992 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
3993 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
3994 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
3995 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
3996 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
3997 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
3998 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
3999 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
4000 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
4001 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
4002 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
4003 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
4004 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
4005 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
4006 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
4007 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
4008 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
4009 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
4010 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
4011 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
4012 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
4013 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
4014 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
4015 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
4016 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
4017 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
4018 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
4019 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
4020 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
4021 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
4022 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
4023 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
4024 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
4025 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
4026 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
4027 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
4028 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
4029 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
4030 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
4031 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
4032 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
4033 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
4034 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
a3170dc6
AH
4035 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
4036 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
a3170dc6
AH
4037 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
4038 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
4039 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
4040 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
4041 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
4042 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
4043 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
4044 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
4045 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
4046 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
4047 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
4048 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
4049 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
4050 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
4051 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
4052 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
4053 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
4054 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
4055 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
4056 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
4057 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
4058 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
4059 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
4060 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
4061 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
4062 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
4063 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
4064 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
4065 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
4066 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
4067 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
4068 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
4069 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
4070
4071 /* SPE binary operations expecting a 5-bit unsigned literal. */
4072 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
4073
4074 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
4075 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
4076 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
4077 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
4078 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
4079 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
4080 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
4081 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
4082 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
4083 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
4084 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
4085 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
4086 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
4087 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
4088 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
4089 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
4090 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
4091 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
4092 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
4093 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
4094 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
4095 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
4096 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
4097 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
4098 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
4099 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
4100
4101 /* Place-holder. Leave as last binary SPE builtin. */
17edbda5 4102 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
4103};
4104
4105/* AltiVec predicates. */
4106
4107struct builtin_description_predicates
4108{
4109 const unsigned int mask;
4110 const enum insn_code icode;
4111 const char *opcode;
4112 const char *const name;
4113 const enum rs6000_builtins code;
4114};
4115
4116static const struct builtin_description_predicates bdesc_altivec_preds[] =
4117{
4118 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
4119 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
4120 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
4121 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
4122 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
4123 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
4124 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
4125 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
4126 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
4127 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
4128 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
4129 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
4130 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 4131};
24408032 4132
a3170dc6
AH
4133/* SPE predicates. */
4134static struct builtin_description bdesc_spe_predicates[] =
4135{
4136 /* Place-holder. Leave as first. */
4137 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
4138 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
4139 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
4140 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4141 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4142 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4143 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4144 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4145 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4146 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4147 /* Place-holder. Leave as last. */
4148 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4149};
4150
4151/* SPE evsel predicates. */
4152static struct builtin_description bdesc_spe_evsel[] =
4153{
4154 /* Place-holder. Leave as first. */
4155 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4156 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4157 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4158 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4159 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4160 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4161 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4162 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4163 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4164 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4165 /* Place-holder. Leave as last. */
4166 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4167};
4168
b6d08ca1 4169/* ABS* operations. */
100c4561
AH
4170
4171static const struct builtin_description bdesc_abs[] =
4172{
4173 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4174 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4175 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4176 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4177 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4178 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4179 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4180};
4181
617e0e1d
DB
4182/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4183 foo (VECa). */
24408032 4184
a3170dc6 4185static struct builtin_description bdesc_1arg[] =
2212663f 4186{
617e0e1d
DB
4187 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4188 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4189 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4190 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4191 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4192 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4193 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4194 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4195 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4196 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4197 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4198 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4199 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4200 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4201 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4202 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4203 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4204
4205 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4206 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4207 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4208 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4209 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4210 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4211 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4212 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4213 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4214 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4215 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4216 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4217 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4218 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4219 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4220 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4221 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4222 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4223 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4224 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4225 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4226 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4227 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4228 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4229 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4230 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4231 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4232 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4233 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4234 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4235 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4236 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4237
4238 /* Place-holder. Leave as last unary SPE builtin. */
4239 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4240};
4241
4242static rtx
92898235 4243rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4244 enum insn_code icode;
4245 tree arglist;
4246 rtx target;
4247{
4248 rtx pat;
4249 tree arg0 = TREE_VALUE (arglist);
4250 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4251 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4252 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4253
0559cc77
DE
4254 if (icode == CODE_FOR_nothing)
4255 /* Builtin not supported on this processor. */
4256 return 0;
4257
20e26713
AH
4258 /* If we got invalid arguments bail out before generating bad rtl. */
4259 if (arg0 == error_mark_node)
9a171fcd 4260 return const0_rtx;
20e26713 4261
0559cc77
DE
4262 if (icode == CODE_FOR_altivec_vspltisb
4263 || icode == CODE_FOR_altivec_vspltish
4264 || icode == CODE_FOR_altivec_vspltisw
4265 || icode == CODE_FOR_spe_evsplatfi
4266 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4267 {
4268 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4269 if (GET_CODE (op0) != CONST_INT
4270 || INTVAL (op0) > 0x1f
4271 || INTVAL (op0) < -0x1f)
4272 {
4273 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4274 return const0_rtx;
b44140e7 4275 }
b44140e7
AH
4276 }
4277
c62f2db5 4278 if (target == 0
2212663f
DB
4279 || GET_MODE (target) != tmode
4280 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4281 target = gen_reg_rtx (tmode);
4282
4283 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4284 op0 = copy_to_mode_reg (mode0, op0);
4285
4286 pat = GEN_FCN (icode) (target, op0);
4287 if (! pat)
4288 return 0;
4289 emit_insn (pat);
0ac081f6 4290
2212663f
DB
4291 return target;
4292}
ae4b4a02 4293
100c4561
AH
4294static rtx
4295altivec_expand_abs_builtin (icode, arglist, target)
4296 enum insn_code icode;
4297 tree arglist;
4298 rtx target;
4299{
4300 rtx pat, scratch1, scratch2;
4301 tree arg0 = TREE_VALUE (arglist);
4302 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4303 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4304 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4305
4306 /* If we have invalid arguments, bail out before generating bad rtl. */
4307 if (arg0 == error_mark_node)
9a171fcd 4308 return const0_rtx;
100c4561
AH
4309
4310 if (target == 0
4311 || GET_MODE (target) != tmode
4312 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4313 target = gen_reg_rtx (tmode);
4314
4315 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4316 op0 = copy_to_mode_reg (mode0, op0);
4317
4318 scratch1 = gen_reg_rtx (mode0);
4319 scratch2 = gen_reg_rtx (mode0);
4320
4321 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4322 if (! pat)
4323 return 0;
4324 emit_insn (pat);
4325
4326 return target;
4327}
4328
0ac081f6 4329static rtx
92898235 4330rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4331 enum insn_code icode;
4332 tree arglist;
4333 rtx target;
4334{
4335 rtx pat;
4336 tree arg0 = TREE_VALUE (arglist);
4337 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4338 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4339 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4340 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4341 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4342 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4343
0559cc77
DE
4344 if (icode == CODE_FOR_nothing)
4345 /* Builtin not supported on this processor. */
4346 return 0;
4347
20e26713
AH
4348 /* If we got invalid arguments bail out before generating bad rtl. */
4349 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4350 return const0_rtx;
20e26713 4351
0559cc77
DE
4352 if (icode == CODE_FOR_altivec_vcfux
4353 || icode == CODE_FOR_altivec_vcfsx
4354 || icode == CODE_FOR_altivec_vctsxs
4355 || icode == CODE_FOR_altivec_vctuxs
4356 || icode == CODE_FOR_altivec_vspltb
4357 || icode == CODE_FOR_altivec_vsplth
4358 || icode == CODE_FOR_altivec_vspltw
4359 || icode == CODE_FOR_spe_evaddiw
4360 || icode == CODE_FOR_spe_evldd
4361 || icode == CODE_FOR_spe_evldh
4362 || icode == CODE_FOR_spe_evldw
4363 || icode == CODE_FOR_spe_evlhhesplat
4364 || icode == CODE_FOR_spe_evlhhossplat
4365 || icode == CODE_FOR_spe_evlhhousplat
4366 || icode == CODE_FOR_spe_evlwhe
4367 || icode == CODE_FOR_spe_evlwhos
4368 || icode == CODE_FOR_spe_evlwhou
4369 || icode == CODE_FOR_spe_evlwhsplat
4370 || icode == CODE_FOR_spe_evlwwsplat
4371 || icode == CODE_FOR_spe_evrlwi
4372 || icode == CODE_FOR_spe_evslwi
4373 || icode == CODE_FOR_spe_evsrwis
4374 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4375 {
4376 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4377 if (TREE_CODE (arg1) != INTEGER_CST
4378 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4379 {
4380 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4381 return const0_rtx;
b44140e7 4382 }
b44140e7
AH
4383 }
4384
c62f2db5 4385 if (target == 0
0ac081f6
AH
4386 || GET_MODE (target) != tmode
4387 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4388 target = gen_reg_rtx (tmode);
4389
4390 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4391 op0 = copy_to_mode_reg (mode0, op0);
4392 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4393 op1 = copy_to_mode_reg (mode1, op1);
4394
4395 pat = GEN_FCN (icode) (target, op0, op1);
4396 if (! pat)
4397 return 0;
4398 emit_insn (pat);
4399
4400 return target;
4401}
6525c0e7 4402
ae4b4a02
AH
4403static rtx
4404altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4405 enum insn_code icode;
4406 const char *opcode;
4407 tree arglist;
4408 rtx target;
4409{
4410 rtx pat, scratch;
4411 tree cr6_form = TREE_VALUE (arglist);
4412 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4413 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4414 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4415 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4416 enum machine_mode tmode = SImode;
4417 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4418 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4419 int cr6_form_int;
4420
4421 if (TREE_CODE (cr6_form) != INTEGER_CST)
4422 {
4423 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4424 return const0_rtx;
ae4b4a02
AH
4425 }
4426 else
4427 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4428
4429 if (mode0 != mode1)
4430 abort ();
4431
4432 /* If we have invalid arguments, bail out before generating bad rtl. */
4433 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4434 return const0_rtx;
ae4b4a02
AH
4435
4436 if (target == 0
4437 || GET_MODE (target) != tmode
4438 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4439 target = gen_reg_rtx (tmode);
4440
4441 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4442 op0 = copy_to_mode_reg (mode0, op0);
4443 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4444 op1 = copy_to_mode_reg (mode1, op1);
4445
4446 scratch = gen_reg_rtx (mode0);
4447
4448 pat = GEN_FCN (icode) (scratch, op0, op1,
4449 gen_rtx (SYMBOL_REF, Pmode, opcode));
4450 if (! pat)
4451 return 0;
4452 emit_insn (pat);
4453
4454 /* The vec_any* and vec_all* predicates use the same opcodes for two
4455 different operations, but the bits in CR6 will be different
4456 depending on what information we want. So we have to play tricks
4457 with CR6 to get the right bits out.
4458
4459 If you think this is disgusting, look at the specs for the
4460 AltiVec predicates. */
4461
4462 switch (cr6_form_int)
4463 {
4464 case 0:
4465 emit_insn (gen_cr6_test_for_zero (target));
4466 break;
4467 case 1:
4468 emit_insn (gen_cr6_test_for_zero_reverse (target));
4469 break;
4470 case 2:
4471 emit_insn (gen_cr6_test_for_lt (target));
4472 break;
4473 case 3:
4474 emit_insn (gen_cr6_test_for_lt_reverse (target));
4475 break;
4476 default:
4477 error ("argument 1 of __builtin_altivec_predicate is out of range");
4478 break;
4479 }
4480
4481 return target;
4482}
4483
6525c0e7
AH
4484static rtx
4485altivec_expand_stv_builtin (icode, arglist)
4486 enum insn_code icode;
4487 tree arglist;
4488{
4489 tree arg0 = TREE_VALUE (arglist);
4490 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4491 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4492 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4493 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4494 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4495 rtx pat;
4496 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4497 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4498 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4499
4500 /* Invalid arguments. Bail before doing anything stoopid! */
4501 if (arg0 == error_mark_node
4502 || arg1 == error_mark_node
4503 || arg2 == error_mark_node)
9a171fcd 4504 return const0_rtx;
6525c0e7
AH
4505
4506 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4507 op0 = copy_to_mode_reg (mode2, op0);
4508 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4509 op1 = copy_to_mode_reg (mode0, op1);
4510 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4511 op2 = copy_to_mode_reg (mode1, op2);
4512
4513 pat = GEN_FCN (icode) (op1, op2, op0);
4514 if (pat)
4515 emit_insn (pat);
4516 return NULL_RTX;
4517}
4518
2212663f 4519static rtx
92898235 4520rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4521 enum insn_code icode;
4522 tree arglist;
4523 rtx target;
4524{
4525 rtx pat;
4526 tree arg0 = TREE_VALUE (arglist);
4527 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4528 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4529 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4530 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4531 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4532 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4533 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4534 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4535 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4536
774b5662
DE
4537 if (icode == CODE_FOR_nothing)
4538 /* Builtin not supported on this processor. */
4539 return 0;
4540
20e26713
AH
4541 /* If we got invalid arguments bail out before generating bad rtl. */
4542 if (arg0 == error_mark_node
4543 || arg1 == error_mark_node
4544 || arg2 == error_mark_node)
9a171fcd 4545 return const0_rtx;
20e26713 4546
774b5662
DE
4547 if (icode == CODE_FOR_altivec_vsldoi_4sf
4548 || icode == CODE_FOR_altivec_vsldoi_4si
4549 || icode == CODE_FOR_altivec_vsldoi_8hi
4550 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4551 {
4552 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4553 if (TREE_CODE (arg2) != INTEGER_CST
4554 || TREE_INT_CST_LOW (arg2) & ~0xf)
4555 {
4556 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4557 return const0_rtx;
b44140e7 4558 }
b44140e7
AH
4559 }
4560
c62f2db5 4561 if (target == 0
2212663f
DB
4562 || GET_MODE (target) != tmode
4563 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4564 target = gen_reg_rtx (tmode);
4565
4566 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4567 op0 = copy_to_mode_reg (mode0, op0);
4568 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4569 op1 = copy_to_mode_reg (mode1, op1);
4570 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4571 op2 = copy_to_mode_reg (mode2, op2);
4572
4573 pat = GEN_FCN (icode) (target, op0, op1, op2);
4574 if (! pat)
4575 return 0;
4576 emit_insn (pat);
4577
4578 return target;
4579}
92898235 4580
3a9b8c7e 4581/* Expand the lvx builtins. */
0ac081f6 4582static rtx
3a9b8c7e 4583altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4584 tree exp;
4585 rtx target;
92898235 4586 bool *expandedp;
0ac081f6 4587{
0ac081f6
AH
4588 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4589 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4590 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4591 tree arg0;
4592 enum machine_mode tmode, mode0;
7c3abc73 4593 rtx pat, op0;
3a9b8c7e 4594 enum insn_code icode;
92898235 4595
0ac081f6
AH
4596 switch (fcode)
4597 {
f18c054f
DB
4598 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4599 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4600 break;
f18c054f
DB
4601 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4602 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4603 break;
4604 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4605 icode = CODE_FOR_altivec_lvx_4si;
4606 break;
4607 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4608 icode = CODE_FOR_altivec_lvx_4sf;
4609 break;
4610 default:
4611 *expandedp = false;
4612 return NULL_RTX;
4613 }
0ac081f6 4614
3a9b8c7e 4615 *expandedp = true;
f18c054f 4616
3a9b8c7e
AH
4617 arg0 = TREE_VALUE (arglist);
4618 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4619 tmode = insn_data[icode].operand[0].mode;
4620 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4621
3a9b8c7e
AH
4622 if (target == 0
4623 || GET_MODE (target) != tmode
4624 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4625 target = gen_reg_rtx (tmode);
24408032 4626
3a9b8c7e
AH
4627 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4628 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4629
3a9b8c7e
AH
4630 pat = GEN_FCN (icode) (target, op0);
4631 if (! pat)
4632 return 0;
4633 emit_insn (pat);
4634 return target;
4635}
f18c054f 4636
3a9b8c7e
AH
4637/* Expand the stvx builtins. */
4638static rtx
4639altivec_expand_st_builtin (exp, target, expandedp)
4640 tree exp;
7c3abc73 4641 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4642 bool *expandedp;
4643{
4644 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4645 tree arglist = TREE_OPERAND (exp, 1);
4646 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4647 tree arg0, arg1;
4648 enum machine_mode mode0, mode1;
7c3abc73 4649 rtx pat, op0, op1;
3a9b8c7e 4650 enum insn_code icode;
f18c054f 4651
3a9b8c7e
AH
4652 switch (fcode)
4653 {
4654 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4655 icode = CODE_FOR_altivec_stvx_16qi;
4656 break;
4657 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4658 icode = CODE_FOR_altivec_stvx_8hi;
4659 break;
4660 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4661 icode = CODE_FOR_altivec_stvx_4si;
4662 break;
4663 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4664 icode = CODE_FOR_altivec_stvx_4sf;
4665 break;
4666 default:
4667 *expandedp = false;
4668 return NULL_RTX;
4669 }
24408032 4670
3a9b8c7e
AH
4671 arg0 = TREE_VALUE (arglist);
4672 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4673 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4674 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4675 mode0 = insn_data[icode].operand[0].mode;
4676 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4677
3a9b8c7e
AH
4678 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4679 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4680 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4681 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4682
3a9b8c7e
AH
4683 pat = GEN_FCN (icode) (op0, op1);
4684 if (pat)
4685 emit_insn (pat);
f18c054f 4686
3a9b8c7e
AH
4687 *expandedp = true;
4688 return NULL_RTX;
4689}
f18c054f 4690
3a9b8c7e
AH
4691/* Expand the dst builtins. */
4692static rtx
4693altivec_expand_dst_builtin (exp, target, expandedp)
4694 tree exp;
7c3abc73 4695 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4696 bool *expandedp;
4697{
4698 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4699 tree arglist = TREE_OPERAND (exp, 1);
4700 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4701 tree arg0, arg1, arg2;
4702 enum machine_mode mode0, mode1, mode2;
7c3abc73 4703 rtx pat, op0, op1, op2;
3a9b8c7e 4704 struct builtin_description *d;
a3170dc6 4705 size_t i;
f18c054f 4706
3a9b8c7e 4707 *expandedp = false;
f18c054f 4708
3a9b8c7e
AH
4709 /* Handle DST variants. */
4710 d = (struct builtin_description *) bdesc_dst;
4711 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4712 if (d->code == fcode)
4713 {
4714 arg0 = TREE_VALUE (arglist);
4715 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4716 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4717 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4718 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4719 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4720 mode0 = insn_data[d->icode].operand[0].mode;
4721 mode1 = insn_data[d->icode].operand[1].mode;
4722 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4723
3a9b8c7e
AH
4724 /* Invalid arguments, bail out before generating bad rtl. */
4725 if (arg0 == error_mark_node
4726 || arg1 == error_mark_node
4727 || arg2 == error_mark_node)
4728 return const0_rtx;
f18c054f 4729
3a9b8c7e
AH
4730 if (TREE_CODE (arg2) != INTEGER_CST
4731 || TREE_INT_CST_LOW (arg2) & ~0x3)
4732 {
4733 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4734 return const0_rtx;
4735 }
f18c054f 4736
3a9b8c7e
AH
4737 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4738 op0 = copy_to_mode_reg (mode0, op0);
4739 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4740 op1 = copy_to_mode_reg (mode1, op1);
24408032 4741
3a9b8c7e
AH
4742 pat = GEN_FCN (d->icode) (op0, op1, op2);
4743 if (pat != 0)
4744 emit_insn (pat);
f18c054f 4745
3a9b8c7e
AH
4746 *expandedp = true;
4747 return NULL_RTX;
4748 }
f18c054f 4749
3a9b8c7e
AH
4750 return NULL_RTX;
4751}
24408032 4752
3a9b8c7e
AH
4753/* Expand the builtin in EXP and store the result in TARGET. Store
4754 true in *EXPANDEDP if we found a builtin to expand. */
4755static rtx
4756altivec_expand_builtin (exp, target, expandedp)
4757 tree exp;
4758 rtx target;
4759 bool *expandedp;
4760{
4761 struct builtin_description *d;
4762 struct builtin_description_predicates *dp;
4763 size_t i;
4764 enum insn_code icode;
4765 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4766 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4767 tree arg0;
4768 rtx op0, pat;
4769 enum machine_mode tmode, mode0;
3a9b8c7e 4770 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4771
3a9b8c7e
AH
4772 target = altivec_expand_ld_builtin (exp, target, expandedp);
4773 if (*expandedp)
4774 return target;
0ac081f6 4775
3a9b8c7e
AH
4776 target = altivec_expand_st_builtin (exp, target, expandedp);
4777 if (*expandedp)
4778 return target;
4779
4780 target = altivec_expand_dst_builtin (exp, target, expandedp);
4781 if (*expandedp)
4782 return target;
4783
4784 *expandedp = true;
95385cbb 4785
3a9b8c7e
AH
4786 switch (fcode)
4787 {
6525c0e7
AH
4788 case ALTIVEC_BUILTIN_STVX:
4789 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4790 case ALTIVEC_BUILTIN_STVEBX:
4791 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4792 case ALTIVEC_BUILTIN_STVEHX:
4793 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4794 case ALTIVEC_BUILTIN_STVEWX:
4795 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4796 case ALTIVEC_BUILTIN_STVXL:
4797 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4798
95385cbb
AH
4799 case ALTIVEC_BUILTIN_MFVSCR:
4800 icode = CODE_FOR_altivec_mfvscr;
4801 tmode = insn_data[icode].operand[0].mode;
4802
4803 if (target == 0
4804 || GET_MODE (target) != tmode
4805 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4806 target = gen_reg_rtx (tmode);
4807
4808 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4809 if (! pat)
4810 return 0;
4811 emit_insn (pat);
95385cbb
AH
4812 return target;
4813
4814 case ALTIVEC_BUILTIN_MTVSCR:
4815 icode = CODE_FOR_altivec_mtvscr;
4816 arg0 = TREE_VALUE (arglist);
4817 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4818 mode0 = insn_data[icode].operand[0].mode;
4819
4820 /* If we got invalid arguments bail out before generating bad rtl. */
4821 if (arg0 == error_mark_node)
9a171fcd 4822 return const0_rtx;
95385cbb
AH
4823
4824 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4825 op0 = copy_to_mode_reg (mode0, op0);
4826
4827 pat = GEN_FCN (icode) (op0);
4828 if (pat)
4829 emit_insn (pat);
4830 return NULL_RTX;
3a9b8c7e 4831
95385cbb
AH
4832 case ALTIVEC_BUILTIN_DSSALL:
4833 emit_insn (gen_altivec_dssall ());
4834 return NULL_RTX;
4835
4836 case ALTIVEC_BUILTIN_DSS:
4837 icode = CODE_FOR_altivec_dss;
4838 arg0 = TREE_VALUE (arglist);
4839 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4840 mode0 = insn_data[icode].operand[0].mode;
4841
4842 /* If we got invalid arguments bail out before generating bad rtl. */
4843 if (arg0 == error_mark_node)
9a171fcd 4844 return const0_rtx;
95385cbb 4845
b44140e7
AH
4846 if (TREE_CODE (arg0) != INTEGER_CST
4847 || TREE_INT_CST_LOW (arg0) & ~0x3)
4848 {
4849 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4850 return const0_rtx;
b44140e7
AH
4851 }
4852
95385cbb
AH
4853 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4854 op0 = copy_to_mode_reg (mode0, op0);
4855
4856 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4857 return NULL_RTX;
4858 }
24408032 4859
100c4561
AH
4860 /* Expand abs* operations. */
4861 d = (struct builtin_description *) bdesc_abs;
ca7558fc 4862 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
4863 if (d->code == fcode)
4864 return altivec_expand_abs_builtin (d->icode, arglist, target);
4865
ae4b4a02
AH
4866 /* Expand the AltiVec predicates. */
4867 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 4868 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
4869 if (dp->code == fcode)
4870 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
4871
6525c0e7
AH
4872 /* LV* are funky. We initialized them differently. */
4873 switch (fcode)
4874 {
4875 case ALTIVEC_BUILTIN_LVSL:
92898235 4876 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
4877 arglist, target);
4878 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
4879 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
4880 arglist, target);
6525c0e7 4881 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
4882 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
4883 arglist, target);
6525c0e7 4884 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
4885 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
4886 arglist, target);
6525c0e7 4887 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
4888 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
4889 arglist, target);
6525c0e7 4890 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
4891 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
4892 arglist, target);
6525c0e7 4893 case ALTIVEC_BUILTIN_LVX:
92898235
AH
4894 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
4895 arglist, target);
6525c0e7
AH
4896 default:
4897 break;
4898 /* Fall through. */
4899 }
95385cbb 4900
92898235 4901 *expandedp = false;
0ac081f6
AH
4902 return NULL_RTX;
4903}
4904
a3170dc6
AH
4905/* Binops that need to be initialized manually, but can be expanded
4906 automagically by rs6000_expand_binop_builtin. */
4907static struct builtin_description bdesc_2arg_spe[] =
4908{
4909 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
4910 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
4911 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
4912 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
4913 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
4914 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
4915 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
4916 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
4917 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
4918 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
4919 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
4920 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
4921 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
4922 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
4923 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
4924 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
4925 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
4926 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
4927 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
4928 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
4929 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
4930 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
4931};
4932
4933/* Expand the builtin in EXP and store the result in TARGET. Store
4934 true in *EXPANDEDP if we found a builtin to expand.
4935
4936 This expands the SPE builtins that are not simple unary and binary
4937 operations. */
4938static rtx
4939spe_expand_builtin (exp, target, expandedp)
4940 tree exp;
4941 rtx target;
4942 bool *expandedp;
4943{
4944 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4945 tree arglist = TREE_OPERAND (exp, 1);
4946 tree arg1, arg0;
4947 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4948 enum insn_code icode;
4949 enum machine_mode tmode, mode0;
4950 rtx pat, op0;
4951 struct builtin_description *d;
4952 size_t i;
4953
4954 *expandedp = true;
4955
4956 /* Syntax check for a 5-bit unsigned immediate. */
4957 switch (fcode)
4958 {
4959 case SPE_BUILTIN_EVSTDD:
4960 case SPE_BUILTIN_EVSTDH:
4961 case SPE_BUILTIN_EVSTDW:
4962 case SPE_BUILTIN_EVSTWHE:
4963 case SPE_BUILTIN_EVSTWHO:
4964 case SPE_BUILTIN_EVSTWWE:
4965 case SPE_BUILTIN_EVSTWWO:
4966 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4967 if (TREE_CODE (arg1) != INTEGER_CST
4968 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4969 {
4970 error ("argument 2 must be a 5-bit unsigned literal");
4971 return const0_rtx;
4972 }
4973 break;
4974 default:
4975 break;
4976 }
4977
4978 d = (struct builtin_description *) bdesc_2arg_spe;
4979 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
4980 if (d->code == fcode)
4981 return rs6000_expand_binop_builtin (d->icode, arglist, target);
4982
4983 d = (struct builtin_description *) bdesc_spe_predicates;
4984 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
4985 if (d->code == fcode)
4986 return spe_expand_predicate_builtin (d->icode, arglist, target);
4987
4988 d = (struct builtin_description *) bdesc_spe_evsel;
4989 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
4990 if (d->code == fcode)
4991 return spe_expand_evsel_builtin (d->icode, arglist, target);
4992
4993 switch (fcode)
4994 {
4995 case SPE_BUILTIN_EVSTDDX:
4996 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
4997 case SPE_BUILTIN_EVSTDHX:
4998 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
4999 case SPE_BUILTIN_EVSTDWX:
5000 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
5001 case SPE_BUILTIN_EVSTWHEX:
5002 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
5003 case SPE_BUILTIN_EVSTWHOX:
5004 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
5005 case SPE_BUILTIN_EVSTWWEX:
5006 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
5007 case SPE_BUILTIN_EVSTWWOX:
5008 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
5009 case SPE_BUILTIN_EVSTDD:
5010 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
5011 case SPE_BUILTIN_EVSTDH:
5012 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
5013 case SPE_BUILTIN_EVSTDW:
5014 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
5015 case SPE_BUILTIN_EVSTWHE:
5016 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
5017 case SPE_BUILTIN_EVSTWHO:
5018 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
5019 case SPE_BUILTIN_EVSTWWE:
5020 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
5021 case SPE_BUILTIN_EVSTWWO:
5022 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
5023 case SPE_BUILTIN_MFSPEFSCR:
5024 icode = CODE_FOR_spe_mfspefscr;
5025 tmode = insn_data[icode].operand[0].mode;
5026
5027 if (target == 0
5028 || GET_MODE (target) != tmode
5029 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
5030 target = gen_reg_rtx (tmode);
5031
5032 pat = GEN_FCN (icode) (target);
5033 if (! pat)
5034 return 0;
5035 emit_insn (pat);
5036 return target;
5037 case SPE_BUILTIN_MTSPEFSCR:
5038 icode = CODE_FOR_spe_mtspefscr;
5039 arg0 = TREE_VALUE (arglist);
5040 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5041 mode0 = insn_data[icode].operand[0].mode;
5042
5043 if (arg0 == error_mark_node)
5044 return const0_rtx;
5045
5046 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
5047 op0 = copy_to_mode_reg (mode0, op0);
5048
5049 pat = GEN_FCN (icode) (op0);
5050 if (pat)
5051 emit_insn (pat);
5052 return NULL_RTX;
5053 default:
5054 break;
5055 }
5056
5057 *expandedp = false;
5058 return NULL_RTX;
5059}
5060
5061static rtx
5062spe_expand_predicate_builtin (icode, arglist, target)
5063 enum insn_code icode;
5064 tree arglist;
5065 rtx target;
5066{
5067 rtx pat, scratch, tmp;
5068 tree form = TREE_VALUE (arglist);
5069 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
5070 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5071 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5072 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5073 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5074 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5075 int form_int;
5076 enum rtx_code code;
5077
5078 if (TREE_CODE (form) != INTEGER_CST)
5079 {
5080 error ("argument 1 of __builtin_spe_predicate must be a constant");
5081 return const0_rtx;
5082 }
5083 else
5084 form_int = TREE_INT_CST_LOW (form);
5085
5086 if (mode0 != mode1)
5087 abort ();
5088
5089 if (arg0 == error_mark_node || arg1 == error_mark_node)
5090 return const0_rtx;
5091
5092 if (target == 0
5093 || GET_MODE (target) != SImode
5094 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
5095 target = gen_reg_rtx (SImode);
5096
5097 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5098 op0 = copy_to_mode_reg (mode0, op0);
5099 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
5100 op1 = copy_to_mode_reg (mode1, op1);
5101
5102 scratch = gen_reg_rtx (CCmode);
5103
5104 pat = GEN_FCN (icode) (scratch, op0, op1);
5105 if (! pat)
5106 return const0_rtx;
5107 emit_insn (pat);
5108
5109 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
5110 _lower_. We use one compare, but look in different bits of the
5111 CR for each variant.
5112
5113 There are 2 elements in each SPE simd type (upper/lower). The CR
5114 bits are set as follows:
5115
5116 BIT0 | BIT 1 | BIT 2 | BIT 3
5117 U | L | (U | L) | (U & L)
5118
5119 So, for an "all" relationship, BIT 3 would be set.
5120 For an "any" relationship, BIT 2 would be set. Etc.
5121
5122 Following traditional nomenclature, these bits map to:
5123
5124 BIT0 | BIT 1 | BIT 2 | BIT 3
5125 LT | GT | EQ | OV
5126
5127 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
5128 */
5129
5130 switch (form_int)
5131 {
5132 /* All variant. OV bit. */
5133 case 0:
5134 /* We need to get to the OV bit, which is the ORDERED bit. We
5135 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
5136 that's ugly and will trigger a validate_condition_mode abort.
5137 So let's just use another pattern. */
5138 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
5139 return target;
5140 /* Any variant. EQ bit. */
5141 case 1:
5142 code = EQ;
5143 break;
5144 /* Upper variant. LT bit. */
5145 case 2:
5146 code = LT;
5147 break;
5148 /* Lower variant. GT bit. */
5149 case 3:
5150 code = GT;
5151 break;
5152 default:
5153 error ("argument 1 of __builtin_spe_predicate is out of range");
5154 return const0_rtx;
5155 }
5156
5157 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5158 emit_move_insn (target, tmp);
5159
5160 return target;
5161}
5162
5163/* The evsel builtins look like this:
5164
5165 e = __builtin_spe_evsel_OP (a, b, c, d);
5166
5167 and work like this:
5168
5169 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5170 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5171*/
5172
5173static rtx
5174spe_expand_evsel_builtin (icode, arglist, target)
5175 enum insn_code icode;
5176 tree arglist;
5177 rtx target;
5178{
5179 rtx pat, scratch;
5180 tree arg0 = TREE_VALUE (arglist);
5181 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5182 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5183 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5184 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5185 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5186 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5187 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5188 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5189 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5190
5191 if (mode0 != mode1)
5192 abort ();
5193
5194 if (arg0 == error_mark_node || arg1 == error_mark_node
5195 || arg2 == error_mark_node || arg3 == error_mark_node)
5196 return const0_rtx;
5197
5198 if (target == 0
5199 || GET_MODE (target) != mode0
5200 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5201 target = gen_reg_rtx (mode0);
5202
5203 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5204 op0 = copy_to_mode_reg (mode0, op0);
5205 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5206 op1 = copy_to_mode_reg (mode0, op1);
5207 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5208 op2 = copy_to_mode_reg (mode0, op2);
5209 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5210 op3 = copy_to_mode_reg (mode0, op3);
5211
5212 /* Generate the compare. */
5213 scratch = gen_reg_rtx (CCmode);
5214 pat = GEN_FCN (icode) (scratch, op0, op1);
5215 if (! pat)
5216 return const0_rtx;
5217 emit_insn (pat);
5218
5219 if (mode0 == V2SImode)
5220 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5221 else
5222 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5223
5224 return target;
5225}
5226
0ac081f6
AH
5227/* Expand an expression EXP that calls a built-in function,
5228 with result going to TARGET if that's convenient
5229 (and in mode MODE if that's convenient).
5230 SUBTARGET may be used as the target for computing one of EXP's operands.
5231 IGNORE is nonzero if the value is to be ignored. */
5232
5233static rtx
5234rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5235 tree exp;
5236 rtx target;
00b960c7
AH
5237 rtx subtarget ATTRIBUTE_UNUSED;
5238 enum machine_mode mode ATTRIBUTE_UNUSED;
5239 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5240{
92898235
AH
5241 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5242 tree arglist = TREE_OPERAND (exp, 1);
5243 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5244 struct builtin_description *d;
5245 size_t i;
5246 rtx ret;
5247 bool success;
5248
0ac081f6 5249 if (TARGET_ALTIVEC)
92898235
AH
5250 {
5251 ret = altivec_expand_builtin (exp, target, &success);
5252
a3170dc6
AH
5253 if (success)
5254 return ret;
5255 }
5256 if (TARGET_SPE)
5257 {
5258 ret = spe_expand_builtin (exp, target, &success);
5259
92898235
AH
5260 if (success)
5261 return ret;
5262 }
5263
0559cc77
DE
5264 if (TARGET_ALTIVEC || TARGET_SPE)
5265 {
5266 /* Handle simple unary operations. */
5267 d = (struct builtin_description *) bdesc_1arg;
5268 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5269 if (d->code == fcode)
5270 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5271
5272 /* Handle simple binary operations. */
5273 d = (struct builtin_description *) bdesc_2arg;
5274 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5275 if (d->code == fcode)
5276 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5277
5278 /* Handle simple ternary operations. */
5279 d = (struct builtin_description *) bdesc_3arg;
5280 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5281 if (d->code == fcode)
5282 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5283 }
0ac081f6
AH
5284
5285 abort ();
92898235 5286 return NULL_RTX;
0ac081f6
AH
5287}
5288
5289static void
6fa3f289 5290rs6000_init_builtins ()
0ac081f6 5291{
a3170dc6
AH
5292 if (TARGET_SPE)
5293 spe_init_builtins ();
0ac081f6
AH
5294 if (TARGET_ALTIVEC)
5295 altivec_init_builtins ();
0559cc77
DE
5296 if (TARGET_ALTIVEC || TARGET_SPE)
5297 rs6000_common_init_builtins ();
0ac081f6
AH
5298}
5299
a3170dc6
AH
5300/* Search through a set of builtins and enable the mask bits.
5301 DESC is an array of builtins.
b6d08ca1 5302 SIZE is the total number of builtins.
a3170dc6
AH
5303 START is the builtin enum at which to start.
5304 END is the builtin enum at which to end. */
0ac081f6 5305static void
a3170dc6
AH
5306enable_mask_for_builtins (desc, size, start, end)
5307 struct builtin_description *desc;
5308 int size;
5309 enum rs6000_builtins start, end;
5310{
5311 int i;
5312
5313 for (i = 0; i < size; ++i)
5314 if (desc[i].code == start)
5315 break;
5316
5317 if (i == size)
5318 return;
5319
5320 for (; i < size; ++i)
5321 {
5322 /* Flip all the bits on. */
5323 desc[i].mask = target_flags;
5324 if (desc[i].code == end)
5325 break;
5326 }
5327}
5328
5329static void
b24c9d35 5330spe_init_builtins ()
0ac081f6 5331{
a3170dc6
AH
5332 tree endlink = void_list_node;
5333 tree puint_type_node = build_pointer_type (unsigned_type_node);
5334 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5335 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5336 struct builtin_description *d;
0ac081f6
AH
5337 size_t i;
5338
a3170dc6
AH
5339 tree v2si_ftype_4_v2si
5340 = build_function_type
5341 (V2SI_type_node,
5342 tree_cons (NULL_TREE, V2SI_type_node,
5343 tree_cons (NULL_TREE, V2SI_type_node,
5344 tree_cons (NULL_TREE, V2SI_type_node,
5345 tree_cons (NULL_TREE, V2SI_type_node,
5346 endlink)))));
5347
5348 tree v2sf_ftype_4_v2sf
5349 = build_function_type
5350 (V2SF_type_node,
5351 tree_cons (NULL_TREE, V2SF_type_node,
5352 tree_cons (NULL_TREE, V2SF_type_node,
5353 tree_cons (NULL_TREE, V2SF_type_node,
5354 tree_cons (NULL_TREE, V2SF_type_node,
5355 endlink)))));
5356
5357 tree int_ftype_int_v2si_v2si
5358 = build_function_type
5359 (integer_type_node,
5360 tree_cons (NULL_TREE, integer_type_node,
5361 tree_cons (NULL_TREE, V2SI_type_node,
5362 tree_cons (NULL_TREE, V2SI_type_node,
5363 endlink))));
5364
5365 tree int_ftype_int_v2sf_v2sf
5366 = build_function_type
5367 (integer_type_node,
5368 tree_cons (NULL_TREE, integer_type_node,
5369 tree_cons (NULL_TREE, V2SF_type_node,
5370 tree_cons (NULL_TREE, V2SF_type_node,
5371 endlink))));
5372
5373 tree void_ftype_v2si_puint_int
5374 = build_function_type (void_type_node,
5375 tree_cons (NULL_TREE, V2SI_type_node,
5376 tree_cons (NULL_TREE, puint_type_node,
5377 tree_cons (NULL_TREE,
5378 integer_type_node,
5379 endlink))));
5380
5381 tree void_ftype_v2si_puint_char
5382 = build_function_type (void_type_node,
5383 tree_cons (NULL_TREE, V2SI_type_node,
5384 tree_cons (NULL_TREE, puint_type_node,
5385 tree_cons (NULL_TREE,
5386 char_type_node,
5387 endlink))));
5388
5389 tree void_ftype_v2si_pv2si_int
5390 = build_function_type (void_type_node,
5391 tree_cons (NULL_TREE, V2SI_type_node,
5392 tree_cons (NULL_TREE, pv2si_type_node,
5393 tree_cons (NULL_TREE,
5394 integer_type_node,
5395 endlink))));
5396
5397 tree void_ftype_v2si_pv2si_char
5398 = build_function_type (void_type_node,
5399 tree_cons (NULL_TREE, V2SI_type_node,
5400 tree_cons (NULL_TREE, pv2si_type_node,
5401 tree_cons (NULL_TREE,
5402 char_type_node,
5403 endlink))));
5404
5405 tree void_ftype_int
5406 = build_function_type (void_type_node,
5407 tree_cons (NULL_TREE, integer_type_node, endlink));
5408
5409 tree int_ftype_void
5410 = build_function_type (integer_type_node,
5411 tree_cons (NULL_TREE, void_type_node, endlink));
5412
5413 tree v2si_ftype_pv2si_int
5414 = build_function_type (V2SI_type_node,
5415 tree_cons (NULL_TREE, pv2si_type_node,
5416 tree_cons (NULL_TREE, integer_type_node,
5417 endlink)));
5418
5419 tree v2si_ftype_puint_int
5420 = build_function_type (V2SI_type_node,
5421 tree_cons (NULL_TREE, puint_type_node,
5422 tree_cons (NULL_TREE, integer_type_node,
5423 endlink)));
5424
5425 tree v2si_ftype_pushort_int
5426 = build_function_type (V2SI_type_node,
5427 tree_cons (NULL_TREE, pushort_type_node,
5428 tree_cons (NULL_TREE, integer_type_node,
5429 endlink)));
5430
5431 /* The initialization of the simple binary and unary builtins is
5432 done in rs6000_common_init_builtins, but we have to enable the
5433 mask bits here manually because we have run out of `target_flags'
5434 bits. We really need to redesign this mask business. */
5435
5436 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5437 ARRAY_SIZE (bdesc_2arg),
5438 SPE_BUILTIN_EVADDW,
5439 SPE_BUILTIN_EVXOR);
5440 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5441 ARRAY_SIZE (bdesc_1arg),
5442 SPE_BUILTIN_EVABS,
5443 SPE_BUILTIN_EVSUBFUSIAAW);
5444 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5445 ARRAY_SIZE (bdesc_spe_predicates),
5446 SPE_BUILTIN_EVCMPEQ,
5447 SPE_BUILTIN_EVFSTSTLT);
5448 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5449 ARRAY_SIZE (bdesc_spe_evsel),
5450 SPE_BUILTIN_EVSEL_CMPGTS,
5451 SPE_BUILTIN_EVSEL_FSTSTEQ);
5452
5453 /* Initialize irregular SPE builtins. */
5454
5455 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5456 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5457 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5458 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5459 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5460 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5461 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5462 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5463 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5464 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5465 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5466 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5467 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5468 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5469 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5470 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5471
5472 /* Loads. */
5473 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5474 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5475 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5476 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5477 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5478 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5479 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5480 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5481 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5482 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5483 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5484 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5485 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5486 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5487 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5488 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5489 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5490 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5491 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5492 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5493 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5494 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5495
5496 /* Predicates. */
5497 d = (struct builtin_description *) bdesc_spe_predicates;
5498 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5499 {
5500 tree type;
5501
5502 switch (insn_data[d->icode].operand[1].mode)
5503 {
5504 case V2SImode:
5505 type = int_ftype_int_v2si_v2si;
5506 break;
5507 case V2SFmode:
5508 type = int_ftype_int_v2sf_v2sf;
5509 break;
5510 default:
5511 abort ();
5512 }
5513
5514 def_builtin (d->mask, d->name, type, d->code);
5515 }
5516
5517 /* Evsel predicates. */
5518 d = (struct builtin_description *) bdesc_spe_evsel;
5519 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5520 {
5521 tree type;
5522
5523 switch (insn_data[d->icode].operand[1].mode)
5524 {
5525 case V2SImode:
5526 type = v2si_ftype_4_v2si;
5527 break;
5528 case V2SFmode:
5529 type = v2sf_ftype_4_v2sf;
5530 break;
5531 default:
5532 abort ();
5533 }
5534
5535 def_builtin (d->mask, d->name, type, d->code);
5536 }
5537}
5538
5539static void
b24c9d35 5540altivec_init_builtins ()
a3170dc6
AH
5541{
5542 struct builtin_description *d;
5543 struct builtin_description_predicates *dp;
5544 size_t i;
5545 tree pfloat_type_node = build_pointer_type (float_type_node);
5546 tree pint_type_node = build_pointer_type (integer_type_node);
5547 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5548 tree pchar_type_node = build_pointer_type (char_type_node);
5549
5550 tree pvoid_type_node = build_pointer_type (void_type_node);
5551
0dbc3651
ZW
5552 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
5553 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
5554 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
5555 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
5556
5557 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
5558
a3170dc6
AH
5559 tree int_ftype_int_v4si_v4si
5560 = build_function_type_list (integer_type_node,
5561 integer_type_node, V4SI_type_node,
5562 V4SI_type_node, NULL_TREE);
0dbc3651
ZW
5563 tree v4sf_ftype_pcfloat
5564 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
a3170dc6 5565 tree void_ftype_pfloat_v4sf
b4de2f7d 5566 = build_function_type_list (void_type_node,
a3170dc6 5567 pfloat_type_node, V4SF_type_node, NULL_TREE);
0dbc3651
ZW
5568 tree v4si_ftype_pcint
5569 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
5570 tree void_ftype_pint_v4si
b4de2f7d
AH
5571 = build_function_type_list (void_type_node,
5572 pint_type_node, V4SI_type_node, NULL_TREE);
0dbc3651
ZW
5573 tree v8hi_ftype_pcshort
5574 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
f18c054f 5575 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5576 = build_function_type_list (void_type_node,
5577 pshort_type_node, V8HI_type_node, NULL_TREE);
0dbc3651
ZW
5578 tree v16qi_ftype_pcchar
5579 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
f18c054f 5580 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5581 = build_function_type_list (void_type_node,
5582 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5583 tree void_ftype_v4si
b4de2f7d 5584 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5585 tree v8hi_ftype_void
5586 = build_function_type (V8HI_type_node, void_list_node);
5587 tree void_ftype_void
5588 = build_function_type (void_type_node, void_list_node);
5589 tree void_ftype_qi
5590 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
0dbc3651
ZW
5591
5592 tree v16qi_ftype_int_pcvoid
a3170dc6 5593 = build_function_type_list (V16QI_type_node,
0dbc3651
ZW
5594 integer_type_node, pcvoid_type_node, NULL_TREE);
5595 tree v8hi_ftype_int_pcvoid
a3170dc6 5596 = build_function_type_list (V8HI_type_node,
0dbc3651
ZW
5597 integer_type_node, pcvoid_type_node, NULL_TREE);
5598 tree v4si_ftype_int_pcvoid
a3170dc6 5599 = build_function_type_list (V4SI_type_node,
0dbc3651
ZW
5600 integer_type_node, pcvoid_type_node, NULL_TREE);
5601
14b32f4e 5602 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5603 = build_function_type_list (void_type_node,
5604 V4SI_type_node, integer_type_node,
5605 pvoid_type_node, NULL_TREE);
6525c0e7 5606 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5607 = build_function_type_list (void_type_node,
5608 V16QI_type_node, integer_type_node,
5609 pvoid_type_node, NULL_TREE);
6525c0e7 5610 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5611 = build_function_type_list (void_type_node,
5612 V8HI_type_node, integer_type_node,
5613 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5614 tree int_ftype_int_v8hi_v8hi
5615 = build_function_type_list (integer_type_node,
5616 integer_type_node, V8HI_type_node,
5617 V8HI_type_node, NULL_TREE);
5618 tree int_ftype_int_v16qi_v16qi
5619 = build_function_type_list (integer_type_node,
5620 integer_type_node, V16QI_type_node,
5621 V16QI_type_node, NULL_TREE);
5622 tree int_ftype_int_v4sf_v4sf
5623 = build_function_type_list (integer_type_node,
5624 integer_type_node, V4SF_type_node,
5625 V4SF_type_node, NULL_TREE);
5626 tree v4si_ftype_v4si
5627 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5628 tree v8hi_ftype_v8hi
5629 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5630 tree v16qi_ftype_v16qi
5631 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5632 tree v4sf_ftype_v4sf
5633 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
0dbc3651 5634 tree void_ftype_pcvoid_int_char
a3170dc6 5635 = build_function_type_list (void_type_node,
0dbc3651 5636 pcvoid_type_node, integer_type_node,
a3170dc6 5637 char_type_node, NULL_TREE);
0dbc3651
ZW
5638
5639 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
5640 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5641 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
5642 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5643 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
5644 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5645 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
5646 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5647 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
5648 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5649 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
5650 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5651 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
5652 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5653 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
5654 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
a3170dc6
AH
5655 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5656 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5657 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5658 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
0dbc3651
ZW
5659 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSL);
5660 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSR);
5661 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEBX);
5662 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEHX);
5663 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEWX);
5664 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVXL);
5665 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVX);
a3170dc6
AH
5666 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5667 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5668 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5669 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5670 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5671
5672 /* Add the DST variants. */
5673 d = (struct builtin_description *) bdesc_dst;
5674 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
0dbc3651 5675 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_char, d->code);
a3170dc6
AH
5676
5677 /* Initialize the predicates. */
5678 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5679 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5680 {
5681 enum machine_mode mode1;
5682 tree type;
5683
5684 mode1 = insn_data[dp->icode].operand[1].mode;
5685
5686 switch (mode1)
5687 {
5688 case V4SImode:
5689 type = int_ftype_int_v4si_v4si;
5690 break;
5691 case V8HImode:
5692 type = int_ftype_int_v8hi_v8hi;
5693 break;
5694 case V16QImode:
5695 type = int_ftype_int_v16qi_v16qi;
5696 break;
5697 case V4SFmode:
5698 type = int_ftype_int_v4sf_v4sf;
5699 break;
5700 default:
5701 abort ();
5702 }
5703
5704 def_builtin (dp->mask, dp->name, type, dp->code);
5705 }
5706
5707 /* Initialize the abs* operators. */
5708 d = (struct builtin_description *) bdesc_abs;
5709 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5710 {
5711 enum machine_mode mode0;
5712 tree type;
5713
5714 mode0 = insn_data[d->icode].operand[0].mode;
5715
5716 switch (mode0)
5717 {
5718 case V4SImode:
5719 type = v4si_ftype_v4si;
5720 break;
5721 case V8HImode:
5722 type = v8hi_ftype_v8hi;
5723 break;
5724 case V16QImode:
5725 type = v16qi_ftype_v16qi;
5726 break;
5727 case V4SFmode:
5728 type = v4sf_ftype_v4sf;
5729 break;
5730 default:
5731 abort ();
5732 }
5733
5734 def_builtin (d->mask, d->name, type, d->code);
5735 }
5736}
5737
5738static void
b24c9d35 5739rs6000_common_init_builtins ()
a3170dc6
AH
5740{
5741 struct builtin_description *d;
5742 size_t i;
5743
5744 tree v4sf_ftype_v4sf_v4sf_v16qi
5745 = build_function_type_list (V4SF_type_node,
5746 V4SF_type_node, V4SF_type_node,
5747 V16QI_type_node, NULL_TREE);
5748 tree v4si_ftype_v4si_v4si_v16qi
5749 = build_function_type_list (V4SI_type_node,
5750 V4SI_type_node, V4SI_type_node,
5751 V16QI_type_node, NULL_TREE);
5752 tree v8hi_ftype_v8hi_v8hi_v16qi
5753 = build_function_type_list (V8HI_type_node,
5754 V8HI_type_node, V8HI_type_node,
5755 V16QI_type_node, NULL_TREE);
5756 tree v16qi_ftype_v16qi_v16qi_v16qi
5757 = build_function_type_list (V16QI_type_node,
5758 V16QI_type_node, V16QI_type_node,
5759 V16QI_type_node, NULL_TREE);
5760 tree v4si_ftype_char
5761 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5762 tree v8hi_ftype_char
5763 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5764 tree v16qi_ftype_char
5765 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5766 tree v8hi_ftype_v16qi
5767 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5768 tree v4sf_ftype_v4sf
5769 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5770
5771 tree v2si_ftype_v2si_v2si
5772 = build_function_type_list (V2SI_type_node,
5773 V2SI_type_node, V2SI_type_node, NULL_TREE);
5774
5775 tree v2sf_ftype_v2sf_v2sf
5776 = build_function_type_list (V2SF_type_node,
5777 V2SF_type_node, V2SF_type_node, NULL_TREE);
5778
5779 tree v2si_ftype_int_int
5780 = build_function_type_list (V2SI_type_node,
5781 integer_type_node, integer_type_node,
5782 NULL_TREE);
5783
5784 tree v2si_ftype_v2si
5785 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5786
5787 tree v2sf_ftype_v2sf
5788 = build_function_type_list (V2SF_type_node,
5789 V2SF_type_node, NULL_TREE);
5790
5791 tree v2sf_ftype_v2si
5792 = build_function_type_list (V2SF_type_node,
5793 V2SI_type_node, NULL_TREE);
5794
5795 tree v2si_ftype_v2sf
5796 = build_function_type_list (V2SI_type_node,
5797 V2SF_type_node, NULL_TREE);
5798
5799 tree v2si_ftype_v2si_char
5800 = build_function_type_list (V2SI_type_node,
5801 V2SI_type_node, char_type_node, NULL_TREE);
5802
5803 tree v2si_ftype_int_char
5804 = build_function_type_list (V2SI_type_node,
5805 integer_type_node, char_type_node, NULL_TREE);
5806
5807 tree v2si_ftype_char
5808 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5809
5810 tree int_ftype_int_int
5811 = build_function_type_list (integer_type_node,
5812 integer_type_node, integer_type_node,
5813 NULL_TREE);
95385cbb 5814
0ac081f6 5815 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5816 = build_function_type_list (V4SI_type_node,
5817 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5818 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5819 = build_function_type_list (V4SF_type_node,
5820 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5821 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5822 = build_function_type_list (V4SI_type_node,
5823 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5824 tree v4si_ftype_v4si_char
b4de2f7d
AH
5825 = build_function_type_list (V4SI_type_node,
5826 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5827 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5828 = build_function_type_list (V8HI_type_node,
5829 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5830 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5831 = build_function_type_list (V16QI_type_node,
5832 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5833 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5834 = build_function_type_list (V16QI_type_node,
5835 V16QI_type_node, V16QI_type_node,
5836 char_type_node, NULL_TREE);
24408032 5837 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5838 = build_function_type_list (V8HI_type_node,
5839 V8HI_type_node, V8HI_type_node,
5840 char_type_node, NULL_TREE);
24408032 5841 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5842 = build_function_type_list (V4SI_type_node,
5843 V4SI_type_node, V4SI_type_node,
5844 char_type_node, NULL_TREE);
24408032 5845 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5846 = build_function_type_list (V4SF_type_node,
5847 V4SF_type_node, V4SF_type_node,
5848 char_type_node, NULL_TREE);
0ac081f6 5849 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5850 = build_function_type_list (V4SF_type_node,
5851 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5852 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5853 = build_function_type_list (V4SF_type_node,
5854 V4SF_type_node, V4SF_type_node,
5855 V4SI_type_node, NULL_TREE);
2212663f 5856 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5857 = build_function_type_list (V4SF_type_node,
5858 V4SF_type_node, V4SF_type_node,
5859 V4SF_type_node, NULL_TREE);
617e0e1d 5860 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
5861 = build_function_type_list (V4SI_type_node,
5862 V4SI_type_node, V4SI_type_node,
5863 V4SI_type_node, NULL_TREE);
0ac081f6 5864 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
5865 = build_function_type_list (V8HI_type_node,
5866 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 5867 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
5868 = build_function_type_list (V8HI_type_node,
5869 V8HI_type_node, V8HI_type_node,
5870 V8HI_type_node, NULL_TREE);
2212663f 5871 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
5872 = build_function_type_list (V4SI_type_node,
5873 V8HI_type_node, V8HI_type_node,
5874 V4SI_type_node, NULL_TREE);
2212663f 5875 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
5876 = build_function_type_list (V4SI_type_node,
5877 V16QI_type_node, V16QI_type_node,
5878 V4SI_type_node, NULL_TREE);
0ac081f6 5879 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
5880 = build_function_type_list (V16QI_type_node,
5881 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5882 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
5883 = build_function_type_list (V4SI_type_node,
5884 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 5885 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
5886 = build_function_type_list (V8HI_type_node,
5887 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5888 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
5889 = build_function_type_list (V4SI_type_node,
5890 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5891 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
5892 = build_function_type_list (V8HI_type_node,
5893 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 5894 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
5895 = build_function_type_list (V16QI_type_node,
5896 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5897 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
5898 = build_function_type_list (V4SI_type_node,
5899 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 5900 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
5901 = build_function_type_list (V4SI_type_node,
5902 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5903 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
5904 = build_function_type_list (V4SI_type_node,
5905 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5906 tree v4si_ftype_v8hi
5907 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
5908 tree int_ftype_v4si_v4si
5909 = build_function_type_list (integer_type_node,
5910 V4SI_type_node, V4SI_type_node, NULL_TREE);
5911 tree int_ftype_v4sf_v4sf
5912 = build_function_type_list (integer_type_node,
5913 V4SF_type_node, V4SF_type_node, NULL_TREE);
5914 tree int_ftype_v16qi_v16qi
5915 = build_function_type_list (integer_type_node,
5916 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 5917 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
5918 = build_function_type_list (integer_type_node,
5919 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 5920
6f317ef3 5921 /* Add the simple ternary operators. */
2212663f 5922 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 5923 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
5924 {
5925
5926 enum machine_mode mode0, mode1, mode2, mode3;
5927 tree type;
5928
0559cc77 5929 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
5930 continue;
5931
5932 mode0 = insn_data[d->icode].operand[0].mode;
5933 mode1 = insn_data[d->icode].operand[1].mode;
5934 mode2 = insn_data[d->icode].operand[2].mode;
5935 mode3 = insn_data[d->icode].operand[3].mode;
5936
5937 /* When all four are of the same mode. */
5938 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
5939 {
5940 switch (mode0)
5941 {
617e0e1d
DB
5942 case V4SImode:
5943 type = v4si_ftype_v4si_v4si_v4si;
5944 break;
2212663f
DB
5945 case V4SFmode:
5946 type = v4sf_ftype_v4sf_v4sf_v4sf;
5947 break;
5948 case V8HImode:
5949 type = v8hi_ftype_v8hi_v8hi_v8hi;
5950 break;
5951 case V16QImode:
5952 type = v16qi_ftype_v16qi_v16qi_v16qi;
5953 break;
5954 default:
5955 abort();
5956 }
5957 }
5958 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
5959 {
5960 switch (mode0)
5961 {
5962 case V4SImode:
5963 type = v4si_ftype_v4si_v4si_v16qi;
5964 break;
5965 case V4SFmode:
5966 type = v4sf_ftype_v4sf_v4sf_v16qi;
5967 break;
5968 case V8HImode:
5969 type = v8hi_ftype_v8hi_v8hi_v16qi;
5970 break;
5971 case V16QImode:
5972 type = v16qi_ftype_v16qi_v16qi_v16qi;
5973 break;
5974 default:
5975 abort();
5976 }
5977 }
5978 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
5979 && mode3 == V4SImode)
24408032 5980 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
5981 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
5982 && mode3 == V4SImode)
24408032 5983 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
5984 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
5985 && mode3 == V4SImode)
24408032
AH
5986 type = v4sf_ftype_v4sf_v4sf_v4si;
5987
5988 /* vchar, vchar, vchar, 4 bit literal. */
5989 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
5990 && mode3 == QImode)
5991 type = v16qi_ftype_v16qi_v16qi_char;
5992
5993 /* vshort, vshort, vshort, 4 bit literal. */
5994 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
5995 && mode3 == QImode)
5996 type = v8hi_ftype_v8hi_v8hi_char;
5997
5998 /* vint, vint, vint, 4 bit literal. */
5999 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
6000 && mode3 == QImode)
6001 type = v4si_ftype_v4si_v4si_char;
6002
6003 /* vfloat, vfloat, vfloat, 4 bit literal. */
6004 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
6005 && mode3 == QImode)
6006 type = v4sf_ftype_v4sf_v4sf_char;
6007
2212663f
DB
6008 else
6009 abort ();
6010
6011 def_builtin (d->mask, d->name, type, d->code);
6012 }
6013
0ac081f6 6014 /* Add the simple binary operators. */
00b960c7 6015 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 6016 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
6017 {
6018 enum machine_mode mode0, mode1, mode2;
6019 tree type;
6020
0559cc77 6021 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
6022 continue;
6023
6024 mode0 = insn_data[d->icode].operand[0].mode;
6025 mode1 = insn_data[d->icode].operand[1].mode;
6026 mode2 = insn_data[d->icode].operand[2].mode;
6027
6028 /* When all three operands are of the same mode. */
6029 if (mode0 == mode1 && mode1 == mode2)
6030 {
6031 switch (mode0)
6032 {
6033 case V4SFmode:
6034 type = v4sf_ftype_v4sf_v4sf;
6035 break;
6036 case V4SImode:
6037 type = v4si_ftype_v4si_v4si;
6038 break;
6039 case V16QImode:
6040 type = v16qi_ftype_v16qi_v16qi;
6041 break;
6042 case V8HImode:
6043 type = v8hi_ftype_v8hi_v8hi;
6044 break;
a3170dc6
AH
6045 case V2SImode:
6046 type = v2si_ftype_v2si_v2si;
6047 break;
6048 case V2SFmode:
6049 type = v2sf_ftype_v2sf_v2sf;
6050 break;
6051 case SImode:
6052 type = int_ftype_int_int;
6053 break;
0ac081f6
AH
6054 default:
6055 abort ();
6056 }
6057 }
6058
6059 /* A few other combos we really don't want to do manually. */
6060
6061 /* vint, vfloat, vfloat. */
6062 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
6063 type = v4si_ftype_v4sf_v4sf;
6064
6065 /* vshort, vchar, vchar. */
6066 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
6067 type = v8hi_ftype_v16qi_v16qi;
6068
6069 /* vint, vshort, vshort. */
6070 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
6071 type = v4si_ftype_v8hi_v8hi;
6072
6073 /* vshort, vint, vint. */
6074 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
6075 type = v8hi_ftype_v4si_v4si;
6076
6077 /* vchar, vshort, vshort. */
6078 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
6079 type = v16qi_ftype_v8hi_v8hi;
6080
6081 /* vint, vchar, vint. */
6082 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
6083 type = v4si_ftype_v16qi_v4si;
6084
fa066a23
AH
6085 /* vint, vchar, vchar. */
6086 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
6087 type = v4si_ftype_v16qi_v16qi;
6088
0ac081f6
AH
6089 /* vint, vshort, vint. */
6090 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
6091 type = v4si_ftype_v8hi_v4si;
2212663f
DB
6092
6093 /* vint, vint, 5 bit literal. */
6094 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
6095 type = v4si_ftype_v4si_char;
6096
6097 /* vshort, vshort, 5 bit literal. */
6098 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
6099 type = v8hi_ftype_v8hi_char;
6100
6101 /* vchar, vchar, 5 bit literal. */
6102 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
6103 type = v16qi_ftype_v16qi_char;
0ac081f6 6104
617e0e1d
DB
6105 /* vfloat, vint, 5 bit literal. */
6106 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
6107 type = v4sf_ftype_v4si_char;
6108
6109 /* vint, vfloat, 5 bit literal. */
6110 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
6111 type = v4si_ftype_v4sf_char;
6112
a3170dc6
AH
6113 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
6114 type = v2si_ftype_int_int;
6115
6116 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
6117 type = v2si_ftype_v2si_char;
6118
6119 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
6120 type = v2si_ftype_int_char;
6121
0ac081f6
AH
6122 /* int, x, x. */
6123 else if (mode0 == SImode)
6124 {
6125 switch (mode1)
6126 {
6127 case V4SImode:
6128 type = int_ftype_v4si_v4si;
6129 break;
6130 case V4SFmode:
6131 type = int_ftype_v4sf_v4sf;
6132 break;
6133 case V16QImode:
6134 type = int_ftype_v16qi_v16qi;
6135 break;
6136 case V8HImode:
6137 type = int_ftype_v8hi_v8hi;
6138 break;
6139 default:
6140 abort ();
6141 }
6142 }
6143
6144 else
6145 abort ();
6146
2212663f
DB
6147 def_builtin (d->mask, d->name, type, d->code);
6148 }
24408032 6149
2212663f
DB
6150 /* Add the simple unary operators. */
6151 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 6152 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
6153 {
6154 enum machine_mode mode0, mode1;
6155 tree type;
6156
0559cc77 6157 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
6158 continue;
6159
6160 mode0 = insn_data[d->icode].operand[0].mode;
6161 mode1 = insn_data[d->icode].operand[1].mode;
6162
6163 if (mode0 == V4SImode && mode1 == QImode)
6164 type = v4si_ftype_char;
6165 else if (mode0 == V8HImode && mode1 == QImode)
6166 type = v8hi_ftype_char;
6167 else if (mode0 == V16QImode && mode1 == QImode)
6168 type = v16qi_ftype_char;
617e0e1d
DB
6169 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6170 type = v4sf_ftype_v4sf;
20e26713
AH
6171 else if (mode0 == V8HImode && mode1 == V16QImode)
6172 type = v8hi_ftype_v16qi;
6173 else if (mode0 == V4SImode && mode1 == V8HImode)
6174 type = v4si_ftype_v8hi;
a3170dc6
AH
6175 else if (mode0 == V2SImode && mode1 == V2SImode)
6176 type = v2si_ftype_v2si;
6177 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6178 type = v2sf_ftype_v2sf;
6179 else if (mode0 == V2SFmode && mode1 == V2SImode)
6180 type = v2sf_ftype_v2si;
6181 else if (mode0 == V2SImode && mode1 == V2SFmode)
6182 type = v2si_ftype_v2sf;
6183 else if (mode0 == V2SImode && mode1 == QImode)
6184 type = v2si_ftype_char;
2212663f
DB
6185 else
6186 abort ();
6187
0ac081f6
AH
6188 def_builtin (d->mask, d->name, type, d->code);
6189 }
6190}
6191
35aff10b 6192\f
7e69e155
MM
6193/* Expand a block move operation, and return 1 if successful. Return 0
6194 if we should let the compiler generate normal code.
6195
6196 operands[0] is the destination
6197 operands[1] is the source
6198 operands[2] is the length
6199 operands[3] is the alignment */
6200
3933e0e1
MM
6201#define MAX_MOVE_REG 4
6202
7e69e155
MM
6203int
6204expand_block_move (operands)
6205 rtx operands[];
6206{
b6c9286a
MM
6207 rtx orig_dest = operands[0];
6208 rtx orig_src = operands[1];
7e69e155 6209 rtx bytes_rtx = operands[2];
7e69e155 6210 rtx align_rtx = operands[3];
3933e0e1 6211 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6212 int align;
3933e0e1
MM
6213 int bytes;
6214 int offset;
7e69e155
MM
6215 int move_bytes;
6216
3933e0e1 6217 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6218 if (! constp)
3933e0e1
MM
6219 return 0;
6220
5ee95df6
FS
6221 /* If this is not a fixed size alignment, abort */
6222 if (GET_CODE (align_rtx) != CONST_INT)
6223 abort ();
6224 align = INTVAL (align_rtx);
6225
7e69e155 6226 /* Anything to move? */
3933e0e1
MM
6227 bytes = INTVAL (bytes_rtx);
6228 if (bytes <= 0)
7e69e155
MM
6229 return 1;
6230
ea9982a8 6231 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6232 reg_parm_stack_space. */
ea9982a8 6233 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6234 return 0;
6235
3933e0e1 6236 if (TARGET_STRING) /* string instructions are available */
7e69e155 6237 {
35aff10b 6238 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6239 {
35aff10b
AM
6240 union {
6241 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
6242 rtx (*mov) PARAMS ((rtx, rtx));
6243 } gen_func;
6244 enum machine_mode mode = BLKmode;
6245 rtx src, dest;
6246
3933e0e1 6247 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6248 && ! fixed_regs[5]
6249 && ! fixed_regs[6]
6250 && ! fixed_regs[7]
6251 && ! fixed_regs[8]
6252 && ! fixed_regs[9]
6253 && ! fixed_regs[10]
6254 && ! fixed_regs[11]
6255 && ! fixed_regs[12])
3933e0e1
MM
6256 {
6257 move_bytes = (bytes > 32) ? 32 : bytes;
35aff10b 6258 gen_func.movstrsi = gen_movstrsi_8reg;
3933e0e1
MM
6259 }
6260 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6261 && ! fixed_regs[5]
6262 && ! fixed_regs[6]
cc0d9ba8
DE
6263 && ! fixed_regs[7]
6264 && ! fixed_regs[8]
6265 && ! fixed_regs[9]
f9562f27 6266 && ! fixed_regs[10])
3933e0e1
MM
6267 {
6268 move_bytes = (bytes > 24) ? 24 : bytes;
35aff10b 6269 gen_func.movstrsi = gen_movstrsi_6reg;
3933e0e1
MM
6270 }
6271 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6272 && ! fixed_regs[5]
6273 && ! fixed_regs[6]
6274 && ! fixed_regs[7]
6275 && ! fixed_regs[8])
3933e0e1
MM
6276 {
6277 move_bytes = (bytes > 16) ? 16 : bytes;
35aff10b 6278 gen_func.movstrsi = gen_movstrsi_4reg;
3933e0e1 6279 }
acad7ed3 6280 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6281 /* 64-bit loads and stores require word-aligned
82e41834 6282 displacements. */
a4f6c312 6283 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6284 {
6285 move_bytes = 8;
35aff10b
AM
6286 mode = DImode;
6287 gen_func.mov = gen_movdi;
acad7ed3 6288 }
09a625f7 6289 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6290 { /* move up to 8 bytes at a time */
6291 move_bytes = (bytes > 8) ? 8 : bytes;
35aff10b 6292 gen_func.movstrsi = gen_movstrsi_2reg;
3933e0e1 6293 }
cc0d9ba8 6294 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6295 { /* move 4 bytes */
6296 move_bytes = 4;
35aff10b
AM
6297 mode = SImode;
6298 gen_func.mov = gen_movsi;
3933e0e1 6299 }
cc0d9ba8 6300 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6301 { /* move 2 bytes */
6302 move_bytes = 2;
35aff10b
AM
6303 mode = HImode;
6304 gen_func.mov = gen_movhi;
3933e0e1
MM
6305 }
6306 else if (bytes == 1) /* move 1 byte */
6307 {
6308 move_bytes = 1;
35aff10b
AM
6309 mode = QImode;
6310 gen_func.mov = gen_movqi;
3933e0e1
MM
6311 }
6312 else
6313 { /* move up to 4 bytes at a time */
6314 move_bytes = (bytes > 4) ? 4 : bytes;
35aff10b 6315 gen_func.movstrsi = gen_movstrsi_1reg;
3933e0e1 6316 }
4c64a852 6317
35aff10b
AM
6318 src = adjust_address (orig_src, mode, offset);
6319 dest = adjust_address (orig_dest, mode, offset);
6320
6321 if (mode == BLKmode)
015892ee 6322 {
35aff10b
AM
6323 /* Move the address into scratch registers. The movstrsi
6324 patterns require zero offset. */
6325 if (!REG_P (XEXP (src, 0)))
cc0d9ba8 6326 {
35aff10b
AM
6327 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
6328 src = replace_equiv_address (src, src_reg);
cc0d9ba8 6329 }
35aff10b
AM
6330 set_mem_size (src, GEN_INT (move_bytes));
6331
6332 if (!REG_P (XEXP (dest, 0)))
cc0d9ba8 6333 {
35aff10b
AM
6334 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
6335 dest = replace_equiv_address (dest, dest_reg);
cc0d9ba8 6336 }
35aff10b
AM
6337 set_mem_size (dest, GEN_INT (move_bytes));
6338
6339 emit_insn ((*gen_func.movstrsi) (dest, src,
6340 GEN_INT (move_bytes & 31),
6341 align_rtx));
6342 }
6343 else
6344 {
6345 rtx tmp_reg = gen_reg_rtx (mode);
6346
6347 emit_insn ((*gen_func.mov) (tmp_reg, src));
6348 emit_insn ((*gen_func.mov) (dest, tmp_reg));
015892ee 6349 }
4c64a852 6350 }
3933e0e1
MM
6351 }
6352
6353 else /* string instructions not available */
6354 {
35aff10b
AM
6355 rtx stores[MAX_MOVE_REG];
6356 int num_reg = 0;
6357 int i;
6358
6359 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6360 {
35aff10b
AM
6361 rtx (*gen_mov_func) PARAMS ((rtx, rtx));
6362 enum machine_mode mode;
6363 rtx src, dest, tmp_reg;
3933e0e1 6364
cc0d9ba8
DE
6365 /* Generate the appropriate load and store, saving the stores
6366 for later. */
6367 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6368 /* 64-bit loads and stores require word-aligned
6369 displacements. */
cc0d9ba8 6370 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6371 {
6372 move_bytes = 8;
35aff10b
AM
6373 mode = DImode;
6374 gen_mov_func = gen_movdi;
b6c9286a 6375 }
cc0d9ba8 6376 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6377 {
6378 move_bytes = 4;
35aff10b
AM
6379 mode = SImode;
6380 gen_mov_func = gen_movsi;
3933e0e1 6381 }
cc0d9ba8 6382 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6383 {
6384 move_bytes = 2;
35aff10b
AM
6385 mode = HImode;
6386 gen_mov_func = gen_movhi;
3933e0e1
MM
6387 }
6388 else
6389 {
6390 move_bytes = 1;
35aff10b
AM
6391 mode = QImode;
6392 gen_mov_func = gen_movqi;
3933e0e1
MM
6393 }
6394
35aff10b
AM
6395 src = adjust_address (orig_src, mode, offset);
6396 dest = adjust_address (orig_dest, mode, offset);
6397 tmp_reg = gen_reg_rtx (mode);
6398
6399 emit_insn ((*gen_mov_func) (tmp_reg, src));
6400 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
6401
3933e0e1
MM
6402 if (num_reg >= MAX_MOVE_REG)
6403 {
6404 for (i = 0; i < num_reg; i++)
6405 emit_insn (stores[i]);
6406 num_reg = 0;
7e69e155
MM
6407 }
6408 }
3933e0e1 6409
b6c9286a
MM
6410 for (i = 0; i < num_reg; i++)
6411 emit_insn (stores[i]);
7e69e155
MM
6412 }
6413
6414 return 1;
6415}
6416
9878760c
RK
6417\f
6418/* Return 1 if OP is a load multiple operation. It is known to be a
6419 PARALLEL and the first section will be tested. */
6420
6421int
6422load_multiple_operation (op, mode)
6423 rtx op;
296b8152 6424 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6425{
6426 int count = XVECLEN (op, 0);
e2c953b6 6427 unsigned int dest_regno;
9878760c
RK
6428 rtx src_addr;
6429 int i;
6430
6431 /* Perform a quick check so we don't blow up below. */
6432 if (count <= 1
6433 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6434 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6435 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6436 return 0;
6437
6438 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6439 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6440
6441 for (i = 1; i < count; i++)
6442 {
6443 rtx elt = XVECEXP (op, 0, i);
6444
6445 if (GET_CODE (elt) != SET
6446 || GET_CODE (SET_DEST (elt)) != REG
6447 || GET_MODE (SET_DEST (elt)) != SImode
6448 || REGNO (SET_DEST (elt)) != dest_regno + i
6449 || GET_CODE (SET_SRC (elt)) != MEM
6450 || GET_MODE (SET_SRC (elt)) != SImode
6451 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6452 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6453 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6454 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6455 return 0;
6456 }
6457
6458 return 1;
6459}
6460
6461/* Similar, but tests for store multiple. Here, the second vector element
6462 is a CLOBBER. It will be tested later. */
6463
6464int
6465store_multiple_operation (op, mode)
6466 rtx op;
296b8152 6467 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6468{
6469 int count = XVECLEN (op, 0) - 1;
e2c953b6 6470 unsigned int src_regno;
9878760c
RK
6471 rtx dest_addr;
6472 int i;
6473
6474 /* Perform a quick check so we don't blow up below. */
6475 if (count <= 1
6476 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6477 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6478 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6479 return 0;
6480
6481 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6482 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6483
6484 for (i = 1; i < count; i++)
6485 {
6486 rtx elt = XVECEXP (op, 0, i + 1);
6487
6488 if (GET_CODE (elt) != SET
6489 || GET_CODE (SET_SRC (elt)) != REG
6490 || GET_MODE (SET_SRC (elt)) != SImode
6491 || REGNO (SET_SRC (elt)) != src_regno + i
6492 || GET_CODE (SET_DEST (elt)) != MEM
6493 || GET_MODE (SET_DEST (elt)) != SImode
6494 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6495 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6496 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6497 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6498 return 0;
6499 }
6500
6501 return 1;
6502}
9ebbca7d 6503
9caa3eb2
DE
6504/* Return a string to perform a load_multiple operation.
6505 operands[0] is the vector.
6506 operands[1] is the source address.
6507 operands[2] is the first destination register. */
6508
6509const char *
6510rs6000_output_load_multiple (operands)
ebe637e3 6511 rtx operands[3];
9caa3eb2
DE
6512{
6513 /* We have to handle the case where the pseudo used to contain the address
6514 is assigned to one of the output registers. */
6515 int i, j;
6516 int words = XVECLEN (operands[0], 0);
6517 rtx xop[10];
6518
6519 if (XVECLEN (operands[0], 0) == 1)
6520 return "{l|lwz} %2,0(%1)";
6521
6522 for (i = 0; i < words; i++)
6523 if (refers_to_regno_p (REGNO (operands[2]) + i,
6524 REGNO (operands[2]) + i + 1, operands[1], 0))
6525 {
6526 if (i == words-1)
6527 {
6528 xop[0] = GEN_INT (4 * (words-1));
6529 xop[1] = operands[1];
6530 xop[2] = operands[2];
6531 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
6532 return "";
6533 }
6534 else if (i == 0)
6535 {
6536 xop[0] = GEN_INT (4 * (words-1));
6537 xop[1] = operands[1];
6538 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
6539 output_asm_insn ("{cal %1,4(%1)|addi %1,%1,4}\n\t{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,-4(%1)", xop);
6540 return "";
6541 }
6542 else
6543 {
6544 for (j = 0; j < words; j++)
6545 if (j != i)
6546 {
6547 xop[0] = GEN_INT (j * 4);
6548 xop[1] = operands[1];
6549 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
6550 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
6551 }
6552 xop[0] = GEN_INT (i * 4);
6553 xop[1] = operands[1];
6554 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
6555 return "";
6556 }
6557 }
6558
6559 return "{lsi|lswi} %2,%1,%N0";
6560}
6561
00b960c7
AH
6562/* Return 1 for a parallel vrsave operation. */
6563
6564int
6565vrsave_operation (op, mode)
6566 rtx op;
6567 enum machine_mode mode ATTRIBUTE_UNUSED;
6568{
6569 int count = XVECLEN (op, 0);
6570 unsigned int dest_regno, src_regno;
6571 int i;
6572
6573 if (count <= 1
6574 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6575 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6576 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6577 return 0;
6578
6579 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6580 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6581
6582 if (dest_regno != VRSAVE_REGNO
6583 && src_regno != VRSAVE_REGNO)
6584 return 0;
6585
6586 for (i = 1; i < count; i++)
6587 {
6588 rtx elt = XVECEXP (op, 0, i);
6589
9aa86737
AH
6590 if (GET_CODE (elt) != CLOBBER
6591 && GET_CODE (elt) != SET)
00b960c7
AH
6592 return 0;
6593 }
6594
6595 return 1;
6596}
6597
a4f6c312 6598/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6599
6600int
6601mtcrf_operation (op, mode)
6602 rtx op;
6603 enum machine_mode mode ATTRIBUTE_UNUSED;
6604{
6605 int count = XVECLEN (op, 0);
6606 int i;
9ebbca7d
GK
6607 rtx src_reg;
6608
6609 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6610 if (count < 1
6611 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6612 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6613 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6614 return 0;
e35b9579 6615 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6616
6617 if (GET_CODE (src_reg) != REG
6618 || GET_MODE (src_reg) != SImode
6619 || ! INT_REGNO_P (REGNO (src_reg)))
6620 return 0;
6621
e35b9579 6622 for (i = 0; i < count; i++)
9ebbca7d
GK
6623 {
6624 rtx exp = XVECEXP (op, 0, i);
6625 rtx unspec;
6626 int maskval;
6627
6628 if (GET_CODE (exp) != SET
6629 || GET_CODE (SET_DEST (exp)) != REG
6630 || GET_MODE (SET_DEST (exp)) != CCmode
6631 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6632 return 0;
6633 unspec = SET_SRC (exp);
6634 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6635
6636 if (GET_CODE (unspec) != UNSPEC
6637 || XINT (unspec, 1) != 20
6638 || XVECLEN (unspec, 0) != 2
6639 || XVECEXP (unspec, 0, 0) != src_reg
6640 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6641 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6642 return 0;
6643 }
e35b9579 6644 return 1;
9ebbca7d
GK
6645}
6646
a4f6c312 6647/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6648
6649int
6650lmw_operation (op, mode)
6651 rtx op;
6652 enum machine_mode mode ATTRIBUTE_UNUSED;
6653{
6654 int count = XVECLEN (op, 0);
e2c953b6 6655 unsigned int dest_regno;
9ebbca7d 6656 rtx src_addr;
e2c953b6 6657 unsigned int base_regno;
9ebbca7d
GK
6658 HOST_WIDE_INT offset;
6659 int i;
6660
6661 /* Perform a quick check so we don't blow up below. */
6662 if (count <= 1
6663 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6664 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6665 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6666 return 0;
6667
6668 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6669 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6670
6671 if (dest_regno > 31
e2c953b6 6672 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6673 return 0;
6674
258bfae2 6675 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6676 {
6677 offset = 0;
6678 base_regno = REGNO (src_addr);
6679 if (base_regno == 0)
6680 return 0;
6681 }
258bfae2 6682 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6683 {
6684 offset = INTVAL (XEXP (src_addr, 1));
6685 base_regno = REGNO (XEXP (src_addr, 0));
6686 }
6687 else
6688 return 0;
6689
6690 for (i = 0; i < count; i++)
6691 {
6692 rtx elt = XVECEXP (op, 0, i);
6693 rtx newaddr;
6694 rtx addr_reg;
6695 HOST_WIDE_INT newoffset;
6696
6697 if (GET_CODE (elt) != SET
6698 || GET_CODE (SET_DEST (elt)) != REG
6699 || GET_MODE (SET_DEST (elt)) != SImode
6700 || REGNO (SET_DEST (elt)) != dest_regno + i
6701 || GET_CODE (SET_SRC (elt)) != MEM
6702 || GET_MODE (SET_SRC (elt)) != SImode)
6703 return 0;
6704 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6705 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6706 {
6707 newoffset = 0;
6708 addr_reg = newaddr;
6709 }
258bfae2 6710 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6711 {
6712 addr_reg = XEXP (newaddr, 0);
6713 newoffset = INTVAL (XEXP (newaddr, 1));
6714 }
6715 else
6716 return 0;
6717 if (REGNO (addr_reg) != base_regno
6718 || newoffset != offset + 4 * i)
6719 return 0;
6720 }
6721
6722 return 1;
6723}
6724
a4f6c312 6725/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6726
6727int
6728stmw_operation (op, mode)
6729 rtx op;
6730 enum machine_mode mode ATTRIBUTE_UNUSED;
6731{
6732 int count = XVECLEN (op, 0);
e2c953b6 6733 unsigned int src_regno;
9ebbca7d 6734 rtx dest_addr;
e2c953b6 6735 unsigned int base_regno;
9ebbca7d
GK
6736 HOST_WIDE_INT offset;
6737 int i;
6738
6739 /* Perform a quick check so we don't blow up below. */
6740 if (count <= 1
6741 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6742 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6743 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6744 return 0;
6745
6746 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6747 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6748
6749 if (src_regno > 31
e2c953b6 6750 || count != 32 - (int) src_regno)
9ebbca7d
GK
6751 return 0;
6752
258bfae2 6753 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6754 {
6755 offset = 0;
6756 base_regno = REGNO (dest_addr);
6757 if (base_regno == 0)
6758 return 0;
6759 }
258bfae2 6760 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6761 {
6762 offset = INTVAL (XEXP (dest_addr, 1));
6763 base_regno = REGNO (XEXP (dest_addr, 0));
6764 }
6765 else
6766 return 0;
6767
6768 for (i = 0; i < count; i++)
6769 {
6770 rtx elt = XVECEXP (op, 0, i);
6771 rtx newaddr;
6772 rtx addr_reg;
6773 HOST_WIDE_INT newoffset;
6774
6775 if (GET_CODE (elt) != SET
6776 || GET_CODE (SET_SRC (elt)) != REG
6777 || GET_MODE (SET_SRC (elt)) != SImode
6778 || REGNO (SET_SRC (elt)) != src_regno + i
6779 || GET_CODE (SET_DEST (elt)) != MEM
6780 || GET_MODE (SET_DEST (elt)) != SImode)
6781 return 0;
6782 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6783 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6784 {
6785 newoffset = 0;
6786 addr_reg = newaddr;
6787 }
258bfae2 6788 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6789 {
6790 addr_reg = XEXP (newaddr, 0);
6791 newoffset = INTVAL (XEXP (newaddr, 1));
6792 }
6793 else
6794 return 0;
6795 if (REGNO (addr_reg) != base_regno
6796 || newoffset != offset + 4 * i)
6797 return 0;
6798 }
6799
6800 return 1;
6801}
9878760c 6802\f
a4f6c312
SS
6803/* A validation routine: say whether CODE, a condition code, and MODE
6804 match. The other alternatives either don't make sense or should
6805 never be generated. */
39a10a29 6806
39a10a29
GK
6807static void
6808validate_condition_mode (code, mode)
6809 enum rtx_code code;
6810 enum machine_mode mode;
6811{
6812 if (GET_RTX_CLASS (code) != '<'
6813 || GET_MODE_CLASS (mode) != MODE_CC)
6814 abort ();
6815
6816 /* These don't make sense. */
6817 if ((code == GT || code == LT || code == GE || code == LE)
6818 && mode == CCUNSmode)
6819 abort ();
6820
6821 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6822 && mode != CCUNSmode)
6823 abort ();
6824
6825 if (mode != CCFPmode
6826 && (code == ORDERED || code == UNORDERED
6827 || code == UNEQ || code == LTGT
6828 || code == UNGT || code == UNLT
6829 || code == UNGE || code == UNLE))
a4f6c312 6830 abort ();
39a10a29 6831
de6c5979 6832 /* These should never be generated except for
ad72b533 6833 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6834 if (mode == CCFPmode
de6c5979 6835 && ! flag_unsafe_math_optimizations
ad72b533 6836 && ! flag_finite_math_only
39a10a29
GK
6837 && (code == LE || code == GE
6838 || code == UNEQ || code == LTGT
6839 || code == UNGT || code == UNLT))
6840 abort ();
6841
6842 /* These are invalid; the information is not there. */
6843 if (mode == CCEQmode
6844 && code != EQ && code != NE)
6845 abort ();
6846}
6847
9878760c
RK
6848/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6849 We only check the opcode against the mode of the CC value here. */
6850
6851int
6852branch_comparison_operator (op, mode)
592696dd 6853 rtx op;
296b8152 6854 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6855{
6856 enum rtx_code code = GET_CODE (op);
6857 enum machine_mode cc_mode;
6858
6859 if (GET_RTX_CLASS (code) != '<')
6860 return 0;
6861
6862 cc_mode = GET_MODE (XEXP (op, 0));
6863 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6864 return 0;
6865
39a10a29 6866 validate_condition_mode (code, cc_mode);
9878760c 6867
39a10a29
GK
6868 return 1;
6869}
6870
6871/* Return 1 if OP is a comparison operation that is valid for a branch
6872 insn and which is true if the corresponding bit in the CC register
6873 is set. */
6874
6875int
6876branch_positive_comparison_operator (op, mode)
592696dd 6877 rtx op;
39a10a29
GK
6878 enum machine_mode mode;
6879{
6880 enum rtx_code code;
6881
6882 if (! branch_comparison_operator (op, mode))
9878760c
RK
6883 return 0;
6884
39a10a29
GK
6885 code = GET_CODE (op);
6886 return (code == EQ || code == LT || code == GT
a3170dc6 6887 || (TARGET_SPE && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
6888 || code == LTU || code == GTU
6889 || code == UNORDERED);
9878760c
RK
6890}
6891
6892/* Return 1 if OP is a comparison operation that is valid for an scc insn.
6893 We check the opcode against the mode of the CC value and disallow EQ or
6894 NE comparisons for integers. */
6895
6896int
6897scc_comparison_operator (op, mode)
592696dd 6898 rtx op;
9878760c
RK
6899 enum machine_mode mode;
6900{
6901 enum rtx_code code = GET_CODE (op);
6902 enum machine_mode cc_mode;
6903
6904 if (GET_MODE (op) != mode && mode != VOIDmode)
6905 return 0;
6906
6907 if (GET_RTX_CLASS (code) != '<')
6908 return 0;
6909
6910 cc_mode = GET_MODE (XEXP (op, 0));
6911 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
6912 return 0;
6913
39a10a29 6914 validate_condition_mode (code, cc_mode);
9878760c 6915
39a10a29 6916 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
6917 return 0;
6918
9878760c
RK
6919 return 1;
6920}
e0cd0770
JC
6921
6922int
6923trap_comparison_operator (op, mode)
6924 rtx op;
6925 enum machine_mode mode;
6926{
6927 if (mode != VOIDmode && mode != GET_MODE (op))
6928 return 0;
39a10a29 6929 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 6930}
dfbdccdb
GK
6931
6932int
6933boolean_operator (op, mode)
6934 rtx op;
6935 enum machine_mode mode ATTRIBUTE_UNUSED;
6936{
6937 enum rtx_code code = GET_CODE (op);
6938 return (code == AND || code == IOR || code == XOR);
6939}
1d328b19
GK
6940
6941int
6942boolean_or_operator (op, mode)
6943 rtx op;
6944 enum machine_mode mode ATTRIBUTE_UNUSED;
6945{
6946 enum rtx_code code = GET_CODE (op);
6947 return (code == IOR || code == XOR);
6948}
50a0b056
GK
6949
6950int
6951min_max_operator (op, mode)
6952 rtx op;
6953 enum machine_mode mode ATTRIBUTE_UNUSED;
6954{
6955 enum rtx_code code = GET_CODE (op);
6956 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
6957}
9878760c
RK
6958\f
6959/* Return 1 if ANDOP is a mask that has no bits on that are not in the
6960 mask required to convert the result of a rotate insn into a shift
b1765bde 6961 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
6962
6963int
6964includes_lshift_p (shiftop, andop)
592696dd
SS
6965 rtx shiftop;
6966 rtx andop;
9878760c 6967{
e2c953b6
DE
6968 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
6969
6970 shift_mask <<= INTVAL (shiftop);
9878760c 6971
b1765bde 6972 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
6973}
6974
6975/* Similar, but for right shift. */
6976
6977int
6978includes_rshift_p (shiftop, andop)
592696dd
SS
6979 rtx shiftop;
6980 rtx andop;
9878760c 6981{
a7653a2c 6982 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
6983
6984 shift_mask >>= INTVAL (shiftop);
6985
b1765bde 6986 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
6987}
6988
c5059423
AM
6989/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
6990 to perform a left shift. It must have exactly SHIFTOP least
b6d08ca1 6991 significant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
6992
6993int
c5059423 6994includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
6995 rtx shiftop;
6996 rtx andop;
e2c953b6 6997{
c5059423
AM
6998 if (GET_CODE (andop) == CONST_INT)
6999 {
02071907 7000 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 7001
c5059423 7002 c = INTVAL (andop);
02071907 7003 if (c == 0 || c == ~0)
c5059423 7004 return 0;
e2c953b6 7005
02071907 7006 shift_mask = ~0;
c5059423
AM
7007 shift_mask <<= INTVAL (shiftop);
7008
b6d08ca1 7009 /* Find the least significant one bit. */
c5059423
AM
7010 lsb = c & -c;
7011
7012 /* It must coincide with the LSB of the shift mask. */
7013 if (-lsb != shift_mask)
7014 return 0;
e2c953b6 7015
c5059423
AM
7016 /* Invert to look for the next transition (if any). */
7017 c = ~c;
7018
7019 /* Remove the low group of ones (originally low group of zeros). */
7020 c &= -lsb;
7021
7022 /* Again find the lsb, and check we have all 1's above. */
7023 lsb = c & -c;
7024 return c == -lsb;
7025 }
7026 else if (GET_CODE (andop) == CONST_DOUBLE
7027 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
7028 {
02071907
AM
7029 HOST_WIDE_INT low, high, lsb;
7030 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
7031
7032 low = CONST_DOUBLE_LOW (andop);
7033 if (HOST_BITS_PER_WIDE_INT < 64)
7034 high = CONST_DOUBLE_HIGH (andop);
7035
7036 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 7037 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
7038 return 0;
7039
7040 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
7041 {
02071907 7042 shift_mask_high = ~0;
c5059423
AM
7043 if (INTVAL (shiftop) > 32)
7044 shift_mask_high <<= INTVAL (shiftop) - 32;
7045
7046 lsb = high & -high;
7047
7048 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
7049 return 0;
7050
7051 high = ~high;
7052 high &= -lsb;
7053
7054 lsb = high & -high;
7055 return high == -lsb;
7056 }
7057
02071907 7058 shift_mask_low = ~0;
c5059423
AM
7059 shift_mask_low <<= INTVAL (shiftop);
7060
7061 lsb = low & -low;
7062
7063 if (-lsb != shift_mask_low)
7064 return 0;
7065
7066 if (HOST_BITS_PER_WIDE_INT < 64)
7067 high = ~high;
7068 low = ~low;
7069 low &= -lsb;
7070
7071 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
7072 {
7073 lsb = high & -high;
7074 return high == -lsb;
7075 }
7076
7077 lsb = low & -low;
7078 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
7079 }
7080 else
7081 return 0;
7082}
e2c953b6 7083
c5059423
AM
7084/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
7085 to perform a left shift. It must have SHIFTOP or more least
7086 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 7087
c5059423
AM
7088int
7089includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
7090 rtx shiftop;
7091 rtx andop;
c5059423 7092{
e2c953b6 7093 if (GET_CODE (andop) == CONST_INT)
c5059423 7094 {
02071907 7095 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 7096
02071907 7097 shift_mask = ~0;
c5059423
AM
7098 shift_mask <<= INTVAL (shiftop);
7099 c = INTVAL (andop);
7100
7101 /* Find the least signifigant one bit. */
7102 lsb = c & -c;
7103
7104 /* It must be covered by the shift mask.
a4f6c312 7105 This test also rejects c == 0. */
c5059423
AM
7106 if ((lsb & shift_mask) == 0)
7107 return 0;
7108
7109 /* Check we have all 1's above the transition, and reject all 1's. */
7110 return c == -lsb && lsb != 1;
7111 }
7112 else if (GET_CODE (andop) == CONST_DOUBLE
7113 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
7114 {
02071907 7115 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
7116
7117 low = CONST_DOUBLE_LOW (andop);
7118
7119 if (HOST_BITS_PER_WIDE_INT < 64)
7120 {
02071907 7121 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
7122
7123 high = CONST_DOUBLE_HIGH (andop);
7124
7125 if (low == 0)
7126 {
02071907 7127 shift_mask_high = ~0;
c5059423
AM
7128 if (INTVAL (shiftop) > 32)
7129 shift_mask_high <<= INTVAL (shiftop) - 32;
7130
7131 lsb = high & -high;
7132
7133 if ((lsb & shift_mask_high) == 0)
7134 return 0;
7135
7136 return high == -lsb;
7137 }
7138 if (high != ~0)
7139 return 0;
7140 }
7141
02071907 7142 shift_mask_low = ~0;
c5059423
AM
7143 shift_mask_low <<= INTVAL (shiftop);
7144
7145 lsb = low & -low;
7146
7147 if ((lsb & shift_mask_low) == 0)
7148 return 0;
7149
7150 return low == -lsb && lsb != 1;
7151 }
e2c953b6 7152 else
c5059423 7153 return 0;
9878760c 7154}
35068b43
RK
7155
7156/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
7157 for lfq and stfq insns.
7158
7159 Note reg1 and reg2 *must* be hard registers. To be sure we will
7160 abort if we are passed pseudo registers. */
7161
7162int
7163registers_ok_for_quad_peep (reg1, reg2)
7164 rtx reg1, reg2;
7165{
7166 /* We might have been passed a SUBREG. */
7167 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
7168 return 0;
7169
7170 return (REGNO (reg1) == REGNO (reg2) - 1);
7171}
7172
a4f6c312
SS
7173/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
7174 addr1 and addr2 must be in consecutive memory locations
7175 (addr2 == addr1 + 8). */
35068b43
RK
7176
7177int
7178addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
7179 rtx addr1;
7180 rtx addr2;
35068b43 7181{
e2c953b6 7182 unsigned int reg1;
35068b43
RK
7183 int offset1;
7184
7185 /* Extract an offset (if used) from the first addr. */
7186 if (GET_CODE (addr1) == PLUS)
7187 {
7188 /* If not a REG, return zero. */
7189 if (GET_CODE (XEXP (addr1, 0)) != REG)
7190 return 0;
7191 else
7192 {
7193 reg1 = REGNO (XEXP (addr1, 0));
7194 /* The offset must be constant! */
7195 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7196 return 0;
7197 offset1 = INTVAL (XEXP (addr1, 1));
7198 }
7199 }
7200 else if (GET_CODE (addr1) != REG)
7201 return 0;
7202 else
7203 {
7204 reg1 = REGNO (addr1);
7205 /* This was a simple (mem (reg)) expression. Offset is 0. */
7206 offset1 = 0;
7207 }
7208
acad7ed3 7209 /* Make sure the second address is a (mem (plus (reg) (const_int))). */
35068b43
RK
7210 if (GET_CODE (addr2) != PLUS)
7211 return 0;
7212
7213 if (GET_CODE (XEXP (addr2, 0)) != REG
7214 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7215 return 0;
7216
7217 if (reg1 != REGNO (XEXP (addr2, 0)))
7218 return 0;
7219
7220 /* The offset for the second addr must be 8 more than the first addr. */
7221 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7222 return 0;
7223
7224 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7225 instructions. */
7226 return 1;
7227}
9878760c
RK
7228\f
7229/* Return the register class of a scratch register needed to copy IN into
7230 or out of a register in CLASS in MODE. If it can be done directly,
7231 NO_REGS is returned. */
7232
7233enum reg_class
7234secondary_reload_class (class, mode, in)
7235 enum reg_class class;
296b8152 7236 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7237 rtx in;
7238{
5accd822 7239 int regno;
9878760c 7240
ab82a49f
AP
7241 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
7242#if TARGET_MACHO
7243 && MACHOPIC_INDIRECT
7244#endif
7245 ))
46fad5b7
DJ
7246 {
7247 /* We cannot copy a symbolic operand directly into anything
7248 other than BASE_REGS for TARGET_ELF. So indicate that a
7249 register from BASE_REGS is needed as an intermediate
7250 register.
7251
7252 On Darwin, pic addresses require a load from memory, which
7253 needs a base register. */
7254 if (class != BASE_REGS
7255 && (GET_CODE (in) == SYMBOL_REF
7256 || GET_CODE (in) == HIGH
7257 || GET_CODE (in) == LABEL_REF
7258 || GET_CODE (in) == CONST))
7259 return BASE_REGS;
7260 }
e7b7998a 7261
5accd822
DE
7262 if (GET_CODE (in) == REG)
7263 {
7264 regno = REGNO (in);
7265 if (regno >= FIRST_PSEUDO_REGISTER)
7266 {
7267 regno = true_regnum (in);
7268 if (regno >= FIRST_PSEUDO_REGISTER)
7269 regno = -1;
7270 }
7271 }
7272 else if (GET_CODE (in) == SUBREG)
7273 {
7274 regno = true_regnum (in);
7275 if (regno >= FIRST_PSEUDO_REGISTER)
7276 regno = -1;
7277 }
7278 else
7279 regno = -1;
7280
9878760c
RK
7281 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7282 into anything. */
7283 if (class == GENERAL_REGS || class == BASE_REGS
7284 || (regno >= 0 && INT_REGNO_P (regno)))
7285 return NO_REGS;
7286
7287 /* Constants, memory, and FP registers can go into FP registers. */
7288 if ((regno == -1 || FP_REGNO_P (regno))
7289 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7290 return NO_REGS;
7291
0ac081f6
AH
7292 /* Memory, and AltiVec registers can go into AltiVec registers. */
7293 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7294 && class == ALTIVEC_REGS)
7295 return NO_REGS;
7296
9878760c
RK
7297 /* We can copy among the CR registers. */
7298 if ((class == CR_REGS || class == CR0_REGS)
7299 && regno >= 0 && CR_REGNO_P (regno))
7300 return NO_REGS;
7301
7302 /* Otherwise, we need GENERAL_REGS. */
7303 return GENERAL_REGS;
7304}
7305\f
7306/* Given a comparison operation, return the bit number in CCR to test. We
7307 know this is a valid comparison.
7308
7309 SCC_P is 1 if this is for an scc. That means that %D will have been
7310 used instead of %C, so the bits will be in different places.
7311
b4ac57ab 7312 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7313
7314int
7315ccr_bit (op, scc_p)
592696dd 7316 rtx op;
9878760c
RK
7317 int scc_p;
7318{
7319 enum rtx_code code = GET_CODE (op);
7320 enum machine_mode cc_mode;
7321 int cc_regnum;
7322 int base_bit;
9ebbca7d 7323 rtx reg;
9878760c
RK
7324
7325 if (GET_RTX_CLASS (code) != '<')
7326 return -1;
7327
9ebbca7d
GK
7328 reg = XEXP (op, 0);
7329
7330 if (GET_CODE (reg) != REG
7331 || ! CR_REGNO_P (REGNO (reg)))
7332 abort ();
7333
7334 cc_mode = GET_MODE (reg);
7335 cc_regnum = REGNO (reg);
7336 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7337
39a10a29 7338 validate_condition_mode (code, cc_mode);
c5defebb 7339
9878760c
RK
7340 switch (code)
7341 {
7342 case NE:
a3170dc6
AH
7343 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7344 return base_bit + 1;
9878760c
RK
7345 return scc_p ? base_bit + 3 : base_bit + 2;
7346 case EQ:
a3170dc6
AH
7347 if (TARGET_SPE && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
7348 return base_bit + 1;
9878760c 7349 return base_bit + 2;
1c882ea4 7350 case GT: case GTU: case UNLE:
9878760c 7351 return base_bit + 1;
1c882ea4 7352 case LT: case LTU: case UNGE:
9878760c 7353 return base_bit;
1c882ea4
GK
7354 case ORDERED: case UNORDERED:
7355 return base_bit + 3;
9878760c
RK
7356
7357 case GE: case GEU:
39a10a29 7358 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7359 unordered position. So test that bit. For integer, this is ! LT
7360 unless this is an scc insn. */
39a10a29 7361 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7362
7363 case LE: case LEU:
39a10a29 7364 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7365
9878760c
RK
7366 default:
7367 abort ();
7368 }
7369}
1ff7789b 7370\f
8d30c4ee 7371/* Return the GOT register. */
1ff7789b
MM
7372
7373struct rtx_def *
7374rs6000_got_register (value)
5f59ecb7 7375 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7376{
a4f6c312
SS
7377 /* The second flow pass currently (June 1999) can't update
7378 regs_ever_live without disturbing other parts of the compiler, so
7379 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7380 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7381 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7382
8d30c4ee 7383 current_function_uses_pic_offset_table = 1;
3cb999d8 7384
1ff7789b
MM
7385 return pic_offset_table_rtx;
7386}
a7df97e6 7387\f
e2500fed
GK
7388/* Function to init struct machine_function.
7389 This will be called, via a pointer variable,
7390 from push_function_context. */
a7df97e6 7391
e2500fed
GK
7392static struct machine_function *
7393rs6000_init_machine_status ()
a7df97e6 7394{
e2500fed 7395 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7396}
9878760c 7397\f
0ba1b2ff
AM
7398/* These macros test for integers and extract the low-order bits. */
7399#define INT_P(X) \
7400((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7401 && GET_MODE (X) == VOIDmode)
7402
7403#define INT_LOWPART(X) \
7404 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7405
7406int
7407extract_MB (op)
7408 rtx op;
7409{
7410 int i;
7411 unsigned long val = INT_LOWPART (op);
7412
7413 /* If the high bit is zero, the value is the first 1 bit we find
7414 from the left. */
7415 if ((val & 0x80000000) == 0)
7416 {
7417 if ((val & 0xffffffff) == 0)
7418 abort ();
7419
7420 i = 1;
7421 while (((val <<= 1) & 0x80000000) == 0)
7422 ++i;
7423 return i;
7424 }
7425
7426 /* If the high bit is set and the low bit is not, or the mask is all
7427 1's, the value is zero. */
7428 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7429 return 0;
7430
7431 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7432 from the right. */
7433 i = 31;
7434 while (((val >>= 1) & 1) != 0)
7435 --i;
7436
7437 return i;
7438}
7439
7440int
7441extract_ME (op)
7442 rtx op;
7443{
7444 int i;
7445 unsigned long val = INT_LOWPART (op);
7446
7447 /* If the low bit is zero, the value is the first 1 bit we find from
7448 the right. */
7449 if ((val & 1) == 0)
7450 {
7451 if ((val & 0xffffffff) == 0)
7452 abort ();
7453
7454 i = 30;
7455 while (((val >>= 1) & 1) == 0)
7456 --i;
7457
7458 return i;
7459 }
7460
7461 /* If the low bit is set and the high bit is not, or the mask is all
7462 1's, the value is 31. */
7463 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7464 return 31;
7465
7466 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7467 from the left. */
7468 i = 0;
7469 while (((val <<= 1) & 0x80000000) != 0)
7470 ++i;
7471
7472 return i;
7473}
7474
9878760c
RK
7475/* Print an operand. Recognize special options, documented below. */
7476
38c1f2d7 7477#if TARGET_ELF
d9407988 7478#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7479#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7480#else
7481#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7482#define SMALL_DATA_REG 0
ba5e43aa
MM
7483#endif
7484
9878760c
RK
7485void
7486print_operand (file, x, code)
7487 FILE *file;
7488 rtx x;
9ebbca7d 7489 int code;
9878760c
RK
7490{
7491 int i;
a260abc9 7492 HOST_WIDE_INT val;
0ba1b2ff 7493 unsigned HOST_WIDE_INT uval;
9878760c
RK
7494
7495 switch (code)
7496 {
a8b3aeda 7497 case '.':
a85d226b
RK
7498 /* Write out an instruction after the call which may be replaced
7499 with glue code by the loader. This depends on the AIX version. */
7500 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7501 return;
7502
81eace42
GK
7503 /* %a is output_address. */
7504
9854d9ed
RK
7505 case 'A':
7506 /* If X is a constant integer whose low-order 5 bits are zero,
7507 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7508 in the AIX assembler where "sri" with a zero shift count
20e26713 7509 writes a trash instruction. */
9854d9ed 7510 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7511 putc ('l', file);
9854d9ed 7512 else
76229ac8 7513 putc ('r', file);
9854d9ed
RK
7514 return;
7515
7516 case 'b':
e2c953b6
DE
7517 /* If constant, low-order 16 bits of constant, unsigned.
7518 Otherwise, write normally. */
7519 if (INT_P (x))
7520 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7521 else
7522 print_operand (file, x, 0);
cad12a8d
RK
7523 return;
7524
a260abc9
DE
7525 case 'B':
7526 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7527 for 64-bit mask direction. */
296b8152 7528 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7529 return;
a260abc9 7530
81eace42
GK
7531 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7532 output_operand. */
7533
9854d9ed 7534 case 'D':
39a10a29
GK
7535 /* There used to be a comment for 'C' reading "This is an
7536 optional cror needed for certain floating-point
7537 comparisons. Otherwise write nothing." */
7538
9854d9ed
RK
7539 /* Similar, except that this is for an scc, so we must be able to
7540 encode the test in a single bit that is one. We do the above
7541 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7542 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7543 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7544 {
9ebbca7d 7545 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7546
7547 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7548 base_bit + 2,
7549 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7550 }
7551
7552 else if (GET_CODE (x) == NE)
7553 {
9ebbca7d 7554 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7555
7556 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7557 base_bit + 2, base_bit + 2);
7558 }
a3170dc6
AH
7559 else if (TARGET_SPE && TARGET_HARD_FLOAT
7560 && GET_CODE (x) == EQ
7561 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7562 {
7563 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7564
7565 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7566 base_bit + 1, base_bit + 1);
7567 }
9854d9ed
RK
7568 return;
7569
7570 case 'E':
39a10a29 7571 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7572 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7573 output_operand_lossage ("invalid %%E value");
78fbdbf7 7574 else
39a10a29 7575 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7576 return;
9854d9ed
RK
7577
7578 case 'f':
7579 /* X is a CR register. Print the shift count needed to move it
7580 to the high-order four bits. */
7581 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7582 output_operand_lossage ("invalid %%f value");
7583 else
9ebbca7d 7584 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7585 return;
7586
7587 case 'F':
7588 /* Similar, but print the count for the rotate in the opposite
7589 direction. */
7590 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7591 output_operand_lossage ("invalid %%F value");
7592 else
9ebbca7d 7593 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7594 return;
7595
7596 case 'G':
7597 /* X is a constant integer. If it is negative, print "m",
43aa4e05 7598 otherwise print "z". This is to make an aze or ame insn. */
9854d9ed
RK
7599 if (GET_CODE (x) != CONST_INT)
7600 output_operand_lossage ("invalid %%G value");
7601 else if (INTVAL (x) >= 0)
76229ac8 7602 putc ('z', file);
9854d9ed 7603 else
76229ac8 7604 putc ('m', file);
9854d9ed 7605 return;
e2c953b6 7606
9878760c 7607 case 'h':
a4f6c312
SS
7608 /* If constant, output low-order five bits. Otherwise, write
7609 normally. */
9878760c 7610 if (INT_P (x))
5f59ecb7 7611 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7612 else
7613 print_operand (file, x, 0);
7614 return;
7615
64305719 7616 case 'H':
a4f6c312
SS
7617 /* If constant, output low-order six bits. Otherwise, write
7618 normally. */
64305719 7619 if (INT_P (x))
5f59ecb7 7620 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7621 else
7622 print_operand (file, x, 0);
7623 return;
7624
9854d9ed
RK
7625 case 'I':
7626 /* Print `i' if this is a constant, else nothing. */
9878760c 7627 if (INT_P (x))
76229ac8 7628 putc ('i', file);
9878760c
RK
7629 return;
7630
9854d9ed
RK
7631 case 'j':
7632 /* Write the bit number in CCR for jump. */
7633 i = ccr_bit (x, 0);
7634 if (i == -1)
7635 output_operand_lossage ("invalid %%j code");
9878760c 7636 else
9854d9ed 7637 fprintf (file, "%d", i);
9878760c
RK
7638 return;
7639
9854d9ed
RK
7640 case 'J':
7641 /* Similar, but add one for shift count in rlinm for scc and pass
7642 scc flag to `ccr_bit'. */
7643 i = ccr_bit (x, 1);
7644 if (i == -1)
7645 output_operand_lossage ("invalid %%J code");
7646 else
a0466a68
RK
7647 /* If we want bit 31, write a shift count of zero, not 32. */
7648 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7649 return;
7650
9854d9ed
RK
7651 case 'k':
7652 /* X must be a constant. Write the 1's complement of the
7653 constant. */
9878760c 7654 if (! INT_P (x))
9854d9ed 7655 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7656 else
7657 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7658 return;
7659
81eace42 7660 case 'K':
9ebbca7d
GK
7661 /* X must be a symbolic constant on ELF. Write an
7662 expression suitable for an 'addi' that adds in the low 16
7663 bits of the MEM. */
7664 if (GET_CODE (x) != CONST)
7665 {
7666 print_operand_address (file, x);
7667 fputs ("@l", file);
7668 }
7669 else
7670 {
7671 if (GET_CODE (XEXP (x, 0)) != PLUS
7672 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7673 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7674 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7675 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7676 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7677 fputs ("@l", file);
ed8d2920
MM
7678 /* For GNU as, there must be a non-alphanumeric character
7679 between 'l' and the number. The '-' is added by
7680 print_operand() already. */
7681 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7682 fputs ("+", file);
9ebbca7d
GK
7683 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7684 }
81eace42
GK
7685 return;
7686
7687 /* %l is output_asm_label. */
9ebbca7d 7688
9854d9ed
RK
7689 case 'L':
7690 /* Write second word of DImode or DFmode reference. Works on register
7691 or non-indexed memory only. */
7692 if (GET_CODE (x) == REG)
5ebfb2ba 7693 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7694 else if (GET_CODE (x) == MEM)
7695 {
7696 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7697 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7698 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7699 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7700 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7701 UNITS_PER_WORD));
9854d9ed 7702 else
d7624dc0
RK
7703 output_address (XEXP (adjust_address_nv (x, SImode,
7704 UNITS_PER_WORD),
7705 0));
ed8908e7 7706
ba5e43aa 7707 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7708 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7709 reg_names[SMALL_DATA_REG]);
9854d9ed 7710 }
9878760c 7711 return;
9854d9ed 7712
9878760c
RK
7713 case 'm':
7714 /* MB value for a mask operand. */
b1765bde 7715 if (! mask_operand (x, SImode))
9878760c
RK
7716 output_operand_lossage ("invalid %%m value");
7717
0ba1b2ff 7718 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7719 return;
7720
7721 case 'M':
7722 /* ME value for a mask operand. */
b1765bde 7723 if (! mask_operand (x, SImode))
a260abc9 7724 output_operand_lossage ("invalid %%M value");
9878760c 7725
0ba1b2ff 7726 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7727 return;
7728
81eace42
GK
7729 /* %n outputs the negative of its operand. */
7730
9878760c
RK
7731 case 'N':
7732 /* Write the number of elements in the vector times 4. */
7733 if (GET_CODE (x) != PARALLEL)
7734 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7735 else
7736 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7737 return;
7738
7739 case 'O':
7740 /* Similar, but subtract 1 first. */
7741 if (GET_CODE (x) != PARALLEL)
1427100a 7742 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7743 else
7744 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7745 return;
7746
9854d9ed
RK
7747 case 'p':
7748 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7749 if (! INT_P (x)
2bfcf297 7750 || INT_LOWPART (x) < 0
9854d9ed
RK
7751 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7752 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7753 else
7754 fprintf (file, "%d", i);
9854d9ed
RK
7755 return;
7756
9878760c
RK
7757 case 'P':
7758 /* The operand must be an indirect memory reference. The result
a4f6c312 7759 is the register number. */
9878760c
RK
7760 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7761 || REGNO (XEXP (x, 0)) >= 32)
7762 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7763 else
7764 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7765 return;
7766
dfbdccdb
GK
7767 case 'q':
7768 /* This outputs the logical code corresponding to a boolean
7769 expression. The expression may have one or both operands
39a10a29
GK
7770 negated (if one, only the first one). For condition register
7771 logical operations, it will also treat the negated
7772 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7773 {
63bc1d05 7774 const char *const *t = 0;
dfbdccdb
GK
7775 const char *s;
7776 enum rtx_code code = GET_CODE (x);
7777 static const char * const tbl[3][3] = {
7778 { "and", "andc", "nor" },
7779 { "or", "orc", "nand" },
7780 { "xor", "eqv", "xor" } };
7781
7782 if (code == AND)
7783 t = tbl[0];
7784 else if (code == IOR)
7785 t = tbl[1];
7786 else if (code == XOR)
7787 t = tbl[2];
7788 else
7789 output_operand_lossage ("invalid %%q value");
7790
7791 if (GET_CODE (XEXP (x, 0)) != NOT)
7792 s = t[0];
7793 else
7794 {
7795 if (GET_CODE (XEXP (x, 1)) == NOT)
7796 s = t[2];
7797 else
7798 s = t[1];
7799 }
7800
7801 fputs (s, file);
7802 }
7803 return;
7804
9854d9ed
RK
7805 case 'R':
7806 /* X is a CR register. Print the mask for `mtcrf'. */
7807 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7808 output_operand_lossage ("invalid %%R value");
7809 else
9ebbca7d 7810 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7811 return;
9854d9ed
RK
7812
7813 case 's':
7814 /* Low 5 bits of 32 - value */
7815 if (! INT_P (x))
7816 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7817 else
7818 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7819 return;
9854d9ed 7820
a260abc9 7821 case 'S':
0ba1b2ff 7822 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7823 CONST_INT 32-bit mask is considered sign-extended so any
7824 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7825 if (! mask64_operand (x, DImode))
a260abc9
DE
7826 output_operand_lossage ("invalid %%S value");
7827
0ba1b2ff 7828 uval = INT_LOWPART (x);
a260abc9 7829
0ba1b2ff 7830 if (uval & 1) /* Clear Left */
a260abc9 7831 {
f099d360
GK
7832#if HOST_BITS_PER_WIDE_INT > 64
7833 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
7834#endif
0ba1b2ff 7835 i = 64;
a260abc9 7836 }
0ba1b2ff 7837 else /* Clear Right */
a260abc9 7838 {
0ba1b2ff 7839 uval = ~uval;
f099d360
GK
7840#if HOST_BITS_PER_WIDE_INT > 64
7841 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
7842#endif
0ba1b2ff 7843 i = 63;
a260abc9 7844 }
0ba1b2ff
AM
7845 while (uval != 0)
7846 --i, uval >>= 1;
7847 if (i < 0)
7848 abort ();
7849 fprintf (file, "%d", i);
7850 return;
a260abc9 7851
a3170dc6
AH
7852 case 't':
7853 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
7854 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
7855 abort ();
7856
7857 /* Bit 3 is OV bit. */
7858 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
7859
7860 /* If we want bit 31, write a shift count of zero, not 32. */
7861 fprintf (file, "%d", i == 31 ? 0 : i + 1);
7862 return;
7863
cccf3bdc
DE
7864 case 'T':
7865 /* Print the symbolic name of a branch target register. */
7866 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
7867 && REGNO (x) != COUNT_REGISTER_REGNUM))
7868 output_operand_lossage ("invalid %%T value");
e2c953b6 7869 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
7870 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
7871 else
7872 fputs ("ctr", file);
7873 return;
7874
9854d9ed 7875 case 'u':
802a0058 7876 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
7877 if (! INT_P (x))
7878 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
7879 else
7880 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7881 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
7882 return;
7883
802a0058
MM
7884 case 'v':
7885 /* High-order 16 bits of constant for use in signed operand. */
7886 if (! INT_P (x))
7887 output_operand_lossage ("invalid %%v value");
e2c953b6 7888 else
134c32f6
DE
7889 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
7890 (INT_LOWPART (x) >> 16) & 0xffff);
7891 return;
802a0058 7892
9854d9ed
RK
7893 case 'U':
7894 /* Print `u' if this has an auto-increment or auto-decrement. */
7895 if (GET_CODE (x) == MEM
7896 && (GET_CODE (XEXP (x, 0)) == PRE_INC
7897 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 7898 putc ('u', file);
9854d9ed 7899 return;
9878760c 7900
e0cd0770
JC
7901 case 'V':
7902 /* Print the trap code for this operand. */
7903 switch (GET_CODE (x))
7904 {
7905 case EQ:
7906 fputs ("eq", file); /* 4 */
7907 break;
7908 case NE:
7909 fputs ("ne", file); /* 24 */
7910 break;
7911 case LT:
7912 fputs ("lt", file); /* 16 */
7913 break;
7914 case LE:
7915 fputs ("le", file); /* 20 */
7916 break;
7917 case GT:
7918 fputs ("gt", file); /* 8 */
7919 break;
7920 case GE:
7921 fputs ("ge", file); /* 12 */
7922 break;
7923 case LTU:
7924 fputs ("llt", file); /* 2 */
7925 break;
7926 case LEU:
7927 fputs ("lle", file); /* 6 */
7928 break;
7929 case GTU:
7930 fputs ("lgt", file); /* 1 */
7931 break;
7932 case GEU:
7933 fputs ("lge", file); /* 5 */
7934 break;
7935 default:
7936 abort ();
7937 }
7938 break;
7939
9854d9ed
RK
7940 case 'w':
7941 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
7942 normally. */
7943 if (INT_P (x))
5f59ecb7
DE
7944 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
7945 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
7946 else
7947 print_operand (file, x, 0);
9878760c
RK
7948 return;
7949
9854d9ed 7950 case 'W':
e2c953b6 7951 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
7952 val = (GET_CODE (x) == CONST_INT
7953 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
7954
7955 if (val < 0)
7956 i = -1;
9854d9ed 7957 else
e2c953b6
DE
7958 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
7959 if ((val <<= 1) < 0)
7960 break;
7961
7962#if HOST_BITS_PER_WIDE_INT == 32
7963 if (GET_CODE (x) == CONST_INT && i >= 0)
7964 i += 32; /* zero-extend high-part was all 0's */
7965 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
7966 {
7967 val = CONST_DOUBLE_LOW (x);
7968
7969 if (val == 0)
a4f6c312 7970 abort ();
e2c953b6
DE
7971 else if (val < 0)
7972 --i;
7973 else
7974 for ( ; i < 64; i++)
7975 if ((val <<= 1) < 0)
7976 break;
7977 }
7978#endif
7979
7980 fprintf (file, "%d", i + 1);
9854d9ed 7981 return;
9878760c 7982
9854d9ed
RK
7983 case 'X':
7984 if (GET_CODE (x) == MEM
258bfae2 7985 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 7986 putc ('x', file);
9854d9ed 7987 return;
9878760c 7988
9854d9ed
RK
7989 case 'Y':
7990 /* Like 'L', for third word of TImode */
7991 if (GET_CODE (x) == REG)
5ebfb2ba 7992 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 7993 else if (GET_CODE (x) == MEM)
9878760c 7994 {
9854d9ed
RK
7995 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7996 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 7997 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 7998 else
d7624dc0 7999 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 8000 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8001 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8002 reg_names[SMALL_DATA_REG]);
9878760c
RK
8003 }
8004 return;
9854d9ed 8005
9878760c 8006 case 'z':
b4ac57ab
RS
8007 /* X is a SYMBOL_REF. Write out the name preceded by a
8008 period and without any trailing data in brackets. Used for function
4d30c363
MM
8009 names. If we are configured for System V (or the embedded ABI) on
8010 the PowerPC, do not emit the period, since those systems do not use
8011 TOCs and the like. */
9878760c
RK
8012 if (GET_CODE (x) != SYMBOL_REF)
8013 abort ();
8014
b6c9286a
MM
8015 if (XSTR (x, 0)[0] != '.')
8016 {
8017 switch (DEFAULT_ABI)
8018 {
8019 default:
8020 abort ();
8021
8022 case ABI_AIX:
8023 putc ('.', file);
8024 break;
8025
8026 case ABI_V4:
8027 case ABI_AIX_NODESC:
ee890fe2 8028 case ABI_DARWIN:
b6c9286a 8029 break;
b6c9286a
MM
8030 }
8031 }
54ee9799
DE
8032#if TARGET_AIX
8033 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
8034#else
9ebbca7d 8035 assemble_name (file, XSTR (x, 0));
54ee9799 8036#endif
9878760c
RK
8037 return;
8038
9854d9ed
RK
8039 case 'Z':
8040 /* Like 'L', for last word of TImode. */
8041 if (GET_CODE (x) == REG)
5ebfb2ba 8042 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
8043 else if (GET_CODE (x) == MEM)
8044 {
8045 if (GET_CODE (XEXP (x, 0)) == PRE_INC
8046 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 8047 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 8048 else
d7624dc0 8049 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 8050 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8051 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8052 reg_names[SMALL_DATA_REG]);
9854d9ed 8053 }
5c23c401 8054 return;
0ac081f6 8055
a3170dc6 8056 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
8057 case 'y':
8058 {
8059 rtx tmp;
8060
8061 if (GET_CODE (x) != MEM)
8062 abort ();
8063
8064 tmp = XEXP (x, 0);
8065
a3170dc6
AH
8066 if (TARGET_SPE)
8067 {
8068 /* Handle [reg]. */
8069 if (GET_CODE (tmp) == REG)
8070 {
8071 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
8072 break;
8073 }
8074 /* Handle [reg+UIMM]. */
8075 else if (GET_CODE (tmp) == PLUS &&
8076 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
8077 {
8078 int x;
8079
8080 if (GET_CODE (XEXP (tmp, 0)) != REG)
8081 abort ();
8082
8083 x = INTVAL (XEXP (tmp, 1));
8084 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
8085 break;
8086 }
8087
8088 /* Fall through. Must be [reg+reg]. */
8089 }
0ac081f6 8090 if (GET_CODE (tmp) == REG)
c62f2db5 8091 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
8092 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
8093 {
8094 if (REGNO (XEXP (tmp, 0)) == 0)
8095 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
8096 reg_names[ REGNO (XEXP (tmp, 0)) ]);
8097 else
8098 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
8099 reg_names[ REGNO (XEXP (tmp, 1)) ]);
8100 }
8101 else
8102 abort ();
8103 break;
8104 }
9854d9ed 8105
9878760c
RK
8106 case 0:
8107 if (GET_CODE (x) == REG)
8108 fprintf (file, "%s", reg_names[REGNO (x)]);
8109 else if (GET_CODE (x) == MEM)
8110 {
8111 /* We need to handle PRE_INC and PRE_DEC here, since we need to
8112 know the width from the mode. */
8113 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
8114 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
8115 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 8116 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
8117 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
8118 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 8119 else
a54d04b7 8120 output_address (XEXP (x, 0));
9878760c
RK
8121 }
8122 else
a54d04b7 8123 output_addr_const (file, x);
a85d226b 8124 return;
9878760c
RK
8125
8126 default:
8127 output_operand_lossage ("invalid %%xn code");
8128 }
8129}
8130\f
8131/* Print the address of an operand. */
8132
8133void
8134print_operand_address (file, x)
8135 FILE *file;
592696dd 8136 rtx x;
9878760c
RK
8137{
8138 if (GET_CODE (x) == REG)
4697a36c 8139 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
8140 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
8141 || GET_CODE (x) == LABEL_REF)
9878760c
RK
8142 {
8143 output_addr_const (file, x);
ba5e43aa 8144 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8145 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8146 reg_names[SMALL_DATA_REG]);
9ebbca7d 8147 else if (TARGET_TOC)
a4f6c312 8148 abort ();
9878760c
RK
8149 }
8150 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
8151 {
8152 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
8153 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
8154 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 8155 else
4697a36c
MM
8156 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
8157 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
8158 }
8159 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
8160 {
8161 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
8162 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8163 }
3cb999d8
DE
8164#if TARGET_ELF
8165 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8166 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
8167 {
8168 output_addr_const (file, XEXP (x, 1));
8169 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8170 }
c859cda6
DJ
8171#endif
8172#if TARGET_MACHO
8173 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8174 && CONSTANT_P (XEXP (x, 1)))
8175 {
8176 fprintf (file, "lo16(");
8177 output_addr_const (file, XEXP (x, 1));
8178 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8179 }
3cb999d8 8180#endif
9ebbca7d
GK
8181 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
8182 {
2bfcf297 8183 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 8184 {
2bfcf297
DB
8185 rtx contains_minus = XEXP (x, 1);
8186 rtx minus, symref;
8187 const char *name;
9ebbca7d
GK
8188
8189 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 8190 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
8191 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8192 contains_minus = XEXP (contains_minus, 0);
8193
2bfcf297
DB
8194 minus = XEXP (contains_minus, 0);
8195 symref = XEXP (minus, 0);
8196 XEXP (contains_minus, 0) = symref;
8197 if (TARGET_ELF)
8198 {
8199 char *newname;
8200
8201 name = XSTR (symref, 0);
8202 newname = alloca (strlen (name) + sizeof ("@toc"));
8203 strcpy (newname, name);
8204 strcat (newname, "@toc");
8205 XSTR (symref, 0) = newname;
8206 }
8207 output_addr_const (file, XEXP (x, 1));
8208 if (TARGET_ELF)
8209 XSTR (symref, 0) = name;
9ebbca7d
GK
8210 XEXP (contains_minus, 0) = minus;
8211 }
8212 else
8213 output_addr_const (file, XEXP (x, 1));
8214
8215 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8216 }
9878760c
RK
8217 else
8218 abort ();
8219}
8220\f
88cad84b 8221/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
8222 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8223 is defined. It also needs to handle DI-mode objects on 64-bit
8224 targets. */
8225
8226static bool
8227rs6000_assemble_integer (x, size, aligned_p)
8228 rtx x;
8229 unsigned int size;
8230 int aligned_p;
8231{
8232#ifdef RELOCATABLE_NEEDS_FIXUP
8233 /* Special handling for SI values. */
8234 if (size == 4 && aligned_p)
8235 {
8236 extern int in_toc_section PARAMS ((void));
8237 static int recurse = 0;
8238
8239 /* For -mrelocatable, we mark all addresses that need to be fixed up
8240 in the .fixup section. */
8241 if (TARGET_RELOCATABLE
8242 && !in_toc_section ()
8243 && !in_text_section ()
8244 && !recurse
8245 && GET_CODE (x) != CONST_INT
8246 && GET_CODE (x) != CONST_DOUBLE
8247 && CONSTANT_P (x))
8248 {
8249 char buf[256];
8250
8251 recurse = 1;
8252 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8253 fixuplabelno++;
8254 ASM_OUTPUT_LABEL (asm_out_file, buf);
8255 fprintf (asm_out_file, "\t.long\t(");
8256 output_addr_const (asm_out_file, x);
8257 fprintf (asm_out_file, ")@fixup\n");
8258 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8259 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8260 fprintf (asm_out_file, "\t.long\t");
8261 assemble_name (asm_out_file, buf);
8262 fprintf (asm_out_file, "\n\t.previous\n");
8263 recurse = 0;
8264 return true;
8265 }
8266 /* Remove initial .'s to turn a -mcall-aixdesc function
8267 address into the address of the descriptor, not the function
8268 itself. */
8269 else if (GET_CODE (x) == SYMBOL_REF
8270 && XSTR (x, 0)[0] == '.'
8271 && DEFAULT_ABI == ABI_AIX)
8272 {
8273 const char *name = XSTR (x, 0);
8274 while (*name == '.')
8275 name++;
8276
8277 fprintf (asm_out_file, "\t.long\t%s\n", name);
8278 return true;
8279 }
8280 }
8281#endif /* RELOCATABLE_NEEDS_FIXUP */
8282 return default_assemble_integer (x, size, aligned_p);
8283}
93638d7a
AM
8284
8285#ifdef HAVE_GAS_HIDDEN
8286/* Emit an assembler directive to set symbol visibility for DECL to
8287 VISIBILITY_TYPE. */
8288
5add3202 8289static void
25fdb4dc 8290rs6000_assemble_visibility (decl, vis)
93638d7a 8291 tree decl;
25fdb4dc 8292 int vis;
93638d7a 8293{
93638d7a
AM
8294 /* Functions need to have their entry point symbol visibility set as
8295 well as their descriptor symbol visibility. */
8296 if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
8297 {
25fdb4dc
RH
8298 static const char * const visibility_types[] = {
8299 NULL, "internal", "hidden", "protected"
8300 };
8301
8302 const char *name, *type;
93638d7a
AM
8303
8304 name = ((* targetm.strip_name_encoding)
8305 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
25fdb4dc 8306 type = visibility_types[vis];
93638d7a 8307
25fdb4dc
RH
8308 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
8309 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
93638d7a 8310 }
25fdb4dc
RH
8311 else
8312 default_assemble_visibility (decl, vis);
93638d7a
AM
8313}
8314#endif
301d03af 8315\f
39a10a29
GK
8316enum rtx_code
8317rs6000_reverse_condition (mode, code)
8318 enum machine_mode mode;
8319 enum rtx_code code;
8320{
8321 /* Reversal of FP compares takes care -- an ordered compare
8322 becomes an unordered compare and vice versa. */
de40e1df 8323 if (mode == CCFPmode && !flag_unsafe_math_optimizations)
bab6226b 8324 return reverse_condition_maybe_unordered (code);
39a10a29 8325 else
bab6226b 8326 return reverse_condition (code);
39a10a29
GK
8327}
8328
39a10a29
GK
8329/* Generate a compare for CODE. Return a brand-new rtx that
8330 represents the result of the compare. */
a4f6c312 8331
39a10a29
GK
8332static rtx
8333rs6000_generate_compare (code)
8334 enum rtx_code code;
8335{
8336 enum machine_mode comp_mode;
8337 rtx compare_result;
8338
8339 if (rs6000_compare_fp_p)
8340 comp_mode = CCFPmode;
8341 else if (code == GTU || code == LTU
8342 || code == GEU || code == LEU)
8343 comp_mode = CCUNSmode;
8344 else
8345 comp_mode = CCmode;
8346
8347 /* First, the compare. */
8348 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
8349
8350 /* SPE FP compare instructions on the GPRs. Yuck! */
8351 if ((TARGET_SPE && TARGET_HARD_FLOAT) && rs6000_compare_fp_p)
8352 {
8353 rtx cmp, or1, or2, or_result, compare_result2;
8354
8355 switch (code)
8356 {
8357 case EQ:
8358 case UNEQ:
8359 case NE:
8360 case LTGT:
8361 cmp = flag_unsafe_math_optimizations
8362 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8363 rs6000_compare_op1)
8364 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8365 rs6000_compare_op1);
8366 break;
8367 case GT:
8368 case GTU:
8369 case UNGT:
8370 case UNGE:
8371 case GE:
8372 case GEU:
8373 cmp = flag_unsafe_math_optimizations
8374 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8375 rs6000_compare_op1)
8376 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8377 rs6000_compare_op1);
8378 break;
8379 case LT:
8380 case LTU:
8381 case UNLT:
8382 case UNLE:
8383 case LE:
8384 case LEU:
8385 cmp = flag_unsafe_math_optimizations
8386 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8387 rs6000_compare_op1)
8388 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8389 rs6000_compare_op1);
8390 break;
8391 default:
8392 abort ();
8393 }
8394
8395 /* Synthesize LE and GE from LT/GT || EQ. */
8396 if (code == LE || code == GE || code == LEU || code == GEU)
8397 {
8398 /* Synthesize GE/LE frome GT/LT || EQ. */
8399
8400 emit_insn (cmp);
8401
8402 switch (code)
8403 {
8404 case LE: code = LT; break;
8405 case GE: code = GT; break;
8406 case LEU: code = LT; break;
8407 case GEU: code = GT; break;
8408 default: abort ();
8409 }
8410
8411 or1 = gen_reg_rtx (SImode);
8412 or2 = gen_reg_rtx (SImode);
8413 or_result = gen_reg_rtx (CCEQmode);
8414 compare_result2 = gen_reg_rtx (CCFPmode);
8415
8416 /* Do the EQ. */
8417 cmp = flag_unsafe_math_optimizations
8418 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8419 rs6000_compare_op1)
8420 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8421 rs6000_compare_op1);
8422 emit_insn (cmp);
8423
8424 /* The MC8540 FP compare instructions set the CR bits
8425 differently than other PPC compare instructions. For
8426 that matter, there is no generic test instruction, but a
8427 testgt, testlt, and testeq. For a true condition, bit 2
8428 is set (x1xx) in the CR. Following the traditional CR
8429 values:
8430
8431 LT GT EQ OV
8432 bit3 bit2 bit1 bit0
8433
8434 ... bit 2 would be a GT CR alias, so later on we
b6d08ca1 8435 look in the GT bits for the branch instructions.
a3170dc6
AH
8436 However, we must be careful to emit correct RTL in
8437 the meantime, so optimizations don't get confused. */
8438
8439 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8440 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8441
8442 /* OR them together. */
8443 cmp = gen_rtx_SET (VOIDmode, or_result,
8444 gen_rtx_COMPARE (CCEQmode,
8445 gen_rtx_IOR (SImode, or1, or2),
8446 const_true_rtx));
8447 compare_result = or_result;
8448 code = EQ;
8449 }
8450 else
8451 {
8452 /* We only care about 1 bit (x1xx), so map everything to NE to
8453 maintain rtl sanity. We'll get to the right bit (x1xx) at
8454 code output time. */
8455 if (code == NE || code == LTGT)
8456 /* Do the inverse here because we have no cmpne
8457 instruction. We use the cmpeq instruction and expect
8458 to get a 0 instead. */
8459 code = EQ;
8460 else
8461 code = NE;
8462 }
8463
8464 emit_insn (cmp);
8465 }
8466 else
8467 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8468 gen_rtx_COMPARE (comp_mode,
8469 rs6000_compare_op0,
8470 rs6000_compare_op1)));
39a10a29 8471
ca5adc63 8472 /* Some kinds of FP comparisons need an OR operation;
de6c5979 8473 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 8474 if (rs6000_compare_fp_p
de6c5979 8475 && ! flag_unsafe_math_optimizations
a3170dc6 8476 && ! (TARGET_HARD_FLOAT && TARGET_SPE)
39a10a29
GK
8477 && (code == LE || code == GE
8478 || code == UNEQ || code == LTGT
8479 || code == UNGT || code == UNLT))
8480 {
8481 enum rtx_code or1, or2;
8482 rtx or1_rtx, or2_rtx, compare2_rtx;
8483 rtx or_result = gen_reg_rtx (CCEQmode);
8484
8485 switch (code)
8486 {
8487 case LE: or1 = LT; or2 = EQ; break;
8488 case GE: or1 = GT; or2 = EQ; break;
8489 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8490 case LTGT: or1 = LT; or2 = GT; break;
8491 case UNGT: or1 = UNORDERED; or2 = GT; break;
8492 case UNLT: or1 = UNORDERED; or2 = LT; break;
8493 default: abort ();
8494 }
8495 validate_condition_mode (or1, comp_mode);
8496 validate_condition_mode (or2, comp_mode);
8497 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8498 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8499 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8500 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8501 const_true_rtx);
8502 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8503
8504 compare_result = or_result;
8505 code = EQ;
8506 }
8507
8508 validate_condition_mode (code, GET_MODE (compare_result));
8509
8510 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8511}
8512
8513
8514/* Emit the RTL for an sCOND pattern. */
8515
8516void
8517rs6000_emit_sCOND (code, result)
8518 enum rtx_code code;
8519 rtx result;
8520{
8521 rtx condition_rtx;
8522 enum machine_mode op_mode;
8523
8524 condition_rtx = rs6000_generate_compare (code);
8525
8526 op_mode = GET_MODE (rs6000_compare_op0);
8527 if (op_mode == VOIDmode)
8528 op_mode = GET_MODE (rs6000_compare_op1);
8529
8530 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8531 {
8532 PUT_MODE (condition_rtx, DImode);
8533 convert_move (result, condition_rtx, 0);
8534 }
8535 else
8536 {
8537 PUT_MODE (condition_rtx, SImode);
8538 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8539 }
8540}
8541
39a10a29
GK
8542/* Emit a branch of kind CODE to location LOC. */
8543
8544void
8545rs6000_emit_cbranch (code, loc)
8546 enum rtx_code code;
8547 rtx loc;
8548{
8549 rtx condition_rtx, loc_ref;
8550
8551 condition_rtx = rs6000_generate_compare (code);
8552 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8553 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8554 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8555 loc_ref, pc_rtx)));
8556}
8557
12a4e8c5
GK
8558/* Return the string to output a conditional branch to LABEL, which is
8559 the operand number of the label, or -1 if the branch is really a
8560 conditional return.
8561
8562 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8563 condition code register and its mode specifies what kind of
8564 comparison we made.
8565
a0ab749a 8566 REVERSED is nonzero if we should reverse the sense of the comparison.
12a4e8c5
GK
8567
8568 INSN is the insn. */
8569
8570char *
8571output_cbranch (op, label, reversed, insn)
8572 rtx op;
8573 const char * label;
8574 int reversed;
8575 rtx insn;
8576{
8577 static char string[64];
8578 enum rtx_code code = GET_CODE (op);
8579 rtx cc_reg = XEXP (op, 0);
8580 enum machine_mode mode = GET_MODE (cc_reg);
8581 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 8582 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
8583 int really_reversed = reversed ^ need_longbranch;
8584 char *s = string;
8585 const char *ccode;
8586 const char *pred;
8587 rtx note;
8588
39a10a29
GK
8589 validate_condition_mode (code, mode);
8590
8591 /* Work out which way this really branches. We could use
8592 reverse_condition_maybe_unordered here always but this
8593 makes the resulting assembler clearer. */
12a4e8c5 8594 if (really_reversed)
de40e1df
DJ
8595 {
8596 /* Reversal of FP compares takes care -- an ordered compare
8597 becomes an unordered compare and vice versa. */
8598 if (mode == CCFPmode)
8599 code = reverse_condition_maybe_unordered (code);
8600 else
8601 code = reverse_condition (code);
8602 }
12a4e8c5 8603
a3170dc6
AH
8604 if ((TARGET_SPE && TARGET_HARD_FLOAT) && mode == CCFPmode)
8605 {
8606 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8607 to the GT bit. */
8608 if (code == EQ)
8609 /* Opposite of GT. */
8610 code = UNLE;
8611 else if (code == NE)
8612 code = GT;
8613 else
8614 abort ();
8615 }
8616
39a10a29 8617 switch (code)
12a4e8c5
GK
8618 {
8619 /* Not all of these are actually distinct opcodes, but
8620 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
8621 case NE: case LTGT:
8622 ccode = "ne"; break;
8623 case EQ: case UNEQ:
8624 ccode = "eq"; break;
8625 case GE: case GEU:
8626 ccode = "ge"; break;
8627 case GT: case GTU: case UNGT:
8628 ccode = "gt"; break;
8629 case LE: case LEU:
8630 ccode = "le"; break;
8631 case LT: case LTU: case UNLT:
8632 ccode = "lt"; break;
12a4e8c5
GK
8633 case UNORDERED: ccode = "un"; break;
8634 case ORDERED: ccode = "nu"; break;
8635 case UNGE: ccode = "nl"; break;
8636 case UNLE: ccode = "ng"; break;
8637 default:
a4f6c312 8638 abort ();
12a4e8c5
GK
8639 }
8640
94a54f47
GK
8641 /* Maybe we have a guess as to how likely the branch is.
8642 The old mnemonics don't have a way to specify this information. */
f4857b9b 8643 pred = "";
12a4e8c5
GK
8644 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8645 if (note != NULL_RTX)
8646 {
8647 /* PROB is the difference from 50%. */
8648 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
8649 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8650
8651 /* Only hint for highly probable/improbable branches on newer
8652 cpus as static prediction overrides processor dynamic
8653 prediction. For older cpus we may as well always hint, but
8654 assume not taken for branches that are very close to 50% as a
8655 mispredicted taken branch is more expensive than a
8656 mispredicted not-taken branch. */
8657 if (always_hint
8658 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8659 {
8660 if (abs (prob) > REG_BR_PROB_BASE / 20
8661 && ((prob > 0) ^ need_longbranch))
7f3d8013 8662 pred = "+";
f4857b9b
AM
8663 else
8664 pred = "-";
8665 }
12a4e8c5 8666 }
12a4e8c5
GK
8667
8668 if (label == NULL)
94a54f47 8669 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 8670 else
94a54f47 8671 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 8672
37c67319
GK
8673 /* We need to escape any '%' characters in the reg_names string.
8674 Assume they'd only be the first character... */
8675 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8676 *s++ = '%';
94a54f47 8677 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
8678
8679 if (label != NULL)
8680 {
8681 /* If the branch distance was too far, we may have to use an
8682 unconditional branch to go the distance. */
8683 if (need_longbranch)
44518ddd 8684 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
8685 else
8686 s += sprintf (s, ",%s", label);
8687 }
8688
8689 return string;
8690}
50a0b056
GK
8691
8692/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8693 operands of the last comparison is nonzero/true, FALSE_COND if it
8694 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 8695
50a0b056
GK
8696int
8697rs6000_emit_cmove (dest, op, true_cond, false_cond)
8698 rtx dest;
8699 rtx op;
8700 rtx true_cond;
8701 rtx false_cond;
8702{
8703 enum rtx_code code = GET_CODE (op);
8704 rtx op0 = rs6000_compare_op0;
8705 rtx op1 = rs6000_compare_op1;
8706 REAL_VALUE_TYPE c1;
3148ad6d
DJ
8707 enum machine_mode compare_mode = GET_MODE (op0);
8708 enum machine_mode result_mode = GET_MODE (dest);
50a0b056
GK
8709 rtx temp;
8710
3148ad6d 8711 /* These modes should always match. */
a3170dc6
AH
8712 if (GET_MODE (op1) != compare_mode
8713 /* In the isel case however, we can use a compare immediate, so
8714 op1 may be a small constant. */
8715 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 8716 return 0;
178c3eff 8717 if (GET_MODE (true_cond) != result_mode)
3148ad6d 8718 return 0;
178c3eff 8719 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
8720 return 0;
8721
50a0b056
GK
8722 /* First, work out if the hardware can do this at all, or
8723 if it's too slow... */
50a0b056 8724 if (! rs6000_compare_fp_p)
a3170dc6
AH
8725 {
8726 if (TARGET_ISEL)
8727 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8728 return 0;
8729 }
50a0b056
GK
8730
8731 /* Eliminate half of the comparisons by switching operands, this
8732 makes the remaining code simpler. */
8733 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8734 || code == LTGT || code == LT)
8735 {
8736 code = reverse_condition_maybe_unordered (code);
8737 temp = true_cond;
8738 true_cond = false_cond;
8739 false_cond = temp;
8740 }
8741
8742 /* UNEQ and LTGT take four instructions for a comparison with zero,
8743 it'll probably be faster to use a branch here too. */
8744 if (code == UNEQ)
8745 return 0;
8746
8747 if (GET_CODE (op1) == CONST_DOUBLE)
8748 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8749
b6d08ca1 8750 /* We're going to try to implement comparisons by performing
50a0b056
GK
8751 a subtract, then comparing against zero. Unfortunately,
8752 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 8753 know that the operand is finite and the comparison
50a0b056
GK
8754 would treat EQ different to UNORDERED, we can't do it. */
8755 if (! flag_unsafe_math_optimizations
8756 && code != GT && code != UNGE
045572c7 8757 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
8758 /* Constructs of the form (a OP b ? a : b) are safe. */
8759 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8760 || (! rtx_equal_p (op0, true_cond)
8761 && ! rtx_equal_p (op1, true_cond))))
8762 return 0;
8763 /* At this point we know we can use fsel. */
8764
8765 /* Reduce the comparison to a comparison against zero. */
3148ad6d 8766 temp = gen_reg_rtx (compare_mode);
50a0b056 8767 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8768 gen_rtx_MINUS (compare_mode, op0, op1)));
50a0b056 8769 op0 = temp;
3148ad6d 8770 op1 = CONST0_RTX (compare_mode);
50a0b056
GK
8771
8772 /* If we don't care about NaNs we can reduce some of the comparisons
8773 down to faster ones. */
8774 if (flag_unsafe_math_optimizations)
8775 switch (code)
8776 {
8777 case GT:
8778 code = LE;
8779 temp = true_cond;
8780 true_cond = false_cond;
8781 false_cond = temp;
8782 break;
8783 case UNGE:
8784 code = GE;
8785 break;
8786 case UNEQ:
8787 code = EQ;
8788 break;
8789 default:
8790 break;
8791 }
8792
8793 /* Now, reduce everything down to a GE. */
8794 switch (code)
8795 {
8796 case GE:
8797 break;
8798
8799 case LE:
3148ad6d
DJ
8800 temp = gen_reg_rtx (compare_mode);
8801 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8802 op0 = temp;
8803 break;
8804
8805 case ORDERED:
3148ad6d
DJ
8806 temp = gen_reg_rtx (compare_mode);
8807 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
8808 op0 = temp;
8809 break;
8810
8811 case EQ:
3148ad6d 8812 temp = gen_reg_rtx (compare_mode);
50a0b056 8813 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
8814 gen_rtx_NEG (compare_mode,
8815 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
8816 op0 = temp;
8817 break;
8818
8819 case UNGE:
3148ad6d 8820 temp = gen_reg_rtx (result_mode);
50a0b056 8821 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8822 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8823 gen_rtx_GE (VOIDmode,
8824 op0, op1),
8825 true_cond, false_cond)));
8826 false_cond = temp;
8827 true_cond = false_cond;
8828
3148ad6d
DJ
8829 temp = gen_reg_rtx (compare_mode);
8830 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8831 op0 = temp;
8832 break;
8833
8834 case GT:
3148ad6d 8835 temp = gen_reg_rtx (result_mode);
50a0b056 8836 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8837 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8838 gen_rtx_GE (VOIDmode,
8839 op0, op1),
8840 true_cond, false_cond)));
8841 true_cond = temp;
8842 false_cond = true_cond;
8843
3148ad6d
DJ
8844 temp = gen_reg_rtx (compare_mode);
8845 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8846 op0 = temp;
8847 break;
8848
8849 default:
8850 abort ();
8851 }
8852
8853 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 8854 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8855 gen_rtx_GE (VOIDmode,
8856 op0, op1),
8857 true_cond, false_cond)));
8858 return 1;
8859}
8860
a3170dc6
AH
8861/* Same as above, but for ints (isel). */
8862
8863static int
8864rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
8865 rtx dest;
8866 rtx op;
8867 rtx true_cond;
8868 rtx false_cond;
8869{
8870 rtx condition_rtx, cr;
8871
8872 /* All isel implementations thus far are 32-bits. */
8873 if (GET_MODE (rs6000_compare_op0) != SImode)
8874 return 0;
8875
8876 /* We still have to do the compare, because isel doesn't do a
8877 compare, it just looks at the CRx bits set by a previous compare
8878 instruction. */
8879 condition_rtx = rs6000_generate_compare (GET_CODE (op));
8880 cr = XEXP (condition_rtx, 0);
8881
8882 if (GET_MODE (cr) == CCmode)
8883 emit_insn (gen_isel_signed (dest, condition_rtx,
8884 true_cond, false_cond, cr));
8885 else
8886 emit_insn (gen_isel_unsigned (dest, condition_rtx,
8887 true_cond, false_cond, cr));
8888
8889 return 1;
8890}
8891
8892const char *
8893output_isel (operands)
8894 rtx *operands;
8895{
8896 enum rtx_code code;
8897
8898 code = GET_CODE (operands[1]);
8899 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
8900 {
8901 PUT_CODE (operands[1], reverse_condition (code));
8902 return "isel %0,%3,%2,%j1";
8903 }
8904 else
8905 return "isel %0,%2,%3,%j1";
8906}
8907
50a0b056
GK
8908void
8909rs6000_emit_minmax (dest, code, op0, op1)
8910 rtx dest;
8911 enum rtx_code code;
8912 rtx op0;
8913 rtx op1;
8914{
8915 enum machine_mode mode = GET_MODE (op0);
5dc8d536 8916 enum rtx_code c;
50a0b056 8917 rtx target;
5dc8d536
AH
8918
8919 if (code == SMAX || code == SMIN)
8920 c = GE;
8921 else
8922 c = GEU;
8923
50a0b056 8924 if (code == SMAX || code == UMAX)
5dc8d536 8925 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8926 op0, op1, mode, 0);
8927 else
5dc8d536 8928 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
8929 op1, op0, mode, 0);
8930 if (target == NULL_RTX)
8931 abort ();
8932 if (target != dest)
8933 emit_move_insn (dest, target);
8934}
12a4e8c5 8935\f
a4f6c312
SS
8936/* This page contains routines that are used to determine what the
8937 function prologue and epilogue code will do and write them out. */
9878760c 8938
a4f6c312
SS
8939/* Return the first fixed-point register that is required to be
8940 saved. 32 if none. */
9878760c
RK
8941
8942int
8943first_reg_to_save ()
8944{
8945 int first_reg;
8946
8947 /* Find lowest numbered live register. */
8948 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
8949 if (regs_ever_live[first_reg]
8950 && (! call_used_regs[first_reg]
1db02437 8951 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 8952 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 8953 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
8954 break;
8955
ee890fe2 8956#if TARGET_MACHO
93638d7a
AM
8957 if (flag_pic
8958 && current_function_uses_pic_offset_table
8959 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 8960 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
8961#endif
8962
9878760c
RK
8963 return first_reg;
8964}
8965
8966/* Similar, for FP regs. */
8967
8968int
8969first_fp_reg_to_save ()
8970{
8971 int first_reg;
8972
8973 /* Find lowest numbered live register. */
8974 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
8975 if (regs_ever_live[first_reg])
8976 break;
8977
8978 return first_reg;
8979}
00b960c7
AH
8980
8981/* Similar, for AltiVec regs. */
8982
8983static int
8984first_altivec_reg_to_save ()
8985{
8986 int i;
8987
8988 /* Stack frame remains as is unless we are in AltiVec ABI. */
8989 if (! TARGET_ALTIVEC_ABI)
8990 return LAST_ALTIVEC_REGNO + 1;
8991
8992 /* Find lowest numbered live register. */
8993 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
8994 if (regs_ever_live[i])
8995 break;
8996
8997 return i;
8998}
8999
9000/* Return a 32-bit mask of the AltiVec registers we need to set in
9001 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
9002 the 32-bit word is 0. */
9003
9004static unsigned int
9005compute_vrsave_mask ()
9006{
9007 unsigned int i, mask = 0;
9008
9009 /* First, find out if we use _any_ altivec registers. */
9010 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
9011 if (regs_ever_live[i])
9012 mask |= ALTIVEC_REG_BIT (i);
9013
9014 if (mask == 0)
9015 return mask;
9016
9017 /* Next, add all registers that are call-clobbered. We do this
9018 because post-reload register optimizers such as regrename_optimize
9019 may choose to use them. They never change the register class
9020 chosen by reload, so cannot create new uses of altivec registers
9021 if there were none before, so the early exit above is safe. */
9022 /* ??? Alternately, we could define HARD_REGNO_RENAME_OK to disallow
9023 altivec registers not saved in the mask, which might well make the
9024 adjustments below more effective in eliding the save/restore of
9025 VRSAVE in small functions. */
9026 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
9027 if (call_used_regs[i])
9028 mask |= ALTIVEC_REG_BIT (i);
9029
9030 /* Next, remove the argument registers from the set. These must
9031 be in the VRSAVE mask set by the caller, so we don't need to add
9032 them in again. More importantly, the mask we compute here is
9033 used to generate CLOBBERs in the set_vrsave insn, and we do not
9034 wish the argument registers to die. */
9035 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
9036 mask &= ~ALTIVEC_REG_BIT (i);
9037
9038 /* Similarly, remove the return value from the set. */
9039 {
9040 bool yes = false;
9041 diddle_return_value (is_altivec_return_reg, &yes);
9042 if (yes)
9043 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
9044 }
9045
9046 return mask;
9047}
9048
9049static void
9050is_altivec_return_reg (reg, xyes)
9051 rtx reg;
9052 void *xyes;
9053{
9054 bool *yes = (bool *) xyes;
9055 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
9056 *yes = true;
9057}
9058
4697a36c
MM
9059\f
9060/* Calculate the stack information for the current function. This is
9061 complicated by having two separate calling sequences, the AIX calling
9062 sequence and the V.4 calling sequence.
9063
592696dd 9064 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 9065 32-bit 64-bit
4697a36c 9066 SP----> +---------------------------------------+
a260abc9 9067 | back chain to caller | 0 0
4697a36c 9068 +---------------------------------------+
a260abc9 9069 | saved CR | 4 8 (8-11)
4697a36c 9070 +---------------------------------------+
a260abc9 9071 | saved LR | 8 16
4697a36c 9072 +---------------------------------------+
a260abc9 9073 | reserved for compilers | 12 24
4697a36c 9074 +---------------------------------------+
a260abc9 9075 | reserved for binders | 16 32
4697a36c 9076 +---------------------------------------+
a260abc9 9077 | saved TOC pointer | 20 40
4697a36c 9078 +---------------------------------------+
a260abc9 9079 | Parameter save area (P) | 24 48
4697a36c 9080 +---------------------------------------+
a260abc9 9081 | Alloca space (A) | 24+P etc.
802a0058 9082 +---------------------------------------+
a7df97e6 9083 | Local variable space (L) | 24+P+A
4697a36c 9084 +---------------------------------------+
a7df97e6 9085 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 9086 +---------------------------------------+
00b960c7
AH
9087 | Save area for AltiVec registers (W) | 24+P+A+L+X
9088 +---------------------------------------+
9089 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
9090 +---------------------------------------+
9091 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 9092 +---------------------------------------+
00b960c7
AH
9093 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
9094 +---------------------------------------+
9095 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
9096 +---------------------------------------+
9097 old SP->| back chain to caller's caller |
9098 +---------------------------------------+
9099
5376a30c
KR
9100 The required alignment for AIX configurations is two words (i.e., 8
9101 or 16 bytes).
9102
9103
4697a36c
MM
9104 V.4 stack frames look like:
9105
9106 SP----> +---------------------------------------+
9107 | back chain to caller | 0
9108 +---------------------------------------+
5eb387b8 9109 | caller's saved LR | 4
4697a36c
MM
9110 +---------------------------------------+
9111 | Parameter save area (P) | 8
9112 +---------------------------------------+
a7df97e6
MM
9113 | Alloca space (A) | 8+P
9114 +---------------------------------------+
9115 | Varargs save area (V) | 8+P+A
9116 +---------------------------------------+
9117 | Local variable space (L) | 8+P+A+V
9118 +---------------------------------------+
9119 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 9120 +---------------------------------------+
00b960c7
AH
9121 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
9122 +---------------------------------------+
9123 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
9124 +---------------------------------------+
9125 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
9126 +---------------------------------------+
a3170dc6
AH
9127 | SPE: area for 64-bit GP registers |
9128 +---------------------------------------+
9129 | SPE alignment padding |
9130 +---------------------------------------+
00b960c7 9131 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 9132 +---------------------------------------+
00b960c7 9133 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 9134 +---------------------------------------+
00b960c7 9135 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
9136 +---------------------------------------+
9137 old SP->| back chain to caller's caller |
9138 +---------------------------------------+
b6c9286a 9139
5376a30c
KR
9140 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
9141 given. (But note below and in sysv4.h that we require only 8 and
9142 may round up the size of our stack frame anyways. The historical
9143 reason is early versions of powerpc-linux which didn't properly
9144 align the stack at program startup. A happy side-effect is that
9145 -mno-eabi libraries can be used with -meabi programs.)
9146
5376a30c
KR
9147 The EABI configuration defaults to the V.4 layout, unless
9148 -mcall-aix is used, in which case the AIX layout is used. However,
9149 the stack alignment requirements may differ. If -mno-eabi is not
9150 given, the required stack alignment is 8 bytes; if -mno-eabi is
9151 given, the required alignment is 16 bytes. (But see V.4 comment
9152 above.) */
4697a36c 9153
61b2fbe7
MM
9154#ifndef ABI_STACK_BOUNDARY
9155#define ABI_STACK_BOUNDARY STACK_BOUNDARY
9156#endif
9157
4697a36c
MM
9158rs6000_stack_t *
9159rs6000_stack_info ()
9160{
9161 static rs6000_stack_t info, zero_info;
9162 rs6000_stack_t *info_ptr = &info;
9ebbca7d 9163 int reg_size = TARGET_POWERPC64 ? 8 : 4;
24d304eb 9164 enum rs6000_abi abi;
83720594 9165 int ehrd_size;
b6c9286a 9166 int total_raw_size;
c19de7aa 9167 static int insn_chain_scanned = -1;
4697a36c 9168
a4f6c312 9169 /* Zero all fields portably. */
4697a36c
MM
9170 info = zero_info;
9171
c19de7aa
AH
9172 if (TARGET_SPE)
9173 {
9174 /* Cache value so we don't rescan instruction chain over and over. */
9175 if (insn_chain_scanned < 0)
9176 insn_chain_scanned = (int) spe_func_has_64bit_regs_p ();
9177 info_ptr->spe_64bit_regs_used = insn_chain_scanned;
9178 }
9179
a4f6c312 9180 /* Select which calling sequence. */
b6c9286a 9181 info_ptr->abi = abi = DEFAULT_ABI;
9878760c 9182
a4f6c312 9183 /* Calculate which registers need to be saved & save area size. */
4697a36c 9184 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 9185 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 9186 even if it currently looks like we won't. */
2bfcf297 9187 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
f607bc57
ZW
9188 || (flag_pic == 1 && abi == ABI_V4)
9189 || (flag_pic && abi == ABI_DARWIN))
1db02437
FS
9190 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
9191 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
9192 else
9193 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 9194
a3170dc6
AH
9195 /* For the SPE, we have an additional upper 32-bits on each GPR.
9196 Ideally we should save the entire 64-bits only when the upper
9197 half is used in SIMD instructions. Since we only record
9198 registers live (not the size they are used in), this proves
9199 difficult because we'd have to traverse the instruction chain at
9200 the right time, taking reload into account. This is a real pain,
c19de7aa
AH
9201 so we opt to save the GPRs in 64-bits always if but one register
9202 gets used in 64-bits. Otherwise, all the registers in the frame
9203 get saved in 32-bits.
a3170dc6 9204
c19de7aa 9205 So... since when we save all GPRs (except the SP) in 64-bits, the
a3170dc6 9206 traditional GP save area will be empty. */
c19de7aa 9207 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
9208 info_ptr->gp_size = 0;
9209
4697a36c
MM
9210 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
9211 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
9212
00b960c7
AH
9213 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9214 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9215 - info_ptr->first_altivec_reg_save);
9216
592696dd 9217 /* Does this function call anything? */
71f123ca
FS
9218 info_ptr->calls_p = (! current_function_is_leaf
9219 || cfun->machine->ra_needs_full_frame);
b6c9286a 9220
a4f6c312 9221 /* Determine if we need to save the link register. */
71f123ca 9222 if (rs6000_ra_ever_killed ()
70f4f91c 9223 || (DEFAULT_ABI == ABI_AIX && current_function_profile)
4697a36c
MM
9224#ifdef TARGET_RELOCATABLE
9225 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9226#endif
9227 || (info_ptr->first_fp_reg_save != 64
9228 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 9229 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
24d304eb 9230 || (abi == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
9231 || (DEFAULT_ABI == ABI_DARWIN
9232 && flag_pic
9233 && current_function_uses_pic_offset_table)
4697a36c
MM
9234 || info_ptr->calls_p)
9235 {
9236 info_ptr->lr_save_p = 1;
9ebbca7d 9237 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9238 }
9239
9ebbca7d
GK
9240 /* Determine if we need to save the condition code registers. */
9241 if (regs_ever_live[CR2_REGNO]
9242 || regs_ever_live[CR3_REGNO]
9243 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9244 {
9245 info_ptr->cr_save_p = 1;
f607bc57 9246 if (abi == ABI_V4)
4697a36c
MM
9247 info_ptr->cr_size = reg_size;
9248 }
9249
83720594
RH
9250 /* If the current function calls __builtin_eh_return, then we need
9251 to allocate stack space for registers that will hold data for
9252 the exception handler. */
9253 if (current_function_calls_eh_return)
9254 {
9255 unsigned int i;
9256 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9257 continue;
a3170dc6
AH
9258
9259 /* SPE saves EH registers in 64-bits. */
c19de7aa
AH
9260 ehrd_size = i * (TARGET_SPE_ABI
9261 && info_ptr->spe_64bit_regs_used != 0
9262 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9263 }
9264 else
9265 ehrd_size = 0;
9266
592696dd 9267 /* Determine various sizes. */
4697a36c
MM
9268 info_ptr->reg_size = reg_size;
9269 info_ptr->fixed_size = RS6000_SAVE_AREA;
9270 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9271 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9272 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9273 8);
00b960c7 9274
c19de7aa 9275 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
9276 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9277 else
9278 info_ptr->spe_gp_size = 0;
9279
08b57fb3 9280 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9281 {
9282 info_ptr->vrsave_mask = compute_vrsave_mask ();
9283 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9284 }
9285 else
9286 {
9287 info_ptr->vrsave_mask = 0;
9288 info_ptr->vrsave_size = 0;
9289 }
b6c9286a 9290
592696dd 9291 /* Calculate the offsets. */
24d304eb 9292 switch (abi)
4697a36c 9293 {
b6c9286a 9294 case ABI_NONE:
24d304eb 9295 default:
b6c9286a
MM
9296 abort ();
9297
9298 case ABI_AIX:
9299 case ABI_AIX_NODESC:
ee890fe2 9300 case ABI_DARWIN:
b6c9286a
MM
9301 info_ptr->fp_save_offset = - info_ptr->fp_size;
9302 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9303
9304 if (TARGET_ALTIVEC_ABI)
9305 {
9306 info_ptr->vrsave_save_offset
9307 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9308
9309 /* Align stack so vector save area is on a quadword boundary. */
9310 if (info_ptr->altivec_size != 0)
9311 info_ptr->altivec_padding_size
9312 = 16 - (-info_ptr->vrsave_save_offset % 16);
9313 else
9314 info_ptr->altivec_padding_size = 0;
9315
9316 info_ptr->altivec_save_offset
9317 = info_ptr->vrsave_save_offset
9318 - info_ptr->altivec_padding_size
9319 - info_ptr->altivec_size;
9320
9321 /* Adjust for AltiVec case. */
9322 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9323 }
9324 else
9325 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9326 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9327 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9328 break;
9329
9330 case ABI_V4:
b6c9286a
MM
9331 info_ptr->fp_save_offset = - info_ptr->fp_size;
9332 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9333 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9334
c19de7aa 9335 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
9336 {
9337 /* Align stack so SPE GPR save area is aligned on a
9338 double-word boundary. */
9339 if (info_ptr->spe_gp_size != 0)
9340 info_ptr->spe_padding_size
9341 = 8 - (-info_ptr->cr_save_offset % 8);
9342 else
9343 info_ptr->spe_padding_size = 0;
9344
9345 info_ptr->spe_gp_save_offset
9346 = info_ptr->cr_save_offset
9347 - info_ptr->spe_padding_size
9348 - info_ptr->spe_gp_size;
9349
9350 /* Adjust for SPE case. */
9351 info_ptr->toc_save_offset
9352 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9353 }
9354 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9355 {
9356 info_ptr->vrsave_save_offset
9357 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9358
9359 /* Align stack so vector save area is on a quadword boundary. */
9360 if (info_ptr->altivec_size != 0)
9361 info_ptr->altivec_padding_size
9362 = 16 - (-info_ptr->vrsave_save_offset % 16);
9363 else
9364 info_ptr->altivec_padding_size = 0;
9365
9366 info_ptr->altivec_save_offset
9367 = info_ptr->vrsave_save_offset
9368 - info_ptr->altivec_padding_size
9369 - info_ptr->altivec_size;
9370
9371 /* Adjust for AltiVec case. */
9372 info_ptr->toc_save_offset
9373 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9374 }
9375 else
9376 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9377 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9378 info_ptr->lr_save_offset = reg_size;
9379 break;
4697a36c
MM
9380 }
9381
00b960c7
AH
9382 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9383 + info_ptr->gp_size
9384 + info_ptr->altivec_size
9385 + info_ptr->altivec_padding_size
9386 + info_ptr->vrsave_size
a3170dc6
AH
9387 + info_ptr->spe_gp_size
9388 + info_ptr->spe_padding_size
00b960c7
AH
9389 + ehrd_size
9390 + info_ptr->cr_size
9391 + info_ptr->lr_size
9392 + info_ptr->vrsave_size
9393 + info_ptr->toc_size,
9394 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9395 ? 16 : 8);
9396
ff381587
MM
9397 total_raw_size = (info_ptr->vars_size
9398 + info_ptr->parm_size
ff381587
MM
9399 + info_ptr->save_size
9400 + info_ptr->varargs_size
9401 + info_ptr->fixed_size);
9402
a4f6c312
SS
9403 info_ptr->total_size =
9404 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9405
9406 /* Determine if we need to allocate any stack frame:
9407
a4f6c312
SS
9408 For AIX we need to push the stack if a frame pointer is needed
9409 (because the stack might be dynamically adjusted), if we are
9410 debugging, if we make calls, or if the sum of fp_save, gp_save,
9411 and local variables are more than the space needed to save all
9412 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9413 + 18*8 = 288 (GPR13 reserved).
ff381587 9414
a4f6c312
SS
9415 For V.4 we don't have the stack cushion that AIX uses, but assume
9416 that the debugger can handle stackless frames. */
ff381587
MM
9417
9418 if (info_ptr->calls_p)
9419 info_ptr->push_p = 1;
9420
f607bc57 9421 else if (abi == ABI_V4)
e72247f4 9422 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587
MM
9423
9424 else
9425 info_ptr->push_p = (frame_pointer_needed
ee890fe2 9426 || (abi != ABI_DARWIN && write_symbols != NO_DEBUG)
ff381587 9427 || ((total_raw_size - info_ptr->fixed_size)
bfc79d3b 9428 > (TARGET_32BIT ? 220 : 288)));
ff381587 9429
a4f6c312 9430 /* Zero offsets if we're not saving those registers. */
8dda1a21 9431 if (info_ptr->fp_size == 0)
4697a36c
MM
9432 info_ptr->fp_save_offset = 0;
9433
8dda1a21 9434 if (info_ptr->gp_size == 0)
4697a36c
MM
9435 info_ptr->gp_save_offset = 0;
9436
00b960c7
AH
9437 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9438 info_ptr->altivec_save_offset = 0;
9439
9440 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9441 info_ptr->vrsave_save_offset = 0;
9442
c19de7aa
AH
9443 if (! TARGET_SPE_ABI
9444 || info_ptr->spe_64bit_regs_used == 0
9445 || info_ptr->spe_gp_size == 0)
a3170dc6
AH
9446 info_ptr->spe_gp_save_offset = 0;
9447
c81fc13e 9448 if (! info_ptr->lr_save_p)
4697a36c
MM
9449 info_ptr->lr_save_offset = 0;
9450
c81fc13e 9451 if (! info_ptr->cr_save_p)
4697a36c
MM
9452 info_ptr->cr_save_offset = 0;
9453
c81fc13e 9454 if (! info_ptr->toc_save_p)
b6c9286a
MM
9455 info_ptr->toc_save_offset = 0;
9456
4697a36c
MM
9457 return info_ptr;
9458}
9459
c19de7aa
AH
9460/* Return true if the current function uses any GPRs in 64-bit SIMD
9461 mode. */
9462
9463static bool
9464spe_func_has_64bit_regs_p ()
9465{
9466 rtx insns, insn;
9467
9468 /* Functions that save and restore all the call-saved registers will
9469 need to save/restore the registers in 64-bits. */
9470 if (current_function_calls_eh_return
9471 || current_function_calls_setjmp
9472 || current_function_has_nonlocal_goto)
9473 return true;
9474
9475 insns = get_insns ();
9476
9477 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
9478 {
9479 if (INSN_P (insn))
9480 {
9481 rtx i;
9482
9483 i = PATTERN (insn);
9484 if (GET_CODE (i) == SET
9485 && SPE_VECTOR_MODE (GET_MODE (SET_SRC (i))))
9486 return true;
9487 }
9488 }
9489
9490 return false;
9491}
9492
4697a36c
MM
9493void
9494debug_stack_info (info)
9495 rs6000_stack_t *info;
9878760c 9496{
d330fd93 9497 const char *abi_string;
24d304eb 9498
c81fc13e 9499 if (! info)
4697a36c
MM
9500 info = rs6000_stack_info ();
9501
9502 fprintf (stderr, "\nStack information for function %s:\n",
9503 ((current_function_decl && DECL_NAME (current_function_decl))
9504 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9505 : "<unknown>"));
9506
24d304eb
RK
9507 switch (info->abi)
9508 {
b6c9286a
MM
9509 default: abi_string = "Unknown"; break;
9510 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9511 case ABI_AIX:
b6c9286a 9512 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9513 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9514 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9515 }
9516
9517 fprintf (stderr, "\tABI = %5s\n", abi_string);
9518
00b960c7
AH
9519 if (TARGET_ALTIVEC_ABI)
9520 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9521
a3170dc6
AH
9522 if (TARGET_SPE_ABI)
9523 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9524
4697a36c
MM
9525 if (info->first_gp_reg_save != 32)
9526 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9527
9528 if (info->first_fp_reg_save != 64)
9529 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9530
00b960c7
AH
9531 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9532 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9533 info->first_altivec_reg_save);
9534
4697a36c
MM
9535 if (info->lr_save_p)
9536 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9537
4697a36c
MM
9538 if (info->cr_save_p)
9539 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9540
b6c9286a
MM
9541 if (info->toc_save_p)
9542 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9543
00b960c7
AH
9544 if (info->vrsave_mask)
9545 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9546
4697a36c
MM
9547 if (info->push_p)
9548 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9549
9550 if (info->calls_p)
9551 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9552
4697a36c
MM
9553 if (info->gp_save_offset)
9554 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9555
9556 if (info->fp_save_offset)
9557 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9558
00b960c7
AH
9559 if (info->altivec_save_offset)
9560 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9561 info->altivec_save_offset);
9562
a3170dc6
AH
9563 if (info->spe_gp_save_offset)
9564 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9565 info->spe_gp_save_offset);
9566
00b960c7
AH
9567 if (info->vrsave_save_offset)
9568 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9569 info->vrsave_save_offset);
9570
4697a36c
MM
9571 if (info->lr_save_offset)
9572 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9573
9574 if (info->cr_save_offset)
9575 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9576
b6c9286a
MM
9577 if (info->toc_save_offset)
9578 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9579
4697a36c
MM
9580 if (info->varargs_save_offset)
9581 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9582
9583 if (info->total_size)
9584 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9585
9586 if (info->varargs_size)
9587 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9588
9589 if (info->vars_size)
9590 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9591
9592 if (info->parm_size)
9593 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9594
9595 if (info->fixed_size)
9596 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9597
9598 if (info->gp_size)
9599 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9600
a3170dc6
AH
9601 if (info->spe_gp_size)
9602 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9603
4697a36c
MM
9604 if (info->fp_size)
9605 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9606
00b960c7
AH
9607 if (info->altivec_size)
9608 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9609
9610 if (info->vrsave_size)
9611 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9612
9613 if (info->altivec_padding_size)
9614 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9615 info->altivec_padding_size);
9616
a3170dc6
AH
9617 if (info->spe_padding_size)
9618 fprintf (stderr, "\tspe_padding_size = %5d\n",
9619 info->spe_padding_size);
9620
a4f6c312 9621 if (info->lr_size)
ed947a96 9622 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9623
4697a36c
MM
9624 if (info->cr_size)
9625 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9626
a4f6c312 9627 if (info->toc_size)
b6c9286a
MM
9628 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9629
4697a36c
MM
9630 if (info->save_size)
9631 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9632
9633 if (info->reg_size != 4)
9634 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9635
9636 fprintf (stderr, "\n");
9878760c 9637}
71f123ca
FS
9638
9639rtx
9640rs6000_return_addr (count, frame)
9641 int count;
9642 rtx frame;
9643{
a4f6c312
SS
9644 /* Currently we don't optimize very well between prolog and body
9645 code and for PIC code the code can be actually quite bad, so
9646 don't try to be too clever here. */
f585a356 9647 if (count != 0 || flag_pic != 0)
71f123ca
FS
9648 {
9649 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9650
9651 return
9652 gen_rtx_MEM
9653 (Pmode,
9654 memory_address
9655 (Pmode,
9656 plus_constant (copy_to_reg
9657 (gen_rtx_MEM (Pmode,
9658 memory_address (Pmode, frame))),
9659 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9660 }
9661
9e2f7ec7 9662 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9663}
9664
5e1bf043
DJ
9665/* Say whether a function is a candidate for sibcall handling or not.
9666 We do not allow indirect calls to be optimized into sibling calls.
9667 Also, we can't do it if there are any vector parameters; there's
9668 nowhere to put the VRsave code so it works; note that functions with
9669 vector parameters are required to have a prototype, so the argument
9670 type info must be available here. (The tail recursion case can work
9671 with vector parameters, but there's no way to distinguish here.) */
4977bab6
ZW
9672static bool
9673rs6000_function_ok_for_sibcall (decl, exp)
9674 tree decl;
9675 tree exp ATTRIBUTE_UNUSED;
5e1bf043
DJ
9676{
9677 tree type;
4977bab6 9678 if (decl)
5e1bf043
DJ
9679 {
9680 if (TARGET_ALTIVEC_VRSAVE)
9681 {
4977bab6 9682 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
5e1bf043
DJ
9683 type; type = TREE_CHAIN (type))
9684 {
c15b529f 9685 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
4977bab6 9686 return false;
5e1bf043
DJ
9687 }
9688 }
9689 if (DEFAULT_ABI == ABI_DARWIN
4977bab6 9690 || (*targetm.binds_local_p) (decl))
2bcc50d0 9691 {
4977bab6 9692 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
2bcc50d0
AM
9693
9694 if (!lookup_attribute ("longcall", attr_list)
9695 || lookup_attribute ("shortcall", attr_list))
4977bab6 9696 return true;
2bcc50d0 9697 }
5e1bf043 9698 }
4977bab6 9699 return false;
5e1bf043
DJ
9700}
9701
71f123ca
FS
9702static int
9703rs6000_ra_ever_killed ()
9704{
9705 rtx top;
5e1bf043
DJ
9706 rtx reg;
9707 rtx insn;
71f123ca 9708
3961e8fe
RH
9709 /* Irritatingly, there are two kinds of thunks -- those created with
9710 TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
9711 through the regular part of the compiler. This is a very hacky
9712 way to tell them apart. */
9713 if (current_function_is_thunk && !no_new_pseudos)
71f123ca 9714 return 0;
eb0424da 9715
36f7e964
AH
9716 /* regs_ever_live has LR marked as used if any sibcalls are present,
9717 but this should not force saving and restoring in the
9718 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
9719 clobbers LR, so that is inappropriate. */
9720
5e1bf043
DJ
9721 /* Also, the prologue can generate a store into LR that
9722 doesn't really count, like this:
36f7e964 9723
5e1bf043
DJ
9724 move LR->R0
9725 bcl to set PIC register
9726 move LR->R31
9727 move R0->LR
36f7e964
AH
9728
9729 When we're called from the epilogue, we need to avoid counting
9730 this as a store. */
5e1bf043 9731
71f123ca
FS
9732 push_topmost_sequence ();
9733 top = get_insns ();
9734 pop_topmost_sequence ();
5e1bf043 9735 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9736
5e1bf043
DJ
9737 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9738 {
9739 if (INSN_P (insn))
9740 {
9741 if (FIND_REG_INC_NOTE (insn, reg))
9742 return 1;
9743 else if (GET_CODE (insn) == CALL_INSN
c15b529f 9744 && !SIBLING_CALL_P (insn))
5e1bf043 9745 return 1;
36f7e964
AH
9746 else if (set_of (reg, insn) != NULL_RTX
9747 && !prologue_epilogue_contains (insn))
5e1bf043
DJ
9748 return 1;
9749 }
9750 }
9751 return 0;
71f123ca 9752}
4697a36c 9753\f
8cd8f856
GK
9754/* Add a REG_MAYBE_DEAD note to the insn. */
9755static void
9756rs6000_maybe_dead (insn)
9757 rtx insn;
9758{
9759 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9760 const0_rtx,
9761 REG_NOTES (insn));
9762}
9763
9ebbca7d 9764/* Emit instructions needed to load the TOC register.
c7ca610e 9765 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9766 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9767
9768void
9ebbca7d
GK
9769rs6000_emit_load_toc_table (fromprolog)
9770 int fromprolog;
c7ca610e 9771{
9ebbca7d 9772 rtx dest;
1db02437 9773 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9774
20b71b17
AM
9775 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9776 {
9777 rtx temp = (fromprolog
9778 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9779 : gen_reg_rtx (Pmode));
9780 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_pic_si (temp)));
9781 rs6000_maybe_dead (emit_move_insn (dest, temp));
9782 }
9783 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
9784 {
9785 char buf[30];
9786 rtx tempLR = (fromprolog
9787 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9788 : gen_reg_rtx (Pmode));
9789 rtx temp0 = (fromprolog
9790 ? gen_rtx_REG (Pmode, 0)
9791 : gen_reg_rtx (Pmode));
9792 rtx symF;
9793
9794 /* possibly create the toc section */
9795 if (! toc_initialized)
38c1f2d7 9796 {
20b71b17
AM
9797 toc_section ();
9798 function_section (current_function_decl);
38c1f2d7 9799 }
9ebbca7d 9800
20b71b17
AM
9801 if (fromprolog)
9802 {
9803 rtx symL;
38c1f2d7 9804
20b71b17
AM
9805 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
9806 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9807
20b71b17
AM
9808 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
9809 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9810
9811 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9812 symF)));
9813 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9814 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9815 symL,
9816 symF)));
9ebbca7d
GK
9817 }
9818 else
20b71b17
AM
9819 {
9820 rtx tocsym;
9821 static int reload_toc_labelno = 0;
9822
9823 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
9824
9825 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
9826 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9827
9828 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1b (tempLR,
9829 symF,
9830 tocsym)));
9831 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9832 rs6000_maybe_dead (emit_move_insn (temp0,
9833 gen_rtx_MEM (Pmode, dest)));
9834 }
9835 rs6000_maybe_dead (emit_insn (gen_addsi3 (dest, temp0, dest)));
9ebbca7d 9836 }
20b71b17
AM
9837 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
9838 {
9839 /* This is for AIX code running in non-PIC ELF32. */
9840 char buf[30];
9841 rtx realsym;
9842 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9843 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9844
9845 rs6000_maybe_dead (emit_insn (gen_elf_high (dest, realsym)));
9846 rs6000_maybe_dead (emit_insn (gen_elf_low (dest, dest, realsym)));
9847 }
9848 else if (DEFAULT_ABI == ABI_AIX)
9ebbca7d
GK
9849 {
9850 if (TARGET_32BIT)
20b71b17 9851 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_si (dest)));
9ebbca7d 9852 else
20b71b17 9853 rs6000_maybe_dead (emit_insn (gen_load_toc_aix_di (dest)));
9ebbca7d 9854 }
20b71b17
AM
9855 else
9856 abort ();
9ebbca7d
GK
9857}
9858
9859int
9860get_TOC_alias_set ()
9861{
9862 static int set = -1;
9863 if (set == -1)
9864 set = new_alias_set ();
9865 return set;
9866}
9867
9868/* This retuns nonzero if the current function uses the TOC. This is
9869 determined by the presence of (unspec ... 7), which is generated by
9870 the various load_toc_* patterns. */
a4f6c312 9871
9ebbca7d
GK
9872int
9873uses_TOC ()
9874{
9875 rtx insn;
38c1f2d7 9876
9ebbca7d 9877 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 9878 if (INSN_P (insn))
9ebbca7d
GK
9879 {
9880 rtx pat = PATTERN (insn);
9881 int i;
9882
8cd8f856 9883 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
9884 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
9885 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
9886 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
9887 return 1;
38c1f2d7 9888 }
9ebbca7d
GK
9889 return 0;
9890}
38c1f2d7 9891
9ebbca7d 9892rtx
a4f6c312 9893create_TOC_reference (symbol)
9ebbca7d
GK
9894 rtx symbol;
9895{
a8a05998
ZW
9896 return gen_rtx_PLUS (Pmode,
9897 gen_rtx_REG (Pmode, TOC_REGISTER),
9898 gen_rtx_CONST (Pmode,
9899 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 9900 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 9901}
38c1f2d7 9902
9ebbca7d
GK
9903#if TARGET_AIX
9904/* __throw will restore its own return address to be the same as the
9905 return address of the function that the throw is being made to.
9906 This is unfortunate, because we want to check the original
9907 return address to see if we need to restore the TOC.
9908 So we have to squirrel it away here.
9909 This is used only in compiling __throw and __rethrow.
c7ca610e 9910
9ebbca7d
GK
9911 Most of this code should be removed by CSE. */
9912static rtx insn_after_throw;
c7ca610e 9913
a4f6c312 9914/* This does the saving... */
9ebbca7d
GK
9915void
9916rs6000_aix_emit_builtin_unwind_init ()
9917{
9918 rtx mem;
9919 rtx stack_top = gen_reg_rtx (Pmode);
9920 rtx opcode_addr = gen_reg_rtx (Pmode);
9921
9922 insn_after_throw = gen_reg_rtx (SImode);
9923
9924 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
9925 emit_move_insn (stack_top, mem);
9926
9927 mem = gen_rtx_MEM (Pmode,
9928 gen_rtx_PLUS (Pmode, stack_top,
9929 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
9930 emit_move_insn (opcode_addr, mem);
9931 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
9932}
9933
a4f6c312
SS
9934/* Emit insns to _restore_ the TOC register, at runtime (specifically
9935 in _eh.o). Only used on AIX.
9ebbca7d
GK
9936
9937 The idea is that on AIX, function calls look like this:
9938 bl somefunction-trampoline
9939 lwz r2,20(sp)
9940
a4f6c312 9941 and later,
9ebbca7d
GK
9942 somefunction-trampoline:
9943 stw r2,20(sp)
9944 ... load function address in the count register ...
9945 bctr
9946 or like this, if the linker determines that this is not a cross-module call
9947 and so the TOC need not be restored:
9948 bl somefunction
9949 nop
9950 or like this, if the compiler could determine that this is not a
9951 cross-module call:
9952 bl somefunction
9953 now, the tricky bit here is that register 2 is saved and restored
9954 by the _linker_, so we can't readily generate debugging information
9955 for it. So we need to go back up the call chain looking at the
9956 insns at return addresses to see which calls saved the TOC register
9957 and so see where it gets restored from.
9958
9959 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
9960 just before the actual epilogue.
9961
9962 On the bright side, this incurs no space or time overhead unless an
9963 exception is thrown, except for the extra code in libgcc.a.
9964
9965 The parameter STACKSIZE is a register containing (at runtime)
9966 the amount to be popped off the stack in addition to the stack frame
9967 of this routine (which will be __throw or __rethrow, and so is
9968 guaranteed to have a stack frame). */
a4f6c312 9969
9ebbca7d
GK
9970void
9971rs6000_emit_eh_toc_restore (stacksize)
9972 rtx stacksize;
9973{
9974 rtx top_of_stack;
9975 rtx bottom_of_stack = gen_reg_rtx (Pmode);
9976 rtx tocompare = gen_reg_rtx (SImode);
9977 rtx opcode = gen_reg_rtx (SImode);
9978 rtx opcode_addr = gen_reg_rtx (Pmode);
9979 rtx mem;
9980 rtx loop_start = gen_label_rtx ();
9981 rtx no_toc_restore_needed = gen_label_rtx ();
9982 rtx loop_exit = gen_label_rtx ();
9983
9984 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 9985 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
9986 emit_move_insn (bottom_of_stack, mem);
9987
9988 top_of_stack = expand_binop (Pmode, add_optab,
9989 bottom_of_stack, stacksize,
9990 NULL_RTX, 1, OPTAB_WIDEN);
9991
2496c7bd
LB
9992 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
9993 : 0xE8410028, SImode));
9ebbca7d
GK
9994
9995 if (insn_after_throw == NULL_RTX)
a4f6c312 9996 abort ();
9ebbca7d
GK
9997 emit_move_insn (opcode, insn_after_throw);
9998
6496a589 9999 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
10000 emit_label (loop_start);
10001
10002 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 10003 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
10004 no_toc_restore_needed);
10005
10006 mem = gen_rtx_MEM (Pmode,
10007 gen_rtx_PLUS (Pmode, bottom_of_stack,
10008 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
10009 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
10010
10011 emit_label (no_toc_restore_needed);
10012 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 10013 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
10014 loop_exit);
10015
10016 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 10017 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10018 emit_move_insn (bottom_of_stack, mem);
10019
10020 mem = gen_rtx_MEM (Pmode,
10021 gen_rtx_PLUS (Pmode, bottom_of_stack,
10022 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
10023 emit_move_insn (opcode_addr, mem);
10024 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
10025
6496a589 10026 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 10027 emit_jump (loop_start);
6496a589 10028 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
10029 emit_label (loop_exit);
10030}
10031#endif /* TARGET_AIX */
38c1f2d7 10032\f
ba4828e0
RK
10033/* This ties together stack memory (MEM with an alias set of
10034 rs6000_sr_alias_set) and the change to the stack pointer. */
10035
9ebbca7d
GK
10036static void
10037rs6000_emit_stack_tie ()
10038{
ba4828e0
RK
10039 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
10040
10041 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10042 emit_insn (gen_stack_tie (mem));
10043}
38c1f2d7 10044
9ebbca7d
GK
10045/* Emit the correct code for allocating stack space, as insns.
10046 If COPY_R12, make sure a copy of the old frame is left in r12.
10047 The generated code may use hard register 0 as a temporary. */
10048
10049static void
10050rs6000_emit_allocate_stack (size, copy_r12)
10051 HOST_WIDE_INT size;
38c1f2d7
MM
10052 int copy_r12;
10053{
9ebbca7d
GK
10054 rtx insn;
10055 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10056 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
10057 rtx todec = GEN_INT (-size);
a157febd
GK
10058
10059 if (current_function_limit_stack)
10060 {
10061 if (REG_P (stack_limit_rtx)
10062 && REGNO (stack_limit_rtx) > 1
10063 && REGNO (stack_limit_rtx) <= 31)
10064 {
5b71a4e7 10065 emit_insn (TARGET_32BIT
9ebbca7d
GK
10066 ? gen_addsi3 (tmp_reg,
10067 stack_limit_rtx,
10068 GEN_INT (size))
10069 : gen_adddi3 (tmp_reg,
10070 stack_limit_rtx,
10071 GEN_INT (size)));
5b71a4e7 10072
9ebbca7d
GK
10073 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
10074 const0_rtx));
a157febd
GK
10075 }
10076 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 10077 && TARGET_32BIT
f607bc57 10078 && DEFAULT_ABI == ABI_V4)
a157febd 10079 {
9ebbca7d
GK
10080 rtx toload = gen_rtx_CONST (VOIDmode,
10081 gen_rtx_PLUS (Pmode,
10082 stack_limit_rtx,
10083 GEN_INT (size)));
5b71a4e7 10084
9ebbca7d
GK
10085 emit_insn (gen_elf_high (tmp_reg, toload));
10086 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
10087 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
10088 const0_rtx));
a157febd
GK
10089 }
10090 else
10091 warning ("stack limit expression is not supported");
10092 }
10093
9ebbca7d
GK
10094 if (copy_r12 || ! TARGET_UPDATE)
10095 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
10096
38c1f2d7
MM
10097 if (TARGET_UPDATE)
10098 {
9ebbca7d 10099 if (size > 32767)
38c1f2d7 10100 {
9ebbca7d
GK
10101 /* Need a note here so that try_split doesn't get confused. */
10102 if (get_last_insn() == NULL_RTX)
10103 emit_note (0, NOTE_INSN_DELETED);
10104 insn = emit_move_insn (tmp_reg, todec);
10105 try_split (PATTERN (insn), insn, 0);
10106 todec = tmp_reg;
38c1f2d7 10107 }
5b71a4e7
DE
10108
10109 insn = emit_insn (TARGET_32BIT
10110 ? gen_movsi_update (stack_reg, stack_reg,
10111 todec, stack_reg)
10112 : gen_movdi_update (stack_reg, stack_reg,
9ebbca7d 10113 todec, stack_reg));
38c1f2d7
MM
10114 }
10115 else
10116 {
5b71a4e7
DE
10117 insn = emit_insn (TARGET_32BIT
10118 ? gen_addsi3 (stack_reg, stack_reg, todec)
10119 : gen_adddi3 (stack_reg, stack_reg, todec));
9ebbca7d
GK
10120 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
10121 gen_rtx_REG (Pmode, 12));
10122 }
5b71a4e7 10123
9ebbca7d
GK
10124 RTX_FRAME_RELATED_P (insn) = 1;
10125 REG_NOTES (insn) =
10126 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10127 gen_rtx_SET (VOIDmode, stack_reg,
10128 gen_rtx_PLUS (Pmode, stack_reg,
10129 GEN_INT (-size))),
10130 REG_NOTES (insn));
10131}
10132
a4f6c312
SS
10133/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
10134 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
10135 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
10136 deduce these equivalences by itself so it wasn't necessary to hold
10137 its hand so much. */
9ebbca7d
GK
10138
10139static void
10140rs6000_frame_related (insn, reg, val, reg2, rreg)
10141 rtx insn;
10142 rtx reg;
10143 HOST_WIDE_INT val;
10144 rtx reg2;
10145 rtx rreg;
10146{
10147 rtx real, temp;
10148
e56c4463
JL
10149 /* copy_rtx will not make unique copies of registers, so we need to
10150 ensure we don't have unwanted sharing here. */
10151 if (reg == reg2)
10152 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10153
10154 if (reg == rreg)
10155 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10156
9ebbca7d
GK
10157 real = copy_rtx (PATTERN (insn));
10158
89e7058f
AH
10159 if (reg2 != NULL_RTX)
10160 real = replace_rtx (real, reg2, rreg);
10161
9ebbca7d
GK
10162 real = replace_rtx (real, reg,
10163 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
10164 STACK_POINTER_REGNUM),
10165 GEN_INT (val)));
10166
10167 /* We expect that 'real' is either a SET or a PARALLEL containing
10168 SETs (and possibly other stuff). In a PARALLEL, all the SETs
10169 are important so they all have to be marked RTX_FRAME_RELATED_P. */
10170
10171 if (GET_CODE (real) == SET)
10172 {
10173 rtx set = real;
10174
10175 temp = simplify_rtx (SET_SRC (set));
10176 if (temp)
10177 SET_SRC (set) = temp;
10178 temp = simplify_rtx (SET_DEST (set));
10179 if (temp)
10180 SET_DEST (set) = temp;
10181 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 10182 {
9ebbca7d
GK
10183 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10184 if (temp)
10185 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 10186 }
38c1f2d7 10187 }
9ebbca7d
GK
10188 else if (GET_CODE (real) == PARALLEL)
10189 {
10190 int i;
10191 for (i = 0; i < XVECLEN (real, 0); i++)
10192 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
10193 {
10194 rtx set = XVECEXP (real, 0, i);
10195
10196 temp = simplify_rtx (SET_SRC (set));
10197 if (temp)
10198 SET_SRC (set) = temp;
10199 temp = simplify_rtx (SET_DEST (set));
10200 if (temp)
10201 SET_DEST (set) = temp;
10202 if (GET_CODE (SET_DEST (set)) == MEM)
10203 {
10204 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10205 if (temp)
10206 XEXP (SET_DEST (set), 0) = temp;
10207 }
10208 RTX_FRAME_RELATED_P (set) = 1;
10209 }
10210 }
10211 else
a4f6c312 10212 abort ();
c19de7aa
AH
10213
10214 if (TARGET_SPE)
10215 real = spe_synthesize_frame_save (real);
10216
9ebbca7d
GK
10217 RTX_FRAME_RELATED_P (insn) = 1;
10218 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10219 real,
10220 REG_NOTES (insn));
38c1f2d7
MM
10221}
10222
c19de7aa
AH
10223/* Given an SPE frame note, return a PARALLEL of SETs with the
10224 original note, plus a synthetic register save. */
10225
10226static rtx
10227spe_synthesize_frame_save (real)
10228 rtx real;
10229{
10230 rtx synth, offset, reg, real2;
10231
10232 if (GET_CODE (real) != SET
10233 || GET_MODE (SET_SRC (real)) != V2SImode)
10234 return real;
10235
10236 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
10237 frame related note. The parallel contains a set of the register
41f3a930 10238 being saved, and another set to a synthetic register (n+1200).
c19de7aa
AH
10239 This is so we can differentiate between 64-bit and 32-bit saves.
10240 Words cannot describe this nastiness. */
10241
10242 if (GET_CODE (SET_DEST (real)) != MEM
10243 || GET_CODE (XEXP (SET_DEST (real), 0)) != PLUS
10244 || GET_CODE (SET_SRC (real)) != REG)
10245 abort ();
10246
10247 /* Transform:
10248 (set (mem (plus (reg x) (const y)))
10249 (reg z))
10250 into:
10251 (set (mem (plus (reg x) (const y+4)))
41f3a930 10252 (reg z+1200))
c19de7aa
AH
10253 */
10254
10255 real2 = copy_rtx (real);
10256 PUT_MODE (SET_DEST (real2), SImode);
10257 reg = SET_SRC (real2);
10258 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
10259 synth = copy_rtx (real2);
10260
10261 if (BYTES_BIG_ENDIAN)
10262 {
10263 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
10264 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
10265 }
10266
10267 reg = SET_SRC (synth);
41f3a930 10268
c19de7aa 10269 synth = replace_rtx (synth, reg,
41f3a930 10270 gen_rtx_REG (SImode, REGNO (reg) + 1200));
c19de7aa
AH
10271
10272 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
10273 synth = replace_rtx (synth, offset,
10274 GEN_INT (INTVAL (offset)
10275 + (BYTES_BIG_ENDIAN ? 0 : 4)));
10276
10277 RTX_FRAME_RELATED_P (synth) = 1;
10278 RTX_FRAME_RELATED_P (real2) = 1;
10279 if (BYTES_BIG_ENDIAN)
10280 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
10281 else
10282 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
10283
10284 return real;
10285}
10286
00b960c7
AH
10287/* Returns an insn that has a vrsave set operation with the
10288 appropriate CLOBBERs. */
10289
10290static rtx
9aa86737 10291generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
10292 rtx reg;
10293 rs6000_stack_t *info;
9aa86737 10294 int epiloguep;
00b960c7
AH
10295{
10296 int nclobs, i;
10297 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 10298 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 10299
a004eb82
AH
10300 clobs[0]
10301 = gen_rtx_SET (VOIDmode,
10302 vrsave,
10303 gen_rtx_UNSPEC_VOLATILE (SImode,
10304 gen_rtvec (2, reg, vrsave),
10305 30));
00b960c7
AH
10306
10307 nclobs = 1;
10308
9aa86737
AH
10309 /* We need to clobber the registers in the mask so the scheduler
10310 does not move sets to VRSAVE before sets of AltiVec registers.
10311
10312 However, if the function receives nonlocal gotos, reload will set
10313 all call saved registers live. We will end up with:
10314
10315 (set (reg 999) (mem))
10316 (parallel [ (set (reg vrsave) (unspec blah))
10317 (clobber (reg 999))])
10318
10319 The clobber will cause the store into reg 999 to be dead, and
10320 flow will attempt to delete an epilogue insn. In this case, we
10321 need an unspec use/set of the register. */
00b960c7
AH
10322
10323 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10324 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10325 {
10326 if (!epiloguep || call_used_regs [i])
10327 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10328 gen_rtx_REG (V4SImode, i));
10329 else
10330 {
10331 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10332
10333 clobs[nclobs++]
a004eb82
AH
10334 = gen_rtx_SET (VOIDmode,
10335 reg,
10336 gen_rtx_UNSPEC (V4SImode,
10337 gen_rtvec (1, reg), 27));
9aa86737
AH
10338 }
10339 }
00b960c7
AH
10340
10341 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10342
10343 for (i = 0; i < nclobs; ++i)
10344 XVECEXP (insn, 0, i) = clobs[i];
10345
10346 return insn;
10347}
10348
89e7058f
AH
10349/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10350 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10351
10352static void
10353emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10354 rtx frame_reg;
10355 rtx frame_ptr;
10356 enum machine_mode mode;
10357 unsigned int regno;
10358 int offset;
10359 int total_size;
10360{
10361 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10362 rtx replacea, replaceb;
10363
10364 int_rtx = GEN_INT (offset);
10365
10366 /* Some cases that need register indexed addressing. */
10367 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10368 || (TARGET_SPE_ABI
10369 && SPE_VECTOR_MODE (mode)
10370 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10371 {
10372 /* Whomever calls us must make sure r11 is available in the
10373 flow path of instructions in the prologue. */
10374 offset_rtx = gen_rtx_REG (Pmode, 11);
10375 emit_move_insn (offset_rtx, int_rtx);
10376
10377 replacea = offset_rtx;
10378 replaceb = int_rtx;
10379 }
10380 else
10381 {
10382 offset_rtx = int_rtx;
10383 replacea = NULL_RTX;
10384 replaceb = NULL_RTX;
10385 }
10386
10387 reg = gen_rtx_REG (mode, regno);
10388 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10389 mem = gen_rtx_MEM (mode, addr);
10390 set_mem_alias_set (mem, rs6000_sr_alias_set);
10391
10392 insn = emit_move_insn (mem, reg);
10393
10394 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10395}
10396
a3170dc6
AH
10397/* Emit an offset memory reference suitable for a frame store, while
10398 converting to a valid addressing mode. */
10399
10400static rtx
10401gen_frame_mem_offset (mode, reg, offset)
10402 enum machine_mode mode;
10403 rtx reg;
10404 int offset;
10405{
10406 rtx int_rtx, offset_rtx;
10407
10408 int_rtx = GEN_INT (offset);
10409
10410 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10411 {
10412 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10413 emit_move_insn (offset_rtx, int_rtx);
10414 }
10415 else
10416 offset_rtx = int_rtx;
10417
10418 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10419}
10420
9ebbca7d
GK
10421/* Emit function prologue as insns. */
10422
9878760c 10423void
83720594 10424rs6000_emit_prologue ()
9878760c 10425{
4697a36c 10426 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10427 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10428 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10429 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10430 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10431 rtx frame_reg_rtx = sp_reg_rtx;
10432 rtx cr_save_rtx = NULL;
10433 rtx insn;
10434 int saving_FPRs_inline;
10435 int using_store_multiple;
10436 HOST_WIDE_INT sp_offset = 0;
10437
c19de7aa 10438 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
10439 {
10440 reg_mode = V2SImode;
10441 reg_size = 8;
10442 }
10443
9ebbca7d 10444 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
10445 && (!TARGET_SPE_ABI
10446 || info->spe_64bit_regs_used == 0)
9ebbca7d
GK
10447 && info->first_gp_reg_save < 31);
10448 saving_FPRs_inline = (info->first_fp_reg_save == 64
10449 || FP_SAVE_INLINE (info->first_fp_reg_save));
10450
10451 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10452 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10453 {
10454 if (info->total_size < 32767)
10455 sp_offset = info->total_size;
10456 else
10457 frame_reg_rtx = frame_ptr_rtx;
10458 rs6000_emit_allocate_stack (info->total_size,
10459 (frame_reg_rtx != sp_reg_rtx
10460 && (info->cr_save_p
10461 || info->lr_save_p
10462 || info->first_fp_reg_save < 64
10463 || info->first_gp_reg_save < 32
10464 )));
10465 if (frame_reg_rtx != sp_reg_rtx)
10466 rs6000_emit_stack_tie ();
10467 }
10468
9aa86737
AH
10469 /* Save AltiVec registers if needed. */
10470 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10471 {
10472 int i;
10473
10474 /* There should be a non inline version of this, for when we
10475 are saving lots of vector registers. */
10476 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10477 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10478 {
10479 rtx areg, savereg, mem;
10480 int offset;
10481
10482 offset = info->altivec_save_offset + sp_offset
10483 + 16 * (i - info->first_altivec_reg_save);
10484
10485 savereg = gen_rtx_REG (V4SImode, i);
10486
10487 areg = gen_rtx_REG (Pmode, 0);
10488 emit_move_insn (areg, GEN_INT (offset));
10489
10490 /* AltiVec addressing mode is [reg+reg]. */
10491 mem = gen_rtx_MEM (V4SImode,
10492 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10493
10494 set_mem_alias_set (mem, rs6000_sr_alias_set);
10495
10496 insn = emit_move_insn (mem, savereg);
10497
5c242421
SB
10498 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10499 areg, GEN_INT (offset));
9aa86737
AH
10500 }
10501 }
10502
10503 /* VRSAVE is a bit vector representing which AltiVec registers
10504 are used. The OS uses this to determine which vector
10505 registers to save on a context switch. We need to save
10506 VRSAVE on the stack frame, add whatever AltiVec registers we
10507 used in this function, and do the corresponding magic in the
10508 epilogue. */
10509
10510 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10511 {
a004eb82 10512 rtx reg, mem, vrsave;
9aa86737
AH
10513 int offset;
10514
10515 /* Get VRSAVE onto a GPR. */
10516 reg = gen_rtx_REG (SImode, 12);
a004eb82 10517 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10518 if (TARGET_MACHO)
10519 emit_insn (gen_get_vrsave_internal (reg));
10520 else
10521 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10522
10523 /* Save VRSAVE. */
10524 offset = info->vrsave_save_offset + sp_offset;
10525 mem
10526 = gen_rtx_MEM (SImode,
10527 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10528 set_mem_alias_set (mem, rs6000_sr_alias_set);
10529 insn = emit_move_insn (mem, reg);
10530
10531 /* Include the registers in the mask. */
10532 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10533
10534 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10535 }
10536
9ebbca7d
GK
10537 /* If we use the link register, get it into r0. */
10538 if (info->lr_save_p)
71f123ca 10539 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10540 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10541
10542 /* If we need to save CR, put it into r12. */
10543 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10544 {
10545 cr_save_rtx = gen_rtx_REG (SImode, 12);
10546 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10547 }
10548
a4f6c312
SS
10549 /* Do any required saving of fpr's. If only one or two to save, do
10550 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10551 if (saving_FPRs_inline)
10552 {
10553 int i;
10554 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10555 if ((regs_ever_live[info->first_fp_reg_save+i]
10556 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10557 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10558 info->first_fp_reg_save + i,
10559 info->fp_save_offset + sp_offset + 8 * i,
10560 info->total_size);
9ebbca7d
GK
10561 }
10562 else if (info->first_fp_reg_save != 64)
10563 {
10564 int i;
10565 char rname[30];
520a57c8 10566 const char *alloc_rname;
9ebbca7d
GK
10567 rtvec p;
10568 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10569
10570 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10571 gen_rtx_REG (Pmode,
10572 LINK_REGISTER_REGNUM));
10573 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10574 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10575 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10576 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10577 gen_rtx_SYMBOL_REF (Pmode,
10578 alloc_rname));
10579 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10580 {
10581 rtx addr, reg, mem;
10582 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10583 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10584 GEN_INT (info->fp_save_offset
10585 + sp_offset + 8*i));
10586 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10587 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10588
10589 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10590 }
10591 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10592 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10593 NULL_RTX, NULL_RTX);
10594 }
b6c9286a 10595
9ebbca7d
GK
10596 /* Save GPRs. This is done as a PARALLEL if we are using
10597 the store-multiple instructions. */
10598 if (using_store_multiple)
b6c9286a 10599 {
308c142a 10600 rtvec p;
9ebbca7d
GK
10601 int i;
10602 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10603 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10604 {
10605 rtx addr, reg, mem;
10606 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10607 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10608 GEN_INT (info->gp_save_offset
10609 + sp_offset
10610 + reg_size * i));
10611 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10612 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10613
10614 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10615 }
10616 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10617 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10618 NULL_RTX, NULL_RTX);
b6c9286a
MM
10619 }
10620 else
10621 {
9ebbca7d
GK
10622 int i;
10623 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10624 if ((regs_ever_live[info->first_gp_reg_save+i]
10625 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10626 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 10627 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 10628 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10629 {
10630 rtx addr, reg, mem;
10631 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10632
c19de7aa 10633 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
10634 {
10635 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10636 rtx b;
10637
10638 if (!SPE_CONST_OFFSET_OK (offset))
10639 {
10640 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10641 emit_move_insn (b, GEN_INT (offset));
10642 }
10643 else
10644 b = GEN_INT (offset);
10645
10646 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10647 mem = gen_rtx_MEM (V2SImode, addr);
10648 set_mem_alias_set (mem, rs6000_sr_alias_set);
10649 insn = emit_move_insn (mem, reg);
10650
10651 if (GET_CODE (b) == CONST_INT)
10652 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10653 NULL_RTX, NULL_RTX);
10654 else
10655 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10656 b, GEN_INT (offset));
10657 }
10658 else
10659 {
10660 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10661 GEN_INT (info->gp_save_offset
10662 + sp_offset
10663 + reg_size * i));
10664 mem = gen_rtx_MEM (reg_mode, addr);
10665 set_mem_alias_set (mem, rs6000_sr_alias_set);
10666
10667 insn = emit_move_insn (mem, reg);
10668 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10669 NULL_RTX, NULL_RTX);
10670 }
10671 }
9ebbca7d
GK
10672 }
10673
83720594
RH
10674 /* ??? There's no need to emit actual instructions here, but it's the
10675 easiest way to get the frame unwind information emitted. */
10676 if (current_function_calls_eh_return)
10677 {
78e1b90d
DE
10678 unsigned int i, regno;
10679
83720594
RH
10680 for (i = 0; ; ++i)
10681 {
83720594
RH
10682 regno = EH_RETURN_DATA_REGNO (i);
10683 if (regno == INVALID_REGNUM)
10684 break;
10685
89e7058f
AH
10686 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10687 info->ehrd_offset + sp_offset
10688 + reg_size * (int) i,
10689 info->total_size);
83720594
RH
10690 }
10691 }
10692
9ebbca7d
GK
10693 /* Save lr if we used it. */
10694 if (info->lr_save_p)
10695 {
10696 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10697 GEN_INT (info->lr_save_offset + sp_offset));
10698 rtx reg = gen_rtx_REG (Pmode, 0);
10699 rtx mem = gen_rtx_MEM (Pmode, addr);
10700 /* This should not be of rs6000_sr_alias_set, because of
10701 __builtin_return_address. */
10702
10703 insn = emit_move_insn (mem, reg);
10704 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10705 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10706 }
10707
10708 /* Save CR if we use any that must be preserved. */
10709 if (info->cr_save_p)
10710 {
10711 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10712 GEN_INT (info->cr_save_offset + sp_offset));
10713 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10714
10715 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10716
10717 /* If r12 was used to hold the original sp, copy cr into r0 now
10718 that it's free. */
10719 if (REGNO (frame_reg_rtx) == 12)
10720 {
10721 cr_save_rtx = gen_rtx_REG (SImode, 0);
10722 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10723 }
10724 insn = emit_move_insn (mem, cr_save_rtx);
10725
10726 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10727 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10728 OK. All we have to do is specify that _one_ condition code
10729 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10730 will then restore all the call-saved registers.
10731 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10732 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10733 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10734 }
10735
10736 /* Update stack and set back pointer unless this is V.4,
10737 for which it was done previously. */
f607bc57 10738 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10739 rs6000_emit_allocate_stack (info->total_size, FALSE);
10740
10741 /* Set frame pointer, if needed. */
10742 if (frame_pointer_needed)
10743 {
a3170dc6 10744 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10745 sp_reg_rtx);
10746 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10747 }
9878760c 10748
1db02437 10749 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10750 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10751 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10752 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10753 {
10754 /* If emit_load_toc_table will use the link register, we need to save
10755 it. We use R11 for this purpose because emit_load_toc_table
10756 can use register 0. This allows us to use a plain 'blr' to return
10757 from the procedure more often. */
d5fa86ba
GK
10758 int save_LR_around_toc_setup = (TARGET_ELF && flag_pic != 0
10759 && ! info->lr_save_p
10760 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10761 if (save_LR_around_toc_setup)
10762 emit_move_insn (gen_rtx_REG (Pmode, 11),
10763 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10764
10765 rs6000_emit_load_toc_table (TRUE);
10766
10767 if (save_LR_around_toc_setup)
10768 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10769 gen_rtx_REG (Pmode, 11));
10770 }
ee890fe2 10771
fcce224d 10772#if TARGET_MACHO
ee890fe2
SS
10773 if (DEFAULT_ABI == ABI_DARWIN
10774 && flag_pic && current_function_uses_pic_offset_table)
10775 {
10776 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
f099d360 10777 const char *picbase = machopic_function_base_name ();
f51eee6a 10778 rtx src = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (picbase, -1));
ee890fe2 10779
f51eee6a 10780 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
ee890fe2
SS
10781
10782 rs6000_maybe_dead (
1db02437 10783 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10784 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10785 }
fcce224d 10786#endif
9ebbca7d
GK
10787}
10788
9ebbca7d 10789/* Write function prologue. */
a4f6c312 10790
08c148a8
NB
10791static void
10792rs6000_output_function_prologue (file, size)
9ebbca7d 10793 FILE *file;
08c148a8 10794 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10795{
10796 rs6000_stack_t *info = rs6000_stack_info ();
10797
4697a36c
MM
10798 if (TARGET_DEBUG_STACK)
10799 debug_stack_info (info);
9878760c 10800
a4f6c312
SS
10801 /* Write .extern for any function we will call to save and restore
10802 fp values. */
10803 if (info->first_fp_reg_save < 64
10804 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10805 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10806 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10807 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10808 RESTORE_FP_SUFFIX);
9878760c 10809
c764f757
RK
10810 /* Write .extern for AIX common mode routines, if needed. */
10811 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10812 {
f6709c70
JW
10813 fputs ("\t.extern __mulh\n", file);
10814 fputs ("\t.extern __mull\n", file);
10815 fputs ("\t.extern __divss\n", file);
10816 fputs ("\t.extern __divus\n", file);
10817 fputs ("\t.extern __quoss\n", file);
10818 fputs ("\t.extern __quous\n", file);
c764f757
RK
10819 common_mode_defined = 1;
10820 }
9878760c 10821
9ebbca7d 10822 if (! HAVE_prologue)
979721f8 10823 {
9ebbca7d 10824 start_sequence ();
9dda4cc8 10825
a4f6c312
SS
10826 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10827 the "toplevel" insn chain. */
9ebbca7d
GK
10828 emit_note (0, NOTE_INSN_DELETED);
10829 rs6000_emit_prologue ();
10830 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10831
10832 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10833 {
10834 rtx insn;
10835 unsigned addr = 0;
10836 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10837 {
10838 INSN_ADDRESSES_NEW (insn, addr);
10839 addr += 4;
10840 }
10841 }
9dda4cc8 10842
9ebbca7d 10843 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10844 debug_rtx_list (get_insns (), 100);
10845 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10846 end_sequence ();
979721f8
MM
10847 }
10848
9ebbca7d
GK
10849 rs6000_pic_labelno++;
10850}
10851
10852/* Emit function epilogue as insns.
9878760c 10853
9ebbca7d
GK
10854 At present, dwarf2out_frame_debug_expr doesn't understand
10855 register restores, so we don't bother setting RTX_FRAME_RELATED_P
10856 anywhere in the epilogue. Most of the insns below would in any case
10857 need special notes to explain where r11 is in relation to the stack. */
9878760c 10858
9ebbca7d 10859void
83720594 10860rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
10861 int sibcall;
10862{
10863 rs6000_stack_t *info;
10864 int restoring_FPRs_inline;
10865 int using_load_multiple;
10866 int using_mfcr_multiple;
10867 int use_backchain_to_restore_sp;
10868 int sp_offset = 0;
10869 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
10870 rtx frame_reg_rtx = sp_reg_rtx;
10871 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10872 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10873 int i;
10874
c19de7aa
AH
10875 info = rs6000_stack_info ();
10876
10877 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
10878 {
10879 reg_mode = V2SImode;
10880 reg_size = 8;
10881 }
10882
9ebbca7d 10883 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
10884 && (!TARGET_SPE_ABI
10885 || info->spe_64bit_regs_used == 0)
9ebbca7d
GK
10886 && info->first_gp_reg_save < 31);
10887 restoring_FPRs_inline = (sibcall
83720594 10888 || current_function_calls_eh_return
9ebbca7d
GK
10889 || info->first_fp_reg_save == 64
10890 || FP_SAVE_INLINE (info->first_fp_reg_save));
10891 use_backchain_to_restore_sp = (frame_pointer_needed
10892 || current_function_calls_alloca
10893 || info->total_size > 32767);
10894 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
10895 || rs6000_cpu == PROCESSOR_PPC603
10896 || rs6000_cpu == PROCESSOR_PPC750
10897 || optimize_size);
10898
10899 /* If we have a frame pointer, a call to alloca, or a large stack
10900 frame, restore the old stack pointer using the backchain. Otherwise,
10901 we know what size to update it with. */
10902 if (use_backchain_to_restore_sp)
bacbde18 10903 {
9ebbca7d
GK
10904 /* Under V.4, don't reset the stack pointer until after we're done
10905 loading the saved registers. */
f607bc57 10906 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 10907 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 10908
9ebbca7d
GK
10909 emit_move_insn (frame_reg_rtx,
10910 gen_rtx_MEM (Pmode, sp_reg_rtx));
10911
bacbde18 10912 }
9ebbca7d 10913 else if (info->push_p)
85638c0d 10914 {
f607bc57 10915 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10916 sp_offset = info->total_size;
10917 else
10918 {
10919 emit_insn (TARGET_32BIT
10920 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
10921 GEN_INT (info->total_size))
10922 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
10923 GEN_INT (info->total_size)));
10924 }
85638c0d 10925 }
9ebbca7d 10926
9aa86737
AH
10927 /* Restore AltiVec registers if needed. */
10928 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10929 {
10930 int i;
10931
10932 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10933 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10934 {
10935 rtx addr, areg, mem;
10936
10937 areg = gen_rtx_REG (Pmode, 0);
10938 emit_move_insn
10939 (areg, GEN_INT (info->altivec_save_offset
10940 + sp_offset
10941 + 16 * (i - info->first_altivec_reg_save)));
10942
10943 /* AltiVec addressing mode is [reg+reg]. */
10944 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
10945 mem = gen_rtx_MEM (V4SImode, addr);
10946 set_mem_alias_set (mem, rs6000_sr_alias_set);
10947
10948 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
10949 }
10950 }
10951
10952 /* Restore VRSAVE if needed. */
10953 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
10954 {
10955 rtx addr, mem, reg;
10956
10957 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10958 GEN_INT (info->vrsave_save_offset + sp_offset));
10959 mem = gen_rtx_MEM (SImode, addr);
10960 set_mem_alias_set (mem, rs6000_sr_alias_set);
10961 reg = gen_rtx_REG (SImode, 12);
10962 emit_move_insn (reg, mem);
10963
10964 emit_insn (generate_set_vrsave (reg, info, 1));
10965 }
10966
9ebbca7d
GK
10967 /* Get the old lr if we saved it. */
10968 if (info->lr_save_p)
b6c9286a 10969 {
a3170dc6
AH
10970 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
10971 info->lr_save_offset + sp_offset);
ba4828e0
RK
10972
10973 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10974
9ebbca7d 10975 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 10976 }
9ebbca7d
GK
10977
10978 /* Get the old cr if we saved it. */
10979 if (info->cr_save_p)
10980 {
10981 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10982 GEN_INT (info->cr_save_offset + sp_offset));
10983 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10984
10985 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 10986
9ebbca7d
GK
10987 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
10988 }
10989
10990 /* Set LR here to try to overlap restores below. */
4697a36c 10991 if (info->lr_save_p)
9ebbca7d
GK
10992 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10993 gen_rtx_REG (Pmode, 0));
10994
83720594
RH
10995 /* Load exception handler data registers, if needed. */
10996 if (current_function_calls_eh_return)
10997 {
78e1b90d
DE
10998 unsigned int i, regno;
10999
83720594
RH
11000 for (i = 0; ; ++i)
11001 {
a3170dc6 11002 rtx mem;
83720594
RH
11003
11004 regno = EH_RETURN_DATA_REGNO (i);
11005 if (regno == INVALID_REGNUM)
11006 break;
11007
a3170dc6
AH
11008 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
11009 info->ehrd_offset + sp_offset
11010 + reg_size * (int) i);
ba4828e0 11011 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
11012
11013 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
11014 }
11015 }
9ebbca7d
GK
11016
11017 /* Restore GPRs. This is done as a PARALLEL if we are using
11018 the load-multiple instructions. */
11019 if (using_load_multiple)
979721f8 11020 {
9ebbca7d
GK
11021 rtvec p;
11022 p = rtvec_alloc (32 - info->first_gp_reg_save);
11023 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 11024 {
9ebbca7d
GK
11025 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11026 GEN_INT (info->gp_save_offset
11027 + sp_offset
11028 + reg_size * i));
11029 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
11030
11031 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11032
11033 RTVEC_ELT (p, i) =
11034 gen_rtx_SET (VOIDmode,
11035 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
11036 mem);
979721f8 11037 }
9ebbca7d 11038 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 11039 }
9ebbca7d
GK
11040 else
11041 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
11042 if ((regs_ever_live[info->first_gp_reg_save+i]
11043 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 11044 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 11045 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 11046 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
11047 {
11048 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11049 GEN_INT (info->gp_save_offset
11050 + sp_offset
11051 + reg_size * i));
11052 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 11053
a3170dc6 11054 /* Restore 64-bit quantities for SPE. */
c19de7aa 11055 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
11056 {
11057 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
11058 rtx b;
11059
11060 if (!SPE_CONST_OFFSET_OK (offset))
11061 {
11062 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
11063 emit_move_insn (b, GEN_INT (offset));
11064 }
11065 else
11066 b = GEN_INT (offset);
11067
11068 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
11069 mem = gen_rtx_MEM (V2SImode, addr);
11070 }
11071
ba4828e0 11072 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11073
11074 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 11075 info->first_gp_reg_save + i), mem);
9ebbca7d 11076 }
9878760c 11077
9ebbca7d
GK
11078 /* Restore fpr's if we need to do it without calling a function. */
11079 if (restoring_FPRs_inline)
11080 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
11081 if ((regs_ever_live[info->first_fp_reg_save+i]
11082 && ! call_used_regs[info->first_fp_reg_save+i]))
11083 {
11084 rtx addr, mem;
11085 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11086 GEN_INT (info->fp_save_offset
11087 + sp_offset
a4f6c312 11088 + 8 * i));
9ebbca7d 11089 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 11090 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11091
11092 emit_move_insn (gen_rtx_REG (DFmode,
11093 info->first_fp_reg_save + i),
11094 mem);
11095 }
8d30c4ee 11096
9ebbca7d
GK
11097 /* If we saved cr, restore it here. Just those that were used. */
11098 if (info->cr_save_p)
979721f8 11099 {
9ebbca7d 11100 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 11101 int count = 0;
9ebbca7d
GK
11102
11103 if (using_mfcr_multiple)
979721f8 11104 {
9ebbca7d
GK
11105 for (i = 0; i < 8; i++)
11106 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 11107 count++;
9ebbca7d 11108 if (count == 0)
e35b9579
GK
11109 abort ();
11110 }
11111
11112 if (using_mfcr_multiple && count > 1)
11113 {
11114 rtvec p;
11115 int ndx;
9ebbca7d 11116
e35b9579 11117 p = rtvec_alloc (count);
9ebbca7d 11118
e35b9579 11119 ndx = 0;
9ebbca7d
GK
11120 for (i = 0; i < 8; i++)
11121 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
11122 {
11123 rtvec r = rtvec_alloc (2);
11124 RTVEC_ELT (r, 0) = r12_rtx;
11125 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 11126 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
11127 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
11128 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 11129 ndx++;
9ebbca7d
GK
11130 }
11131 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
11132 if (ndx != count)
11133 abort ();
979721f8
MM
11134 }
11135 else
9ebbca7d
GK
11136 for (i = 0; i < 8; i++)
11137 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 11138 {
9ebbca7d
GK
11139 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
11140 CR0_REGNO+i),
11141 r12_rtx));
979721f8 11142 }
979721f8
MM
11143 }
11144
9ebbca7d
GK
11145 /* If this is V.4, unwind the stack pointer after all of the loads
11146 have been done. We need to emit a block here so that sched
11147 doesn't decide to move the sp change before the register restores
11148 (which may not have any obvious dependency on the stack). This
11149 doesn't hurt performance, because there is no scheduling that can
11150 be done after this point. */
f607bc57 11151 if (DEFAULT_ABI == ABI_V4)
b6c9286a 11152 {
9ebbca7d
GK
11153 if (frame_reg_rtx != sp_reg_rtx)
11154 rs6000_emit_stack_tie ();
b6c9286a 11155
9ebbca7d 11156 if (use_backchain_to_restore_sp)
b6c9286a 11157 {
9ebbca7d 11158 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 11159 }
9ebbca7d 11160 else if (sp_offset != 0)
13f1623b 11161 {
5b71a4e7 11162 emit_insn (TARGET_32BIT
9ebbca7d
GK
11163 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
11164 GEN_INT (sp_offset))
11165 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
11166 GEN_INT (sp_offset)));
13f1623b 11167 }
9ebbca7d 11168 }
b6c9286a 11169
83720594
RH
11170 if (current_function_calls_eh_return)
11171 {
11172 rtx sa = EH_RETURN_STACKADJ_RTX;
5b71a4e7 11173 emit_insn (TARGET_32BIT
83720594
RH
11174 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
11175 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
11176 }
11177
9ebbca7d
GK
11178 if (!sibcall)
11179 {
11180 rtvec p;
11181 if (! restoring_FPRs_inline)
11182 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
11183 else
11184 p = rtvec_alloc (2);
b6c9286a 11185
e35b9579
GK
11186 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
11187 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
11188 gen_rtx_REG (Pmode,
11189 LINK_REGISTER_REGNUM));
9ebbca7d
GK
11190
11191 /* If we have to restore more than two FP registers, branch to the
11192 restore function. It will return to our caller. */
11193 if (! restoring_FPRs_inline)
11194 {
11195 int i;
11196 char rname[30];
520a57c8 11197 const char *alloc_rname;
979721f8 11198
9ebbca7d
GK
11199 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
11200 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 11201 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
11202 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
11203 gen_rtx_SYMBOL_REF (Pmode,
11204 alloc_rname));
b6c9286a 11205
9ebbca7d
GK
11206 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
11207 {
11208 rtx addr, mem;
11209 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
11210 GEN_INT (info->fp_save_offset + 8*i));
11211 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 11212 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11213
11214 RTVEC_ELT (p, i+3) =
11215 gen_rtx_SET (VOIDmode,
11216 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
11217 mem);
b6c9286a
MM
11218 }
11219 }
9ebbca7d
GK
11220
11221 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 11222 }
9878760c
RK
11223}
11224
11225/* Write function epilogue. */
11226
08c148a8
NB
11227static void
11228rs6000_output_function_epilogue (file, size)
9878760c 11229 FILE *file;
08c148a8 11230 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 11231{
4697a36c 11232 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 11233
9ebbca7d 11234 if (! HAVE_epilogue)
9878760c 11235 {
9ebbca7d
GK
11236 rtx insn = get_last_insn ();
11237 /* If the last insn was a BARRIER, we don't have to write anything except
11238 the trace table. */
11239 if (GET_CODE (insn) == NOTE)
11240 insn = prev_nonnote_insn (insn);
11241 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 11242 {
9ebbca7d
GK
11243 /* This is slightly ugly, but at least we don't have two
11244 copies of the epilogue-emitting code. */
11245 start_sequence ();
11246
11247 /* A NOTE_INSN_DELETED is supposed to be at the start
11248 and end of the "toplevel" insn chain. */
11249 emit_note (0, NOTE_INSN_DELETED);
11250 rs6000_emit_epilogue (FALSE);
11251 emit_note (0, NOTE_INSN_DELETED);
11252
178c3eff
DJ
11253 /* Expand INSN_ADDRESSES so final() doesn't crash. */
11254 {
11255 rtx insn;
11256 unsigned addr = 0;
11257 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
11258 {
11259 INSN_ADDRESSES_NEW (insn, addr);
11260 addr += 4;
11261 }
11262 }
11263
9ebbca7d 11264 if (TARGET_DEBUG_STACK)
a4f6c312
SS
11265 debug_rtx_list (get_insns (), 100);
11266 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 11267 end_sequence ();
4697a36c 11268 }
9878760c 11269 }
b4ac57ab 11270
9b30bae2 11271 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
11272 on its format.
11273
11274 We don't output a traceback table if -finhibit-size-directive was
11275 used. The documentation for -finhibit-size-directive reads
11276 ``don't output a @code{.size} assembler directive, or anything
11277 else that would cause trouble if the function is split in the
11278 middle, and the two halves are placed at locations far apart in
11279 memory.'' The traceback table has this property, since it
11280 includes the offset from the start of the function to the
4d30c363
MM
11281 traceback table itself.
11282
11283 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 11284 different traceback table. */
57ac7be9
AM
11285 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
11286 && rs6000_traceback != traceback_none)
9b30bae2 11287 {
69c75916 11288 const char *fname = NULL;
3ac88239 11289 const char *language_string = lang_hooks.name;
6041bf2f 11290 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 11291 int i;
57ac7be9
AM
11292 int optional_tbtab;
11293
11294 if (rs6000_traceback == traceback_full)
11295 optional_tbtab = 1;
11296 else if (rs6000_traceback == traceback_part)
11297 optional_tbtab = 0;
11298 else
11299 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 11300
69c75916
AM
11301 if (optional_tbtab)
11302 {
11303 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
11304 while (*fname == '.') /* V.4 encodes . in the name */
11305 fname++;
11306
11307 /* Need label immediately before tbtab, so we can compute
11308 its offset from the function start. */
11309 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11310 ASM_OUTPUT_LABEL (file, fname);
11311 }
314fc5a9
ILT
11312
11313 /* The .tbtab pseudo-op can only be used for the first eight
11314 expressions, since it can't handle the possibly variable
11315 length fields that follow. However, if you omit the optional
11316 fields, the assembler outputs zeros for all optional fields
11317 anyways, giving each variable length field is minimum length
11318 (as defined in sys/debug.h). Thus we can not use the .tbtab
11319 pseudo-op at all. */
11320
11321 /* An all-zero word flags the start of the tbtab, for debuggers
11322 that have to find it by searching forward from the entry
11323 point or from the current pc. */
19d2d16f 11324 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11325
11326 /* Tbtab format type. Use format type 0. */
19d2d16f 11327 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11328
11329 /* Language type. Unfortunately, there doesn't seem to be any
11330 official way to get this info, so we use language_string. C
11331 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11332 value for C for now. There is no official value for Java,
6f573ff9 11333 although IBM appears to be using 13. There is no official value
f710504c 11334 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11335 if (! strcmp (language_string, "GNU C")
e2c953b6 11336 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11337 i = 0;
11338 else if (! strcmp (language_string, "GNU F77"))
11339 i = 1;
11340 else if (! strcmp (language_string, "GNU Ada"))
11341 i = 3;
8b83775b 11342 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11343 i = 2;
11344 else if (! strcmp (language_string, "GNU C++"))
11345 i = 9;
9517ead8
AG
11346 else if (! strcmp (language_string, "GNU Java"))
11347 i = 13;
6f573ff9
JL
11348 else if (! strcmp (language_string, "GNU CHILL"))
11349 i = 44;
314fc5a9
ILT
11350 else
11351 abort ();
11352 fprintf (file, "%d,", i);
11353
11354 /* 8 single bit fields: global linkage (not set for C extern linkage,
11355 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11356 from start of procedure stored in tbtab, internal function, function
11357 has controlled storage, function has no toc, function uses fp,
11358 function logs/aborts fp operations. */
11359 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11360 fprintf (file, "%d,",
11361 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11362
11363 /* 6 bitfields: function is interrupt handler, name present in
11364 proc table, function calls alloca, on condition directives
11365 (controls stack walks, 3 bits), saves condition reg, saves
11366 link reg. */
11367 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11368 set up as a frame pointer, even when there is no alloca call. */
11369 fprintf (file, "%d,",
6041bf2f
DE
11370 ((optional_tbtab << 6)
11371 | ((optional_tbtab & frame_pointer_needed) << 5)
11372 | (info->cr_save_p << 1)
11373 | (info->lr_save_p)));
314fc5a9 11374
6041bf2f 11375 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11376 (6 bits). */
11377 fprintf (file, "%d,",
4697a36c 11378 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11379
11380 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11381 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11382
6041bf2f
DE
11383 if (optional_tbtab)
11384 {
11385 /* Compute the parameter info from the function decl argument
11386 list. */
11387 tree decl;
11388 int next_parm_info_bit = 31;
314fc5a9 11389
6041bf2f
DE
11390 for (decl = DECL_ARGUMENTS (current_function_decl);
11391 decl; decl = TREE_CHAIN (decl))
11392 {
11393 rtx parameter = DECL_INCOMING_RTL (decl);
11394 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11395
6041bf2f
DE
11396 if (GET_CODE (parameter) == REG)
11397 {
11398 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11399 {
11400 int bits;
11401
11402 float_parms++;
11403
11404 if (mode == SFmode)
11405 bits = 0x2;
fcce224d 11406 else if (mode == DFmode || mode == TFmode)
6041bf2f
DE
11407 bits = 0x3;
11408 else
11409 abort ();
11410
11411 /* If only one bit will fit, don't or in this entry. */
11412 if (next_parm_info_bit > 0)
11413 parm_info |= (bits << (next_parm_info_bit - 1));
11414 next_parm_info_bit -= 2;
11415 }
11416 else
11417 {
11418 fixed_parms += ((GET_MODE_SIZE (mode)
11419 + (UNITS_PER_WORD - 1))
11420 / UNITS_PER_WORD);
11421 next_parm_info_bit -= 1;
11422 }
11423 }
11424 }
11425 }
314fc5a9
ILT
11426
11427 /* Number of fixed point parameters. */
11428 /* This is actually the number of words of fixed point parameters; thus
11429 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11430 fprintf (file, "%d,", fixed_parms);
11431
11432 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11433 all on stack. */
11434 /* This is actually the number of fp registers that hold parameters;
11435 and thus the maximum value is 13. */
11436 /* Set parameters on stack bit if parameters are not in their original
11437 registers, regardless of whether they are on the stack? Xlc
11438 seems to set the bit when not optimizing. */
11439 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11440
6041bf2f
DE
11441 if (! optional_tbtab)
11442 return;
11443
314fc5a9
ILT
11444 /* Optional fields follow. Some are variable length. */
11445
11446 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11447 11 double float. */
11448 /* There is an entry for each parameter in a register, in the order that
11449 they occur in the parameter list. Any intervening arguments on the
11450 stack are ignored. If the list overflows a long (max possible length
11451 34 bits) then completely leave off all elements that don't fit. */
11452 /* Only emit this long if there was at least one parameter. */
11453 if (fixed_parms || float_parms)
11454 fprintf (file, "\t.long %d\n", parm_info);
11455
11456 /* Offset from start of code to tb table. */
19d2d16f 11457 fputs ("\t.long ", file);
314fc5a9 11458 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11459#if TARGET_AIX
11460 RS6000_OUTPUT_BASENAME (file, fname);
11461#else
9ebbca7d 11462 assemble_name (file, fname);
54ee9799 11463#endif
19d2d16f 11464 fputs ("-.", file);
54ee9799
DE
11465#if TARGET_AIX
11466 RS6000_OUTPUT_BASENAME (file, fname);
11467#else
9ebbca7d 11468 assemble_name (file, fname);
54ee9799 11469#endif
19d2d16f 11470 putc ('\n', file);
314fc5a9
ILT
11471
11472 /* Interrupt handler mask. */
11473 /* Omit this long, since we never set the interrupt handler bit
11474 above. */
11475
11476 /* Number of CTL (controlled storage) anchors. */
11477 /* Omit this long, since the has_ctl bit is never set above. */
11478
11479 /* Displacement into stack of each CTL anchor. */
11480 /* Omit this list of longs, because there are no CTL anchors. */
11481
11482 /* Length of function name. */
69c75916
AM
11483 if (*fname == '*')
11484 ++fname;
296b8152 11485 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11486
11487 /* Function name. */
11488 assemble_string (fname, strlen (fname));
11489
11490 /* Register for alloca automatic storage; this is always reg 31.
11491 Only emit this if the alloca bit was set above. */
11492 if (frame_pointer_needed)
19d2d16f 11493 fputs ("\t.byte 31\n", file);
b1765bde
DE
11494
11495 fputs ("\t.align 2\n", file);
9b30bae2 11496 }
9878760c 11497}
17167fd8 11498\f
a4f6c312
SS
11499/* A C compound statement that outputs the assembler code for a thunk
11500 function, used to implement C++ virtual function calls with
11501 multiple inheritance. The thunk acts as a wrapper around a virtual
11502 function, adjusting the implicit object parameter before handing
11503 control off to the real function.
11504
11505 First, emit code to add the integer DELTA to the location that
11506 contains the incoming first argument. Assume that this argument
11507 contains a pointer, and is the one used to pass the `this' pointer
11508 in C++. This is the incoming argument *before* the function
11509 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11510 values of all other incoming arguments.
17167fd8
MM
11511
11512 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11513 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11514 not touch the return address. Hence returning from FUNCTION will
11515 return to whoever called the current `thunk'.
17167fd8 11516
a4f6c312
SS
11517 The effect must be as if FUNCTION had been called directly with the
11518 adjusted first argument. This macro is responsible for emitting
11519 all of the code for a thunk function; output_function_prologue()
11520 and output_function_epilogue() are not invoked.
17167fd8 11521
a4f6c312
SS
11522 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11523 been extracted from it.) It might possibly be useful on some
11524 targets, but probably not.
17167fd8 11525
a4f6c312
SS
11526 If you do not define this macro, the target-independent code in the
11527 C++ frontend will generate a less efficient heavyweight thunk that
11528 calls FUNCTION instead of jumping to it. The generic approach does
11529 not support varargs. */
17167fd8 11530
3961e8fe
RH
11531static void
11532rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
17167fd8 11533 FILE *file;
d330fd93 11534 tree thunk_fndecl ATTRIBUTE_UNUSED;
eb0424da 11535 HOST_WIDE_INT delta;
5b71a4e7 11536 HOST_WIDE_INT vcall_offset;
17167fd8
MM
11537 tree function;
11538{
5b71a4e7 11539 rtx this, insn, funexp;
17167fd8 11540
5b71a4e7
DE
11541 reload_completed = 1;
11542 no_new_pseudos = 1;
56a7189a 11543
5b71a4e7
DE
11544 /* Mark the end of the (empty) prologue. */
11545 emit_note (NULL, NOTE_INSN_PROLOGUE_END);
17167fd8 11546
5b71a4e7
DE
11547 /* Find the "this" pointer. If the function returns a structure,
11548 the structure return pointer is in r3. */
11549 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
11550 this = gen_rtx_REG (Pmode, 4);
56a7189a 11551 else
5b71a4e7 11552 this = gen_rtx_REG (Pmode, 3);
17167fd8 11553
5b71a4e7
DE
11554 /* Apply the constant offset, if required. */
11555 if (delta)
11556 {
11557 rtx delta_rtx = GEN_INT (delta);
11558 emit_insn (TARGET_32BIT
11559 ? gen_addsi3 (this, this, delta_rtx)
11560 : gen_adddi3 (this, this, delta_rtx));
17167fd8
MM
11561 }
11562
5b71a4e7
DE
11563 /* Apply the offset from the vtable, if required. */
11564 if (vcall_offset)
17167fd8 11565 {
5b71a4e7
DE
11566 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
11567 rtx tmp = gen_rtx_REG (Pmode, 12);
17167fd8 11568
5b71a4e7
DE
11569 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
11570 emit_insn (TARGET_32BIT
11571 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
11572 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
11573 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
11574 emit_insn (TARGET_32BIT
11575 ? gen_addsi3 (this, this, tmp)
11576 : gen_adddi3 (this, this, tmp));
17167fd8
MM
11577 }
11578
5b71a4e7
DE
11579 /* Generate a tail call to the target function. */
11580 if (!TREE_USED (function))
11581 {
11582 assemble_external (function);
11583 TREE_USED (function) = 1;
11584 }
11585 funexp = XEXP (DECL_RTL (function), 0);
42820a49 11586
5b71a4e7
DE
11587 SYMBOL_REF_FLAG (funexp) = 0;
11588 if (current_file_function_operand (funexp, VOIDmode)
a5c76ee6
ZW
11589 && (! lookup_attribute ("longcall",
11590 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11591 || lookup_attribute ("shortcall",
11592 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
5b71a4e7 11593 SYMBOL_REF_FLAG (funexp) = 1;
17167fd8 11594
5b71a4e7 11595 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
ee890fe2
SS
11596
11597#if TARGET_MACHO
ab82a49f 11598 if (MACHOPIC_INDIRECT)
5b71a4e7 11599 funexp = machopic_indirect_call_target (funexp);
ee890fe2 11600#endif
5b71a4e7
DE
11601
11602 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
11603 generate sibcall RTL explicitly to avoid constraint abort. */
11604 insn = emit_call_insn (
11605 gen_rtx_PARALLEL (VOIDmode,
11606 gen_rtvec (4,
11607 gen_rtx_CALL (VOIDmode,
11608 funexp, const0_rtx),
11609 gen_rtx_USE (VOIDmode, const0_rtx),
11610 gen_rtx_USE (VOIDmode,
11611 gen_rtx_REG (SImode,
11612 LINK_REGISTER_REGNUM)),
11613 gen_rtx_RETURN (VOIDmode))));
11614 SIBLING_CALL_P (insn) = 1;
11615 emit_barrier ();
11616
11617 /* Run just enough of rest_of_compilation to get the insns emitted.
11618 There's not really enough bulk here to make other passes such as
11619 instruction scheduling worth while. Note that use_thunk calls
11620 assemble_start_function and assemble_end_function. */
11621 insn = get_insns ();
11622 shorten_branches (insn);
11623 final_start_function (insn, file, 1);
11624 final (insn, file, 1, 0);
11625 final_end_function ();
11626
11627 reload_completed = 0;
11628 no_new_pseudos = 0;
9ebbca7d 11629}
9ebbca7d
GK
11630\f
11631/* A quick summary of the various types of 'constant-pool tables'
11632 under PowerPC:
11633
11634 Target Flags Name One table per
11635 AIX (none) AIX TOC object file
11636 AIX -mfull-toc AIX TOC object file
11637 AIX -mminimal-toc AIX minimal TOC translation unit
11638 SVR4/EABI (none) SVR4 SDATA object file
11639 SVR4/EABI -fpic SVR4 pic object file
11640 SVR4/EABI -fPIC SVR4 PIC translation unit
11641 SVR4/EABI -mrelocatable EABI TOC function
11642 SVR4/EABI -maix AIX TOC object file
11643 SVR4/EABI -maix -mminimal-toc
11644 AIX minimal TOC translation unit
11645
11646 Name Reg. Set by entries contains:
11647 made by addrs? fp? sum?
11648
11649 AIX TOC 2 crt0 as Y option option
11650 AIX minimal TOC 30 prolog gcc Y Y option
11651 SVR4 SDATA 13 crt0 gcc N Y N
11652 SVR4 pic 30 prolog ld Y not yet N
11653 SVR4 PIC 30 prolog gcc Y option option
11654 EABI TOC 30 prolog gcc Y option option
11655
11656*/
11657
9ebbca7d
GK
11658/* Hash functions for the hash table. */
11659
11660static unsigned
11661rs6000_hash_constant (k)
11662 rtx k;
11663{
46b33600
RH
11664 enum rtx_code code = GET_CODE (k);
11665 enum machine_mode mode = GET_MODE (k);
11666 unsigned result = (code << 3) ^ mode;
11667 const char *format;
11668 int flen, fidx;
9ebbca7d 11669
46b33600
RH
11670 format = GET_RTX_FORMAT (code);
11671 flen = strlen (format);
11672 fidx = 0;
9ebbca7d 11673
46b33600
RH
11674 switch (code)
11675 {
11676 case LABEL_REF:
11677 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
11678
11679 case CONST_DOUBLE:
11680 if (mode != VOIDmode)
11681 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
11682 flen = 2;
11683 break;
11684
11685 case CODE_LABEL:
11686 fidx = 3;
11687 break;
11688
11689 default:
11690 break;
11691 }
9ebbca7d
GK
11692
11693 for (; fidx < flen; fidx++)
11694 switch (format[fidx])
11695 {
11696 case 's':
11697 {
11698 unsigned i, len;
11699 const char *str = XSTR (k, fidx);
11700 len = strlen (str);
11701 result = result * 613 + len;
11702 for (i = 0; i < len; i++)
11703 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11704 break;
11705 }
9ebbca7d
GK
11706 case 'u':
11707 case 'e':
11708 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11709 break;
11710 case 'i':
11711 case 'n':
11712 result = result * 613 + (unsigned) XINT (k, fidx);
11713 break;
11714 case 'w':
11715 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11716 result = result * 613 + (unsigned) XWINT (k, fidx);
11717 else
11718 {
11719 size_t i;
11720 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11721 result = result * 613 + (unsigned) (XWINT (k, fidx)
11722 >> CHAR_BIT * i);
11723 }
11724 break;
11725 default:
a4f6c312 11726 abort ();
9ebbca7d 11727 }
46b33600 11728
9ebbca7d
GK
11729 return result;
11730}
11731
11732static unsigned
11733toc_hash_function (hash_entry)
11734 const void * hash_entry;
11735{
a9098fd0
GK
11736 const struct toc_hash_struct *thc =
11737 (const struct toc_hash_struct *) hash_entry;
11738 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11739}
11740
11741/* Compare H1 and H2 for equivalence. */
11742
11743static int
11744toc_hash_eq (h1, h2)
11745 const void * h1;
11746 const void * h2;
11747{
11748 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11749 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11750
a9098fd0
GK
11751 if (((const struct toc_hash_struct *) h1)->key_mode
11752 != ((const struct toc_hash_struct *) h2)->key_mode)
11753 return 0;
11754
5692c7bc 11755 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11756}
11757
28e510bd
MM
11758/* These are the names given by the C++ front-end to vtables, and
11759 vtable-like objects. Ideally, this logic should not be here;
11760 instead, there should be some programmatic way of inquiring as
11761 to whether or not an object is a vtable. */
11762
11763#define VTABLE_NAME_P(NAME) \
11764 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11765 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11766 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11767 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11768
11769void
11770rs6000_output_symbol_ref (file, x)
11771 FILE *file;
11772 rtx x;
11773{
11774 /* Currently C++ toc references to vtables can be emitted before it
11775 is decided whether the vtable is public or private. If this is
11776 the case, then the linker will eventually complain that there is
11777 a reference to an unknown section. Thus, for vtables only,
11778 we emit the TOC reference to reference the symbol and not the
11779 section. */
11780 const char *name = XSTR (x, 0);
54ee9799
DE
11781
11782 if (VTABLE_NAME_P (name))
11783 {
11784 RS6000_OUTPUT_BASENAME (file, name);
11785 }
11786 else
11787 assemble_name (file, name);
28e510bd
MM
11788}
11789
a4f6c312
SS
11790/* Output a TOC entry. We derive the entry name from what is being
11791 written. */
9878760c
RK
11792
11793void
a9098fd0 11794output_toc (file, x, labelno, mode)
9878760c
RK
11795 FILE *file;
11796 rtx x;
11797 int labelno;
a9098fd0 11798 enum machine_mode mode;
9878760c
RK
11799{
11800 char buf[256];
3cce094d 11801 const char *name = buf;
ec940faa 11802 const char *real_name;
9878760c
RK
11803 rtx base = x;
11804 int offset = 0;
11805
4697a36c
MM
11806 if (TARGET_NO_TOC)
11807 abort ();
11808
9ebbca7d
GK
11809 /* When the linker won't eliminate them, don't output duplicate
11810 TOC entries (this happens on AIX if there is any kind of TOC,
17211ab5
GK
11811 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
11812 CODE_LABELs. */
11813 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
9ebbca7d
GK
11814 {
11815 struct toc_hash_struct *h;
11816 void * * found;
11817
17211ab5
GK
11818 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
11819 time because GGC is not initialised at that point. */
11820 if (toc_hash_table == NULL)
11821 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
11822 toc_hash_eq, NULL);
11823
9ebbca7d
GK
11824 h = ggc_alloc (sizeof (*h));
11825 h->key = x;
a9098fd0 11826 h->key_mode = mode;
9ebbca7d
GK
11827 h->labelno = labelno;
11828
11829 found = htab_find_slot (toc_hash_table, h, 1);
11830 if (*found == NULL)
11831 *found = h;
11832 else /* This is indeed a duplicate.
11833 Set this label equal to that label. */
11834 {
11835 fputs ("\t.set ", file);
11836 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11837 fprintf (file, "%d,", labelno);
11838 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11839 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11840 found)->labelno));
11841 return;
11842 }
11843 }
11844
11845 /* If we're going to put a double constant in the TOC, make sure it's
11846 aligned properly when strict alignment is on. */
ff1720ed
RK
11847 if (GET_CODE (x) == CONST_DOUBLE
11848 && STRICT_ALIGNMENT
a9098fd0 11849 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
11850 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
11851 ASM_OUTPUT_ALIGN (file, 3);
11852 }
11853
4977bab6 11854 (*targetm.asm_out.internal_label) (file, "LC", labelno);
9878760c 11855
37c37a57
RK
11856 /* Handle FP constants specially. Note that if we have a minimal
11857 TOC, things we put here aren't actually in the TOC, so we can allow
11858 FP constants. */
fcce224d
DE
11859 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
11860 {
11861 REAL_VALUE_TYPE rv;
11862 long k[4];
11863
11864 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11865 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
11866
11867 if (TARGET_64BIT)
11868 {
11869 if (TARGET_MINIMAL_TOC)
11870 fputs (DOUBLE_INT_ASM_OP, file);
11871 else
11872 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11873 k[0] & 0xffffffff, k[1] & 0xffffffff,
11874 k[2] & 0xffffffff, k[3] & 0xffffffff);
11875 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
11876 k[0] & 0xffffffff, k[1] & 0xffffffff,
11877 k[2] & 0xffffffff, k[3] & 0xffffffff);
11878 return;
11879 }
11880 else
11881 {
11882 if (TARGET_MINIMAL_TOC)
11883 fputs ("\t.long ", file);
11884 else
11885 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
11886 k[0] & 0xffffffff, k[1] & 0xffffffff,
11887 k[2] & 0xffffffff, k[3] & 0xffffffff);
11888 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
11889 k[0] & 0xffffffff, k[1] & 0xffffffff,
11890 k[2] & 0xffffffff, k[3] & 0xffffffff);
11891 return;
11892 }
11893 }
11894 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 11895 {
042259f2
DE
11896 REAL_VALUE_TYPE rv;
11897 long k[2];
0adc764e 11898
042259f2
DE
11899 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11900 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 11901
13ded975
DE
11902 if (TARGET_64BIT)
11903 {
11904 if (TARGET_MINIMAL_TOC)
2bfcf297 11905 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 11906 else
2f0552b6
AM
11907 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11908 k[0] & 0xffffffff, k[1] & 0xffffffff);
11909 fprintf (file, "0x%lx%08lx\n",
11910 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11911 return;
11912 }
1875cc88 11913 else
13ded975
DE
11914 {
11915 if (TARGET_MINIMAL_TOC)
2bfcf297 11916 fputs ("\t.long ", file);
13ded975 11917 else
2f0552b6
AM
11918 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
11919 k[0] & 0xffffffff, k[1] & 0xffffffff);
11920 fprintf (file, "0x%lx,0x%lx\n",
11921 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
11922 return;
11923 }
9878760c 11924 }
a9098fd0 11925 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 11926 {
042259f2
DE
11927 REAL_VALUE_TYPE rv;
11928 long l;
9878760c 11929
042259f2
DE
11930 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
11931 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
11932
31bfaa0b
DE
11933 if (TARGET_64BIT)
11934 {
11935 if (TARGET_MINIMAL_TOC)
2bfcf297 11936 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 11937 else
2f0552b6
AM
11938 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11939 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
11940 return;
11941 }
042259f2 11942 else
31bfaa0b
DE
11943 {
11944 if (TARGET_MINIMAL_TOC)
2bfcf297 11945 fputs ("\t.long ", file);
31bfaa0b 11946 else
2f0552b6
AM
11947 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
11948 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
11949 return;
11950 }
042259f2 11951 }
f176e826 11952 else if (GET_MODE (x) == VOIDmode
a9098fd0 11953 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 11954 {
e2c953b6 11955 unsigned HOST_WIDE_INT low;
042259f2
DE
11956 HOST_WIDE_INT high;
11957
11958 if (GET_CODE (x) == CONST_DOUBLE)
11959 {
11960 low = CONST_DOUBLE_LOW (x);
11961 high = CONST_DOUBLE_HIGH (x);
11962 }
11963 else
11964#if HOST_BITS_PER_WIDE_INT == 32
11965 {
11966 low = INTVAL (x);
0858c623 11967 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
11968 }
11969#else
11970 {
0858c623 11971 low = INTVAL (x) & 0xffffffff;
042259f2
DE
11972 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
11973 }
11974#endif
9878760c 11975
a9098fd0
GK
11976 /* TOC entries are always Pmode-sized, but since this
11977 is a bigendian machine then if we're putting smaller
11978 integer constants in the TOC we have to pad them.
11979 (This is still a win over putting the constants in
11980 a separate constant pool, because then we'd have
02a4ec28
FS
11981 to have both a TOC entry _and_ the actual constant.)
11982
11983 For a 32-bit target, CONST_INT values are loaded and shifted
11984 entirely within `low' and can be stored in one TOC entry. */
11985
11986 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 11987 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
11988
11989 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
11990 {
11991#if HOST_BITS_PER_WIDE_INT == 32
11992 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
11993 POINTER_SIZE, &low, &high, 0);
11994#else
11995 low |= high << 32;
11996 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
11997 high = (HOST_WIDE_INT) low >> 32;
11998 low &= 0xffffffff;
11999#endif
12000 }
a9098fd0 12001
13ded975
DE
12002 if (TARGET_64BIT)
12003 {
12004 if (TARGET_MINIMAL_TOC)
2bfcf297 12005 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 12006 else
2f0552b6
AM
12007 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
12008 (long) high & 0xffffffff, (long) low & 0xffffffff);
12009 fprintf (file, "0x%lx%08lx\n",
12010 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
12011 return;
12012 }
1875cc88 12013 else
13ded975 12014 {
02a4ec28
FS
12015 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
12016 {
12017 if (TARGET_MINIMAL_TOC)
2bfcf297 12018 fputs ("\t.long ", file);
02a4ec28 12019 else
2bfcf297 12020 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
12021 (long) high & 0xffffffff, (long) low & 0xffffffff);
12022 fprintf (file, "0x%lx,0x%lx\n",
12023 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 12024 }
13ded975 12025 else
02a4ec28
FS
12026 {
12027 if (TARGET_MINIMAL_TOC)
2bfcf297 12028 fputs ("\t.long ", file);
02a4ec28 12029 else
2f0552b6
AM
12030 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
12031 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 12032 }
13ded975
DE
12033 return;
12034 }
9878760c
RK
12035 }
12036
12037 if (GET_CODE (x) == CONST)
12038 {
2bfcf297
DB
12039 if (GET_CODE (XEXP (x, 0)) != PLUS)
12040 abort ();
12041
9878760c
RK
12042 base = XEXP (XEXP (x, 0), 0);
12043 offset = INTVAL (XEXP (XEXP (x, 0), 1));
12044 }
12045
12046 if (GET_CODE (base) == SYMBOL_REF)
12047 name = XSTR (base, 0);
12048 else if (GET_CODE (base) == LABEL_REF)
12049 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
12050 else if (GET_CODE (base) == CODE_LABEL)
12051 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
12052 else
12053 abort ();
12054
772c5265 12055 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 12056 if (TARGET_MINIMAL_TOC)
2bfcf297 12057 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
12058 else
12059 {
b6c9286a 12060 fprintf (file, "\t.tc %s", real_name);
9878760c 12061
1875cc88
JW
12062 if (offset < 0)
12063 fprintf (file, ".N%d", - offset);
12064 else if (offset)
12065 fprintf (file, ".P%d", offset);
9878760c 12066
19d2d16f 12067 fputs ("[TC],", file);
1875cc88 12068 }
581bc4de
MM
12069
12070 /* Currently C++ toc references to vtables can be emitted before it
12071 is decided whether the vtable is public or private. If this is
12072 the case, then the linker will eventually complain that there is
12073 a TOC reference to an unknown section. Thus, for vtables only,
12074 we emit the TOC reference to reference the symbol and not the
12075 section. */
28e510bd 12076 if (VTABLE_NAME_P (name))
581bc4de 12077 {
54ee9799 12078 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
12079 if (offset < 0)
12080 fprintf (file, "%d", offset);
12081 else if (offset > 0)
12082 fprintf (file, "+%d", offset);
12083 }
12084 else
12085 output_addr_const (file, x);
19d2d16f 12086 putc ('\n', file);
9878760c
RK
12087}
12088\f
12089/* Output an assembler pseudo-op to write an ASCII string of N characters
12090 starting at P to FILE.
12091
12092 On the RS/6000, we have to do this using the .byte operation and
12093 write out special characters outside the quoted string.
12094 Also, the assembler is broken; very long strings are truncated,
a4f6c312 12095 so we must artificially break them up early. */
9878760c
RK
12096
12097void
12098output_ascii (file, p, n)
12099 FILE *file;
d330fd93 12100 const char *p;
9878760c
RK
12101 int n;
12102{
12103 char c;
12104 int i, count_string;
d330fd93
KG
12105 const char *for_string = "\t.byte \"";
12106 const char *for_decimal = "\t.byte ";
12107 const char *to_close = NULL;
9878760c
RK
12108
12109 count_string = 0;
12110 for (i = 0; i < n; i++)
12111 {
12112 c = *p++;
12113 if (c >= ' ' && c < 0177)
12114 {
12115 if (for_string)
12116 fputs (for_string, file);
12117 putc (c, file);
12118
12119 /* Write two quotes to get one. */
12120 if (c == '"')
12121 {
12122 putc (c, file);
12123 ++count_string;
12124 }
12125
12126 for_string = NULL;
12127 for_decimal = "\"\n\t.byte ";
12128 to_close = "\"\n";
12129 ++count_string;
12130
12131 if (count_string >= 512)
12132 {
12133 fputs (to_close, file);
12134
12135 for_string = "\t.byte \"";
12136 for_decimal = "\t.byte ";
12137 to_close = NULL;
12138 count_string = 0;
12139 }
12140 }
12141 else
12142 {
12143 if (for_decimal)
12144 fputs (for_decimal, file);
12145 fprintf (file, "%d", c);
12146
12147 for_string = "\n\t.byte \"";
12148 for_decimal = ", ";
12149 to_close = "\n";
12150 count_string = 0;
12151 }
12152 }
12153
12154 /* Now close the string if we have written one. Then end the line. */
12155 if (to_close)
9ebbca7d 12156 fputs (to_close, file);
9878760c
RK
12157}
12158\f
12159/* Generate a unique section name for FILENAME for a section type
12160 represented by SECTION_DESC. Output goes into BUF.
12161
12162 SECTION_DESC can be any string, as long as it is different for each
12163 possible section type.
12164
12165 We name the section in the same manner as xlc. The name begins with an
12166 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
12167 names) with the last period replaced by the string SECTION_DESC. If
12168 FILENAME does not contain a period, SECTION_DESC is appended to the end of
12169 the name. */
9878760c
RK
12170
12171void
12172rs6000_gen_section_name (buf, filename, section_desc)
12173 char **buf;
9ebbca7d
GK
12174 const char *filename;
12175 const char *section_desc;
9878760c 12176{
9ebbca7d 12177 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
12178 char *p;
12179 int len;
9878760c
RK
12180
12181 after_last_slash = filename;
12182 for (q = filename; *q; q++)
11e5fe42
RK
12183 {
12184 if (*q == '/')
12185 after_last_slash = q + 1;
12186 else if (*q == '.')
12187 last_period = q;
12188 }
9878760c 12189
11e5fe42 12190 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 12191 *buf = (char *) xmalloc (len);
9878760c
RK
12192
12193 p = *buf;
12194 *p++ = '_';
12195
12196 for (q = after_last_slash; *q; q++)
12197 {
11e5fe42 12198 if (q == last_period)
9878760c
RK
12199 {
12200 strcpy (p, section_desc);
12201 p += strlen (section_desc);
e3981aab 12202 break;
9878760c
RK
12203 }
12204
e9a780ec 12205 else if (ISALNUM (*q))
9878760c
RK
12206 *p++ = *q;
12207 }
12208
11e5fe42 12209 if (last_period == 0)
9878760c
RK
12210 strcpy (p, section_desc);
12211 else
12212 *p = '\0';
12213}
e165f3f0 12214\f
a4f6c312 12215/* Emit profile function. */
411707f4 12216
411707f4
CC
12217void
12218output_profile_hook (labelno)
57ac7be9 12219 int labelno ATTRIBUTE_UNUSED;
411707f4 12220{
8480e480
CC
12221 if (DEFAULT_ABI == ABI_AIX)
12222 {
57ac7be9
AM
12223#ifdef NO_PROFILE_COUNTERS
12224 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
12225#else
8480e480 12226 char buf[30];
40501e5f 12227 const char *label_name;
8480e480 12228 rtx fun;
411707f4 12229
8480e480 12230 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 12231 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 12232 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 12233
8480e480
CC
12234 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
12235 fun, Pmode);
57ac7be9 12236#endif
8480e480 12237 }
ee890fe2
SS
12238 else if (DEFAULT_ABI == ABI_DARWIN)
12239 {
d5fa86ba 12240 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
12241 int caller_addr_regno = LINK_REGISTER_REGNUM;
12242
12243 /* Be conservative and always set this, at least for now. */
12244 current_function_uses_pic_offset_table = 1;
12245
12246#if TARGET_MACHO
12247 /* For PIC code, set up a stub and collect the caller's address
12248 from r0, which is where the prologue puts it. */
ab82a49f 12249 if (MACHOPIC_INDIRECT)
ee890fe2
SS
12250 {
12251 mcount_name = machopic_stub_name (mcount_name);
12252 if (current_function_uses_pic_offset_table)
12253 caller_addr_regno = 0;
12254 }
12255#endif
12256 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
12257 0, VOIDmode, 1,
12258 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12259 }
411707f4
CC
12260}
12261
a4f6c312 12262/* Write function profiler code. */
e165f3f0
RK
12263
12264void
12265output_function_profiler (file, labelno)
12266 FILE *file;
12267 int labelno;
12268{
3daf36a4 12269 char buf[100];
09eeeacb 12270 int save_lr = 8;
e165f3f0 12271
3daf36a4 12272 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7 12273 switch (DEFAULT_ABI)
3daf36a4 12274 {
38c1f2d7
MM
12275 default:
12276 abort ();
12277
12278 case ABI_V4:
09eeeacb
AM
12279 save_lr = 4;
12280 /* Fall through. */
12281
38c1f2d7 12282 case ABI_AIX_NODESC:
09eeeacb
AM
12283 if (!TARGET_32BIT)
12284 {
12285 warning ("no profiling of 64-bit code for this ABI");
12286 return;
12287 }
38c1f2d7
MM
12288 fprintf (file, "\tmflr %s\n", reg_names[0]);
12289 if (flag_pic == 1)
12290 {
dfdfa60f 12291 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12292 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12293 reg_names[0], save_lr, reg_names[1]);
17167fd8 12294 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12295 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12296 assemble_name (file, buf);
17167fd8 12297 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12298 }
9ebbca7d 12299 else if (flag_pic > 1)
38c1f2d7 12300 {
09eeeacb
AM
12301 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12302 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12303 /* Now, we need to get the address of the label. */
12304 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12305 assemble_name (file, buf);
9ebbca7d
GK
12306 fputs ("-.\n1:", file);
12307 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12308 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12309 reg_names[0], reg_names[11]);
12310 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12311 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12312 }
38c1f2d7
MM
12313 else
12314 {
17167fd8 12315 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12316 assemble_name (file, buf);
dfdfa60f 12317 fputs ("@ha\n", file);
09eeeacb
AM
12318 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12319 reg_names[0], save_lr, reg_names[1]);
a260abc9 12320 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12321 assemble_name (file, buf);
17167fd8 12322 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12323 }
12324
09eeeacb
AM
12325 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12326 {
12327 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12328 reg_names[STATIC_CHAIN_REGNUM],
12329 12, reg_names[1]);
12330 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12331 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12332 reg_names[STATIC_CHAIN_REGNUM],
12333 12, reg_names[1]);
12334 }
12335 else
12336 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12337 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12338 break;
12339
12340 case ABI_AIX:
ee890fe2 12341 case ABI_DARWIN:
a4f6c312 12342 /* Don't do anything, done in output_profile_hook (). */
38c1f2d7
MM
12343 break;
12344 }
e165f3f0 12345}
a251ffd0 12346
b54cf83a
DE
12347\f
12348static int
12349rs6000_use_dfa_pipeline_interface ()
12350{
12351 return 1;
12352}
12353
b54cf83a
DE
12354/* Power4 load update and store update instructions are cracked into a
12355 load or store and an integer insn which are executed in the same cycle.
12356 Branches have their own dispatch slot which does not count against the
12357 GCC issue rate, but it changes the program flow so there are no other
12358 instructions to issue in this cycle. */
12359
12360static int
12361rs6000_variable_issue (stream, verbose, insn, more)
12362 FILE *stream ATTRIBUTE_UNUSED;
12363 int verbose ATTRIBUTE_UNUSED;
12364 rtx insn;
12365 int more;
12366{
12367 if (GET_CODE (PATTERN (insn)) == USE
12368 || GET_CODE (PATTERN (insn)) == CLOBBER)
12369 return more;
12370
12371 if (rs6000_cpu == PROCESSOR_POWER4)
12372 {
12373 enum attr_type type = get_attr_type (insn);
12374 if (type == TYPE_LOAD_EXT_U || type == TYPE_LOAD_EXT_UX
12375 || type == TYPE_LOAD_UX || type == TYPE_STORE_UX
12376 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX)
12377 return 0;
12378 else if (type == TYPE_LOAD_U || type == TYPE_STORE_U
12379 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
12380 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR)
3317bab1 12381 return more > 2 ? more - 2 : 0;
b54cf83a 12382 }
165b263e
DE
12383
12384 return more - 1;
b54cf83a
DE
12385}
12386
a251ffd0
TG
12387/* Adjust the cost of a scheduling dependency. Return the new cost of
12388 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12389
c237e94a 12390static int
a06faf84 12391rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12392 rtx insn;
12393 rtx link;
296b8152 12394 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12395 int cost;
12396{
12397 if (! recog_memoized (insn))
12398 return 0;
12399
12400 if (REG_NOTE_KIND (link) != 0)
12401 return 0;
12402
12403 if (REG_NOTE_KIND (link) == 0)
12404 {
ed947a96
DJ
12405 /* Data dependency; DEP_INSN writes a register that INSN reads
12406 some cycles later. */
12407 switch (get_attr_type (insn))
12408 {
12409 case TYPE_JMPREG:
309323c2 12410 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12411 a mtctr and bctr (and mtlr and br/blr). The first
12412 scheduling pass will not know about this latency since
12413 the mtctr instruction, which has the latency associated
12414 to it, will be generated by reload. */
309323c2 12415 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12416 case TYPE_BRANCH:
12417 /* Leave some extra cycles between a compare and its
12418 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12419 if ((rs6000_cpu_attr == CPU_PPC603
12420 || rs6000_cpu_attr == CPU_PPC604
12421 || rs6000_cpu_attr == CPU_PPC604E
12422 || rs6000_cpu_attr == CPU_PPC620
12423 || rs6000_cpu_attr == CPU_PPC630
12424 || rs6000_cpu_attr == CPU_PPC750
12425 || rs6000_cpu_attr == CPU_PPC7400
12426 || rs6000_cpu_attr == CPU_PPC7450
12427 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12428 && recog_memoized (dep_insn)
12429 && (INSN_CODE (dep_insn) >= 0)
b54cf83a
DE
12430 && (get_attr_type (dep_insn) == TYPE_CMP
12431 || get_attr_type (dep_insn) == TYPE_COMPARE
ed947a96
DJ
12432 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
12433 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
b54cf83a
DE
12434 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL
12435 || get_attr_type (dep_insn) == TYPE_DELAYED_CR))
ed947a96
DJ
12436 return cost + 2;
12437 default:
12438 break;
12439 }
a251ffd0
TG
12440 /* Fall out to return default cost. */
12441 }
12442
12443 return cost;
12444}
b6c9286a 12445
a4f6c312
SS
12446/* A C statement (sans semicolon) to update the integer scheduling
12447 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12448 INSN earlier, increase the priority to execute INSN later. Do not
12449 define this macro if you do not need to adjust the scheduling
12450 priorities of insns. */
bef84347 12451
c237e94a 12452static int
bef84347 12453rs6000_adjust_priority (insn, priority)
d330fd93 12454 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12455 int priority;
12456{
a4f6c312
SS
12457 /* On machines (like the 750) which have asymmetric integer units,
12458 where one integer unit can do multiply and divides and the other
12459 can't, reduce the priority of multiply/divide so it is scheduled
12460 before other integer operations. */
bef84347
VM
12461
12462#if 0
2c3c49de 12463 if (! INSN_P (insn))
bef84347
VM
12464 return priority;
12465
12466 if (GET_CODE (PATTERN (insn)) == USE)
12467 return priority;
12468
12469 switch (rs6000_cpu_attr) {
12470 case CPU_PPC750:
12471 switch (get_attr_type (insn))
12472 {
12473 default:
12474 break;
12475
12476 case TYPE_IMUL:
12477 case TYPE_IDIV:
3cb999d8
DE
12478 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12479 priority, priority);
bef84347
VM
12480 if (priority >= 0 && priority < 0x01000000)
12481 priority >>= 3;
12482 break;
12483 }
12484 }
12485#endif
12486
12487 return priority;
12488}
12489
a4f6c312
SS
12490/* Return how many instructions the machine can issue per cycle. */
12491
c237e94a
ZW
12492static int
12493rs6000_issue_rate ()
b6c9286a 12494{
3317bab1
DE
12495 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
12496 if (!reload_completed)
12497 return 1;
12498
b6c9286a 12499 switch (rs6000_cpu_attr) {
3cb999d8
DE
12500 case CPU_RIOS1: /* ? */
12501 case CPU_RS64A:
12502 case CPU_PPC601: /* ? */
ed947a96 12503 case CPU_PPC7450:
3cb999d8 12504 return 3;
b54cf83a 12505 case CPU_PPC440:
b6c9286a 12506 case CPU_PPC603:
bef84347 12507 case CPU_PPC750:
ed947a96 12508 case CPU_PPC7400:
bef84347 12509 return 2;
3cb999d8 12510 case CPU_RIOS2:
b6c9286a 12511 case CPU_PPC604:
19684119 12512 case CPU_PPC604E:
b6c9286a 12513 case CPU_PPC620:
3cb999d8 12514 case CPU_PPC630:
309323c2 12515 case CPU_POWER4:
b6c9286a
MM
12516 return 4;
12517 default:
12518 return 1;
12519 }
12520}
12521
b6c9286a 12522\f
b6c9286a
MM
12523/* Length in units of the trampoline for entering a nested function. */
12524
12525int
12526rs6000_trampoline_size ()
12527{
12528 int ret = 0;
12529
12530 switch (DEFAULT_ABI)
12531 {
12532 default:
12533 abort ();
12534
12535 case ABI_AIX:
8f802bfb 12536 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12537 break;
12538
4dabc42d 12539 case ABI_DARWIN:
b6c9286a
MM
12540 case ABI_V4:
12541 case ABI_AIX_NODESC:
03a7e1a5 12542 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12543 break;
b6c9286a
MM
12544 }
12545
12546 return ret;
12547}
12548
12549/* Emit RTL insns to initialize the variable parts of a trampoline.
12550 FNADDR is an RTX for the address of the function's pure code.
12551 CXT is an RTX for the static chain value for the function. */
12552
12553void
12554rs6000_initialize_trampoline (addr, fnaddr, cxt)
12555 rtx addr;
12556 rtx fnaddr;
12557 rtx cxt;
12558{
ac2a93a1 12559 enum machine_mode pmode = Pmode;
8bd04c56
MM
12560 int regsize = (TARGET_32BIT) ? 4 : 8;
12561 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12562
12563 switch (DEFAULT_ABI)
12564 {
12565 default:
12566 abort ();
12567
8bd04c56 12568/* Macros to shorten the code expansions below. */
39403d82 12569#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12570#define MEM_PLUS(addr,offset) \
12571 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12572
b6c9286a
MM
12573 /* Under AIX, just build the 3 word function descriptor */
12574 case ABI_AIX:
8bd04c56
MM
12575 {
12576 rtx fn_reg = gen_reg_rtx (pmode);
12577 rtx toc_reg = gen_reg_rtx (pmode);
12578 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12579 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12580 emit_move_insn (MEM_DEREF (addr), fn_reg);
12581 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12582 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12583 }
b6c9286a
MM
12584 break;
12585
4dabc42d
TC
12586 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12587 case ABI_DARWIN:
b6c9286a
MM
12588 case ABI_V4:
12589 case ABI_AIX_NODESC:
39403d82 12590 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12591 FALSE, VOIDmode, 4,
12592 addr, pmode,
12593 GEN_INT (rs6000_trampoline_size ()), SImode,
12594 fnaddr, pmode,
12595 ctx_reg, pmode);
b6c9286a 12596 break;
b6c9286a
MM
12597 }
12598
12599 return;
12600}
7509c759
MM
12601
12602\f
91d231cb 12603/* Table of valid machine attributes. */
a4f6c312 12604
91d231cb 12605const struct attribute_spec rs6000_attribute_table[] =
7509c759 12606{
91d231cb 12607 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12608 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12609 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12610 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12611};
7509c759 12612
a5c76ee6
ZW
12613/* Handle a "longcall" or "shortcall" attribute; arguments as in
12614 struct attribute_spec.handler. */
a4f6c312 12615
91d231cb
JM
12616static tree
12617rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12618 tree *node;
12619 tree name;
12620 tree args ATTRIBUTE_UNUSED;
12621 int flags ATTRIBUTE_UNUSED;
12622 bool *no_add_attrs;
12623{
12624 if (TREE_CODE (*node) != FUNCTION_TYPE
12625 && TREE_CODE (*node) != FIELD_DECL
12626 && TREE_CODE (*node) != TYPE_DECL)
12627 {
12628 warning ("`%s' attribute only applies to functions",
12629 IDENTIFIER_POINTER (name));
12630 *no_add_attrs = true;
12631 }
6a4cee5f 12632
91d231cb 12633 return NULL_TREE;
7509c759
MM
12634}
12635
a5c76ee6
ZW
12636/* Set longcall attributes on all functions declared when
12637 rs6000_default_long_calls is true. */
12638static void
12639rs6000_set_default_type_attributes (type)
12640 tree type;
12641{
12642 if (rs6000_default_long_calls
12643 && (TREE_CODE (type) == FUNCTION_TYPE
12644 || TREE_CODE (type) == METHOD_TYPE))
12645 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12646 NULL_TREE,
12647 TYPE_ATTRIBUTES (type));
12648}
12649
3cb999d8
DE
12650/* Return a reference suitable for calling a function with the
12651 longcall attribute. */
a4f6c312 12652
6a4cee5f
MM
12653struct rtx_def *
12654rs6000_longcall_ref (call_ref)
12655 rtx call_ref;
12656{
d330fd93 12657 const char *call_name;
6a4cee5f
MM
12658 tree node;
12659
12660 if (GET_CODE (call_ref) != SYMBOL_REF)
12661 return call_ref;
12662
12663 /* System V adds '.' to the internal name, so skip them. */
12664 call_name = XSTR (call_ref, 0);
12665 if (*call_name == '.')
12666 {
12667 while (*call_name == '.')
12668 call_name++;
12669
12670 node = get_identifier (call_name);
39403d82 12671 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12672 }
12673
12674 return force_reg (Pmode, call_ref);
12675}
12676
7509c759 12677\f
b64a1b53
RH
12678#ifdef USING_ELFOS_H
12679
7509c759
MM
12680/* A C statement or statements to switch to the appropriate section
12681 for output of RTX in mode MODE. You can assume that RTX is some
12682 kind of constant in RTL. The argument MODE is redundant except in
12683 the case of a `const_int' rtx. Select the section by calling
12684 `text_section' or one of the alternatives for other sections.
12685
12686 Do not define this macro if you put all constants in the read-only
12687 data section. */
12688
b64a1b53
RH
12689static void
12690rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12691 enum machine_mode mode;
7509c759 12692 rtx x;
b64a1b53 12693 unsigned HOST_WIDE_INT align;
7509c759 12694{
a9098fd0 12695 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12696 toc_section ();
7509c759 12697 else
b64a1b53 12698 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12699}
12700
12701/* A C statement or statements to switch to the appropriate
12702 section for output of DECL. DECL is either a `VAR_DECL' node
12703 or a constant of some sort. RELOC indicates whether forming
12704 the initial value of DECL requires link-time relocations. */
12705
ae46c4e0
RH
12706static void
12707rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12708 tree decl;
12709 int reloc;
0e5dbd9b 12710 unsigned HOST_WIDE_INT align;
7509c759 12711{
0e5dbd9b
DE
12712 default_elf_select_section_1 (decl, reloc, align,
12713 flag_pic || DEFAULT_ABI == ABI_AIX);
63019373
GK
12714}
12715
12716/* A C statement to build up a unique section name, expressed as a
12717 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12718 RELOC indicates whether the initial value of EXP requires
12719 link-time relocations. If you do not define this macro, GCC will use
12720 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12721 macro can now be called for uninitialized data items as well as
4912a07c 12722 initialized data and functions. */
63019373 12723
ae46c4e0
RH
12724static void
12725rs6000_elf_unique_section (decl, reloc)
63019373
GK
12726 tree decl;
12727 int reloc;
12728{
0e5dbd9b
DE
12729 default_unique_section_1 (decl, reloc,
12730 flag_pic || DEFAULT_ABI == ABI_AIX);
7509c759 12731}
d9407988
MM
12732
12733\f
d9407988
MM
12734/* If we are referencing a function that is static or is known to be
12735 in this file, make the SYMBOL_REF special. We can use this to indicate
12736 that we can branch to this function without emitting a no-op after the
9ebbca7d 12737 call. For real AIX calling sequences, we also replace the
d9407988
MM
12738 function name with the real name (1 or 2 leading .'s), rather than
12739 the function descriptor name. This saves a lot of overriding code
a260abc9 12740 to read the prefixes. */
d9407988 12741
fb49053f
RH
12742static void
12743rs6000_elf_encode_section_info (decl, first)
d9407988 12744 tree decl;
b2003250 12745 int first;
d9407988 12746{
b2003250
RH
12747 if (!first)
12748 return;
12749
d9407988
MM
12750 if (TREE_CODE (decl) == FUNCTION_DECL)
12751 {
12752 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
b629ba0c 12753 if ((*targetm.binds_local_p) (decl))
d9407988
MM
12754 SYMBOL_REF_FLAG (sym_ref) = 1;
12755
9ebbca7d 12756 if (DEFAULT_ABI == ABI_AIX)
d9407988 12757 {
ff669a6c
RH
12758 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12759 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12760 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12761 str[0] = '.';
12762 str[1] = '.';
12763 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12764
520a57c8 12765 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12766 }
12767 }
12768 else if (rs6000_sdata != SDATA_NONE
f607bc57 12769 && DEFAULT_ABI == ABI_V4
d9407988
MM
12770 && TREE_CODE (decl) == VAR_DECL)
12771 {
c40e5172 12772 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
d9407988
MM
12773 int size = int_size_in_bytes (TREE_TYPE (decl));
12774 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12775 const char *name = (char *)0;
d9407988
MM
12776 int len = 0;
12777
c40e5172
JS
12778 if ((*targetm.binds_local_p) (decl))
12779 SYMBOL_REF_FLAG (sym_ref) = 1;
12780
d9407988
MM
12781 if (section_name)
12782 {
12783 if (TREE_CODE (section_name) == STRING_CST)
12784 {
12785 name = TREE_STRING_POINTER (section_name);
12786 len = TREE_STRING_LENGTH (section_name);
12787 }
12788 else
12789 abort ();
12790 }
12791
2792d578
DE
12792 if (name
12793 ? ((len == sizeof (".sdata") - 1
12794 && strcmp (name, ".sdata") == 0)
12795 || (len == sizeof (".sdata2") - 1
12796 && strcmp (name, ".sdata2") == 0)
12797 || (len == sizeof (".sbss") - 1
12798 && strcmp (name, ".sbss") == 0)
12799 || (len == sizeof (".sbss2") - 1
12800 && strcmp (name, ".sbss2") == 0)
12801 || (len == sizeof (".PPC.EMB.sdata0") - 1
12802 && strcmp (name, ".PPC.EMB.sdata0") == 0)
12803 || (len == sizeof (".PPC.EMB.sbss0") - 1
12804 && strcmp (name, ".PPC.EMB.sbss0") == 0))
12805 : (size > 0 && size <= g_switch_value))
d9407988 12806 {
ff669a6c 12807 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 12808 char *str = alloca (len + 2);
ff669a6c 12809
ff669a6c
RH
12810 str[0] = '@';
12811 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 12812 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
12813 }
12814 }
12815}
12816
772c5265
RH
12817static const char *
12818rs6000_elf_strip_name_encoding (str)
12819 const char *str;
12820{
12821 while (*str == '*' || *str == '@')
12822 str++;
12823 return str;
12824}
12825
0e5dbd9b
DE
12826static bool
12827rs6000_elf_in_small_data_p (decl)
12828 tree decl;
12829{
12830 if (rs6000_sdata == SDATA_NONE)
12831 return false;
12832
12833 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
12834 {
12835 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
12836 if (strcmp (section, ".sdata") == 0
12837 || strcmp (section, ".sdata2") == 0
12838 || strcmp (section, ".sbss") == 0)
12839 return true;
12840 }
12841 else
12842 {
12843 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
12844
12845 if (size > 0
12846 && size <= g_switch_value
12847 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
12848 return true;
12849 }
12850
12851 return false;
12852}
12853
b91da81f 12854#endif /* USING_ELFOS_H */
000034eb 12855
a6c2a102 12856\f
000034eb 12857/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
12858 ADDR can be effectively incremented by incrementing REG.
12859
12860 r0 is special and we must not select it as an address
12861 register by this routine since our caller will try to
12862 increment the returned register via an "la" instruction. */
000034eb
DE
12863
12864struct rtx_def *
12865find_addr_reg (addr)
12866 rtx addr;
12867{
12868 while (GET_CODE (addr) == PLUS)
12869 {
02441cd6
JL
12870 if (GET_CODE (XEXP (addr, 0)) == REG
12871 && REGNO (XEXP (addr, 0)) != 0)
000034eb 12872 addr = XEXP (addr, 0);
02441cd6
JL
12873 else if (GET_CODE (XEXP (addr, 1)) == REG
12874 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
12875 addr = XEXP (addr, 1);
12876 else if (CONSTANT_P (XEXP (addr, 0)))
12877 addr = XEXP (addr, 1);
12878 else if (CONSTANT_P (XEXP (addr, 1)))
12879 addr = XEXP (addr, 0);
12880 else
12881 abort ();
12882 }
02441cd6 12883 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
12884 return addr;
12885 abort ();
12886}
12887
a6c2a102
DE
12888void
12889rs6000_fatal_bad_address (op)
12890 rtx op;
12891{
12892 fatal_insn ("bad address", op);
12893}
c8023011 12894
ee890fe2
SS
12895#if TARGET_MACHO
12896
12897#if 0
12898/* Returns 1 if OP is either a symbol reference or a sum of a symbol
12899 reference and a constant. */
12900
12901int
12902symbolic_operand (op)
592696dd 12903 rtx op;
ee890fe2
SS
12904{
12905 switch (GET_CODE (op))
12906 {
12907 case SYMBOL_REF:
12908 case LABEL_REF:
12909 return 1;
12910 case CONST:
12911 op = XEXP (op, 0);
12912 return (GET_CODE (op) == SYMBOL_REF ||
12913 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
12914 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
12915 && GET_CODE (XEXP (op, 1)) == CONST_INT);
12916 default:
12917 return 0;
12918 }
c8023011 12919}
ee890fe2
SS
12920#endif
12921
12922#ifdef RS6000_LONG_BRANCH
12923
12924static tree stub_list = 0;
12925
12926/* ADD_COMPILER_STUB adds the compiler generated stub for handling
12927 procedure calls to the linked list. */
12928
12929void
12930add_compiler_stub (label_name, function_name, line_number)
12931 tree label_name;
12932 tree function_name;
12933 int line_number;
12934{
12935 tree stub = build_tree_list (function_name, label_name);
12936 TREE_TYPE (stub) = build_int_2 (line_number, 0);
12937 TREE_CHAIN (stub) = stub_list;
12938 stub_list = stub;
12939}
12940
12941#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
12942#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
12943#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
12944
a4f6c312
SS
12945/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
12946 handling procedure calls from the linked list and initializes the
12947 linked list. */
ee890fe2 12948
a4f6c312
SS
12949void
12950output_compiler_stub ()
ee890fe2
SS
12951{
12952 char tmp_buf[256];
12953 char label_buf[256];
308c142a 12954 tree stub;
ee890fe2
SS
12955
12956 if (!flag_pic)
12957 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
12958 {
12959 fprintf (asm_out_file,
12960 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
12961
12962#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12963 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12964 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
12965#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12966
12967 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
12968 strcpy (label_buf,
12969 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
12970 else
12971 {
12972 label_buf[0] = '_';
12973 strcpy (label_buf+1,
12974 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
12975 }
12976
12977 strcpy (tmp_buf, "lis r12,hi16(");
12978 strcat (tmp_buf, label_buf);
12979 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
12980 strcat (tmp_buf, label_buf);
12981 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
12982 output_asm_insn (tmp_buf, 0);
12983
12984#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
12985 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
12986 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
12987#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
12988 }
12989
12990 stub_list = 0;
12991}
12992
12993/* NO_PREVIOUS_DEF checks in the link list whether the function name is
12994 already there or not. */
12995
a4f6c312
SS
12996int
12997no_previous_def (function_name)
ee890fe2
SS
12998 tree function_name;
12999{
13000 tree stub;
13001 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
13002 if (function_name == STUB_FUNCTION_NAME (stub))
13003 return 0;
13004 return 1;
13005}
13006
13007/* GET_PREV_LABEL gets the label name from the previous definition of
13008 the function. */
13009
a4f6c312
SS
13010tree
13011get_prev_label (function_name)
ee890fe2
SS
13012 tree function_name;
13013{
13014 tree stub;
13015 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
13016 if (function_name == STUB_FUNCTION_NAME (stub))
13017 return STUB_LABEL_NAME (stub);
13018 return 0;
13019}
13020
13021/* INSN is either a function call or a millicode call. It may have an
13022 unconditional jump in its delay slot.
13023
13024 CALL_DEST is the routine we are calling. */
13025
13026char *
13027output_call (insn, call_dest, operand_number)
13028 rtx insn;
13029 rtx call_dest;
13030 int operand_number;
13031{
13032 static char buf[256];
13033 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
13034 {
13035 tree labelname;
13036 tree funname = get_identifier (XSTR (call_dest, 0));
13037
13038 if (no_previous_def (funname))
13039 {
308c142a 13040 int line_number = 0;
ee890fe2
SS
13041 rtx label_rtx = gen_label_rtx ();
13042 char *label_buf, temp_buf[256];
13043 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
13044 CODE_LABEL_NUMBER (label_rtx));
13045 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
13046 labelname = get_identifier (label_buf);
13047 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
13048 if (insn)
13049 line_number = NOTE_LINE_NUMBER (insn);
13050 add_compiler_stub (labelname, funname, line_number);
13051 }
13052 else
13053 labelname = get_prev_label (funname);
13054
13055 sprintf (buf, "jbsr %%z%d,%.246s",
13056 operand_number, IDENTIFIER_POINTER (labelname));
13057 return buf;
13058 }
13059 else
13060 {
13061 sprintf (buf, "bl %%z%d", operand_number);
13062 return buf;
13063 }
13064}
13065
13066#endif /* RS6000_LONG_BRANCH */
13067
13068#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
13069 do { \
83182544 13070 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
13071 char *buffer_ = (BUF); \
13072 if (symbol_[0] == '"') \
13073 { \
13074 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
13075 } \
13076 else if (name_needs_quotes(symbol_)) \
13077 { \
13078 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
13079 } \
13080 else \
13081 { \
13082 sprintf(buffer_, "L%d$%s", (N), symbol_); \
13083 } \
13084 } while (0)
13085
13086
13087/* Generate PIC and indirect symbol stubs. */
13088
13089void
13090machopic_output_stub (file, symb, stub)
13091 FILE *file;
13092 const char *symb, *stub;
13093{
13094 unsigned int length;
a4f6c312
SS
13095 char *symbol_name, *lazy_ptr_name;
13096 char *local_label_0;
ee890fe2
SS
13097 static int label = 0;
13098
df56a27f 13099 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 13100 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 13101
ee890fe2
SS
13102 label += 1;
13103
ee890fe2
SS
13104 length = strlen (symb);
13105 symbol_name = alloca (length + 32);
13106 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
13107
13108 lazy_ptr_name = alloca (length + 32);
13109 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
13110
13111 local_label_0 = alloca (length + 32);
13112 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
13113
ee890fe2 13114 if (flag_pic == 2)
d3c300d2 13115 machopic_picsymbol_stub1_section ();
ee890fe2 13116 else
d3c300d2
DJ
13117 machopic_symbol_stub1_section ();
13118 fprintf (file, "\t.align 2\n");
ee890fe2
SS
13119
13120 fprintf (file, "%s:\n", stub);
13121 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
13122
13123 if (flag_pic == 2)
13124 {
13125 fprintf (file, "\tmflr r0\n");
13126 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
13127 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
13128 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
13129 lazy_ptr_name, local_label_0);
13130 fprintf (file, "\tmtlr r0\n");
d3c300d2 13131 fprintf (file, "\tlwzu r12,lo16(%s-%s)(r11)\n",
ee890fe2
SS
13132 lazy_ptr_name, local_label_0);
13133 fprintf (file, "\tmtctr r12\n");
ee890fe2
SS
13134 fprintf (file, "\tbctr\n");
13135 }
13136 else
ab82a49f
AP
13137 {
13138 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
13139 fprintf (file, "\tlwzu r12,lo16(%s)(r11)\n", lazy_ptr_name);
13140 fprintf (file, "\tmtctr r12\n");
13141 fprintf (file, "\tbctr\n");
13142 }
ee890fe2
SS
13143
13144 machopic_lazy_symbol_ptr_section ();
13145 fprintf (file, "%s:\n", lazy_ptr_name);
13146 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
13147 fprintf (file, "\t.long dyld_stub_binding_helper\n");
13148}
13149
13150/* Legitimize PIC addresses. If the address is already
13151 position-independent, we return ORIG. Newly generated
13152 position-independent addresses go into a reg. This is REG if non
13153 zero, otherwise we allocate register(s) as necessary. */
13154
c859cda6 13155#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
13156
13157rtx
13158rs6000_machopic_legitimize_pic_address (orig, mode, reg)
13159 rtx orig;
13160 enum machine_mode mode;
13161 rtx reg;
13162{
13163 rtx base, offset;
13164
13165 if (reg == NULL && ! reload_in_progress && ! reload_completed)
13166 reg = gen_reg_rtx (Pmode);
13167
13168 if (GET_CODE (orig) == CONST)
13169 {
13170 if (GET_CODE (XEXP (orig, 0)) == PLUS
13171 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
13172 return orig;
13173
13174 if (GET_CODE (XEXP (orig, 0)) == PLUS)
13175 {
a4f6c312
SS
13176 base =
13177 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
13178 Pmode, reg);
13179 offset =
13180 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
13181 Pmode, reg);
ee890fe2
SS
13182 }
13183 else
13184 abort ();
13185
13186 if (GET_CODE (offset) == CONST_INT)
13187 {
13188 if (SMALL_INT (offset))
ed8908e7 13189 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
13190 else if (! reload_in_progress && ! reload_completed)
13191 offset = force_reg (Pmode, offset);
13192 else
c859cda6
DJ
13193 {
13194 rtx mem = force_const_mem (Pmode, orig);
13195 return machopic_legitimize_pic_address (mem, Pmode, reg);
13196 }
ee890fe2
SS
13197 }
13198 return gen_rtx (PLUS, Pmode, base, offset);
13199 }
13200
13201 /* Fall back on generic machopic code. */
13202 return machopic_legitimize_pic_address (orig, mode, reg);
13203}
13204
13205/* This is just a placeholder to make linking work without having to
13206 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
13207 ever needed for Darwin (not too likely!) this would have to get a
13208 real definition. */
13209
13210void
13211toc_section ()
13212{
13213}
13214
13215#endif /* TARGET_MACHO */
7c262518
RH
13216
13217#if TARGET_ELF
13218static unsigned int
13219rs6000_elf_section_type_flags (decl, name, reloc)
13220 tree decl;
13221 const char *name;
13222 int reloc;
13223{
5add3202
DE
13224 unsigned int flags
13225 = default_section_type_flags_1 (decl, name, reloc,
13226 flag_pic || DEFAULT_ABI == ABI_AIX);
7c262518 13227
270fc29b
RH
13228 if (TARGET_RELOCATABLE)
13229 flags |= SECTION_WRITE;
7c262518 13230
d0101753 13231 return flags;
7c262518 13232}
d9f6800d
RH
13233
13234/* Record an element in the table of global constructors. SYMBOL is
13235 a SYMBOL_REF of the function to be called; PRIORITY is a number
13236 between 0 and MAX_INIT_PRIORITY.
13237
13238 This differs from default_named_section_asm_out_constructor in
13239 that we have special handling for -mrelocatable. */
13240
13241static void
13242rs6000_elf_asm_out_constructor (symbol, priority)
13243 rtx symbol;
13244 int priority;
13245{
13246 const char *section = ".ctors";
13247 char buf[16];
13248
13249 if (priority != DEFAULT_INIT_PRIORITY)
13250 {
13251 sprintf (buf, ".ctors.%.5u",
13252 /* Invert the numbering so the linker puts us in the proper
13253 order; constructors are run from right to left, and the
13254 linker sorts in increasing order. */
13255 MAX_INIT_PRIORITY - priority);
13256 section = buf;
13257 }
13258
715bdd29
RH
13259 named_section_flags (section, SECTION_WRITE);
13260 assemble_align (POINTER_SIZE);
d9f6800d
RH
13261
13262 if (TARGET_RELOCATABLE)
13263 {
13264 fputs ("\t.long (", asm_out_file);
13265 output_addr_const (asm_out_file, symbol);
13266 fputs (")@fixup\n", asm_out_file);
13267 }
13268 else
c8af3574 13269 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
13270}
13271
13272static void
13273rs6000_elf_asm_out_destructor (symbol, priority)
13274 rtx symbol;
13275 int priority;
13276{
13277 const char *section = ".dtors";
13278 char buf[16];
13279
13280 if (priority != DEFAULT_INIT_PRIORITY)
13281 {
13282 sprintf (buf, ".dtors.%.5u",
13283 /* Invert the numbering so the linker puts us in the proper
13284 order; constructors are run from right to left, and the
13285 linker sorts in increasing order. */
13286 MAX_INIT_PRIORITY - priority);
13287 section = buf;
13288 }
13289
715bdd29
RH
13290 named_section_flags (section, SECTION_WRITE);
13291 assemble_align (POINTER_SIZE);
d9f6800d
RH
13292
13293 if (TARGET_RELOCATABLE)
13294 {
13295 fputs ("\t.long (", asm_out_file);
13296 output_addr_const (asm_out_file, symbol);
13297 fputs (")@fixup\n", asm_out_file);
13298 }
13299 else
c8af3574 13300 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 13301}
7c262518
RH
13302#endif
13303
cbaaba19 13304#if TARGET_XCOFF
7c262518 13305static void
b275d088
DE
13306rs6000_xcoff_asm_globalize_label (stream, name)
13307 FILE *stream;
13308 const char *name;
13309{
13310 fputs (GLOBAL_ASM_OP, stream);
13311 RS6000_OUTPUT_BASENAME (stream, name);
13312 putc ('\n', stream);
13313}
13314
13315static void
13316rs6000_xcoff_asm_named_section (name, flags)
7c262518 13317 const char *name;
0e5dbd9b 13318 unsigned int flags;
7c262518 13319{
0e5dbd9b
DE
13320 int smclass;
13321 static const char * const suffix[3] = { "PR", "RO", "RW" };
13322
13323 if (flags & SECTION_CODE)
13324 smclass = 0;
13325 else if (flags & SECTION_WRITE)
13326 smclass = 2;
13327 else
13328 smclass = 1;
13329
5b5198f7 13330 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 13331 (flags & SECTION_CODE) ? "." : "",
5b5198f7 13332 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 13333}
ae46c4e0
RH
13334
13335static void
0e5dbd9b
DE
13336rs6000_xcoff_select_section (decl, reloc, align)
13337 tree decl;
ae46c4e0
RH
13338 int reloc;
13339 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13340{
5add3202 13341 if (decl_readonly_section_1 (decl, reloc, 1))
ae46c4e0 13342 {
0e5dbd9b 13343 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13344 read_only_data_section ();
13345 else
13346 read_only_private_data_section ();
13347 }
13348 else
13349 {
0e5dbd9b 13350 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13351 data_section ();
13352 else
13353 private_data_section ();
13354 }
13355}
13356
13357static void
13358rs6000_xcoff_unique_section (decl, reloc)
13359 tree decl;
772c5265 13360 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13361{
13362 const char *name;
ae46c4e0 13363
5b5198f7
DE
13364 /* Use select_section for private and uninitialized data. */
13365 if (!TREE_PUBLIC (decl)
13366 || DECL_COMMON (decl)
0e5dbd9b
DE
13367 || DECL_INITIAL (decl) == NULL_TREE
13368 || DECL_INITIAL (decl) == error_mark_node
13369 || (flag_zero_initialized_in_bss
13370 && initializer_zerop (DECL_INITIAL (decl))))
13371 return;
13372
13373 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13374 name = (*targetm.strip_name_encoding) (name);
13375 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 13376}
b64a1b53 13377
fb49053f
RH
13378/* Select section for constant in constant pool.
13379
13380 On RS/6000, all constants are in the private read-only data area.
13381 However, if this is being placed in the TOC it must be output as a
13382 toc entry. */
13383
b64a1b53
RH
13384static void
13385rs6000_xcoff_select_rtx_section (mode, x, align)
13386 enum machine_mode mode;
13387 rtx x;
13388 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13389{
13390 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13391 toc_section ();
13392 else
13393 read_only_private_data_section ();
13394}
772c5265
RH
13395
13396/* Remove any trailing [DS] or the like from the symbol name. */
13397
13398static const char *
13399rs6000_xcoff_strip_name_encoding (name)
13400 const char *name;
13401{
13402 size_t len;
13403 if (*name == '*')
13404 name++;
13405 len = strlen (name);
13406 if (name[len - 1] == ']')
13407 return ggc_alloc_string (name, len - 4);
13408 else
13409 return name;
13410}
13411
5add3202
DE
13412/* Section attributes. AIX is always PIC. */
13413
13414static unsigned int
13415rs6000_xcoff_section_type_flags (decl, name, reloc)
13416 tree decl;
13417 const char *name;
13418 int reloc;
13419{
5b5198f7
DE
13420 unsigned int align;
13421 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
13422
13423 /* Align to at least UNIT size. */
13424 if (flags & SECTION_CODE)
13425 align = MIN_UNITS_PER_WORD;
13426 else
13427 /* Increase alignment of large objects if not already stricter. */
13428 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
13429 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
13430 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
13431
13432 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202
DE
13433}
13434
cbaaba19 13435#endif /* TARGET_XCOFF */
fb49053f 13436
0e5dbd9b 13437/* Note that this is also used for PPC64 Linux. */
fb49053f
RH
13438
13439static void
13440rs6000_xcoff_encode_section_info (decl, first)
13441 tree decl;
13442 int first ATTRIBUTE_UNUSED;
13443{
13444 if (TREE_CODE (decl) == FUNCTION_DECL
b629ba0c 13445 && (*targetm.binds_local_p) (decl))
fb49053f
RH
13446 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13447}
0e5dbd9b
DE
13448
13449/* Cross-module name binding. For AIX and PPC64 Linux, which always are
7f3d8013
DJ
13450 PIC, use private copy of flag_pic. Darwin does not support overriding
13451 functions at dynamic-link time. */
0e5dbd9b 13452
2bcc50d0 13453static bool
0e5dbd9b
DE
13454rs6000_binds_local_p (decl)
13455 tree decl;
13456{
7f3d8013
DJ
13457 return default_binds_local_p_1 (decl,
13458 DEFAULT_ABI == ABI_DARWIN ? 0 : flag_pic || rs6000_flag_pic);
0e5dbd9b 13459}
34bb030a 13460
3c50106f
RH
13461/* Compute a (partial) cost for rtx X. Return true if the complete
13462 cost has been computed, and false if subexpressions should be
13463 scanned. In either case, *TOTAL contains the cost result. */
13464
13465static bool
13466rs6000_rtx_costs (x, code, outer_code, total)
13467 rtx x;
13468 int code, outer_code ATTRIBUTE_UNUSED;
13469 int *total;
13470{
13471 switch (code)
13472 {
13473 /* On the RS/6000, if it is valid in the insn, it is free.
13474 So this always returns 0. */
13475 case CONST_INT:
13476 case CONST:
13477 case LABEL_REF:
13478 case SYMBOL_REF:
13479 case CONST_DOUBLE:
13480 case HIGH:
13481 *total = 0;
13482 return true;
13483
13484 case PLUS:
13485 *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
13486 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1))
13487 + 0x8000) >= 0x10000)
13488 && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
13489 ? COSTS_N_INSNS (2)
13490 : COSTS_N_INSNS (1));
13491 return true;
13492
13493 case AND:
13494 case IOR:
13495 case XOR:
13496 *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
13497 && (INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0
13498 && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
13499 ? COSTS_N_INSNS (2)
13500 : COSTS_N_INSNS (1));
13501 return true;
13502
13503 case MULT:
13504 if (optimize_size)
13505 {
13506 *total = COSTS_N_INSNS (2);
13507 return true;
13508 }
13509 switch (rs6000_cpu)
13510 {
13511 case PROCESSOR_RIOS1:
13512 case PROCESSOR_PPC405:
13513 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13514 ? COSTS_N_INSNS (5)
13515 : (INTVAL (XEXP (x, 1)) >= -256
13516 && INTVAL (XEXP (x, 1)) <= 255)
13517 ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
13518 return true;
13519
13520 case PROCESSOR_RS64A:
13521 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13522 ? GET_MODE (XEXP (x, 1)) != DImode
13523 ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34)
13524 : (INTVAL (XEXP (x, 1)) >= -256
13525 && INTVAL (XEXP (x, 1)) <= 255)
13526 ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12));
13527 return true;
13528
13529 case PROCESSOR_RIOS2:
13530 case PROCESSOR_MPCCORE:
13531 case PROCESSOR_PPC604e:
13532 *total = COSTS_N_INSNS (2);
13533 return true;
13534
13535 case PROCESSOR_PPC601:
13536 *total = COSTS_N_INSNS (5);
13537 return true;
13538
13539 case PROCESSOR_PPC603:
13540 case PROCESSOR_PPC7400:
13541 case PROCESSOR_PPC750:
13542 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13543 ? COSTS_N_INSNS (5)
13544 : (INTVAL (XEXP (x, 1)) >= -256
13545 && INTVAL (XEXP (x, 1)) <= 255)
13546 ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3));
13547 return true;
13548
13549 case PROCESSOR_PPC7450:
13550 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13551 ? COSTS_N_INSNS (4)
13552 : COSTS_N_INSNS (3));
13553 return true;
13554
13555 case PROCESSOR_PPC403:
13556 case PROCESSOR_PPC604:
13557 case PROCESSOR_PPC8540:
13558 *total = COSTS_N_INSNS (4);
13559 return true;
13560
13561 case PROCESSOR_PPC620:
13562 case PROCESSOR_PPC630:
13563 case PROCESSOR_POWER4:
13564 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13565 ? GET_MODE (XEXP (x, 1)) != DImode
13566 ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7)
13567 : (INTVAL (XEXP (x, 1)) >= -256
13568 && INTVAL (XEXP (x, 1)) <= 255)
13569 ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
13570 return true;
13571
13572 default:
13573 abort ();
13574 }
13575
13576 case DIV:
13577 case MOD:
13578 if (GET_CODE (XEXP (x, 1)) == CONST_INT
13579 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
13580 {
13581 *total = COSTS_N_INSNS (2);
13582 return true;
13583 }
13584 /* FALLTHRU */
13585
13586 case UDIV:
13587 case UMOD:
13588 switch (rs6000_cpu)
13589 {
13590 case PROCESSOR_RIOS1:
13591 *total = COSTS_N_INSNS (19);
13592 return true;
13593
13594 case PROCESSOR_RIOS2:
13595 *total = COSTS_N_INSNS (13);
13596 return true;
13597
13598 case PROCESSOR_RS64A:
13599 *total = (GET_MODE (XEXP (x, 1)) != DImode
13600 ? COSTS_N_INSNS (65)
13601 : COSTS_N_INSNS (67));
13602 return true;
13603
13604 case PROCESSOR_MPCCORE:
13605 *total = COSTS_N_INSNS (6);
13606 return true;
13607
13608 case PROCESSOR_PPC403:
13609 *total = COSTS_N_INSNS (33);
13610 return true;
13611
13612 case PROCESSOR_PPC405:
13613 *total = COSTS_N_INSNS (35);
13614 return true;
13615
13616 case PROCESSOR_PPC601:
13617 *total = COSTS_N_INSNS (36);
13618 return true;
13619
13620 case PROCESSOR_PPC603:
13621 *total = COSTS_N_INSNS (37);
13622 return true;
13623
13624 case PROCESSOR_PPC604:
13625 case PROCESSOR_PPC604e:
13626 *total = COSTS_N_INSNS (20);
13627 return true;
13628
13629 case PROCESSOR_PPC620:
13630 case PROCESSOR_PPC630:
13631 case PROCESSOR_POWER4:
13632 *total = (GET_MODE (XEXP (x, 1)) != DImode
13633 ? COSTS_N_INSNS (21)
13634 : COSTS_N_INSNS (37));
13635 return true;
13636
13637 case PROCESSOR_PPC750:
13638 case PROCESSOR_PPC8540:
13639 case PROCESSOR_PPC7400:
13640 *total = COSTS_N_INSNS (19);
13641 return true;
13642
13643 case PROCESSOR_PPC7450:
13644 *total = COSTS_N_INSNS (23);
13645 return true;
13646
13647 default:
13648 abort ();
13649 }
13650
13651 case FFS:
13652 *total = COSTS_N_INSNS (4);
13653 return true;
13654
13655 case MEM:
13656 /* MEM should be slightly more expensive than (plus (reg) (const)) */
13657 *total = 5;
13658 return true;
13659
13660 default:
13661 return false;
13662 }
13663}
13664
34bb030a
DE
13665/* A C expression returning the cost of moving data from a register of class
13666 CLASS1 to one of CLASS2. */
13667
13668int
13669rs6000_register_move_cost (mode, from, to)
13670 enum machine_mode mode;
13671 enum reg_class from, to;
13672{
13673 /* Moves from/to GENERAL_REGS. */
13674 if (reg_classes_intersect_p (to, GENERAL_REGS)
13675 || reg_classes_intersect_p (from, GENERAL_REGS))
13676 {
13677 if (! reg_classes_intersect_p (to, GENERAL_REGS))
13678 from = to;
13679
13680 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
13681 return (rs6000_memory_move_cost (mode, from, 0)
13682 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
13683
13684/* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
13685 else if (from == CR_REGS)
13686 return 4;
13687
13688 else
13689/* A move will cost one instruction per GPR moved. */
13690 return 2 * HARD_REGNO_NREGS (0, mode);
13691 }
13692
13693/* Moving between two similar registers is just one instruction. */
13694 else if (reg_classes_intersect_p (to, from))
13695 return mode == TFmode ? 4 : 2;
13696
13697/* Everything else has to go through GENERAL_REGS. */
13698 else
13699 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
13700 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
13701}
13702
13703/* A C expressions returning the cost of moving data of MODE from a register to
13704 or from memory. */
13705
13706int
13707rs6000_memory_move_cost (mode, class, in)
13708 enum machine_mode mode;
13709 enum reg_class class;
13710 int in ATTRIBUTE_UNUSED;
13711{
13712 if (reg_classes_intersect_p (class, GENERAL_REGS))
13713 return 4 * HARD_REGNO_NREGS (0, mode);
13714 else if (reg_classes_intersect_p (class, FLOAT_REGS))
13715 return 4 * HARD_REGNO_NREGS (32, mode);
13716 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
13717 return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO, mode);
13718 else
13719 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
13720}
13721
62e1dfcf
NC
13722/* Return true if TYPE is of type __ev64_opaque__. */
13723
c8e4f0e9 13724static bool
62e1dfcf
NC
13725is_ev64_opaque_type (type)
13726 tree type;
13727{
c8e4f0e9
AH
13728 return (TARGET_SPE
13729 && TREE_CODE (type) == VECTOR_TYPE
13730 && TYPE_NAME (type)
62e1dfcf
NC
13731 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
13732 && DECL_NAME (TYPE_NAME (type))
13733 && strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
13734 "__ev64_opaque__") == 0);
13735}
13736
96714395
AH
13737static rtx
13738rs6000_dwarf_register_span (reg)
13739 rtx reg;
13740{
13741 unsigned regno;
13742
13743 if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
13744 return NULL_RTX;
13745
13746 regno = REGNO (reg);
13747
13748 /* The duality of the SPE register size wreaks all kinds of havoc.
13749 This is a way of distinguishing r0 in 32-bits from r0 in
13750 64-bits. */
13751 return
13752 gen_rtx_PARALLEL (VOIDmode,
13753 gen_rtvec (2,
13754 gen_rtx_REG (SImode, regno),
13755 /* Who, where, what? 1200? This
13756 will get changed to a sane value
13757 when the SPE ABI finalizes. */
13758 gen_rtx_REG (SImode, regno + 1200)));
13759}
13760
17211ab5 13761#include "gt-rs6000.h"