]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/rs6000/rs6000.c
* gcse.c (replace_store_insn): Use single_set.
[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
d744e06e
AH
58#define EASY_VECTOR_15(n, x, y) ((n) >= -16 && (n) <= 15 \
59 && easy_vector_same (x, y))
60
61#define EASY_VECTOR_15_ADD_SELF(n, x, y) ((n) >= 0x10 && (n) <= 0x1e \
62 && !((n) & 1) \
63 && easy_vector_same (x, y))
64
9878760c
RK
65#define min(A,B) ((A) < (B) ? (A) : (B))
66#define max(A,B) ((A) > (B) ? (A) : (B))
67
5248c961
RK
68/* Target cpu type */
69
70enum processor_type rs6000_cpu;
8e3f41e7
MM
71struct rs6000_cpu_select rs6000_select[3] =
72{
815cdc52
MM
73 /* switch name, tune arch */
74 { (const char *)0, "--with-cpu=", 1, 1 },
75 { (const char *)0, "-mcpu=", 1, 1 },
76 { (const char *)0, "-mtune=", 1, 0 },
8e3f41e7 77};
5248c961 78
6fa3f289
ZW
79/* Size of long double */
80const char *rs6000_long_double_size_string;
81int rs6000_long_double_type_size;
82
83/* Whether -mabi=altivec has appeared */
84int rs6000_altivec_abi;
85
08b57fb3
AH
86/* Whether VRSAVE instructions should be generated. */
87int rs6000_altivec_vrsave;
88
89/* String from -mvrsave= option. */
90const char *rs6000_altivec_vrsave_string;
91
a3170dc6
AH
92/* Nonzero if we want SPE ABI extensions. */
93int rs6000_spe_abi;
94
95/* Whether isel instructions should be generated. */
96int rs6000_isel;
97
993f19a8
AH
98/* Whether SPE simd instructions should be generated. */
99int rs6000_spe;
100
5da702b1
AH
101/* Nonzero if floating point operations are done in the GPRs. */
102int rs6000_float_gprs = 0;
103
104/* String from -mfloat-gprs=. */
105const char *rs6000_float_gprs_string;
a3170dc6
AH
106
107/* String from -misel=. */
108const char *rs6000_isel_string;
109
993f19a8
AH
110/* String from -mspe=. */
111const char *rs6000_spe_string;
112
a0ab749a 113/* Set to nonzero once AIX common-mode calls have been defined. */
bbfb86aa 114static GTY(()) int common_mode_defined;
c81bebd7 115
9878760c
RK
116/* Save information from a "cmpxx" operation until the branch or scc is
117 emitted. */
9878760c
RK
118rtx rs6000_compare_op0, rs6000_compare_op1;
119int rs6000_compare_fp_p;
874a0744 120
874a0744
MM
121/* Label number of label created for -mrelocatable, to call to so we can
122 get the address of the GOT section */
123int rs6000_pic_labelno;
c81bebd7 124
b91da81f 125#ifdef USING_ELFOS_H
c81bebd7 126/* Which abi to adhere to */
815cdc52 127const char *rs6000_abi_name = RS6000_ABI_NAME;
d9407988
MM
128
129/* Semantics of the small data area */
130enum rs6000_sdata_type rs6000_sdata = SDATA_DATA;
131
132/* Which small data model to use */
815cdc52 133const char *rs6000_sdata_name = (char *)0;
9ebbca7d
GK
134
135/* Counter for labels which are to be placed in .fixup. */
136int fixuplabelno = 0;
874a0744 137#endif
4697a36c 138
b6c9286a
MM
139/* ABI enumeration available for subtarget to use. */
140enum rs6000_abi rs6000_current_abi;
141
0ac081f6
AH
142/* ABI string from -mabi= option. */
143const char *rs6000_abi_string;
144
38c1f2d7 145/* Debug flags */
815cdc52 146const char *rs6000_debug_name;
38c1f2d7
MM
147int rs6000_debug_stack; /* debug stack applications */
148int rs6000_debug_arg; /* debug argument handling */
149
57ac7be9
AM
150const char *rs6000_traceback_name;
151static enum {
152 traceback_default = 0,
153 traceback_none,
154 traceback_part,
155 traceback_full
156} rs6000_traceback;
157
38c1f2d7
MM
158/* Flag to say the TOC is initialized */
159int toc_initialized;
9ebbca7d 160char toc_label_name[10];
38c1f2d7 161
9ebbca7d
GK
162/* Alias set for saves and restores from the rs6000 stack. */
163static int rs6000_sr_alias_set;
c8023011 164
a5c76ee6
ZW
165/* Call distance, overridden by -mlongcall and #pragma longcall(1).
166 The only place that looks at this is rs6000_set_default_type_attributes;
167 everywhere else should rely on the presence or absence of a longcall
168 attribute on the function declaration. */
169int rs6000_default_long_calls;
170const char *rs6000_longcall_switch;
171
a3170dc6
AH
172struct builtin_description
173{
174 /* mask is not const because we're going to alter it below. This
175 nonsense will go away when we rewrite the -march infrastructure
176 to give us more target flag bits. */
177 unsigned int mask;
178 const enum insn_code icode;
179 const char *const name;
180 const enum rs6000_builtins code;
181};
182
4977bab6 183static bool rs6000_function_ok_for_sibcall PARAMS ((tree, tree));
9ebbca7d 184static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
39a10a29
GK
185static void validate_condition_mode
186 PARAMS ((enum rtx_code, enum machine_mode));
187static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
e50f5f3d 188static void rs6000_maybe_dead PARAMS ((rtx));
9ebbca7d
GK
189static void rs6000_emit_stack_tie PARAMS ((void));
190static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
c19de7aa
AH
191static rtx spe_synthesize_frame_save PARAMS ((rtx));
192static bool spe_func_has_64bit_regs_p PARAMS ((void));
89e7058f
AH
193static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
194 unsigned int, int, int));
a3170dc6 195static rtx gen_frame_mem_offset PARAMS ((enum machine_mode, rtx, int));
9ebbca7d
GK
196static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
197static unsigned rs6000_hash_constant PARAMS ((rtx));
198static unsigned toc_hash_function PARAMS ((const void *));
199static int toc_hash_eq PARAMS ((const void *, const void *));
9ebbca7d 200static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
e2500fed 201static struct machine_function * rs6000_init_machine_status PARAMS ((void));
301d03af 202static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
5add3202 203#ifdef HAVE_GAS_HIDDEN
25fdb4dc 204static void rs6000_assemble_visibility PARAMS ((tree, int));
5add3202 205#endif
71f123ca 206static int rs6000_ra_ever_killed PARAMS ((void));
91d231cb
JM
207static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
208const struct attribute_spec rs6000_attribute_table[];
a5c76ee6 209static void rs6000_set_default_type_attributes PARAMS ((tree));
08c148a8
NB
210static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
211static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
3961e8fe
RH
212static void rs6000_output_mi_thunk PARAMS ((FILE *, tree, HOST_WIDE_INT,
213 HOST_WIDE_INT, tree));
2bfcf297
DB
214static rtx rs6000_emit_set_long_const PARAMS ((rtx,
215 HOST_WIDE_INT, HOST_WIDE_INT));
7c262518
RH
216#if TARGET_ELF
217static unsigned int rs6000_elf_section_type_flags PARAMS ((tree, const char *,
218 int));
d9f6800d
RH
219static void rs6000_elf_asm_out_constructor PARAMS ((rtx, int));
220static void rs6000_elf_asm_out_destructor PARAMS ((rtx, int));
ae46c4e0 221static void rs6000_elf_select_section PARAMS ((tree, int,
5b71a4e7 222 unsigned HOST_WIDE_INT));
ae46c4e0 223static void rs6000_elf_unique_section PARAMS ((tree, int));
b64a1b53
RH
224static void rs6000_elf_select_rtx_section PARAMS ((enum machine_mode, rtx,
225 unsigned HOST_WIDE_INT));
0e5dbd9b
DE
226static void rs6000_elf_encode_section_info PARAMS ((tree, int))
227 ATTRIBUTE_UNUSED;
772c5265 228static const char *rs6000_elf_strip_name_encoding PARAMS ((const char *));
0e5dbd9b 229static bool rs6000_elf_in_small_data_p PARAMS ((tree));
7c262518 230#endif
cbaaba19 231#if TARGET_XCOFF
b275d088
DE
232static void rs6000_xcoff_asm_globalize_label PARAMS ((FILE *, const char *));
233static void rs6000_xcoff_asm_named_section PARAMS ((const char *, unsigned int));
ae46c4e0
RH
234static void rs6000_xcoff_select_section PARAMS ((tree, int,
235 unsigned HOST_WIDE_INT));
236static void rs6000_xcoff_unique_section PARAMS ((tree, int));
b64a1b53
RH
237static void rs6000_xcoff_select_rtx_section PARAMS ((enum machine_mode, rtx,
238 unsigned HOST_WIDE_INT));
772c5265 239static const char * rs6000_xcoff_strip_name_encoding PARAMS ((const char *));
5add3202 240static unsigned int rs6000_xcoff_section_type_flags PARAMS ((tree, const char *, int));
fb49053f
RH
241static void rs6000_xcoff_encode_section_info PARAMS ((tree, int))
242 ATTRIBUTE_UNUSED;
f1384257
AM
243#endif
244#if TARGET_MACHO
2bcc50d0 245static bool rs6000_binds_local_p PARAMS ((tree));
f1384257 246#endif
b54cf83a 247static int rs6000_use_dfa_pipeline_interface PARAMS ((void));
b54cf83a 248static int rs6000_variable_issue PARAMS ((FILE *, int, rtx, int));
3c50106f 249static bool rs6000_rtx_costs PARAMS ((rtx, int, int, int *));
c237e94a
ZW
250static int rs6000_adjust_cost PARAMS ((rtx, rtx, rtx, int));
251static int rs6000_adjust_priority PARAMS ((rtx, int));
252static int rs6000_issue_rate PARAMS ((void));
be12c2b0 253static int rs6000_use_sched_lookahead PARAMS ((void));
c237e94a 254
6fa3f289 255static void rs6000_init_builtins PARAMS ((void));
92898235
AH
256static rtx rs6000_expand_unop_builtin PARAMS ((enum insn_code, tree, rtx));
257static rtx rs6000_expand_binop_builtin PARAMS ((enum insn_code, tree, rtx));
258static rtx rs6000_expand_ternop_builtin PARAMS ((enum insn_code, tree, rtx));
0ac081f6 259static rtx rs6000_expand_builtin PARAMS ((tree, rtx, rtx, enum machine_mode, int));
92898235 260static void altivec_init_builtins PARAMS ((void));
a3170dc6
AH
261static void rs6000_common_init_builtins PARAMS ((void));
262
263static void enable_mask_for_builtins PARAMS ((struct builtin_description *,
264 int, enum rs6000_builtins,
265 enum rs6000_builtins));
266static void spe_init_builtins PARAMS ((void));
267static rtx spe_expand_builtin PARAMS ((tree, rtx, bool *));
268static rtx spe_expand_predicate_builtin PARAMS ((enum insn_code, tree, rtx));
269static rtx spe_expand_evsel_builtin PARAMS ((enum insn_code, tree, rtx));
270static int rs6000_emit_int_cmove PARAMS ((rtx, rtx, rtx, rtx));
271
92898235 272static rtx altivec_expand_builtin PARAMS ((tree, rtx, bool *));
3a9b8c7e
AH
273static rtx altivec_expand_ld_builtin PARAMS ((tree, rtx, bool *));
274static rtx altivec_expand_st_builtin PARAMS ((tree, rtx, bool *));
275static rtx altivec_expand_dst_builtin PARAMS ((tree, rtx, bool *));
100c4561 276static rtx altivec_expand_abs_builtin PARAMS ((enum insn_code, tree, rtx));
ae4b4a02 277static rtx altivec_expand_predicate_builtin PARAMS ((enum insn_code, const char *, tree, rtx));
6525c0e7 278static rtx altivec_expand_stv_builtin PARAMS ((enum insn_code, tree));
0ac081f6 279static void rs6000_parse_abi_options PARAMS ((void));
5da702b1 280static void rs6000_parse_yes_no_option (const char *, const char *, int *);
00b960c7
AH
281static int first_altivec_reg_to_save PARAMS ((void));
282static unsigned int compute_vrsave_mask PARAMS ((void));
283static void is_altivec_return_reg PARAMS ((rtx, void *));
9aa86737 284static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
d744e06e
AH
285int easy_vector_constant PARAMS ((rtx, enum machine_mode));
286static int easy_vector_same PARAMS ((rtx, enum machine_mode));
c8e4f0e9 287static bool is_ev64_opaque_type PARAMS ((tree));
96714395 288static rtx rs6000_dwarf_register_span PARAMS ((rtx));
17211ab5
GK
289
290/* Hash table stuff for keeping track of TOC entries. */
291
292struct toc_hash_struct GTY(())
293{
294 /* `key' will satisfy CONSTANT_P; in fact, it will satisfy
295 ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
296 rtx key;
297 enum machine_mode key_mode;
298 int labelno;
299};
300
301static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
c81bebd7
MM
302\f
303/* Default register names. */
304char rs6000_reg_names[][8] =
305{
802a0058
MM
306 "0", "1", "2", "3", "4", "5", "6", "7",
307 "8", "9", "10", "11", "12", "13", "14", "15",
308 "16", "17", "18", "19", "20", "21", "22", "23",
309 "24", "25", "26", "27", "28", "29", "30", "31",
310 "0", "1", "2", "3", "4", "5", "6", "7",
311 "8", "9", "10", "11", "12", "13", "14", "15",
312 "16", "17", "18", "19", "20", "21", "22", "23",
313 "24", "25", "26", "27", "28", "29", "30", "31",
314 "mq", "lr", "ctr","ap",
315 "0", "1", "2", "3", "4", "5", "6", "7",
0ac081f6
AH
316 "xer",
317 /* AltiVec registers. */
0cd5e3a1
AH
318 "0", "1", "2", "3", "4", "5", "6", "7",
319 "8", "9", "10", "11", "12", "13", "14", "15",
320 "16", "17", "18", "19", "20", "21", "22", "23",
321 "24", "25", "26", "27", "28", "29", "30", "31",
59a4c851
AH
322 "vrsave", "vscr",
323 /* SPE registers. */
324 "spe_acc", "spefscr"
c81bebd7
MM
325};
326
327#ifdef TARGET_REGNAMES
8b60264b 328static const char alt_reg_names[][8] =
c81bebd7 329{
802a0058
MM
330 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
331 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
332 "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23",
333 "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31",
334 "%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7",
335 "%f8", "%f9", "%f10", "%f11", "%f12", "%f13", "%f14", "%f15",
336 "%f16", "%f17", "%f18", "%f19", "%f20", "%f21", "%f22", "%f23",
337 "%f24", "%f25", "%f26", "%f27", "%f28", "%f29", "%f30", "%f31",
338 "mq", "lr", "ctr", "ap",
339 "%cr0", "%cr1", "%cr2", "%cr3", "%cr4", "%cr5", "%cr6", "%cr7",
0ac081f6 340 "xer",
59a4c851 341 /* AltiVec registers. */
0ac081f6 342 "%v0", "%v1", "%v2", "%v3", "%v4", "%v5", "%v6", "%v7",
59a4c851
AH
343 "%v8", "%v9", "%v10", "%v11", "%v12", "%v13", "%v14", "%v15",
344 "%v16", "%v17", "%v18", "%v19", "%v20", "%v21", "%v22", "%v23",
345 "%v24", "%v25", "%v26", "%v27", "%v28", "%v29", "%v30", "%v31",
346 "vrsave", "vscr",
347 /* SPE registers. */
348 "spe_acc", "spefscr"
c81bebd7
MM
349};
350#endif
9878760c 351\f
daf11973
MM
352#ifndef MASK_STRICT_ALIGN
353#define MASK_STRICT_ALIGN 0
354#endif
ffcfcb5f
AM
355#ifndef TARGET_PROFILE_KERNEL
356#define TARGET_PROFILE_KERNEL 0
357#endif
3961e8fe
RH
358
359/* The VRSAVE bitmask puts bit %v0 as the most significant bit. */
360#define ALTIVEC_REG_BIT(REGNO) (0x80000000 >> ((REGNO) - FIRST_ALTIVEC_REGNO))
672a6f42
NB
361\f
362/* Initialize the GCC target structure. */
91d231cb
JM
363#undef TARGET_ATTRIBUTE_TABLE
364#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
a5c76ee6
ZW
365#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
366#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
daf11973 367
301d03af
RS
368#undef TARGET_ASM_ALIGNED_DI_OP
369#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
370
371/* Default unaligned ops are only provided for ELF. Find the ops needed
372 for non-ELF systems. */
373#ifndef OBJECT_FORMAT_ELF
cbaaba19 374#if TARGET_XCOFF
ae6c1efd 375/* For XCOFF. rs6000_assemble_integer will handle unaligned DIs on
301d03af
RS
376 64-bit targets. */
377#undef TARGET_ASM_UNALIGNED_HI_OP
378#define TARGET_ASM_UNALIGNED_HI_OP "\t.vbyte\t2,"
379#undef TARGET_ASM_UNALIGNED_SI_OP
380#define TARGET_ASM_UNALIGNED_SI_OP "\t.vbyte\t4,"
381#undef TARGET_ASM_UNALIGNED_DI_OP
382#define TARGET_ASM_UNALIGNED_DI_OP "\t.vbyte\t8,"
383#else
384/* For Darwin. */
385#undef TARGET_ASM_UNALIGNED_HI_OP
386#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
387#undef TARGET_ASM_UNALIGNED_SI_OP
388#define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
389#endif
390#endif
391
392/* This hook deals with fixups for relocatable code and DI-mode objects
393 in 64-bit code. */
394#undef TARGET_ASM_INTEGER
395#define TARGET_ASM_INTEGER rs6000_assemble_integer
396
93638d7a
AM
397#ifdef HAVE_GAS_HIDDEN
398#undef TARGET_ASM_ASSEMBLE_VISIBILITY
399#define TARGET_ASM_ASSEMBLE_VISIBILITY rs6000_assemble_visibility
400#endif
401
08c148a8
NB
402#undef TARGET_ASM_FUNCTION_PROLOGUE
403#define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
404#undef TARGET_ASM_FUNCTION_EPILOGUE
405#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
406
b54cf83a
DE
407#undef TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE
408#define TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE rs6000_use_dfa_pipeline_interface
b54cf83a
DE
409#undef TARGET_SCHED_VARIABLE_ISSUE
410#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
411
c237e94a
ZW
412#undef TARGET_SCHED_ISSUE_RATE
413#define TARGET_SCHED_ISSUE_RATE rs6000_issue_rate
414#undef TARGET_SCHED_ADJUST_COST
415#define TARGET_SCHED_ADJUST_COST rs6000_adjust_cost
416#undef TARGET_SCHED_ADJUST_PRIORITY
417#define TARGET_SCHED_ADJUST_PRIORITY rs6000_adjust_priority
418
be12c2b0
VM
419#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD
420#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD rs6000_use_sched_lookahead
421
0ac081f6
AH
422#undef TARGET_INIT_BUILTINS
423#define TARGET_INIT_BUILTINS rs6000_init_builtins
424
425#undef TARGET_EXPAND_BUILTIN
426#define TARGET_EXPAND_BUILTIN rs6000_expand_builtin
427
f1384257 428#if TARGET_MACHO
0e5dbd9b
DE
429#undef TARGET_BINDS_LOCAL_P
430#define TARGET_BINDS_LOCAL_P rs6000_binds_local_p
f1384257 431#endif
0e5dbd9b 432
3961e8fe
RH
433#undef TARGET_ASM_OUTPUT_MI_THUNK
434#define TARGET_ASM_OUTPUT_MI_THUNK rs6000_output_mi_thunk
435
3961e8fe 436#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
5b71a4e7 437#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
00b960c7 438
4977bab6
ZW
439#undef TARGET_FUNCTION_OK_FOR_SIBCALL
440#define TARGET_FUNCTION_OK_FOR_SIBCALL rs6000_function_ok_for_sibcall
441
3c50106f
RH
442#undef TARGET_RTX_COSTS
443#define TARGET_RTX_COSTS rs6000_rtx_costs
dcefdf67
RH
444#undef TARGET_ADDRESS_COST
445#define TARGET_ADDRESS_COST hook_int_rtx_0
3c50106f 446
c8e4f0e9
AH
447#undef TARGET_VECTOR_OPAQUE_P
448#define TARGET_VECTOR_OPAQUE_P is_ev64_opaque_type
62e1dfcf 449
96714395
AH
450#undef TARGET_DWARF_REGISTER_SPAN
451#define TARGET_DWARF_REGISTER_SPAN rs6000_dwarf_register_span
452
f6897b10 453struct gcc_target targetm = TARGET_INITIALIZER;
672a6f42 454\f
5248c961
RK
455/* Override command line options. Mostly we process the processor
456 type and sometimes adjust other TARGET_ options. */
457
458void
8e3f41e7 459rs6000_override_options (default_cpu)
d330fd93 460 const char *default_cpu;
5248c961 461{
c4d38ccb 462 size_t i, j;
8e3f41e7 463 struct rs6000_cpu_select *ptr;
5248c961 464
85638c0d
RK
465 /* Simplify the entries below by making a mask for any POWER
466 variant and any PowerPC variant. */
467
938937d8 468#define POWER_MASKS (MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING)
68c49ffa
RK
469#define POWERPC_MASKS (MASK_POWERPC | MASK_PPC_GPOPT \
470 | MASK_PPC_GFXOPT | MASK_POWERPC64)
471#define POWERPC_OPT_MASKS (MASK_PPC_GPOPT | MASK_PPC_GFXOPT)
85638c0d 472
5248c961
RK
473 static struct ptt
474 {
8b60264b
KG
475 const char *const name; /* Canonical processor name. */
476 const enum processor_type processor; /* Processor type enum value. */
477 const int target_enable; /* Target flags to enable. */
478 const int target_disable; /* Target flags to disable. */
479 } const processor_target_table[]
cf27b467
MM
480 = {{"common", PROCESSOR_COMMON, MASK_NEW_MNEMONICS,
481 POWER_MASKS | POWERPC_MASKS},
db7f1e43 482 {"power", PROCESSOR_POWER,
938937d8 483 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43 484 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
8e3f41e7
MM
485 {"power2", PROCESSOR_POWER,
486 MASK_POWER | MASK_POWER2 | MASK_MULTIPLE | MASK_STRING,
487 POWERPC_MASKS | MASK_NEW_MNEMONICS},
c71791e0
DE
488 {"power3", PROCESSOR_PPC630,
489 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
d7b53ca4 490 POWER_MASKS},
309323c2 491 {"power4", PROCESSOR_POWER4,
7f3d8013 492 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
a12f8290 493 POWER_MASKS},
db7f1e43
RK
494 {"powerpc", PROCESSOR_POWERPC,
495 MASK_POWERPC | MASK_NEW_MNEMONICS,
68c49ffa 496 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
3cb999d8
DE
497 {"powerpc64", PROCESSOR_POWERPC64,
498 MASK_POWERPC | MASK_POWERPC64 | MASK_NEW_MNEMONICS,
499 POWER_MASKS | POWERPC_OPT_MASKS},
db7f1e43 500 {"rios", PROCESSOR_RIOS1,
938937d8 501 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
502 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
503 {"rios1", PROCESSOR_RIOS1,
938937d8 504 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
505 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
506 {"rsc", PROCESSOR_PPC601,
938937d8 507 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
508 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
509 {"rsc1", PROCESSOR_PPC601,
938937d8 510 MASK_POWER | MASK_MULTIPLE | MASK_STRING,
db7f1e43
RK
511 MASK_POWER2 | POWERPC_MASKS | MASK_NEW_MNEMONICS},
512 {"rios2", PROCESSOR_RIOS2,
938937d8 513 MASK_POWER | MASK_MULTIPLE | MASK_STRING | MASK_POWER2,
db7f1e43 514 POWERPC_MASKS | MASK_NEW_MNEMONICS},
3cb999d8
DE
515 {"rs64a", PROCESSOR_RS64A,
516 MASK_POWERPC | MASK_NEW_MNEMONICS,
517 POWER_MASKS | POWERPC_OPT_MASKS},
a3a1dbf6
MM
518 {"401", PROCESSOR_PPC403,
519 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
520 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
49a0b204 521 {"403", PROCESSOR_PPC403,
daf11973 522 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN,
49a0b204 523 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
d7a5e253
DE
524 {"405", PROCESSOR_PPC405,
525 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
526 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
4977bab6
ZW
527 {"405f", PROCESSOR_PPC405,
528 MASK_POWERPC | MASK_NEW_MNEMONICS,
529 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
530 {"505", PROCESSOR_MPCCORE,
531 MASK_POWERPC | MASK_NEW_MNEMONICS,
532 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 533 {"601", PROCESSOR_PPC601,
938937d8 534 MASK_POWER | MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_MULTIPLE | MASK_STRING,
68c49ffa 535 MASK_POWER2 | POWERPC_OPT_MASKS | MASK_POWERPC64},
1ec26da6 536 {"602", PROCESSOR_PPC603,
cf27b467
MM
537 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
538 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
5248c961 539 {"603", PROCESSOR_PPC603,
68c49ffa
RK
540 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
541 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a
MM
542 {"603e", PROCESSOR_PPC603,
543 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
544 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b5370a88 545 {"ec603e", PROCESSOR_PPC603,
a3a1dbf6
MM
546 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
547 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
5248c961 548 {"604", PROCESSOR_PPC604,
b6c9286a
MM
549 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
550 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
cac8ce95 551 {"604e", PROCESSOR_PPC604e,
07e6159a
MM
552 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
553 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
b6c9286a 554 {"620", PROCESSOR_PPC620,
68c49ffa 555 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
d7b53ca4 556 POWER_MASKS},
3cb999d8
DE
557 {"630", PROCESSOR_PPC630,
558 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
d7b53ca4 559 POWER_MASKS},
bef84347
VM
560 {"740", PROCESSOR_PPC750,
561 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
562 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
563 {"750", PROCESSOR_PPC750,
564 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
565 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a4f6c312
SS
566 {"7400", PROCESSOR_PPC7400,
567 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
568 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
569 {"7450", PROCESSOR_PPC7450,
570 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
571 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
a3170dc6
AH
572 {"8540", PROCESSOR_PPC8540,
573 MASK_POWERPC | MASK_PPC_GFXOPT | MASK_NEW_MNEMONICS,
574 POWER_MASKS | MASK_PPC_GPOPT | MASK_POWERPC64},
07e6159a
MM
575 {"801", PROCESSOR_MPCCORE,
576 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
577 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
578 {"821", PROCESSOR_MPCCORE,
579 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
580 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
07e6159a
MM
581 {"823", PROCESSOR_MPCCORE,
582 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
583 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64},
cf27b467
MM
584 {"860", PROCESSOR_MPCCORE,
585 MASK_POWERPC | MASK_SOFT_FLOAT | MASK_NEW_MNEMONICS,
586 POWER_MASKS | POWERPC_OPT_MASKS | MASK_POWERPC64}};
5248c961 587
ca7558fc 588 const size_t ptt_size = ARRAY_SIZE (processor_target_table);
5248c961 589
a4f6c312
SS
590 /* Save current -mmultiple/-mno-multiple status. */
591 int multiple = TARGET_MULTIPLE;
592 /* Save current -mstring/-mno-string status. */
593 int string = TARGET_STRING;
8a61d227 594
a4f6c312 595 /* Identify the processor type. */
8e3f41e7 596 rs6000_select[0].string = default_cpu;
3cb999d8 597 rs6000_cpu = TARGET_POWERPC64 ? PROCESSOR_DEFAULT64 : PROCESSOR_DEFAULT;
8e3f41e7 598
b6a1cbae 599 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
5248c961 600 {
8e3f41e7
MM
601 ptr = &rs6000_select[i];
602 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
5248c961 603 {
8e3f41e7
MM
604 for (j = 0; j < ptt_size; j++)
605 if (! strcmp (ptr->string, processor_target_table[j].name))
606 {
607 if (ptr->set_tune_p)
608 rs6000_cpu = processor_target_table[j].processor;
609
610 if (ptr->set_arch_p)
611 {
612 target_flags |= processor_target_table[j].target_enable;
613 target_flags &= ~processor_target_table[j].target_disable;
614 }
615 break;
616 }
617
4406229e 618 if (j == ptt_size)
8e3f41e7 619 error ("bad value (%s) for %s switch", ptr->string, ptr->name);
5248c961
RK
620 }
621 }
8a61d227 622
993f19a8 623 if (TARGET_E500)
a3170dc6
AH
624 rs6000_isel = 1;
625
dff9f1b6
DE
626 /* If we are optimizing big endian systems for space, use the load/store
627 multiple and string instructions. */
ef792183 628 if (BYTES_BIG_ENDIAN && optimize_size)
dff9f1b6 629 target_flags |= MASK_MULTIPLE | MASK_STRING;
ef792183 630
8a61d227
MM
631 /* If -mmultiple or -mno-multiple was explicitly used, don't
632 override with the processor default */
b21fb038 633 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
8a61d227 634 target_flags = (target_flags & ~MASK_MULTIPLE) | multiple;
7e69e155 635
a4f6c312
SS
636 /* If -mstring or -mno-string was explicitly used, don't override
637 with the processor default. */
b21fb038 638 if ((target_flags_explicit & MASK_STRING) != 0)
1f5515bf 639 target_flags = (target_flags & ~MASK_STRING) | string;
938937d8 640
a4f6c312
SS
641 /* Don't allow -mmultiple or -mstring on little endian systems
642 unless the cpu is a 750, because the hardware doesn't support the
643 instructions used in little endian mode, and causes an alignment
644 trap. The 750 does not cause an alignment trap (except when the
645 target is unaligned). */
bef84347 646
b21fb038 647 if (!BYTES_BIG_ENDIAN && rs6000_cpu != PROCESSOR_PPC750)
7e69e155
MM
648 {
649 if (TARGET_MULTIPLE)
650 {
651 target_flags &= ~MASK_MULTIPLE;
b21fb038 652 if ((target_flags_explicit & MASK_MULTIPLE) != 0)
7e69e155
MM
653 warning ("-mmultiple is not supported on little endian systems");
654 }
655
656 if (TARGET_STRING)
657 {
658 target_flags &= ~MASK_STRING;
b21fb038 659 if ((target_flags_explicit & MASK_STRING) != 0)
938937d8 660 warning ("-mstring is not supported on little endian systems");
7e69e155
MM
661 }
662 }
3933e0e1 663
38c1f2d7
MM
664 /* Set debug flags */
665 if (rs6000_debug_name)
666 {
bfc79d3b 667 if (! strcmp (rs6000_debug_name, "all"))
38c1f2d7 668 rs6000_debug_stack = rs6000_debug_arg = 1;
bfc79d3b 669 else if (! strcmp (rs6000_debug_name, "stack"))
38c1f2d7 670 rs6000_debug_stack = 1;
bfc79d3b 671 else if (! strcmp (rs6000_debug_name, "arg"))
38c1f2d7
MM
672 rs6000_debug_arg = 1;
673 else
c725bd79 674 error ("unknown -mdebug-%s switch", rs6000_debug_name);
38c1f2d7
MM
675 }
676
57ac7be9
AM
677 if (rs6000_traceback_name)
678 {
679 if (! strncmp (rs6000_traceback_name, "full", 4))
680 rs6000_traceback = traceback_full;
681 else if (! strncmp (rs6000_traceback_name, "part", 4))
682 rs6000_traceback = traceback_part;
683 else if (! strncmp (rs6000_traceback_name, "no", 2))
684 rs6000_traceback = traceback_none;
685 else
686 error ("unknown -mtraceback arg `%s'; expecting `full', `partial' or `none'",
687 rs6000_traceback_name);
688 }
689
6fa3f289
ZW
690 /* Set size of long double */
691 rs6000_long_double_type_size = 64;
692 if (rs6000_long_double_size_string)
693 {
694 char *tail;
695 int size = strtol (rs6000_long_double_size_string, &tail, 10);
696 if (*tail != '\0' || (size != 64 && size != 128))
697 error ("Unknown switch -mlong-double-%s",
698 rs6000_long_double_size_string);
699 else
700 rs6000_long_double_type_size = size;
701 }
702
0ac081f6
AH
703 /* Handle -mabi= options. */
704 rs6000_parse_abi_options ();
705
5da702b1
AH
706 /* Handle generic -mFOO=YES/NO options. */
707 rs6000_parse_yes_no_option ("vrsave", rs6000_altivec_vrsave_string,
708 &rs6000_altivec_vrsave);
709 rs6000_parse_yes_no_option ("isel", rs6000_isel_string,
710 &rs6000_isel);
711 rs6000_parse_yes_no_option ("spe", rs6000_spe_string, &rs6000_spe);
712 rs6000_parse_yes_no_option ("float-gprs", rs6000_float_gprs_string,
713 &rs6000_float_gprs);
993f19a8 714
a7ae18e2
AH
715#ifdef SUBTARGET_OVERRIDE_OPTIONS
716 SUBTARGET_OVERRIDE_OPTIONS;
717#endif
718#ifdef SUBSUBTARGET_OVERRIDE_OPTIONS
719 SUBSUBTARGET_OVERRIDE_OPTIONS;
720#endif
721
5da702b1
AH
722 if (TARGET_E500)
723 {
724 /* The e500 does not have string instructions, and we set
725 MASK_STRING above when optimizing for size. */
726 if ((target_flags & MASK_STRING) != 0)
727 target_flags = target_flags & ~MASK_STRING;
728 }
729 else if (rs6000_select[1].string != NULL)
730 {
731 /* For the powerpc-eabispe configuration, we set all these by
732 default, so let's unset them if we manually set another
733 CPU that is not the E500. */
734 if (rs6000_abi_string == 0)
735 rs6000_spe_abi = 0;
736 if (rs6000_spe_string == 0)
737 rs6000_spe = 0;
738 if (rs6000_float_gprs_string == 0)
739 rs6000_float_gprs = 0;
740 if (rs6000_isel_string == 0)
741 rs6000_isel = 0;
742 }
b5044283 743
a5c76ee6
ZW
744 /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
745 using TARGET_OPTIONS to handle a toggle switch, but we're out of
746 bits in target_flags so TARGET_SWITCHES cannot be used.
747 Assumption here is that rs6000_longcall_switch points into the
748 text of the complete option, rather than being a copy, so we can
749 scan back for the presence or absence of the no- modifier. */
750 if (rs6000_longcall_switch)
751 {
752 const char *base = rs6000_longcall_switch;
753 while (base[-1] != 'm') base--;
754
755 if (*rs6000_longcall_switch != '\0')
756 error ("invalid option `%s'", base);
757 rs6000_default_long_calls = (base[0] != 'n');
758 }
759
c81bebd7 760#ifdef TARGET_REGNAMES
a4f6c312
SS
761 /* If the user desires alternate register names, copy in the
762 alternate names now. */
c81bebd7 763 if (TARGET_REGNAMES)
4e135bdd 764 memcpy (rs6000_reg_names, alt_reg_names, sizeof (rs6000_reg_names));
c81bebd7
MM
765#endif
766
6fa3f289
ZW
767 /* Set TARGET_AIX_STRUCT_RET last, after the ABI is determined.
768 If -maix-struct-return or -msvr4-struct-return was explicitly
769 used, don't override with the ABI default. */
b21fb038 770 if ((target_flags_explicit & MASK_AIX_STRUCT_RET) == 0)
6fa3f289
ZW
771 {
772 if (DEFAULT_ABI == ABI_V4 && !DRAFT_V4_STRUCT_RET)
773 target_flags = (target_flags & ~MASK_AIX_STRUCT_RET);
774 else
775 target_flags |= MASK_AIX_STRUCT_RET;
776 }
777
fcce224d
DE
778 if (TARGET_LONG_DOUBLE_128
779 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
780 real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
781
9ebbca7d
GK
782 /* Allocate an alias set for register saves & restores from stack. */
783 rs6000_sr_alias_set = new_alias_set ();
784
785 if (TARGET_TOC)
786 ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1);
71f123ca 787
301d03af
RS
788 /* We can only guarantee the availability of DI pseudo-ops when
789 assembling for 64-bit targets. */
ae6c1efd 790 if (!TARGET_64BIT)
301d03af
RS
791 {
792 targetm.asm_out.aligned_op.di = NULL;
793 targetm.asm_out.unaligned_op.di = NULL;
794 }
795
2792d578
DE
796 /* Set maximum branch target alignment at two instructions, eight bytes. */
797 align_jumps_max_skip = 8;
798 align_loops_max_skip = 8;
799
71f123ca
FS
800 /* Arrange to save and restore machine status around nested functions. */
801 init_machine_status = rs6000_init_machine_status;
5248c961 802}
5accd822 803
5da702b1
AH
804/* Handle generic options of the form -mfoo=yes/no.
805 NAME is the option name.
806 VALUE is the option value.
807 FLAG is the pointer to the flag where to store a 1 or 0, depending on
808 whether the option value is 'yes' or 'no' respectively. */
993f19a8 809static void
5da702b1 810rs6000_parse_yes_no_option (const char *name, const char *value, int *flag)
993f19a8 811{
5da702b1 812 if (value == 0)
993f19a8 813 return;
5da702b1
AH
814 else if (!strcmp (value, "yes"))
815 *flag = 1;
816 else if (!strcmp (value, "no"))
817 *flag = 0;
08b57fb3 818 else
5da702b1 819 error ("unknown -m%s= option specified: '%s'", name, value);
08b57fb3
AH
820}
821
0ac081f6 822/* Handle -mabi= options. */
00b960c7
AH
823static void
824rs6000_parse_abi_options ()
0ac081f6
AH
825{
826 if (rs6000_abi_string == 0)
827 return;
828 else if (! strcmp (rs6000_abi_string, "altivec"))
6fa3f289 829 rs6000_altivec_abi = 1;
76a773f3
AH
830 else if (! strcmp (rs6000_abi_string, "no-altivec"))
831 rs6000_altivec_abi = 0;
a3170dc6 832 else if (! strcmp (rs6000_abi_string, "spe"))
01f4962d
NS
833 {
834 rs6000_spe_abi = 1;
835 if (!TARGET_SPE_ABI)
836 error ("not configured for ABI: '%s'", rs6000_abi_string);
837 }
838
a3170dc6
AH
839 else if (! strcmp (rs6000_abi_string, "no-spe"))
840 rs6000_spe_abi = 0;
0ac081f6 841 else
c725bd79 842 error ("unknown ABI specified: '%s'", rs6000_abi_string);
0ac081f6
AH
843}
844
5accd822
DE
845void
846optimization_options (level, size)
e2c953b6 847 int level ATTRIBUTE_UNUSED;
5accd822
DE
848 int size ATTRIBUTE_UNUSED;
849{
5accd822 850}
3cfa4909
MM
851\f
852/* Do anything needed at the start of the asm file. */
853
854void
855rs6000_file_start (file, default_cpu)
856 FILE *file;
d330fd93 857 const char *default_cpu;
3cfa4909 858{
c4d38ccb 859 size_t i;
3cfa4909 860 char buffer[80];
d330fd93 861 const char *start = buffer;
3cfa4909
MM
862 struct rs6000_cpu_select *ptr;
863
864 if (flag_verbose_asm)
865 {
866 sprintf (buffer, "\n%s rs6000/powerpc options:", ASM_COMMENT_START);
867 rs6000_select[0].string = default_cpu;
868
b6a1cbae 869 for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
3cfa4909
MM
870 {
871 ptr = &rs6000_select[i];
872 if (ptr->string != (char *)0 && ptr->string[0] != '\0')
873 {
874 fprintf (file, "%s %s%s", start, ptr->name, ptr->string);
875 start = "";
876 }
877 }
878
b91da81f 879#ifdef USING_ELFOS_H
3cfa4909
MM
880 switch (rs6000_sdata)
881 {
882 case SDATA_NONE: fprintf (file, "%s -msdata=none", start); start = ""; break;
883 case SDATA_DATA: fprintf (file, "%s -msdata=data", start); start = ""; break;
884 case SDATA_SYSV: fprintf (file, "%s -msdata=sysv", start); start = ""; break;
885 case SDATA_EABI: fprintf (file, "%s -msdata=eabi", start); start = ""; break;
886 }
887
888 if (rs6000_sdata && g_switch_value)
889 {
890 fprintf (file, "%s -G %d", start, g_switch_value);
891 start = "";
892 }
893#endif
894
895 if (*start == '\0')
949ea356 896 putc ('\n', file);
3cfa4909
MM
897 }
898}
5248c961 899\f
a0ab749a 900/* Return nonzero if this function is known to have a null epilogue. */
9878760c
RK
901
902int
903direct_return ()
904{
4697a36c
MM
905 if (reload_completed)
906 {
907 rs6000_stack_t *info = rs6000_stack_info ();
908
909 if (info->first_gp_reg_save == 32
910 && info->first_fp_reg_save == 64
00b960c7 911 && info->first_altivec_reg_save == LAST_ALTIVEC_REGNO + 1
c81fc13e
DE
912 && ! info->lr_save_p
913 && ! info->cr_save_p
00b960c7 914 && info->vrsave_mask == 0
c81fc13e 915 && ! info->push_p)
4697a36c
MM
916 return 1;
917 }
918
919 return 0;
9878760c
RK
920}
921
922/* Returns 1 always. */
923
924int
925any_operand (op, mode)
592696dd 926 rtx op ATTRIBUTE_UNUSED;
296b8152 927 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
928{
929 return 1;
930}
931
a4f6c312 932/* Returns 1 if op is the count register. */
38c1f2d7 933int
a4f6c312 934count_register_operand (op, mode)
592696dd 935 rtx op;
296b8152 936 enum machine_mode mode ATTRIBUTE_UNUSED;
b6c9286a
MM
937{
938 if (GET_CODE (op) != REG)
939 return 0;
940
941 if (REGNO (op) == COUNT_REGISTER_REGNUM)
942 return 1;
943
944 if (REGNO (op) > FIRST_PSEUDO_REGISTER)
945 return 1;
946
947 return 0;
948}
949
0ec4e2a8
AH
950/* Returns 1 if op is an altivec register. */
951int
952altivec_register_operand (op, mode)
953 rtx op;
954 enum machine_mode mode ATTRIBUTE_UNUSED;
955{
956
957 return (register_operand (op, mode)
958 && (GET_CODE (op) != REG
959 || REGNO (op) > FIRST_PSEUDO_REGISTER
960 || ALTIVEC_REGNO_P (REGNO (op))));
961}
962
38c1f2d7 963int
a4f6c312 964xer_operand (op, mode)
592696dd 965 rtx op;
296b8152 966 enum machine_mode mode ATTRIBUTE_UNUSED;
802a0058
MM
967{
968 if (GET_CODE (op) != REG)
969 return 0;
970
9ebbca7d 971 if (XER_REGNO_P (REGNO (op)))
802a0058
MM
972 return 1;
973
802a0058
MM
974 return 0;
975}
976
c859cda6 977/* Return 1 if OP is a signed 8-bit constant. Int multiplication
6f317ef3 978 by such constants completes more quickly. */
c859cda6
DJ
979
980int
981s8bit_cint_operand (op, mode)
982 rtx op;
983 enum machine_mode mode ATTRIBUTE_UNUSED;
984{
985 return ( GET_CODE (op) == CONST_INT
986 && (INTVAL (op) >= -128 && INTVAL (op) <= 127));
987}
988
9878760c
RK
989/* Return 1 if OP is a constant that can fit in a D field. */
990
991int
992short_cint_operand (op, mode)
592696dd 993 rtx op;
296b8152 994 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 995{
5f59ecb7
DE
996 return (GET_CODE (op) == CONST_INT
997 && CONST_OK_FOR_LETTER_P (INTVAL (op), 'I'));
9878760c
RK
998}
999
5519a4f9 1000/* Similar for an unsigned D field. */
9878760c
RK
1001
1002int
1003u_short_cint_operand (op, mode)
592696dd 1004 rtx op;
296b8152 1005 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1006{
19684119 1007 return (GET_CODE (op) == CONST_INT
c1f11548 1008 && CONST_OK_FOR_LETTER_P (INTVAL (op) & GET_MODE_MASK (mode), 'K'));
9878760c
RK
1009}
1010
dcfedcd0
RK
1011/* Return 1 if OP is a CONST_INT that cannot fit in a signed D field. */
1012
1013int
1014non_short_cint_operand (op, mode)
592696dd 1015 rtx op;
296b8152 1016 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1017{
1018 return (GET_CODE (op) == CONST_INT
a7653a2c 1019 && (unsigned HOST_WIDE_INT) (INTVAL (op) + 0x8000) >= 0x10000);
dcfedcd0
RK
1020}
1021
2bfcf297
DB
1022/* Returns 1 if OP is a CONST_INT that is a positive value
1023 and an exact power of 2. */
1024
1025int
1026exact_log2_cint_operand (op, mode)
592696dd 1027 rtx op;
2bfcf297
DB
1028 enum machine_mode mode ATTRIBUTE_UNUSED;
1029{
1030 return (GET_CODE (op) == CONST_INT
1031 && INTVAL (op) > 0
1032 && exact_log2 (INTVAL (op)) >= 0);
1033}
1034
9878760c
RK
1035/* Returns 1 if OP is a register that is not special (i.e., not MQ,
1036 ctr, or lr). */
1037
1038int
cd2b37d9 1039gpc_reg_operand (op, mode)
592696dd 1040 rtx op;
9878760c
RK
1041 enum machine_mode mode;
1042{
1043 return (register_operand (op, mode)
802a0058 1044 && (GET_CODE (op) != REG
9ebbca7d
GK
1045 || (REGNO (op) >= ARG_POINTER_REGNUM
1046 && !XER_REGNO_P (REGNO (op)))
1047 || REGNO (op) < MQ_REGNO));
9878760c
RK
1048}
1049
1050/* Returns 1 if OP is either a pseudo-register or a register denoting a
1051 CR field. */
1052
1053int
1054cc_reg_operand (op, mode)
592696dd 1055 rtx op;
9878760c
RK
1056 enum machine_mode mode;
1057{
1058 return (register_operand (op, mode)
1059 && (GET_CODE (op) != REG
1060 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1061 || CR_REGNO_P (REGNO (op))));
1062}
1063
815cdc52
MM
1064/* Returns 1 if OP is either a pseudo-register or a register denoting a
1065 CR field that isn't CR0. */
1066
1067int
1068cc_reg_not_cr0_operand (op, mode)
592696dd 1069 rtx op;
815cdc52
MM
1070 enum machine_mode mode;
1071{
1072 return (register_operand (op, mode)
1073 && (GET_CODE (op) != REG
1074 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1075 || CR_REGNO_NOT_CR0_P (REGNO (op))));
1076}
1077
a4f6c312
SS
1078/* Returns 1 if OP is either a constant integer valid for a D-field or
1079 a non-special register. If a register, it must be in the proper
1080 mode unless MODE is VOIDmode. */
9878760c
RK
1081
1082int
1083reg_or_short_operand (op, mode)
592696dd 1084 rtx op;
9878760c
RK
1085 enum machine_mode mode;
1086{
f5a28898 1087 return short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1088}
1089
a4f6c312
SS
1090/* Similar, except check if the negation of the constant would be
1091 valid for a D-field. */
9878760c
RK
1092
1093int
1094reg_or_neg_short_operand (op, mode)
592696dd 1095 rtx op;
9878760c
RK
1096 enum machine_mode mode;
1097{
1098 if (GET_CODE (op) == CONST_INT)
1099 return CONST_OK_FOR_LETTER_P (INTVAL (op), 'P');
1100
cd2b37d9 1101 return gpc_reg_operand (op, mode);
9878760c
RK
1102}
1103
768070a0
TR
1104/* Returns 1 if OP is either a constant integer valid for a DS-field or
1105 a non-special register. If a register, it must be in the proper
1106 mode unless MODE is VOIDmode. */
1107
1108int
1109reg_or_aligned_short_operand (op, mode)
1110 rtx op;
1111 enum machine_mode mode;
1112{
1113 if (gpc_reg_operand (op, mode))
1114 return 1;
1115 else if (short_cint_operand (op, mode) && !(INTVAL (op) & 3))
1116 return 1;
1117
1118 return 0;
1119}
1120
1121
a4f6c312
SS
1122/* Return 1 if the operand is either a register or an integer whose
1123 high-order 16 bits are zero. */
9878760c
RK
1124
1125int
1126reg_or_u_short_operand (op, mode)
592696dd 1127 rtx op;
9878760c
RK
1128 enum machine_mode mode;
1129{
e675f625 1130 return u_short_cint_operand (op, mode) || gpc_reg_operand (op, mode);
9878760c
RK
1131}
1132
1133/* Return 1 is the operand is either a non-special register or ANY
1134 constant integer. */
1135
1136int
1137reg_or_cint_operand (op, mode)
592696dd 1138 rtx op;
9878760c
RK
1139 enum machine_mode mode;
1140{
a4f6c312 1141 return (GET_CODE (op) == CONST_INT || gpc_reg_operand (op, mode));
f6bf7de2
DE
1142}
1143
1144/* Return 1 is the operand is either a non-special register or ANY
1145 32-bit signed constant integer. */
1146
1147int
1148reg_or_arith_cint_operand (op, mode)
592696dd 1149 rtx op;
f6bf7de2
DE
1150 enum machine_mode mode;
1151{
a4f6c312
SS
1152 return (gpc_reg_operand (op, mode)
1153 || (GET_CODE (op) == CONST_INT
f6bf7de2 1154#if HOST_BITS_PER_WIDE_INT != 32
a4f6c312
SS
1155 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80000000)
1156 < (unsigned HOST_WIDE_INT) 0x100000000ll)
f6bf7de2 1157#endif
a4f6c312 1158 ));
9878760c
RK
1159}
1160
2bfcf297
DB
1161/* Return 1 is the operand is either a non-special register or a 32-bit
1162 signed constant integer valid for 64-bit addition. */
1163
1164int
1165reg_or_add_cint64_operand (op, mode)
592696dd 1166 rtx op;
2bfcf297
DB
1167 enum machine_mode mode;
1168{
a4f6c312
SS
1169 return (gpc_reg_operand (op, mode)
1170 || (GET_CODE (op) == CONST_INT
a65c591c 1171#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1172 && INTVAL (op) < 0x7fff8000
a65c591c 1173#else
a4f6c312
SS
1174 && ((unsigned HOST_WIDE_INT) (INTVAL (op) + 0x80008000)
1175 < 0x100000000ll)
2bfcf297 1176#endif
a4f6c312 1177 ));
2bfcf297
DB
1178}
1179
1180/* Return 1 is the operand is either a non-special register or a 32-bit
1181 signed constant integer valid for 64-bit subtraction. */
1182
1183int
1184reg_or_sub_cint64_operand (op, mode)
592696dd 1185 rtx op;
2bfcf297
DB
1186 enum machine_mode mode;
1187{
a4f6c312
SS
1188 return (gpc_reg_operand (op, mode)
1189 || (GET_CODE (op) == CONST_INT
a65c591c 1190#if HOST_BITS_PER_WIDE_INT == 32
a4f6c312 1191 && (- INTVAL (op)) < 0x7fff8000
a65c591c 1192#else
a4f6c312
SS
1193 && ((unsigned HOST_WIDE_INT) ((- INTVAL (op)) + 0x80008000)
1194 < 0x100000000ll)
2bfcf297 1195#endif
a4f6c312 1196 ));
2bfcf297
DB
1197}
1198
9ebbca7d
GK
1199/* Return 1 is the operand is either a non-special register or ANY
1200 32-bit unsigned constant integer. */
1201
1202int
1d328b19 1203reg_or_logical_cint_operand (op, mode)
592696dd 1204 rtx op;
9ebbca7d
GK
1205 enum machine_mode mode;
1206{
1d328b19
GK
1207 if (GET_CODE (op) == CONST_INT)
1208 {
1209 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT)
1210 {
1211 if (GET_MODE_BITSIZE (mode) <= 32)
a4f6c312 1212 abort ();
1d328b19
GK
1213
1214 if (INTVAL (op) < 0)
1215 return 0;
1216 }
1217
1218 return ((INTVAL (op) & GET_MODE_MASK (mode)
0858c623 1219 & (~ (unsigned HOST_WIDE_INT) 0xffffffff)) == 0);
1d328b19
GK
1220 }
1221 else if (GET_CODE (op) == CONST_DOUBLE)
1222 {
1223 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
1224 || mode != DImode)
a4f6c312 1225 abort ();
1d328b19
GK
1226
1227 return CONST_DOUBLE_HIGH (op) == 0;
1228 }
1229 else
1230 return gpc_reg_operand (op, mode);
9ebbca7d
GK
1231}
1232
51d3e7d6 1233/* Return 1 if the operand is an operand that can be loaded via the GOT. */
766a866c
MM
1234
1235int
1236got_operand (op, mode)
592696dd 1237 rtx op;
296b8152 1238 enum machine_mode mode ATTRIBUTE_UNUSED;
766a866c
MM
1239{
1240 return (GET_CODE (op) == SYMBOL_REF
1241 || GET_CODE (op) == CONST
1242 || GET_CODE (op) == LABEL_REF);
1243}
1244
38c1f2d7
MM
1245/* Return 1 if the operand is a simple references that can be loaded via
1246 the GOT (labels involving addition aren't allowed). */
1247
1248int
1249got_no_const_operand (op, mode)
592696dd 1250 rtx op;
296b8152 1251 enum machine_mode mode ATTRIBUTE_UNUSED;
38c1f2d7
MM
1252{
1253 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF);
1254}
1255
4e74d8ec
MM
1256/* Return the number of instructions it takes to form a constant in an
1257 integer register. */
1258
1259static int
1260num_insns_constant_wide (value)
1261 HOST_WIDE_INT value;
1262{
1263 /* signed constant loadable with {cal|addi} */
5f59ecb7 1264 if (CONST_OK_FOR_LETTER_P (value, 'I'))
0865c631
GK
1265 return 1;
1266
4e74d8ec 1267 /* constant loadable with {cau|addis} */
5f59ecb7 1268 else if (CONST_OK_FOR_LETTER_P (value, 'L'))
4e74d8ec
MM
1269 return 1;
1270
5f59ecb7 1271#if HOST_BITS_PER_WIDE_INT == 64
c81fc13e 1272 else if (TARGET_POWERPC64)
4e74d8ec 1273 {
a65c591c
DE
1274 HOST_WIDE_INT low = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
1275 HOST_WIDE_INT high = value >> 31;
4e74d8ec 1276
a65c591c 1277 if (high == 0 || high == -1)
4e74d8ec
MM
1278 return 2;
1279
a65c591c 1280 high >>= 1;
4e74d8ec 1281
a65c591c 1282 if (low == 0)
4e74d8ec 1283 return num_insns_constant_wide (high) + 1;
4e74d8ec
MM
1284 else
1285 return (num_insns_constant_wide (high)
e396202a 1286 + num_insns_constant_wide (low) + 1);
4e74d8ec
MM
1287 }
1288#endif
1289
1290 else
1291 return 2;
1292}
1293
1294int
1295num_insns_constant (op, mode)
1296 rtx op;
1297 enum machine_mode mode;
1298{
4e74d8ec 1299 if (GET_CODE (op) == CONST_INT)
0d30d435
DE
1300 {
1301#if HOST_BITS_PER_WIDE_INT == 64
4e2c1c44
DE
1302 if ((INTVAL (op) >> 31) != 0 && (INTVAL (op) >> 31) != -1
1303 && mask64_operand (op, mode))
0d30d435
DE
1304 return 2;
1305 else
1306#endif
1307 return num_insns_constant_wide (INTVAL (op));
1308 }
4e74d8ec 1309
6fc48950
MM
1310 else if (GET_CODE (op) == CONST_DOUBLE && mode == SFmode)
1311 {
1312 long l;
1313 REAL_VALUE_TYPE rv;
1314
1315 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1316 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
e72247f4 1317 return num_insns_constant_wide ((HOST_WIDE_INT) l);
6fc48950
MM
1318 }
1319
47ad8c61 1320 else if (GET_CODE (op) == CONST_DOUBLE)
4e74d8ec 1321 {
47ad8c61
MM
1322 HOST_WIDE_INT low;
1323 HOST_WIDE_INT high;
1324 long l[2];
1325 REAL_VALUE_TYPE rv;
1326 int endian = (WORDS_BIG_ENDIAN == 0);
4e74d8ec 1327
47ad8c61
MM
1328 if (mode == VOIDmode || mode == DImode)
1329 {
1330 high = CONST_DOUBLE_HIGH (op);
1331 low = CONST_DOUBLE_LOW (op);
1332 }
1333 else
1334 {
1335 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1336 REAL_VALUE_TO_TARGET_DOUBLE (rv, l);
1337 high = l[endian];
1338 low = l[1 - endian];
1339 }
4e74d8ec 1340
47ad8c61
MM
1341 if (TARGET_32BIT)
1342 return (num_insns_constant_wide (low)
1343 + num_insns_constant_wide (high));
4e74d8ec
MM
1344
1345 else
47ad8c61 1346 {
e72247f4 1347 if (high == 0 && low >= 0)
47ad8c61
MM
1348 return num_insns_constant_wide (low);
1349
e72247f4 1350 else if (high == -1 && low < 0)
47ad8c61
MM
1351 return num_insns_constant_wide (low);
1352
a260abc9
DE
1353 else if (mask64_operand (op, mode))
1354 return 2;
1355
47ad8c61
MM
1356 else if (low == 0)
1357 return num_insns_constant_wide (high) + 1;
1358
1359 else
1360 return (num_insns_constant_wide (high)
1361 + num_insns_constant_wide (low) + 1);
1362 }
4e74d8ec
MM
1363 }
1364
1365 else
1366 abort ();
1367}
1368
a4f6c312
SS
1369/* Return 1 if the operand is a CONST_DOUBLE and it can be put into a
1370 register with one instruction per word. We only do this if we can
1371 safely read CONST_DOUBLE_{LOW,HIGH}. */
9878760c
RK
1372
1373int
1374easy_fp_constant (op, mode)
592696dd
SS
1375 rtx op;
1376 enum machine_mode mode;
9878760c 1377{
9878760c
RK
1378 if (GET_CODE (op) != CONST_DOUBLE
1379 || GET_MODE (op) != mode
4e74d8ec 1380 || (GET_MODE_CLASS (mode) != MODE_FLOAT && mode != DImode))
9878760c
RK
1381 return 0;
1382
a4f6c312 1383 /* Consider all constants with -msoft-float to be easy. */
a3170dc6
AH
1384 if ((TARGET_SOFT_FLOAT || !TARGET_FPRS)
1385 && mode != DImode)
b6c9286a
MM
1386 return 1;
1387
a4f6c312 1388 /* If we are using V.4 style PIC, consider all constants to be hard. */
f607bc57 1389 if (flag_pic && DEFAULT_ABI == ABI_V4)
a7273471
MM
1390 return 0;
1391
5ae4759c 1392#ifdef TARGET_RELOCATABLE
a4f6c312
SS
1393 /* Similarly if we are using -mrelocatable, consider all constants
1394 to be hard. */
5ae4759c
MM
1395 if (TARGET_RELOCATABLE)
1396 return 0;
1397#endif
1398
fcce224d
DE
1399 if (mode == TFmode)
1400 {
1401 long k[4];
1402 REAL_VALUE_TYPE rv;
1403
1404 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1405 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
1406
1407 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1408 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1
1409 && num_insns_constant_wide ((HOST_WIDE_INT) k[2]) == 1
1410 && num_insns_constant_wide ((HOST_WIDE_INT) k[3]) == 1);
1411 }
1412
1413 else if (mode == DFmode)
042259f2
DE
1414 {
1415 long k[2];
1416 REAL_VALUE_TYPE rv;
1417
1418 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1419 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
9878760c 1420
a65c591c
DE
1421 return (num_insns_constant_wide ((HOST_WIDE_INT) k[0]) == 1
1422 && num_insns_constant_wide ((HOST_WIDE_INT) k[1]) == 1);
042259f2 1423 }
4e74d8ec
MM
1424
1425 else if (mode == SFmode)
042259f2
DE
1426 {
1427 long l;
1428 REAL_VALUE_TYPE rv;
1429
1430 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
1431 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
9878760c 1432
4e74d8ec 1433 return num_insns_constant_wide (l) == 1;
042259f2 1434 }
4e74d8ec 1435
a260abc9 1436 else if (mode == DImode)
c81fc13e 1437 return ((TARGET_POWERPC64
a260abc9
DE
1438 && GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_LOW (op) == 0)
1439 || (num_insns_constant (op, DImode) <= 2));
4e74d8ec 1440
a9098fd0
GK
1441 else if (mode == SImode)
1442 return 1;
4e74d8ec
MM
1443 else
1444 abort ();
9878760c 1445}
8f75773e 1446
d744e06e 1447/* Return non zero if all elements of a vector have the same value. */
69ef87e2
AH
1448
1449static int
d744e06e
AH
1450easy_vector_same (op, mode)
1451 rtx op;
1452 enum machine_mode mode ATTRIBUTE_UNUSED;
1453{
1454 int units, i, cst;
1455
1456 units = CONST_VECTOR_NUNITS (op);
1457
1458 cst = INTVAL (CONST_VECTOR_ELT (op, 0));
1459 for (i = 1; i < units; ++i)
1460 if (INTVAL (CONST_VECTOR_ELT (op, i)) != cst)
1461 break;
1462 if (i == units)
1463 return 1;
1464 return 0;
1465}
1466
1467/* Return 1 if the operand is a CONST_INT and can be put into a
1468 register without using memory. */
1469
1470int
1471easy_vector_constant (op, mode)
69ef87e2 1472 rtx op;
d744e06e 1473 enum machine_mode mode;
69ef87e2 1474{
d744e06e 1475 int cst, cst2;
69ef87e2 1476
d744e06e
AH
1477 if (GET_CODE (op) != CONST_VECTOR
1478 || (!TARGET_ALTIVEC
1479 && !TARGET_SPE))
69ef87e2
AH
1480 return 0;
1481
d744e06e
AH
1482 if (zero_constant (op, mode)
1483 && ((TARGET_ALTIVEC && ALTIVEC_VECTOR_MODE (mode))
1484 || (TARGET_SPE && SPE_VECTOR_MODE (mode))))
1485 return 1;
69ef87e2 1486
d744e06e
AH
1487 if (GET_MODE_CLASS (mode) != MODE_VECTOR_INT)
1488 return 0;
1489
1490 cst = INTVAL (CONST_VECTOR_ELT (op, 0));
1491 cst2 = INTVAL (CONST_VECTOR_ELT (op, 1));
1492
1493 /* Limit SPE vectors to 15 bits signed. These we can generate with:
1494 li r0, CONSTANT1
1495 evmergelo r0, r0, r0
1496 li r0, CONSTANT2
1497
1498 I don't know how efficient it would be to allow bigger constants,
1499 considering we'll have an extra 'ori' for every 'li'. I doubt 5
1500 instructions is better than a 64-bit memory load, but I don't
1501 have the e500 timing specs. */
1502 if (TARGET_SPE && mode == V2SImode
1503 && cst >= -0x7fff && cst <= 0x7fff
1504 && cst2 >= -0x7fff && cst <= 0x7fff)
1505 return 1;
1506
1507 if (TARGET_ALTIVEC && EASY_VECTOR_15 (cst, op, mode))
1508 return 1;
1509
1510 if (TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode))
1511 return 1;
1512
1513 return 0;
1514}
1515
1516/* Same as easy_vector_constant but only for EASY_VECTOR_15_ADD_SELF. */
1517
1518int
1519easy_vector_constant_add_self (op, mode)
1520 rtx op;
1521 enum machine_mode mode;
1522{
1523 int cst;
1524
1525 if (!easy_vector_constant (op, mode))
1526 return 0;
1527
1528 cst = INTVAL (CONST_VECTOR_ELT (op, 0));
1529
1530 return TARGET_ALTIVEC && EASY_VECTOR_15_ADD_SELF (cst, op, mode);
1531}
1532
1533const char *
1534output_vec_const_move (operands)
1535 rtx *operands;
1536{
1537 int cst, cst2;
1538 enum machine_mode mode;
1539 rtx dest, vec;
1540
1541 dest = operands[0];
1542 vec = operands[1];
69ef87e2 1543
d744e06e
AH
1544 cst = INTVAL (CONST_VECTOR_ELT (vec, 0));
1545 cst2 = INTVAL (CONST_VECTOR_ELT (vec, 1));
1546 mode = GET_MODE (dest);
69ef87e2 1547
d744e06e
AH
1548 if (TARGET_ALTIVEC)
1549 {
1550 if (zero_constant (vec, mode))
1551 return "vxor %0,%0,%0";
1552 else if (EASY_VECTOR_15 (cst, vec, mode))
98ef3137 1553 {
d744e06e
AH
1554 operands[1] = GEN_INT (cst);
1555 switch (mode)
1556 {
1557 case V4SImode:
1558 return "vspltisw %0,%1";
1559 case V8HImode:
1560 return "vspltish %0,%1";
1561 case V16QImode:
1562 return "vspltisb %0,%1";
1563 default:
1564 abort ();
1565 }
98ef3137 1566 }
d744e06e
AH
1567 else if (EASY_VECTOR_15_ADD_SELF (cst, vec, mode))
1568 return "#";
1569 else
1570 abort ();
69ef87e2
AH
1571 }
1572
d744e06e
AH
1573 if (TARGET_SPE)
1574 {
1575 /* Vector constant 0 is handled as a splitter of V2SI, and in the
1576 pattern of V1DI, V4HI, and V2SF.
1577
1578 FIXME: We should probabl return # and add post reload
1579 splitters for these, but this way is so easy ;-).
1580 */
1581 operands[1] = GEN_INT (cst);
1582 operands[2] = GEN_INT (cst2);
1583 if (cst == cst2)
1584 return "li %0,%1\n\tevmergelo %0,%0,%0";
1585 else
1586 return "li %0,%1\n\tevmergelo %0,%0,%0\n\tli %0,%2";
1587 }
1588
1589 abort ();
69ef87e2
AH
1590}
1591
1592/* Return 1 if the operand is the constant 0. This works for scalars
1593 as well as vectors. */
1594int
1595zero_constant (op, mode)
1596 rtx op;
1597 enum machine_mode mode;
1598{
1599 return op == CONST0_RTX (mode);
1600}
1601
50a0b056
GK
1602/* Return 1 if the operand is 0.0. */
1603int
1604zero_fp_constant (op, mode)
592696dd
SS
1605 rtx op;
1606 enum machine_mode mode;
50a0b056
GK
1607{
1608 return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode);
1609}
1610
a4f6c312
SS
1611/* Return 1 if the operand is in volatile memory. Note that during
1612 the RTL generation phase, memory_operand does not return TRUE for
b6c9286a
MM
1613 volatile memory references. So this function allows us to
1614 recognize volatile references where its safe. */
1615
1616int
1617volatile_mem_operand (op, mode)
592696dd 1618 rtx op;
b6c9286a
MM
1619 enum machine_mode mode;
1620{
1621 if (GET_CODE (op) != MEM)
1622 return 0;
1623
1624 if (!MEM_VOLATILE_P (op))
1625 return 0;
1626
1627 if (mode != GET_MODE (op))
1628 return 0;
1629
1630 if (reload_completed)
1631 return memory_operand (op, mode);
1632
1633 if (reload_in_progress)
1634 return strict_memory_address_p (mode, XEXP (op, 0));
1635
1636 return memory_address_p (mode, XEXP (op, 0));
1637}
1638
97f6e72f 1639/* Return 1 if the operand is an offsettable memory operand. */
914c2e77
RK
1640
1641int
97f6e72f 1642offsettable_mem_operand (op, mode)
592696dd 1643 rtx op;
914c2e77
RK
1644 enum machine_mode mode;
1645{
97f6e72f 1646 return ((GET_CODE (op) == MEM)
677a9668 1647 && offsettable_address_p (reload_completed || reload_in_progress,
97f6e72f 1648 mode, XEXP (op, 0)));
914c2e77
RK
1649}
1650
9878760c
RK
1651/* Return 1 if the operand is either an easy FP constant (see above) or
1652 memory. */
1653
1654int
1655mem_or_easy_const_operand (op, mode)
592696dd 1656 rtx op;
9878760c
RK
1657 enum machine_mode mode;
1658{
1659 return memory_operand (op, mode) || easy_fp_constant (op, mode);
1660}
1661
1662/* Return 1 if the operand is either a non-special register or an item
5f59ecb7 1663 that can be used as the operand of a `mode' add insn. */
9878760c
RK
1664
1665int
1666add_operand (op, mode)
592696dd 1667 rtx op;
9878760c
RK
1668 enum machine_mode mode;
1669{
2bfcf297 1670 if (GET_CODE (op) == CONST_INT)
e72247f4
DE
1671 return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1672 || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
2bfcf297
DB
1673
1674 return gpc_reg_operand (op, mode);
9878760c
RK
1675}
1676
dcfedcd0
RK
1677/* Return 1 if OP is a constant but not a valid add_operand. */
1678
1679int
1680non_add_cint_operand (op, mode)
592696dd 1681 rtx op;
296b8152 1682 enum machine_mode mode ATTRIBUTE_UNUSED;
dcfedcd0
RK
1683{
1684 return (GET_CODE (op) == CONST_INT
e72247f4
DE
1685 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'I')
1686 && !CONST_OK_FOR_LETTER_P (INTVAL (op), 'L'));
dcfedcd0
RK
1687}
1688
9878760c
RK
1689/* Return 1 if the operand is a non-special register or a constant that
1690 can be used as the operand of an OR or XOR insn on the RS/6000. */
1691
1692int
1693logical_operand (op, mode)
592696dd 1694 rtx op;
9878760c
RK
1695 enum machine_mode mode;
1696{
40501e5f 1697 HOST_WIDE_INT opl, oph;
1d328b19 1698
dfbdccdb
GK
1699 if (gpc_reg_operand (op, mode))
1700 return 1;
1d328b19 1701
dfbdccdb 1702 if (GET_CODE (op) == CONST_INT)
40501e5f
AM
1703 {
1704 opl = INTVAL (op) & GET_MODE_MASK (mode);
1705
1706#if HOST_BITS_PER_WIDE_INT <= 32
1707 if (GET_MODE_BITSIZE (mode) > HOST_BITS_PER_WIDE_INT && opl < 0)
1708 return 0;
1709#endif
1710 }
dfbdccdb
GK
1711 else if (GET_CODE (op) == CONST_DOUBLE)
1712 {
1d328b19 1713 if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
40501e5f 1714 abort ();
1d328b19
GK
1715
1716 opl = CONST_DOUBLE_LOW (op);
1717 oph = CONST_DOUBLE_HIGH (op);
40501e5f 1718 if (oph != 0)
38886f37 1719 return 0;
dfbdccdb
GK
1720 }
1721 else
1722 return 0;
1d328b19 1723
40501e5f
AM
1724 return ((opl & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0
1725 || (opl & ~ (unsigned HOST_WIDE_INT) 0xffff0000) == 0);
9878760c
RK
1726}
1727
dcfedcd0 1728/* Return 1 if C is a constant that is not a logical operand (as
1d328b19 1729 above), but could be split into one. */
dcfedcd0
RK
1730
1731int
1732non_logical_cint_operand (op, mode)
592696dd 1733 rtx op;
5f59ecb7 1734 enum machine_mode mode;
dcfedcd0 1735{
dfbdccdb 1736 return ((GET_CODE (op) == CONST_INT || GET_CODE (op) == CONST_DOUBLE)
1d328b19
GK
1737 && ! logical_operand (op, mode)
1738 && reg_or_logical_cint_operand (op, mode));
dcfedcd0
RK
1739}
1740
19ba8161 1741/* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
9878760c
RK
1742 RS/6000. It is if there are no more than two 1->0 or 0->1 transitions.
1743 Reject all ones and all zeros, since these should have been optimized
1744 away and confuse the making of MB and ME. */
1745
1746int
19ba8161 1747mask_operand (op, mode)
592696dd 1748 rtx op;
19ba8161 1749 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c 1750{
02071907 1751 HOST_WIDE_INT c, lsb;
9878760c 1752
19ba8161
DE
1753 if (GET_CODE (op) != CONST_INT)
1754 return 0;
1755
1756 c = INTVAL (op);
1757
57deb3a1
AM
1758 /* Fail in 64-bit mode if the mask wraps around because the upper
1759 32-bits of the mask will all be 1s, contrary to GCC's internal view. */
1760 if (TARGET_POWERPC64 && (c & 0x80000001) == 0x80000001)
1761 return 0;
1762
c5059423
AM
1763 /* We don't change the number of transitions by inverting,
1764 so make sure we start with the LS bit zero. */
1765 if (c & 1)
1766 c = ~c;
1767
1768 /* Reject all zeros or all ones. */
1769 if (c == 0)
9878760c
RK
1770 return 0;
1771
c5059423
AM
1772 /* Find the first transition. */
1773 lsb = c & -c;
1774
1775 /* Invert to look for a second transition. */
1776 c = ~c;
9878760c 1777
c5059423
AM
1778 /* Erase first transition. */
1779 c &= -lsb;
9878760c 1780
c5059423
AM
1781 /* Find the second transition (if any). */
1782 lsb = c & -c;
1783
1784 /* Match if all the bits above are 1's (or c is zero). */
1785 return c == -lsb;
9878760c
RK
1786}
1787
0ba1b2ff
AM
1788/* Return 1 for the PowerPC64 rlwinm corner case. */
1789
1790int
1791mask_operand_wrap (op, mode)
1792 rtx op;
1793 enum machine_mode mode ATTRIBUTE_UNUSED;
1794{
1795 HOST_WIDE_INT c, lsb;
1796
1797 if (GET_CODE (op) != CONST_INT)
1798 return 0;
1799
1800 c = INTVAL (op);
1801
1802 if ((c & 0x80000001) != 0x80000001)
1803 return 0;
1804
1805 c = ~c;
1806 if (c == 0)
1807 return 0;
1808
1809 lsb = c & -c;
1810 c = ~c;
1811 c &= -lsb;
1812 lsb = c & -c;
1813 return c == -lsb;
1814}
1815
a260abc9
DE
1816/* Return 1 if the operand is a constant that is a PowerPC64 mask.
1817 It is if there are no more than one 1->0 or 0->1 transitions.
0ba1b2ff
AM
1818 Reject all zeros, since zero should have been optimized away and
1819 confuses the making of MB and ME. */
9878760c
RK
1820
1821int
a260abc9 1822mask64_operand (op, mode)
592696dd 1823 rtx op;
0ba1b2ff 1824 enum machine_mode mode ATTRIBUTE_UNUSED;
a260abc9
DE
1825{
1826 if (GET_CODE (op) == CONST_INT)
1827 {
02071907 1828 HOST_WIDE_INT c, lsb;
a260abc9 1829
c5059423 1830 c = INTVAL (op);
a260abc9 1831
0ba1b2ff 1832 /* Reject all zeros. */
c5059423 1833 if (c == 0)
e2c953b6
DE
1834 return 0;
1835
0ba1b2ff
AM
1836 /* We don't change the number of transitions by inverting,
1837 so make sure we start with the LS bit zero. */
1838 if (c & 1)
1839 c = ~c;
1840
c5059423
AM
1841 /* Find the transition, and check that all bits above are 1's. */
1842 lsb = c & -c;
e3981aab
DE
1843
1844 /* Match if all the bits above are 1's (or c is zero). */
c5059423 1845 return c == -lsb;
e2c953b6 1846 }
0ba1b2ff
AM
1847 return 0;
1848}
1849
1850/* Like mask64_operand, but allow up to three transitions. This
1851 predicate is used by insn patterns that generate two rldicl or
1852 rldicr machine insns. */
1853
1854int
1855mask64_2_operand (op, mode)
1856 rtx op;
1857 enum machine_mode mode ATTRIBUTE_UNUSED;
1858{
1859 if (GET_CODE (op) == CONST_INT)
a260abc9 1860 {
0ba1b2ff 1861 HOST_WIDE_INT c, lsb;
a260abc9 1862
0ba1b2ff 1863 c = INTVAL (op);
a260abc9 1864
0ba1b2ff
AM
1865 /* Disallow all zeros. */
1866 if (c == 0)
1867 return 0;
a260abc9 1868
0ba1b2ff
AM
1869 /* We don't change the number of transitions by inverting,
1870 so make sure we start with the LS bit zero. */
1871 if (c & 1)
1872 c = ~c;
a260abc9 1873
0ba1b2ff
AM
1874 /* Find the first transition. */
1875 lsb = c & -c;
a260abc9 1876
0ba1b2ff
AM
1877 /* Invert to look for a second transition. */
1878 c = ~c;
1879
1880 /* Erase first transition. */
1881 c &= -lsb;
1882
1883 /* Find the second transition. */
1884 lsb = c & -c;
1885
1886 /* Invert to look for a third transition. */
1887 c = ~c;
1888
1889 /* Erase second transition. */
1890 c &= -lsb;
1891
1892 /* Find the third transition (if any). */
1893 lsb = c & -c;
1894
1895 /* Match if all the bits above are 1's (or c is zero). */
1896 return c == -lsb;
1897 }
1898 return 0;
1899}
1900
1901/* Generates shifts and masks for a pair of rldicl or rldicr insns to
1902 implement ANDing by the mask IN. */
1903void
1904build_mask64_2_operands (in, out)
1905 rtx in;
1906 rtx *out;
1907{
1908#if HOST_BITS_PER_WIDE_INT >= 64
1909 unsigned HOST_WIDE_INT c, lsb, m1, m2;
1910 int shift;
1911
1912 if (GET_CODE (in) != CONST_INT)
1913 abort ();
1914
1915 c = INTVAL (in);
1916 if (c & 1)
1917 {
1918 /* Assume c initially something like 0x00fff000000fffff. The idea
1919 is to rotate the word so that the middle ^^^^^^ group of zeros
1920 is at the MS end and can be cleared with an rldicl mask. We then
1921 rotate back and clear off the MS ^^ group of zeros with a
1922 second rldicl. */
1923 c = ~c; /* c == 0xff000ffffff00000 */
1924 lsb = c & -c; /* lsb == 0x0000000000100000 */
1925 m1 = -lsb; /* m1 == 0xfffffffffff00000 */
1926 c = ~c; /* c == 0x00fff000000fffff */
1927 c &= -lsb; /* c == 0x00fff00000000000 */
1928 lsb = c & -c; /* lsb == 0x0000100000000000 */
1929 c = ~c; /* c == 0xff000fffffffffff */
1930 c &= -lsb; /* c == 0xff00000000000000 */
1931 shift = 0;
1932 while ((lsb >>= 1) != 0)
1933 shift++; /* shift == 44 on exit from loop */
1934 m1 <<= 64 - shift; /* m1 == 0xffffff0000000000 */
1935 m1 = ~m1; /* m1 == 0x000000ffffffffff */
1936 m2 = ~c; /* m2 == 0x00ffffffffffffff */
a260abc9
DE
1937 }
1938 else
0ba1b2ff
AM
1939 {
1940 /* Assume c initially something like 0xff000f0000000000. The idea
1941 is to rotate the word so that the ^^^ middle group of zeros
1942 is at the LS end and can be cleared with an rldicr mask. We then
1943 rotate back and clear off the LS group of ^^^^^^^^^^ zeros with
1944 a second rldicr. */
1945 lsb = c & -c; /* lsb == 0x0000010000000000 */
1946 m2 = -lsb; /* m2 == 0xffffff0000000000 */
1947 c = ~c; /* c == 0x00fff0ffffffffff */
1948 c &= -lsb; /* c == 0x00fff00000000000 */
1949 lsb = c & -c; /* lsb == 0x0000100000000000 */
1950 c = ~c; /* c == 0xff000fffffffffff */
1951 c &= -lsb; /* c == 0xff00000000000000 */
1952 shift = 0;
1953 while ((lsb >>= 1) != 0)
1954 shift++; /* shift == 44 on exit from loop */
1955 m1 = ~c; /* m1 == 0x00ffffffffffffff */
1956 m1 >>= shift; /* m1 == 0x0000000000000fff */
1957 m1 = ~m1; /* m1 == 0xfffffffffffff000 */
1958 }
1959
1960 /* Note that when we only have two 0->1 and 1->0 transitions, one of the
1961 masks will be all 1's. We are guaranteed more than one transition. */
1962 out[0] = GEN_INT (64 - shift);
1963 out[1] = GEN_INT (m1);
1964 out[2] = GEN_INT (shift);
1965 out[3] = GEN_INT (m2);
1966#else
045572c7
GK
1967 (void)in;
1968 (void)out;
0ba1b2ff
AM
1969 abort ();
1970#endif
a260abc9
DE
1971}
1972
1973/* Return 1 if the operand is either a non-special register or a constant
1974 that can be used as the operand of a PowerPC64 logical AND insn. */
1975
1976int
1977and64_operand (op, mode)
592696dd 1978 rtx op;
9878760c
RK
1979 enum machine_mode mode;
1980{
a4f6c312 1981 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
1982 return (gpc_reg_operand (op, mode) || mask64_operand (op, mode));
1983
1984 return (logical_operand (op, mode) || mask64_operand (op, mode));
9878760c
RK
1985}
1986
0ba1b2ff
AM
1987/* Like the above, but also match constants that can be implemented
1988 with two rldicl or rldicr insns. */
1989
1990int
1991and64_2_operand (op, mode)
1992 rtx op;
1993 enum machine_mode mode;
1994{
1995 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
1996 return gpc_reg_operand (op, mode) || mask64_2_operand (op, mode);
1997
1998 return logical_operand (op, mode) || mask64_2_operand (op, mode);
1999}
2000
a260abc9
DE
2001/* Return 1 if the operand is either a non-special register or a
2002 constant that can be used as the operand of an RS/6000 logical AND insn. */
dcfedcd0
RK
2003
2004int
a260abc9 2005and_operand (op, mode)
592696dd 2006 rtx op;
a260abc9 2007 enum machine_mode mode;
dcfedcd0 2008{
a4f6c312 2009 if (fixed_regs[CR0_REGNO]) /* CR0 not available, don't do andi./andis. */
52d3af72
DE
2010 return (gpc_reg_operand (op, mode) || mask_operand (op, mode));
2011
2012 return (logical_operand (op, mode) || mask_operand (op, mode));
dcfedcd0
RK
2013}
2014
9878760c
RK
2015/* Return 1 if the operand is a general register or memory operand. */
2016
2017int
2018reg_or_mem_operand (op, mode)
592696dd
SS
2019 rtx op;
2020 enum machine_mode mode;
9878760c 2021{
b6c9286a
MM
2022 return (gpc_reg_operand (op, mode)
2023 || memory_operand (op, mode)
2024 || volatile_mem_operand (op, mode));
9878760c
RK
2025}
2026
a7a813f7 2027/* Return 1 if the operand is a general register or memory operand without
3cb999d8 2028 pre_inc or pre_dec which produces invalid form of PowerPC lwa
a7a813f7
RK
2029 instruction. */
2030
2031int
2032lwa_operand (op, mode)
592696dd
SS
2033 rtx op;
2034 enum machine_mode mode;
a7a813f7
RK
2035{
2036 rtx inner = op;
2037
2038 if (reload_completed && GET_CODE (inner) == SUBREG)
2039 inner = SUBREG_REG (inner);
2040
2041 return gpc_reg_operand (inner, mode)
2042 || (memory_operand (inner, mode)
2043 && GET_CODE (XEXP (inner, 0)) != PRE_INC
6a40a9d6
DE
2044 && GET_CODE (XEXP (inner, 0)) != PRE_DEC
2045 && (GET_CODE (XEXP (inner, 0)) != PLUS
e903c96a
DE
2046 || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
2047 || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
a7a813f7
RK
2048}
2049
cc4d5fec
JH
2050/* Return 1 if the operand, used inside a MEM, is a SYMBOL_REF. */
2051
2052int
2053symbol_ref_operand (op, mode)
2054 rtx op;
2055 enum machine_mode mode;
2056{
2057 if (mode != VOIDmode && GET_MODE (op) != mode)
2058 return 0;
2059
2060 return (GET_CODE (op) == SYMBOL_REF);
2061}
2062
9878760c 2063/* Return 1 if the operand, used inside a MEM, is a valid first argument
cc4d5fec 2064 to CALL. This is a SYMBOL_REF, a pseudo-register, LR or CTR. */
9878760c
RK
2065
2066int
2067call_operand (op, mode)
592696dd 2068 rtx op;
9878760c
RK
2069 enum machine_mode mode;
2070{
2071 if (mode != VOIDmode && GET_MODE (op) != mode)
2072 return 0;
2073
2074 return (GET_CODE (op) == SYMBOL_REF
cc4d5fec
JH
2075 || (GET_CODE (op) == REG
2076 && (REGNO (op) == LINK_REGISTER_REGNUM
2077 || REGNO (op) == COUNT_REGISTER_REGNUM
2078 || REGNO (op) >= FIRST_PSEUDO_REGISTER)));
9878760c
RK
2079}
2080
2af3d377 2081/* Return 1 if the operand is a SYMBOL_REF for a function known to be in
a4f6c312 2082 this file and the function is not weakly defined. */
2af3d377
RK
2083
2084int
2085current_file_function_operand (op, mode)
592696dd 2086 rtx op;
296b8152 2087 enum machine_mode mode ATTRIBUTE_UNUSED;
2af3d377
RK
2088{
2089 return (GET_CODE (op) == SYMBOL_REF
2090 && (SYMBOL_REF_FLAG (op)
8f1b829e 2091 || (op == XEXP (DECL_RTL (current_function_decl), 0)
c81fc13e 2092 && ! DECL_WEAK (current_function_decl))));
2af3d377
RK
2093}
2094
9878760c
RK
2095/* Return 1 if this operand is a valid input for a move insn. */
2096
2097int
2098input_operand (op, mode)
592696dd 2099 rtx op;
9878760c
RK
2100 enum machine_mode mode;
2101{
eb4e8003 2102 /* Memory is always valid. */
9878760c
RK
2103 if (memory_operand (op, mode))
2104 return 1;
2105
34792e82 2106 /* Only a tiny bit of handling for CONSTANT_P_RTX is necessary. */
01b4cf2b 2107 if (GET_CODE (op) == CONSTANT_P_RTX)
34792e82
JL
2108 return 1;
2109
eb4e8003
RK
2110 /* For floating-point, easy constants are valid. */
2111 if (GET_MODE_CLASS (mode) == MODE_FLOAT
2112 && CONSTANT_P (op)
2113 && easy_fp_constant (op, mode))
2114 return 1;
2115
4e74d8ec
MM
2116 /* Allow any integer constant. */
2117 if (GET_MODE_CLASS (mode) == MODE_INT
e675f625 2118 && (GET_CODE (op) == CONST_INT
e675f625 2119 || GET_CODE (op) == CONST_DOUBLE))
4e74d8ec
MM
2120 return 1;
2121
d744e06e
AH
2122 /* Allow easy vector constants. */
2123 if (GET_CODE (op) == CONST_VECTOR
2124 && easy_vector_constant (op, mode))
2125 return 1;
2126
eb4e8003
RK
2127 /* For floating-point or multi-word mode, the only remaining valid type
2128 is a register. */
9878760c
RK
2129 if (GET_MODE_CLASS (mode) == MODE_FLOAT
2130 || GET_MODE_SIZE (mode) > UNITS_PER_WORD)
eb4e8003 2131 return register_operand (op, mode);
9878760c 2132
88fe15a1
RK
2133 /* The only cases left are integral modes one word or smaller (we
2134 do not get called for MODE_CC values). These can be in any
2135 register. */
2136 if (register_operand (op, mode))
a8b3aeda 2137 return 1;
88fe15a1 2138
84cf9dda 2139 /* A SYMBOL_REF referring to the TOC is valid. */
7fec4abd 2140 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (op))
84cf9dda
RK
2141 return 1;
2142
9ebbca7d
GK
2143 /* A constant pool expression (relative to the TOC) is valid */
2144 if (TOC_RELATIVE_EXPR_P (op))
b6c9286a
MM
2145 return 1;
2146
88228c4b
MM
2147 /* V.4 allows SYMBOL_REFs and CONSTs that are in the small data region
2148 to be valid. */
f607bc57 2149 if (DEFAULT_ABI == ABI_V4
88228c4b
MM
2150 && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST)
2151 && small_data_operand (op, Pmode))
2152 return 1;
2153
042259f2 2154 return 0;
9878760c 2155}
7509c759 2156
a4f6c312 2157/* Return 1 for an operand in small memory on V.4/eabi. */
7509c759
MM
2158
2159int
2160small_data_operand (op, mode)
296b8152
KG
2161 rtx op ATTRIBUTE_UNUSED;
2162 enum machine_mode mode ATTRIBUTE_UNUSED;
7509c759 2163{
38c1f2d7 2164#if TARGET_ELF
5f59ecb7 2165 rtx sym_ref;
7509c759 2166
d9407988 2167 if (rs6000_sdata == SDATA_NONE || rs6000_sdata == SDATA_DATA)
a54d04b7 2168 return 0;
a54d04b7 2169
f607bc57 2170 if (DEFAULT_ABI != ABI_V4)
7509c759
MM
2171 return 0;
2172
88228c4b
MM
2173 if (GET_CODE (op) == SYMBOL_REF)
2174 sym_ref = op;
2175
2176 else if (GET_CODE (op) != CONST
2177 || GET_CODE (XEXP (op, 0)) != PLUS
2178 || GET_CODE (XEXP (XEXP (op, 0), 0)) != SYMBOL_REF
2179 || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT)
7509c759
MM
2180 return 0;
2181
88228c4b 2182 else
dbf55e53
MM
2183 {
2184 rtx sum = XEXP (op, 0);
2185 HOST_WIDE_INT summand;
2186
2187 /* We have to be careful here, because it is the referenced address
2188 that must be 32k from _SDA_BASE_, not just the symbol. */
2189 summand = INTVAL (XEXP (sum, 1));
2190 if (summand < 0 || summand > g_switch_value)
2191 return 0;
2192
2193 sym_ref = XEXP (sum, 0);
2194 }
88228c4b
MM
2195
2196 if (*XSTR (sym_ref, 0) != '@')
7509c759
MM
2197 return 0;
2198
2199 return 1;
d9407988
MM
2200
2201#else
2202 return 0;
2203#endif
7509c759 2204}
9ebbca7d
GK
2205\f
2206static int
2207constant_pool_expr_1 (op, have_sym, have_toc)
2208 rtx op;
2209 int *have_sym;
2210 int *have_toc;
2211{
2212 switch (GET_CODE(op))
2213 {
2214 case SYMBOL_REF:
a4f6c312
SS
2215 if (CONSTANT_POOL_ADDRESS_P (op))
2216 {
2217 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (op), Pmode))
2218 {
2219 *have_sym = 1;
2220 return 1;
2221 }
2222 else
2223 return 0;
2224 }
2225 else if (! strcmp (XSTR (op, 0), toc_label_name))
2226 {
2227 *have_toc = 1;
2228 return 1;
2229 }
2230 else
2231 return 0;
9ebbca7d
GK
2232 case PLUS:
2233 case MINUS:
c1f11548
DE
2234 return (constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc)
2235 && constant_pool_expr_1 (XEXP (op, 1), have_sym, have_toc));
9ebbca7d 2236 case CONST:
a4f6c312 2237 return constant_pool_expr_1 (XEXP (op, 0), have_sym, have_toc);
9ebbca7d 2238 case CONST_INT:
a4f6c312 2239 return 1;
9ebbca7d 2240 default:
a4f6c312 2241 return 0;
9ebbca7d
GK
2242 }
2243}
2244
2245int
2246constant_pool_expr_p (op)
2247 rtx op;
2248{
2249 int have_sym = 0;
2250 int have_toc = 0;
2251 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_sym;
2252}
2253
2254int
2255toc_relative_expr_p (op)
2256 rtx op;
2257{
2258 int have_sym = 0;
2259 int have_toc = 0;
2260 return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
2261}
2262
2263/* Try machine-dependent ways of modifying an illegitimate address
2264 to be legitimate. If we find one, return the new, valid address.
2265 This is used from only one place: `memory_address' in explow.c.
2266
a4f6c312
SS
2267 OLDX is the address as it was before break_out_memory_refs was
2268 called. In some cases it is useful to look at this to decide what
2269 needs to be done.
9ebbca7d 2270
a4f6c312 2271 MODE is passed so that this function can use GO_IF_LEGITIMATE_ADDRESS.
9ebbca7d 2272
a4f6c312
SS
2273 It is always safe for this function to do nothing. It exists to
2274 recognize opportunities to optimize the output.
9ebbca7d
GK
2275
2276 On RS/6000, first check for the sum of a register with a constant
2277 integer that is out of range. If so, generate code to add the
2278 constant with the low-order 16 bits masked to the register and force
2279 this result into another register (this can be done with `cau').
2280 Then generate an address of REG+(CONST&0xffff), allowing for the
2281 possibility of bit 16 being a one.
2282
2283 Then check for the sum of a register and something not constant, try to
2284 load the other things into a register and return the sum. */
2285rtx
2286rs6000_legitimize_address (x, oldx, mode)
2287 rtx x;
2288 rtx oldx ATTRIBUTE_UNUSED;
2289 enum machine_mode mode;
0ac081f6 2290{
9ebbca7d
GK
2291 if (GET_CODE (x) == PLUS
2292 && GET_CODE (XEXP (x, 0)) == REG
2293 && GET_CODE (XEXP (x, 1)) == CONST_INT
2294 && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
2295 {
2296 HOST_WIDE_INT high_int, low_int;
2297 rtx sum;
a65c591c
DE
2298 low_int = ((INTVAL (XEXP (x, 1)) & 0xffff) ^ 0x8000) - 0x8000;
2299 high_int = INTVAL (XEXP (x, 1)) - low_int;
9ebbca7d
GK
2300 sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
2301 GEN_INT (high_int)), 0);
2302 return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
2303 }
2304 else if (GET_CODE (x) == PLUS
2305 && GET_CODE (XEXP (x, 0)) == REG
2306 && GET_CODE (XEXP (x, 1)) != CONST_INT
6ac7bf2c 2307 && GET_MODE_NUNITS (mode) == 1
a3170dc6
AH
2308 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2309 || TARGET_POWERPC64
fcce224d 2310 || (mode != DFmode && mode != TFmode))
9ebbca7d
GK
2311 && (TARGET_POWERPC64 || mode != DImode)
2312 && mode != TImode)
2313 {
2314 return gen_rtx_PLUS (Pmode, XEXP (x, 0),
2315 force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
2316 }
0ac081f6
AH
2317 else if (ALTIVEC_VECTOR_MODE (mode))
2318 {
2319 rtx reg;
2320
2321 /* Make sure both operands are registers. */
2322 if (GET_CODE (x) == PLUS)
9f85ed45 2323 return gen_rtx_PLUS (Pmode, force_reg (Pmode, XEXP (x, 0)),
0ac081f6
AH
2324 force_reg (Pmode, XEXP (x, 1)));
2325
2326 reg = force_reg (Pmode, x);
2327 return reg;
2328 }
a3170dc6
AH
2329 else if (SPE_VECTOR_MODE (mode))
2330 {
2331 /* We accept [reg + reg] and [reg + OFFSET]. */
2332
2333 if (GET_CODE (x) == PLUS)
2334 {
2335 rtx op1 = XEXP (x, 0);
2336 rtx op2 = XEXP (x, 1);
2337
2338 op1 = force_reg (Pmode, op1);
2339
2340 if (GET_CODE (op2) != REG
2341 && (GET_CODE (op2) != CONST_INT
2342 || !SPE_CONST_OFFSET_OK (INTVAL (op2))))
2343 op2 = force_reg (Pmode, op2);
2344
2345 return gen_rtx_PLUS (Pmode, op1, op2);
2346 }
2347
2348 return force_reg (Pmode, x);
2349 }
f1384257
AM
2350 else if (TARGET_ELF
2351 && TARGET_32BIT
2352 && TARGET_NO_TOC
2353 && ! flag_pic
9ebbca7d
GK
2354 && GET_CODE (x) != CONST_INT
2355 && GET_CODE (x) != CONST_DOUBLE
2356 && CONSTANT_P (x)
6ac7bf2c
GK
2357 && GET_MODE_NUNITS (mode) == 1
2358 && (GET_MODE_BITSIZE (mode) <= 32
a3170dc6 2359 || ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode)))
9ebbca7d
GK
2360 {
2361 rtx reg = gen_reg_rtx (Pmode);
2362 emit_insn (gen_elf_high (reg, (x)));
2363 return gen_rtx_LO_SUM (Pmode, reg, (x));
2364 }
ee890fe2
SS
2365 else if (TARGET_MACHO && TARGET_32BIT && TARGET_NO_TOC
2366 && ! flag_pic
ab82a49f
AP
2367#if TARGET_MACHO
2368 && ! MACHO_DYNAMIC_NO_PIC_P
2369#endif
ee890fe2
SS
2370 && GET_CODE (x) != CONST_INT
2371 && GET_CODE (x) != CONST_DOUBLE
2372 && CONSTANT_P (x)
a3170dc6 2373 && ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode)
ee890fe2
SS
2374 && mode != DImode
2375 && mode != TImode)
2376 {
2377 rtx reg = gen_reg_rtx (Pmode);
2378 emit_insn (gen_macho_high (reg, (x)));
2379 return gen_rtx_LO_SUM (Pmode, reg, (x));
2380 }
9ebbca7d
GK
2381 else if (TARGET_TOC
2382 && CONSTANT_POOL_EXPR_P (x)
a9098fd0 2383 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), Pmode))
9ebbca7d
GK
2384 {
2385 return create_TOC_reference (x);
2386 }
2387 else
2388 return NULL_RTX;
2389}
258bfae2 2390
24ea750e
DJ
2391/* The convention appears to be to define this wherever it is used.
2392 With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
2393 is now used here. */
2394#ifndef REG_MODE_OK_FOR_BASE_P
2395#define REG_MODE_OK_FOR_BASE_P(REGNO, MODE) REG_OK_FOR_BASE_P (REGNO)
2396#endif
2397
2398/* Our implementation of LEGITIMIZE_RELOAD_ADDRESS. Returns a value to
2399 replace the input X, or the original X if no replacement is called for.
2400 The output parameter *WIN is 1 if the calling macro should goto WIN,
2401 0 if it should not.
2402
2403 For RS/6000, we wish to handle large displacements off a base
2404 register by splitting the addend across an addiu/addis and the mem insn.
2405 This cuts number of extra insns needed from 3 to 1.
2406
2407 On Darwin, we use this to generate code for floating point constants.
2408 A movsf_low is generated so we wind up with 2 instructions rather than 3.
2409 The Darwin code is inside #if TARGET_MACHO because only then is
2410 machopic_function_base_name() defined. */
2411rtx
2412rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
2413 rtx x;
2414 enum machine_mode mode;
2415 int opnum;
2416 int type;
2417 int ind_levels ATTRIBUTE_UNUSED;
2418 int *win;
2419{
2420 /* We must recognize output that we have already generated ourselves. */
2421 if (GET_CODE (x) == PLUS
2422 && GET_CODE (XEXP (x, 0)) == PLUS
2423 && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
2424 && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
2425 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2426 {
2427 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2428 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2429 opnum, (enum reload_type)type);
2430 *win = 1;
2431 return x;
2432 }
3deb2758 2433
24ea750e
DJ
2434#if TARGET_MACHO
2435 if (DEFAULT_ABI == ABI_DARWIN && flag_pic
2436 && GET_CODE (x) == LO_SUM
2437 && GET_CODE (XEXP (x, 0)) == PLUS
2438 && XEXP (XEXP (x, 0), 0) == pic_offset_table_rtx
2439 && GET_CODE (XEXP (XEXP (x, 0), 1)) == HIGH
2440 && GET_CODE (XEXP (XEXP (XEXP (x, 0), 1), 0)) == CONST
2441 && XEXP (XEXP (XEXP (x, 0), 1), 0) == XEXP (x, 1)
2442 && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
2443 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
2444 && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF)
2445 {
2446 /* Result of previous invocation of this function on Darwin
6f317ef3 2447 floating point constant. */
24ea750e
DJ
2448 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2449 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2450 opnum, (enum reload_type)type);
2451 *win = 1;
2452 return x;
2453 }
2454#endif
2455 if (GET_CODE (x) == PLUS
2456 && GET_CODE (XEXP (x, 0)) == REG
2457 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
2458 && REG_MODE_OK_FOR_BASE_P (XEXP (x, 0), mode)
78c875e8 2459 && GET_CODE (XEXP (x, 1)) == CONST_INT
93638d7a 2460 && !SPE_VECTOR_MODE (mode)
78c875e8 2461 && !ALTIVEC_VECTOR_MODE (mode))
24ea750e
DJ
2462 {
2463 HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
2464 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
2465 HOST_WIDE_INT high
2466 = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
2467
2468 /* Check for 32-bit overflow. */
2469 if (high + low != val)
2470 {
2471 *win = 0;
2472 return x;
2473 }
2474
2475 /* Reload the high part into a base reg; leave the low part
2476 in the mem directly. */
2477
2478 x = gen_rtx_PLUS (GET_MODE (x),
2479 gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0),
2480 GEN_INT (high)),
2481 GEN_INT (low));
2482
2483 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2484 BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
2485 opnum, (enum reload_type)type);
2486 *win = 1;
2487 return x;
2488 }
2489#if TARGET_MACHO
2490 if (GET_CODE (x) == SYMBOL_REF
2491 && DEFAULT_ABI == ABI_DARWIN
69ef87e2 2492 && !ALTIVEC_VECTOR_MODE (mode)
24ea750e
DJ
2493 && flag_pic)
2494 {
2495 /* Darwin load of floating point constant. */
2496 rtx offset = gen_rtx (CONST, Pmode,
2497 gen_rtx (MINUS, Pmode, x,
2498 gen_rtx (SYMBOL_REF, Pmode,
2499 machopic_function_base_name ())));
2500 x = gen_rtx (LO_SUM, GET_MODE (x),
2501 gen_rtx (PLUS, Pmode, pic_offset_table_rtx,
2502 gen_rtx (HIGH, Pmode, offset)), offset);
2503 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2504 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2505 opnum, (enum reload_type)type);
2506 *win = 1;
2507 return x;
2508 }
ab82a49f
AP
2509 if (GET_CODE (x) == SYMBOL_REF
2510 && DEFAULT_ABI == ABI_DARWIN
2511 && !ALTIVEC_VECTOR_MODE (mode)
2512 && MACHO_DYNAMIC_NO_PIC_P)
2513 {
2514 /* Darwin load of floating point constant. */
2515 x = gen_rtx (LO_SUM, GET_MODE (x),
2516 gen_rtx (HIGH, Pmode, x), x);
2517 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
2518 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
2519 opnum, (enum reload_type)type);
2520 *win = 1;
2521 return x;
2522 }
24ea750e
DJ
2523#endif
2524 if (TARGET_TOC
c1f11548
DE
2525 && CONSTANT_POOL_EXPR_P (x)
2526 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x), mode))
24ea750e
DJ
2527 {
2528 (x) = create_TOC_reference (x);
2529 *win = 1;
2530 return x;
2531 }
2532 *win = 0;
2533 return x;
2534}
2535
258bfae2
FS
2536/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
2537 that is a valid memory address for an instruction.
2538 The MODE argument is the machine mode for the MEM expression
2539 that wants to use this address.
2540
2541 On the RS/6000, there are four valid address: a SYMBOL_REF that
2542 refers to a constant pool entry of an address (or the sum of it
2543 plus a constant), a short (16-bit signed) constant plus a register,
2544 the sum of two registers, or a register indirect, possibly with an
5bdc5878 2545 auto-increment. For DFmode and DImode with a constant plus register,
258bfae2
FS
2546 we must ensure that both words are addressable or PowerPC64 with offset
2547 word aligned.
2548
2549 For modes spanning multiple registers (DFmode in 32-bit GPRs,
2550 32-bit DImode, TImode), indexed addressing cannot be used because
2551 adjacent memory cells are accessed by adding word-sized offsets
2552 during assembly output. */
2553int
2554rs6000_legitimate_address (mode, x, reg_ok_strict)
2555 enum machine_mode mode;
2556 rtx x;
2557 int reg_ok_strict;
2558{
2559 if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
2560 return 1;
2561 if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
0d6d6892 2562 && !ALTIVEC_VECTOR_MODE (mode)
a3170dc6 2563 && !SPE_VECTOR_MODE (mode)
258bfae2
FS
2564 && TARGET_UPDATE
2565 && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
2566 return 1;
2567 if (LEGITIMATE_SMALL_DATA_P (mode, x))
2568 return 1;
2569 if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
2570 return 1;
2571 /* If not REG_OK_STRICT (before reload) let pass any stack offset. */
2572 if (! reg_ok_strict
2573 && GET_CODE (x) == PLUS
2574 && GET_CODE (XEXP (x, 0)) == REG
2575 && XEXP (x, 0) == virtual_stack_vars_rtx
2576 && GET_CODE (XEXP (x, 1)) == CONST_INT)
2577 return 1;
2578 if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
2579 return 1;
2580 if (mode != TImode
a3170dc6
AH
2581 && ((TARGET_HARD_FLOAT && TARGET_FPRS)
2582 || TARGET_POWERPC64
fcce224d 2583 || (mode != DFmode && mode != TFmode))
258bfae2
FS
2584 && (TARGET_POWERPC64 || mode != DImode)
2585 && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
2586 return 1;
2587 if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
2588 return 1;
2589 return 0;
2590}
fb4d4348 2591\f
a4f6c312
SS
2592/* Try to output insns to set TARGET equal to the constant C if it can
2593 be done in less than N insns. Do all computations in MODE.
2594 Returns the place where the output has been placed if it can be
2595 done and the insns have been emitted. If it would take more than N
2596 insns, zero is returned and no insns and emitted. */
2bfcf297
DB
2597
2598rtx
2599rs6000_emit_set_const (dest, mode, source, n)
2600 rtx dest, source;
2601 enum machine_mode mode;
2602 int n ATTRIBUTE_UNUSED;
2603{
af8cb5c5 2604 rtx result, insn, set;
2bfcf297
DB
2605 HOST_WIDE_INT c0, c1;
2606
af8cb5c5 2607 if (mode == QImode || mode == HImode)
2bfcf297
DB
2608 {
2609 if (dest == NULL)
2610 dest = gen_reg_rtx (mode);
2611 emit_insn (gen_rtx_SET (VOIDmode, dest, source));
2612 return dest;
2613 }
af8cb5c5 2614 else if (mode == SImode)
2bfcf297 2615 {
af8cb5c5
DE
2616 result = no_new_pseudos ? dest : gen_reg_rtx (SImode);
2617
2618 emit_insn (gen_rtx_SET (VOIDmode, result,
2619 GEN_INT (INTVAL (source)
2620 & (~ (HOST_WIDE_INT) 0xffff))));
2621 emit_insn (gen_rtx_SET (VOIDmode, dest,
2622 gen_rtx_IOR (SImode, result,
2623 GEN_INT (INTVAL (source) & 0xffff))));
2624 result = dest;
2bfcf297 2625 }
af8cb5c5 2626 else if (mode == DImode)
2bfcf297 2627 {
af8cb5c5
DE
2628 if (GET_CODE (source) == CONST_INT)
2629 {
2630 c0 = INTVAL (source);
2631 c1 = -(c0 < 0);
2632 }
2633 else if (GET_CODE (source) == CONST_DOUBLE)
2634 {
2bfcf297 2635#if HOST_BITS_PER_WIDE_INT >= 64
af8cb5c5
DE
2636 c0 = CONST_DOUBLE_LOW (source);
2637 c1 = -(c0 < 0);
2bfcf297 2638#else
af8cb5c5
DE
2639 c0 = CONST_DOUBLE_LOW (source);
2640 c1 = CONST_DOUBLE_HIGH (source);
2bfcf297 2641#endif
af8cb5c5
DE
2642 }
2643 else
2644 abort ();
2645
2646 result = rs6000_emit_set_long_const (dest, c0, c1);
2bfcf297
DB
2647 }
2648 else
a4f6c312 2649 abort ();
2bfcf297 2650
af8cb5c5
DE
2651 insn = get_last_insn ();
2652 set = single_set (insn);
2653 if (! CONSTANT_P (SET_SRC (set)))
2654 set_unique_reg_note (insn, REG_EQUAL, source);
2655
2656 return result;
2bfcf297
DB
2657}
2658
2659/* Having failed to find a 3 insn sequence in rs6000_emit_set_const,
2660 fall back to a straight forward decomposition. We do this to avoid
2661 exponential run times encountered when looking for longer sequences
2662 with rs6000_emit_set_const. */
2663static rtx
2664rs6000_emit_set_long_const (dest, c1, c2)
2665 rtx dest;
2666 HOST_WIDE_INT c1, c2;
2667{
2668 if (!TARGET_POWERPC64)
2669 {
2670 rtx operand1, operand2;
2671
2672 operand1 = operand_subword_force (dest, WORDS_BIG_ENDIAN == 0,
2673 DImode);
2674 operand2 = operand_subword_force (dest, WORDS_BIG_ENDIAN != 0,
2675 DImode);
2676 emit_move_insn (operand1, GEN_INT (c1));
2677 emit_move_insn (operand2, GEN_INT (c2));
2678 }
2679 else
2680 {
bc06712d 2681 HOST_WIDE_INT ud1, ud2, ud3, ud4;
252b88f7 2682
bc06712d
TR
2683 ud1 = c1 & 0xffff;
2684 ud2 = (c1 & 0xffff0000) >> 16;
2bfcf297 2685#if HOST_BITS_PER_WIDE_INT >= 64
bc06712d 2686 c2 = c1 >> 32;
2bfcf297 2687#endif
bc06712d
TR
2688 ud3 = c2 & 0xffff;
2689 ud4 = (c2 & 0xffff0000) >> 16;
2bfcf297 2690
bc06712d
TR
2691 if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000))
2692 || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
2bfcf297 2693 {
bc06712d
TR
2694 if (ud1 & 0x8000)
2695 emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
2696 else
2697 emit_move_insn (dest, GEN_INT (ud1));
2bfcf297 2698 }
2bfcf297 2699
bc06712d
TR
2700 else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000))
2701 || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000)))
252b88f7 2702 {
bc06712d
TR
2703 if (ud2 & 0x8000)
2704 emit_move_insn (dest, GEN_INT (((ud2 << 16) ^ 0x80000000)
2705 - 0x80000000));
252b88f7 2706 else
bc06712d
TR
2707 emit_move_insn (dest, GEN_INT (ud2 << 16));
2708 if (ud1 != 0)
2709 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
252b88f7 2710 }
bc06712d
TR
2711 else if ((ud4 == 0xffff && (ud3 & 0x8000))
2712 || (ud4 == 0 && ! (ud3 & 0x8000)))
2713 {
2714 if (ud3 & 0x8000)
2715 emit_move_insn (dest, GEN_INT (((ud3 << 16) ^ 0x80000000)
2716 - 0x80000000));
2717 else
2718 emit_move_insn (dest, GEN_INT (ud3 << 16));
2719
2720 if (ud2 != 0)
2721 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2)));
2722 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (16)));
2723 if (ud1 != 0)
2724 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2725 }
2726 else
2727 {
2728 if (ud4 & 0x8000)
2729 emit_move_insn (dest, GEN_INT (((ud4 << 16) ^ 0x80000000)
2730 - 0x80000000));
2731 else
2732 emit_move_insn (dest, GEN_INT (ud4 << 16));
2733
2734 if (ud3 != 0)
2735 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3)));
2bfcf297 2736
bc06712d
TR
2737 emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32)));
2738 if (ud2 != 0)
2739 emit_move_insn (dest, gen_rtx_IOR (DImode, dest,
2740 GEN_INT (ud2 << 16)));
2741 if (ud1 != 0)
2742 emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1)));
2743 }
2744 }
2bfcf297
DB
2745 return dest;
2746}
2747
fb4d4348
GK
2748/* Emit a move from SOURCE to DEST in mode MODE. */
2749void
2750rs6000_emit_move (dest, source, mode)
2751 rtx dest;
2752 rtx source;
2753 enum machine_mode mode;
2754{
2755 rtx operands[2];
2756 operands[0] = dest;
2757 operands[1] = source;
2758
2759 /* Sanity checks. Check that we get CONST_DOUBLE only when we should. */
2760 if (GET_CODE (operands[1]) == CONST_DOUBLE
2761 && ! FLOAT_MODE_P (mode)
2762 && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
2763 {
2764 /* FIXME. This should never happen. */
2765 /* Since it seems that it does, do the safe thing and convert
2766 to a CONST_INT. */
2496c7bd 2767 operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), mode);
fb4d4348
GK
2768 }
2769 if (GET_CODE (operands[1]) == CONST_DOUBLE
2770 && ! FLOAT_MODE_P (mode)
2771 && ((CONST_DOUBLE_HIGH (operands[1]) == 0
2772 && CONST_DOUBLE_LOW (operands[1]) >= 0)
2773 || (CONST_DOUBLE_HIGH (operands[1]) == -1
2774 && CONST_DOUBLE_LOW (operands[1]) < 0)))
2775 abort ();
c9e8cb32
DD
2776
2777 /* Check if GCC is setting up a block move that will end up using FP
2778 registers as temporaries. We must make sure this is acceptable. */
2779 if (GET_CODE (operands[0]) == MEM
2780 && GET_CODE (operands[1]) == MEM
2781 && mode == DImode
41543739
GK
2782 && (SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[0]))
2783 || SLOW_UNALIGNED_ACCESS (DImode, MEM_ALIGN (operands[1])))
2784 && ! (SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[0]) > 32
2785 ? 32 : MEM_ALIGN (operands[0])))
2786 || SLOW_UNALIGNED_ACCESS (SImode, (MEM_ALIGN (operands[1]) > 32
2787 ? 32
2788 : MEM_ALIGN (operands[1]))))
2789 && ! MEM_VOLATILE_P (operands [0])
2790 && ! MEM_VOLATILE_P (operands [1]))
c9e8cb32 2791 {
41543739
GK
2792 emit_move_insn (adjust_address (operands[0], SImode, 0),
2793 adjust_address (operands[1], SImode, 0));
2794 emit_move_insn (adjust_address (operands[0], SImode, 4),
2795 adjust_address (operands[1], SImode, 4));
c9e8cb32
DD
2796 return;
2797 }
fb4d4348 2798
67cef334
DE
2799 if (!no_new_pseudos)
2800 {
2801 if (GET_CODE (operands[1]) == MEM && optimize > 0
2802 && (mode == QImode || mode == HImode || mode == SImode)
2803 && GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
2804 {
2805 rtx reg = gen_reg_rtx (word_mode);
2806
2807 emit_insn (gen_rtx_SET (word_mode, reg,
2808 gen_rtx_ZERO_EXTEND (word_mode,
2809 operands[1])));
2810 operands[1] = gen_lowpart (mode, reg);
2811 }
2812 if (GET_CODE (operands[0]) != REG)
2813 operands[1] = force_reg (mode, operands[1]);
2814 }
a9098fd0 2815
a3170dc6
AH
2816 if (mode == SFmode && ! TARGET_POWERPC
2817 && TARGET_HARD_FLOAT && TARGET_FPRS
ffc14f31 2818 && GET_CODE (operands[0]) == MEM)
fb4d4348 2819 {
ffc14f31
GK
2820 int regnum;
2821
2822 if (reload_in_progress || reload_completed)
2823 regnum = true_regnum (operands[1]);
2824 else if (GET_CODE (operands[1]) == REG)
2825 regnum = REGNO (operands[1]);
2826 else
2827 regnum = -1;
fb4d4348
GK
2828
2829 /* If operands[1] is a register, on POWER it may have
2830 double-precision data in it, so truncate it to single
2831 precision. */
2832 if (FP_REGNO_P (regnum) || regnum >= FIRST_PSEUDO_REGISTER)
2833 {
2834 rtx newreg;
2835 newreg = (no_new_pseudos ? operands[1] : gen_reg_rtx (mode));
2836 emit_insn (gen_aux_truncdfsf2 (newreg, operands[1]));
2837 operands[1] = newreg;
2838 }
2839 }
2840
a9098fd0
GK
2841 /* Handle the case where reload calls us with an invalid address;
2842 and the case of CONSTANT_P_RTX. */
16861f33 2843 if (!ALTIVEC_VECTOR_MODE (mode)
69ef87e2
AH
2844 && (! general_operand (operands[1], mode)
2845 || ! nonimmediate_operand (operands[0], mode)
2846 || GET_CODE (operands[1]) == CONSTANT_P_RTX))
fb4d4348
GK
2847 {
2848 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2849 return;
2850 }
a9098fd0 2851
fb4d4348
GK
2852 /* FIXME: In the long term, this switch statement should go away
2853 and be replaced by a sequence of tests based on things like
2854 mode == Pmode. */
2855 switch (mode)
2856 {
2857 case HImode:
2858 case QImode:
2859 if (CONSTANT_P (operands[1])
2860 && GET_CODE (operands[1]) != CONST_INT)
a9098fd0 2861 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2862 break;
2863
06f4e019 2864 case TFmode:
fb4d4348
GK
2865 case DFmode:
2866 case SFmode:
2867 if (CONSTANT_P (operands[1])
2868 && ! easy_fp_constant (operands[1], mode))
a9098fd0 2869 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
2870 break;
2871
0ac081f6
AH
2872 case V16QImode:
2873 case V8HImode:
2874 case V4SFmode:
2875 case V4SImode:
a3170dc6
AH
2876 case V4HImode:
2877 case V2SFmode:
2878 case V2SImode:
00a892b8 2879 case V1DImode:
69ef87e2 2880 if (CONSTANT_P (operands[1])
d744e06e 2881 && !easy_vector_constant (operands[1], mode))
0ac081f6
AH
2882 operands[1] = force_const_mem (mode, operands[1]);
2883 break;
2884
fb4d4348 2885 case SImode:
a9098fd0 2886 case DImode:
fb4d4348
GK
2887 /* Use default pattern for address of ELF small data */
2888 if (TARGET_ELF
a9098fd0 2889 && mode == Pmode
f607bc57 2890 && DEFAULT_ABI == ABI_V4
a9098fd0
GK
2891 && (GET_CODE (operands[1]) == SYMBOL_REF
2892 || GET_CODE (operands[1]) == CONST)
2893 && small_data_operand (operands[1], mode))
fb4d4348
GK
2894 {
2895 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
2896 return;
2897 }
2898
f607bc57 2899 if (DEFAULT_ABI == ABI_V4
a9098fd0
GK
2900 && mode == Pmode && mode == SImode
2901 && flag_pic == 1 && got_operand (operands[1], mode))
fb4d4348
GK
2902 {
2903 emit_insn (gen_movsi_got (operands[0], operands[1]));
2904 return;
2905 }
2906
ee890fe2 2907 if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
f1384257
AM
2908 && TARGET_NO_TOC
2909 && ! flag_pic
a9098fd0 2910 && mode == Pmode
fb4d4348
GK
2911 && CONSTANT_P (operands[1])
2912 && GET_CODE (operands[1]) != HIGH
2913 && GET_CODE (operands[1]) != CONST_INT)
2914 {
a9098fd0 2915 rtx target = (no_new_pseudos ? operands[0] : gen_reg_rtx (mode));
fb4d4348
GK
2916
2917 /* If this is a function address on -mcall-aixdesc,
2918 convert it to the address of the descriptor. */
2919 if (DEFAULT_ABI == ABI_AIX
2920 && GET_CODE (operands[1]) == SYMBOL_REF
2921 && XSTR (operands[1], 0)[0] == '.')
2922 {
2923 const char *name = XSTR (operands[1], 0);
2924 rtx new_ref;
2925 while (*name == '.')
2926 name++;
2927 new_ref = gen_rtx_SYMBOL_REF (Pmode, name);
2928 CONSTANT_POOL_ADDRESS_P (new_ref)
2929 = CONSTANT_POOL_ADDRESS_P (operands[1]);
2930 SYMBOL_REF_FLAG (new_ref) = SYMBOL_REF_FLAG (operands[1]);
2931 SYMBOL_REF_USED (new_ref) = SYMBOL_REF_USED (operands[1]);
2932 operands[1] = new_ref;
2933 }
7509c759 2934
ee890fe2
SS
2935 if (DEFAULT_ABI == ABI_DARWIN)
2936 {
ab82a49f
AP
2937#if TARGET_MACHO
2938 if (MACHO_DYNAMIC_NO_PIC_P)
2939 {
2940 /* Take care of any required data indirection. */
2941 operands[1] = rs6000_machopic_legitimize_pic_address (
2942 operands[1], mode, operands[0]);
2943 if (operands[0] != operands[1])
2944 emit_insn (gen_rtx_SET (VOIDmode,
2945 operands[0], operands[1]));
2946 return;
2947 }
2948#endif
ee890fe2
SS
2949 emit_insn (gen_macho_high (target, operands[1]));
2950 emit_insn (gen_macho_low (operands[0], target, operands[1]));
2951 return;
2952 }
2953
fb4d4348
GK
2954 emit_insn (gen_elf_high (target, operands[1]));
2955 emit_insn (gen_elf_low (operands[0], target, operands[1]));
2956 return;
2957 }
2958
a9098fd0
GK
2959 /* If this is a SYMBOL_REF that refers to a constant pool entry,
2960 and we have put it in the TOC, we just need to make a TOC-relative
2961 reference to it. */
2962 if (TARGET_TOC
2963 && GET_CODE (operands[1]) == SYMBOL_REF
2964 && CONSTANT_POOL_EXPR_P (operands[1])
2965 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (operands[1]),
2966 get_pool_mode (operands[1])))
fb4d4348 2967 {
a9098fd0 2968 operands[1] = create_TOC_reference (operands[1]);
fb4d4348 2969 }
a9098fd0
GK
2970 else if (mode == Pmode
2971 && CONSTANT_P (operands[1])
38886f37
AO
2972 && ((GET_CODE (operands[1]) != CONST_INT
2973 && ! easy_fp_constant (operands[1], mode))
2974 || (GET_CODE (operands[1]) == CONST_INT
2975 && num_insns_constant (operands[1], mode) > 2)
2976 || (GET_CODE (operands[0]) == REG
2977 && FP_REGNO_P (REGNO (operands[0]))))
a9098fd0
GK
2978 && GET_CODE (operands[1]) != HIGH
2979 && ! LEGITIMATE_CONSTANT_POOL_ADDRESS_P (operands[1])
2980 && ! TOC_RELATIVE_EXPR_P (operands[1]))
fb4d4348
GK
2981 {
2982 /* Emit a USE operation so that the constant isn't deleted if
2983 expensive optimizations are turned on because nobody
2984 references it. This should only be done for operands that
2985 contain SYMBOL_REFs with CONSTANT_POOL_ADDRESS_P set.
2986 This should not be done for operands that contain LABEL_REFs.
2987 For now, we just handle the obvious case. */
2988 if (GET_CODE (operands[1]) != LABEL_REF)
2989 emit_insn (gen_rtx_USE (VOIDmode, operands[1]));
2990
c859cda6 2991#if TARGET_MACHO
ee890fe2 2992 /* Darwin uses a special PIC legitimizer. */
ab82a49f 2993 if (DEFAULT_ABI == ABI_DARWIN && MACHOPIC_INDIRECT)
ee890fe2 2994 {
ee890fe2
SS
2995 operands[1] =
2996 rs6000_machopic_legitimize_pic_address (operands[1], mode,
c859cda6
DJ
2997 operands[0]);
2998 if (operands[0] != operands[1])
2999 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
ee890fe2
SS
3000 return;
3001 }
c859cda6 3002#endif
ee890fe2 3003
fb4d4348
GK
3004 /* If we are to limit the number of things we put in the TOC and
3005 this is a symbol plus a constant we can add in one insn,
3006 just put the symbol in the TOC and add the constant. Don't do
3007 this if reload is in progress. */
3008 if (GET_CODE (operands[1]) == CONST
3009 && TARGET_NO_SUM_IN_TOC && ! reload_in_progress
3010 && GET_CODE (XEXP (operands[1], 0)) == PLUS
a9098fd0 3011 && add_operand (XEXP (XEXP (operands[1], 0), 1), mode)
fb4d4348
GK
3012 && (GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF
3013 || GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
3014 && ! side_effects_p (operands[0]))
3015 {
a4f6c312
SS
3016 rtx sym =
3017 force_const_mem (mode, XEXP (XEXP (operands[1], 0), 0));
fb4d4348
GK
3018 rtx other = XEXP (XEXP (operands[1], 0), 1);
3019
a9098fd0
GK
3020 sym = force_reg (mode, sym);
3021 if (mode == SImode)
3022 emit_insn (gen_addsi3 (operands[0], sym, other));
3023 else
3024 emit_insn (gen_adddi3 (operands[0], sym, other));
fb4d4348
GK
3025 return;
3026 }
3027
a9098fd0 3028 operands[1] = force_const_mem (mode, operands[1]);
fb4d4348
GK
3029
3030 if (TARGET_TOC
d34c5b80
DE
3031 && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
3032 && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (
3033 get_pool_constant (XEXP (operands[1], 0)),
3034 get_pool_mode (XEXP (operands[1], 0))))
a9098fd0 3035 {
ba4828e0
RK
3036 operands[1]
3037 = gen_rtx_MEM (mode,
3038 create_TOC_reference (XEXP (operands[1], 0)));
3039 set_mem_alias_set (operands[1], get_TOC_alias_set ());
fb4d4348 3040 RTX_UNCHANGING_P (operands[1]) = 1;
a9098fd0 3041 }
fb4d4348
GK
3042 }
3043 break;
a9098fd0 3044
fb4d4348
GK
3045 case TImode:
3046 if (GET_CODE (operands[0]) == MEM
3047 && GET_CODE (XEXP (operands[0], 0)) != REG
3048 && ! reload_in_progress)
792760b9
RK
3049 operands[0]
3050 = replace_equiv_address (operands[0],
3051 copy_addr_to_reg (XEXP (operands[0], 0)));
fb4d4348
GK
3052
3053 if (GET_CODE (operands[1]) == MEM
3054 && GET_CODE (XEXP (operands[1], 0)) != REG
3055 && ! reload_in_progress)
792760b9
RK
3056 operands[1]
3057 = replace_equiv_address (operands[1],
3058 copy_addr_to_reg (XEXP (operands[1], 0)));
27dc0551
DE
3059 if (TARGET_POWER)
3060 {
3061 emit_insn (gen_rtx_PARALLEL (VOIDmode,
3062 gen_rtvec (2,
3063 gen_rtx_SET (VOIDmode,
3064 operands[0], operands[1]),
3065 gen_rtx_CLOBBER (VOIDmode,
3066 gen_rtx_SCRATCH (SImode)))));
3067 return;
3068 }
fb4d4348
GK
3069 break;
3070
3071 default:
3072 abort ();
3073 }
3074
a9098fd0
GK
3075 /* Above, we may have called force_const_mem which may have returned
3076 an invalid address. If we can, fix this up; otherwise, reload will
3077 have to deal with it. */
3078 if (GET_CODE (operands[1]) == MEM
3079 && ! memory_address_p (mode, XEXP (operands[1], 0))
3080 && ! reload_in_progress)
f4ef873c 3081 operands[1] = adjust_address (operands[1], mode, 0);
a9098fd0 3082
fb4d4348 3083 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
02a4ec28 3084 return;
fb4d4348 3085}
4697a36c
MM
3086\f
3087/* Initialize a variable CUM of type CUMULATIVE_ARGS
3088 for a call to a function whose data type is FNTYPE.
3089 For a library call, FNTYPE is 0.
3090
3091 For incoming args we set the number of arguments in the prototype large
1c20ae99 3092 so we never return a PARALLEL. */
4697a36c
MM
3093
3094void
3095init_cumulative_args (cum, fntype, libname, incoming)
3096 CUMULATIVE_ARGS *cum;
3097 tree fntype;
296b8152 3098 rtx libname ATTRIBUTE_UNUSED;
4697a36c
MM
3099 int incoming;
3100{
3101 static CUMULATIVE_ARGS zero_cumulative;
3102
3103 *cum = zero_cumulative;
3104 cum->words = 0;
3105 cum->fregno = FP_ARG_MIN_REG;
0ac081f6 3106 cum->vregno = ALTIVEC_ARG_MIN_REG;
4697a36c 3107 cum->prototype = (fntype && TYPE_ARG_TYPES (fntype));
7509c759 3108 cum->call_cookie = CALL_NORMAL;
4cc833b7 3109 cum->sysv_gregno = GP_ARG_MIN_REG;
4697a36c
MM
3110
3111 if (incoming)
bd227acc 3112 cum->nargs_prototype = 1000; /* don't return a PARALLEL */
4697a36c
MM
3113
3114 else if (cum->prototype)
3115 cum->nargs_prototype = (list_length (TYPE_ARG_TYPES (fntype)) - 1
3116 + (TYPE_MODE (TREE_TYPE (fntype)) == BLKmode
3117 || RETURN_IN_MEMORY (TREE_TYPE (fntype))));
3118
3119 else
3120 cum->nargs_prototype = 0;
3121
3122 cum->orig_nargs = cum->nargs_prototype;
7509c759 3123
a5c76ee6
ZW
3124 /* Check for a longcall attribute. */
3125 if (fntype
3126 && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
3127 && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
6a4cee5f
MM
3128 cum->call_cookie = CALL_LONG;
3129
4697a36c
MM
3130 if (TARGET_DEBUG_ARG)
3131 {
3132 fprintf (stderr, "\ninit_cumulative_args:");
3133 if (fntype)
3134 {
3135 tree ret_type = TREE_TYPE (fntype);
3136 fprintf (stderr, " ret code = %s,",
3137 tree_code_name[ (int)TREE_CODE (ret_type) ]);
3138 }
3139
6a4cee5f
MM
3140 if (cum->call_cookie & CALL_LONG)
3141 fprintf (stderr, " longcall,");
3142
4697a36c
MM
3143 fprintf (stderr, " proto = %d, nargs = %d\n",
3144 cum->prototype, cum->nargs_prototype);
3145 }
3146}
3147\f
c229cba9
DE
3148/* If defined, a C expression which determines whether, and in which
3149 direction, to pad out an argument with extra space. The value
3150 should be of type `enum direction': either `upward' to pad above
3151 the argument, `downward' to pad below, or `none' to inhibit
3152 padding.
3153
3154 For the AIX ABI structs are always stored left shifted in their
3155 argument slot. */
3156
9ebbca7d 3157enum direction
c229cba9
DE
3158function_arg_padding (mode, type)
3159 enum machine_mode mode;
3160 tree type;
3161{
c85f7c16 3162 if (type != 0 && AGGREGATE_TYPE_P (type))
9ebbca7d 3163 return upward;
c229cba9
DE
3164
3165 /* This is the default definition. */
3166 return (! BYTES_BIG_ENDIAN
9ebbca7d 3167 ? upward
c229cba9
DE
3168 : ((mode == BLKmode
3169 ? (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
3170 && int_size_in_bytes (type) < (PARM_BOUNDARY / BITS_PER_UNIT))
3171 : GET_MODE_BITSIZE (mode) < PARM_BOUNDARY)
9ebbca7d 3172 ? downward : upward));
c229cba9
DE
3173}
3174
b6c9286a
MM
3175/* If defined, a C expression that gives the alignment boundary, in bits,
3176 of an argument with the specified mode and type. If it is not defined,
3177 PARM_BOUNDARY is used for all arguments.
3178
2310f99a 3179 V.4 wants long longs to be double word aligned. */
b6c9286a
MM
3180
3181int
3182function_arg_boundary (mode, type)
3183 enum machine_mode mode;
9ebbca7d 3184 tree type ATTRIBUTE_UNUSED;
b6c9286a 3185{
f607bc57 3186 if (DEFAULT_ABI == ABI_V4 && (mode == DImode || mode == DFmode))
e1f83b4d 3187 return 64;
a3170dc6
AH
3188 else if (SPE_VECTOR_MODE (mode))
3189 return 64;
0ac081f6
AH
3190 else if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3191 return 128;
9ebbca7d 3192 else
b6c9286a 3193 return PARM_BOUNDARY;
b6c9286a
MM
3194}
3195\f
4697a36c
MM
3196/* Update the data in CUM to advance over an argument
3197 of mode MODE and data type TYPE.
3198 (TYPE is null for libcalls where that information may not be available.) */
3199
3200void
3201function_arg_advance (cum, mode, type, named)
3202 CUMULATIVE_ARGS *cum;
3203 enum machine_mode mode;
3204 tree type;
3205 int named;
3206{
3207 cum->nargs_prototype--;
3208
0ac081f6
AH
3209 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3210 {
3211 if (cum->vregno <= ALTIVEC_ARG_MAX_REG && cum->nargs_prototype >= 0)
3212 cum->vregno++;
3213 else
3214 cum->words += RS6000_ARG_SIZE (mode, type);
3215 }
a4b0320c
AH
3216 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode)
3217 && named && cum->sysv_gregno <= GP_ARG_MAX_REG)
3218 cum->sysv_gregno++;
f607bc57 3219 else if (DEFAULT_ABI == ABI_V4)
4697a36c 3220 {
a3170dc6 3221 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7 3222 && (mode == SFmode || mode == DFmode))
4697a36c 3223 {
4cc833b7
RH
3224 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3225 cum->fregno++;
3226 else
3227 {
3228 if (mode == DFmode)
3229 cum->words += cum->words & 1;
d34c5b80 3230 cum->words += RS6000_ARG_SIZE (mode, type);
4cc833b7 3231 }
4697a36c 3232 }
4cc833b7
RH
3233 else
3234 {
3235 int n_words;
3236 int gregno = cum->sysv_gregno;
3237
3238 /* Aggregates and IEEE quad get passed by reference. */
3239 if ((type && AGGREGATE_TYPE_P (type))
3240 || mode == TFmode)
3241 n_words = 1;
3242 else
d34c5b80 3243 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3244
a4b0320c 3245 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3246 if (n_words == 2 && (gregno & 1) == 0)
3247 gregno += 1;
3248
a4b0320c
AH
3249 /* Long long and SPE vectors are not split between registers
3250 and stack. */
4cc833b7
RH
3251 if (gregno + n_words - 1 > GP_ARG_MAX_REG)
3252 {
3253 /* Long long is aligned on the stack. */
3254 if (n_words == 2)
3255 cum->words += cum->words & 1;
3256 cum->words += n_words;
3257 }
4697a36c 3258
4cc833b7
RH
3259 /* Note: continuing to accumulate gregno past when we've started
3260 spilling to the stack indicates the fact that we've started
3261 spilling to the stack to expand_builtin_saveregs. */
3262 cum->sysv_gregno = gregno + n_words;
3263 }
4697a36c 3264
4cc833b7
RH
3265 if (TARGET_DEBUG_ARG)
3266 {
3267 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3268 cum->words, cum->fregno);
3269 fprintf (stderr, "gregno = %2d, nargs = %4d, proto = %d, ",
3270 cum->sysv_gregno, cum->nargs_prototype, cum->prototype);
3271 fprintf (stderr, "mode = %4s, named = %d\n",
3272 GET_MODE_NAME (mode), named);
3273 }
4697a36c
MM
3274 }
3275 else
4cc833b7
RH
3276 {
3277 int align = (TARGET_32BIT && (cum->words & 1) != 0
3278 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
a4f6c312 3279
d34c5b80 3280 cum->words += align + RS6000_ARG_SIZE (mode, type);
4697a36c 3281
a3170dc6
AH
3282 if (GET_MODE_CLASS (mode) == MODE_FLOAT
3283 && TARGET_HARD_FLOAT && TARGET_FPRS)
fcce224d 3284 cum->fregno += (mode == TFmode ? 2 : 1);
4cc833b7
RH
3285
3286 if (TARGET_DEBUG_ARG)
3287 {
3288 fprintf (stderr, "function_adv: words = %2d, fregno = %2d, ",
3289 cum->words, cum->fregno);
3290 fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
3291 cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
3292 fprintf (stderr, "named = %d, align = %d\n", named, align);
3293 }
3294 }
4697a36c
MM
3295}
3296\f
3297/* Determine where to put an argument to a function.
3298 Value is zero to push the argument on the stack,
3299 or a hard register in which to store the argument.
3300
3301 MODE is the argument's machine mode.
3302 TYPE is the data type of the argument (as a tree).
3303 This is null for libcalls where that information may
3304 not be available.
3305 CUM is a variable of type CUMULATIVE_ARGS which gives info about
3306 the preceding args and about the function being called.
3307 NAMED is nonzero if this argument is a named parameter
3308 (otherwise it is an extra parameter matching an ellipsis).
3309
3310 On RS/6000 the first eight words of non-FP are normally in registers
3311 and the rest are pushed. Under AIX, the first 13 FP args are in registers.
3312 Under V.4, the first 8 FP args are in registers.
3313
3314 If this is floating-point and no prototype is specified, we use
3315 both an FP and integer register (or possibly FP reg and stack). Library
3316 functions (when TYPE is zero) always have the proper types for args,
3317 so we can pass the FP value just in one register. emit_library_function
1c20ae99 3318 doesn't support PARALLEL anyway. */
4697a36c
MM
3319
3320struct rtx_def *
3321function_arg (cum, mode, type, named)
3322 CUMULATIVE_ARGS *cum;
3323 enum machine_mode mode;
3324 tree type;
20c29ebe 3325 int named;
4697a36c 3326{
4cc833b7 3327 enum rs6000_abi abi = DEFAULT_ABI;
4697a36c 3328
a4f6c312
SS
3329 /* Return a marker to indicate whether CR1 needs to set or clear the
3330 bit that V.4 uses to say fp args were passed in registers.
3331 Assume that we don't need the marker for software floating point,
3332 or compiler generated library calls. */
4697a36c
MM
3333 if (mode == VOIDmode)
3334 {
f607bc57 3335 if (abi == ABI_V4
7509c759 3336 && cum->nargs_prototype < 0
4697a36c 3337 && type && (cum->prototype || TARGET_NO_PROTOTYPE))
7509c759 3338 {
a3170dc6
AH
3339 /* For the SPE, we need to crxor CR6 always. */
3340 if (TARGET_SPE_ABI)
3341 return GEN_INT (cum->call_cookie | CALL_V4_SET_FP_ARGS);
3342 else if (TARGET_HARD_FLOAT && TARGET_FPRS)
3343 return GEN_INT (cum->call_cookie
3344 | ((cum->fregno == FP_ARG_MIN_REG)
3345 ? CALL_V4_SET_FP_ARGS
3346 : CALL_V4_CLEAR_FP_ARGS));
7509c759 3347 }
4697a36c 3348
7509c759 3349 return GEN_INT (cum->call_cookie);
4697a36c
MM
3350 }
3351
0ac081f6
AH
3352 if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
3353 {
20c29ebe 3354 if (named && cum->vregno <= ALTIVEC_ARG_MAX_REG)
0ac081f6
AH
3355 return gen_rtx_REG (mode, cum->vregno);
3356 else
3357 return NULL;
3358 }
a4b0320c 3359 else if (TARGET_SPE_ABI && TARGET_SPE && SPE_VECTOR_MODE (mode) && named)
a3170dc6 3360 {
a4b0320c 3361 if (cum->sysv_gregno <= GP_ARG_MAX_REG)
a3170dc6
AH
3362 return gen_rtx_REG (mode, cum->sysv_gregno);
3363 else
3364 return NULL;
3365 }
f607bc57 3366 else if (abi == ABI_V4)
4697a36c 3367 {
a3170dc6 3368 if (TARGET_HARD_FLOAT && TARGET_FPRS
4cc833b7
RH
3369 && (mode == SFmode || mode == DFmode))
3370 {
3371 if (cum->fregno <= FP_ARG_V4_MAX_REG)
3372 return gen_rtx_REG (mode, cum->fregno);
3373 else
3374 return NULL;
3375 }
3376 else
3377 {
3378 int n_words;
3379 int gregno = cum->sysv_gregno;
3380
3381 /* Aggregates and IEEE quad get passed by reference. */
3382 if ((type && AGGREGATE_TYPE_P (type))
3383 || mode == TFmode)
3384 n_words = 1;
3385 else
d34c5b80 3386 n_words = RS6000_ARG_SIZE (mode, type);
4cc833b7 3387
a4b0320c 3388 /* Long long and SPE vectors are put in odd registers. */
4cc833b7
RH
3389 if (n_words == 2 && (gregno & 1) == 0)
3390 gregno += 1;
3391
a4b0320c
AH
3392 /* Long long and SPE vectors are not split between registers
3393 and stack. */
4cc833b7 3394 if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
a4b0320c
AH
3395 {
3396 /* SPE vectors in ... get split into 2 registers. */
3397 if (TARGET_SPE && TARGET_SPE_ABI
3398 && SPE_VECTOR_MODE (mode) && !named)
3399 {
3400 rtx r1, r2;
57de2c8f 3401 enum machine_mode m = SImode;
f9dd72da 3402
a4b0320c
AH
3403 r1 = gen_rtx_REG (m, gregno);
3404 r1 = gen_rtx_EXPR_LIST (m, r1, const0_rtx);
3405 r2 = gen_rtx_REG (m, gregno + 1);
3406 r2 = gen_rtx_EXPR_LIST (m, r2, GEN_INT (4));
3407 return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
3408 }
3409 return gen_rtx_REG (mode, gregno);
3410 }
4cc833b7
RH
3411 else
3412 return NULL;
3413 }
4697a36c 3414 }
4cc833b7
RH
3415 else
3416 {
3417 int align = (TARGET_32BIT && (cum->words & 1) != 0
3418 && function_arg_boundary (mode, type) == 64) ? 1 : 0;
3419 int align_words = cum->words + align;
4697a36c 3420
4cc833b7
RH
3421 if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
3422 return NULL_RTX;
3423
3424 if (USE_FP_FOR_ARG_P (*cum, mode, type))
3425 {
3426 if (! type
3427 || ((cum->nargs_prototype > 0)
3428 /* IBM AIX extended its linkage convention definition always
3429 to require FP args after register save area hole on the
3430 stack. */
3431 && (DEFAULT_ABI != ABI_AIX
3432 || ! TARGET_XL_CALL
3433 || (align_words < GP_ARG_NUM_REG))))
3434 return gen_rtx_REG (mode, cum->fregno);
3435
3436 return gen_rtx_PARALLEL (mode,
3437 gen_rtvec (2,
39403d82 3438 gen_rtx_EXPR_LIST (VOIDmode,
1c20ae99
JW
3439 ((align_words >= GP_ARG_NUM_REG)
3440 ? NULL_RTX
3441 : (align_words
d34c5b80 3442 + RS6000_ARG_SIZE (mode, type)
1c20ae99
JW
3443 > GP_ARG_NUM_REG
3444 /* If this is partially on the stack, then
3445 we only include the portion actually
3446 in registers here. */
39403d82 3447 ? gen_rtx_REG (SImode,
1c20ae99 3448 GP_ARG_MIN_REG + align_words)
39403d82 3449 : gen_rtx_REG (mode,
1c20ae99
JW
3450 GP_ARG_MIN_REG + align_words))),
3451 const0_rtx),
39403d82
DE
3452 gen_rtx_EXPR_LIST (VOIDmode,
3453 gen_rtx_REG (mode, cum->fregno),
1c20ae99 3454 const0_rtx)));
4cc833b7
RH
3455 }
3456 else if (align_words < GP_ARG_NUM_REG)
3457 return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
3458 else
3459 return NULL_RTX;
4697a36c 3460 }
4697a36c
MM
3461}
3462\f
3463/* For an arg passed partly in registers and partly in memory,
3464 this is the number of registers used.
3465 For args passed entirely in registers or entirely in memory, zero. */
3466
3467int
3468function_arg_partial_nregs (cum, mode, type, named)
3469 CUMULATIVE_ARGS *cum;
3470 enum machine_mode mode;
3471 tree type;
d34c5b80 3472 int named ATTRIBUTE_UNUSED;
4697a36c 3473{
f607bc57 3474 if (DEFAULT_ABI == ABI_V4)
4697a36c 3475 return 0;
4697a36c 3476
0ac081f6
AH
3477 if (USE_FP_FOR_ARG_P (*cum, mode, type)
3478 || USE_ALTIVEC_FOR_ARG_P (*cum, mode, type))
4697a36c
MM
3479 {
3480 if (cum->nargs_prototype >= 0)
3481 return 0;
3482 }
3483
3484 if (cum->words < GP_ARG_NUM_REG
d34c5b80 3485 && GP_ARG_NUM_REG < (cum->words + RS6000_ARG_SIZE (mode, type)))
4697a36c
MM
3486 {
3487 int ret = GP_ARG_NUM_REG - cum->words;
3488 if (ret && TARGET_DEBUG_ARG)
3489 fprintf (stderr, "function_arg_partial_nregs: %d\n", ret);
3490
3491 return ret;
3492 }
3493
3494 return 0;
3495}
3496\f
3497/* A C expression that indicates when an argument must be passed by
3498 reference. If nonzero for an argument, a copy of that argument is
3499 made in memory and a pointer to the argument is passed instead of
3500 the argument itself. The pointer is passed in whatever way is
3501 appropriate for passing a pointer to that type.
3502
c8c99a68
DE
3503 Under V.4, structures and unions are passed by reference.
3504
3505 As an extension to all ABIs, variable sized types are passed by
3506 reference. */
4697a36c
MM
3507
3508int
3509function_arg_pass_by_reference (cum, mode, type, named)
296b8152
KG
3510 CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED;
3511 enum machine_mode mode ATTRIBUTE_UNUSED;
4697a36c 3512 tree type;
296b8152 3513 int named ATTRIBUTE_UNUSED;
4697a36c 3514{
f607bc57 3515 if (DEFAULT_ABI == ABI_V4
4cc833b7
RH
3516 && ((type && AGGREGATE_TYPE_P (type))
3517 || mode == TFmode))
4697a36c
MM
3518 {
3519 if (TARGET_DEBUG_ARG)
3520 fprintf (stderr, "function_arg_pass_by_reference: aggregate\n");
3521
3522 return 1;
3523 }
c8c99a68 3524 return type && int_size_in_bytes (type) <= 0;
4697a36c 3525}
4697a36c
MM
3526\f
3527/* Perform any needed actions needed for a function that is receiving a
3528 variable number of arguments.
3529
3530 CUM is as above.
3531
3532 MODE and TYPE are the mode and type of the current parameter.
3533
3534 PRETEND_SIZE is a variable that should be set to the amount of stack
3535 that must be pushed by the prolog to pretend that our caller pushed
3536 it.
3537
3538 Normally, this macro will push all remaining incoming registers on the
3539 stack and set PRETEND_SIZE to the length of the registers pushed. */
3540
3541void
3542setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
3543 CUMULATIVE_ARGS *cum;
3544 enum machine_mode mode;
3545 tree type;
de62b72c 3546 int *pretend_size ATTRIBUTE_UNUSED;
4697a36c
MM
3547 int no_rtl;
3548
3549{
4cc833b7
RH
3550 CUMULATIVE_ARGS next_cum;
3551 int reg_size = TARGET_32BIT ? 4 : 8;
ca5adc63 3552 rtx save_area = NULL_RTX, mem;
dfafc897 3553 int first_reg_offset, set;
d34c5b80
DE
3554 tree fntype;
3555 int stdarg_p;
4697a36c 3556
d34c5b80
DE
3557 fntype = TREE_TYPE (current_function_decl);
3558 stdarg_p = (TYPE_ARG_TYPES (fntype) != 0
3559 && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
3560 != void_type_node));
4cc833b7 3561
d34c5b80
DE
3562 /* For varargs, we do not want to skip the dummy va_dcl argument.
3563 For stdargs, we do want to skip the last named argument. */
3564 next_cum = *cum;
3565 if (stdarg_p)
3566 function_arg_advance (&next_cum, mode, type, 1);
4cc833b7 3567
f607bc57 3568 if (DEFAULT_ABI == ABI_V4)
d34c5b80 3569 {
4cc833b7 3570 /* Indicate to allocate space on the stack for varargs save area. */
00dba523 3571 cfun->machine->sysv_varargs_p = 1;
60e2d0ca 3572 if (! no_rtl)
2c4974b7 3573 save_area = plus_constant (virtual_stack_vars_rtx,
bd227acc 3574 - RS6000_VARARGS_SIZE);
4cc833b7
RH
3575
3576 first_reg_offset = next_cum.sysv_gregno - GP_ARG_MIN_REG;
4697a36c 3577 }
60e2d0ca 3578 else
4697a36c 3579 {
d34c5b80 3580 first_reg_offset = next_cum.words;
4cc833b7 3581 save_area = virtual_incoming_args_rtx;
00dba523 3582 cfun->machine->sysv_varargs_p = 0;
4697a36c
MM
3583
3584 if (MUST_PASS_IN_STACK (mode, type))
d34c5b80 3585 first_reg_offset += RS6000_ARG_SIZE (TYPE_MODE (type), type);
4cc833b7 3586 }
4697a36c 3587
dfafc897 3588 set = get_varargs_alias_set ();
c81fc13e 3589 if (! no_rtl && first_reg_offset < GP_ARG_NUM_REG)
4cc833b7 3590 {
dfafc897
FS
3591 mem = gen_rtx_MEM (BLKmode,
3592 plus_constant (save_area,
3593 first_reg_offset * reg_size)),
ba4828e0 3594 set_mem_alias_set (mem, set);
8ac61af7 3595 set_mem_align (mem, BITS_PER_WORD);
dfafc897 3596
4cc833b7 3597 move_block_from_reg
dfafc897 3598 (GP_ARG_MIN_REG + first_reg_offset, mem,
4cc833b7
RH
3599 GP_ARG_NUM_REG - first_reg_offset,
3600 (GP_ARG_NUM_REG - first_reg_offset) * UNITS_PER_WORD);
4697a36c
MM
3601 }
3602
4697a36c 3603 /* Save FP registers if needed. */
f607bc57 3604 if (DEFAULT_ABI == ABI_V4
a3170dc6
AH
3605 && TARGET_HARD_FLOAT && TARGET_FPRS
3606 && ! no_rtl
4cc833b7 3607 && next_cum.fregno <= FP_ARG_V4_MAX_REG)
4697a36c 3608 {
4cc833b7 3609 int fregno = next_cum.fregno;
9ebbca7d 3610 rtx cr1 = gen_rtx_REG (CCmode, CR1_REGNO);
4cc833b7
RH
3611 rtx lab = gen_label_rtx ();
3612 int off = (GP_ARG_NUM_REG * reg_size) + ((fregno - FP_ARG_MIN_REG) * 8);
4697a36c 3613
4cc833b7 3614 emit_jump_insn (gen_rtx_SET (VOIDmode,
4697a36c 3615 pc_rtx,
39403d82 3616 gen_rtx_IF_THEN_ELSE (VOIDmode,
4cc833b7
RH
3617 gen_rtx_NE (VOIDmode, cr1,
3618 const0_rtx),
39403d82 3619 gen_rtx_LABEL_REF (VOIDmode, lab),
4697a36c
MM
3620 pc_rtx)));
3621
4cc833b7
RH
3622 while (fregno <= FP_ARG_V4_MAX_REG)
3623 {
dfafc897 3624 mem = gen_rtx_MEM (DFmode, plus_constant (save_area, off));
ba4828e0 3625 set_mem_alias_set (mem, set);
dfafc897 3626 emit_move_insn (mem, gen_rtx_REG (DFmode, fregno));
4cc833b7
RH
3627 fregno++;
3628 off += 8;
4697a36c 3629 }
4cc833b7
RH
3630
3631 emit_label (lab);
4697a36c 3632 }
4697a36c 3633}
4697a36c 3634
dfafc897 3635/* Create the va_list data type. */
2c4974b7 3636
dfafc897
FS
3637tree
3638rs6000_build_va_list ()
3639{
bab45a51 3640 tree f_gpr, f_fpr, f_ovf, f_sav, record, type_decl;
4697a36c 3641
9ebbca7d
GK
3642 /* For AIX, prefer 'char *' because that's what the system
3643 header files like. */
f607bc57 3644 if (DEFAULT_ABI != ABI_V4)
9ebbca7d 3645 return build_pointer_type (char_type_node);
dfafc897 3646
f1e639b1 3647 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
bab45a51 3648 type_decl = build_decl (TYPE_DECL, get_identifier ("__va_list_tag"), record);
0f4fd75d 3649
9ebbca7d
GK
3650 f_gpr = build_decl (FIELD_DECL, get_identifier ("gpr"),
3651 unsigned_char_type_node);
3652 f_fpr = build_decl (FIELD_DECL, get_identifier ("fpr"),
3653 unsigned_char_type_node);
dfafc897
FS
3654 f_ovf = build_decl (FIELD_DECL, get_identifier ("overflow_arg_area"),
3655 ptr_type_node);
3656 f_sav = build_decl (FIELD_DECL, get_identifier ("reg_save_area"),
3657 ptr_type_node);
3658
3659 DECL_FIELD_CONTEXT (f_gpr) = record;
3660 DECL_FIELD_CONTEXT (f_fpr) = record;
3661 DECL_FIELD_CONTEXT (f_ovf) = record;
3662 DECL_FIELD_CONTEXT (f_sav) = record;
3663
bab45a51
FS
3664 TREE_CHAIN (record) = type_decl;
3665 TYPE_NAME (record) = type_decl;
dfafc897
FS
3666 TYPE_FIELDS (record) = f_gpr;
3667 TREE_CHAIN (f_gpr) = f_fpr;
3668 TREE_CHAIN (f_fpr) = f_ovf;
3669 TREE_CHAIN (f_ovf) = f_sav;
3670
3671 layout_type (record);
3672
3673 /* The correct type is an array type of one element. */
3674 return build_array_type (record, build_index_type (size_zero_node));
3675}
3676
3677/* Implement va_start. */
3678
3679void
e5faf155 3680rs6000_va_start (valist, nextarg)
dfafc897
FS
3681 tree valist;
3682 rtx nextarg;
4697a36c 3683{
dfafc897
FS
3684 HOST_WIDE_INT words, n_gpr, n_fpr;
3685 tree f_gpr, f_fpr, f_ovf, f_sav;
3686 tree gpr, fpr, ovf, sav, t;
2c4974b7 3687
dfafc897 3688 /* Only SVR4 needs something special. */
f607bc57 3689 if (DEFAULT_ABI != ABI_V4)
dfafc897 3690 {
e5faf155 3691 std_expand_builtin_va_start (valist, nextarg);
dfafc897
FS
3692 return;
3693 }
3694
973a648b 3695 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3696 f_fpr = TREE_CHAIN (f_gpr);
3697 f_ovf = TREE_CHAIN (f_fpr);
3698 f_sav = TREE_CHAIN (f_ovf);
3699
8ebecc3b 3700 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3701 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3702 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3703 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3704 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3705
3706 /* Count number of gp and fp argument registers used. */
4cc833b7 3707 words = current_function_args_info.words;
dfafc897
FS
3708 n_gpr = current_function_args_info.sysv_gregno - GP_ARG_MIN_REG;
3709 n_fpr = current_function_args_info.fregno - FP_ARG_MIN_REG;
3710
3711 if (TARGET_DEBUG_ARG)
78e1b90d
DE
3712 {
3713 fputs ("va_start: words = ", stderr);
3714 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, words);
3715 fputs (", n_gpr = ", stderr);
3716 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_gpr);
3717 fputs (", n_fpr = ", stderr);
3718 fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, n_fpr);
3719 putc ('\n', stderr);
3720 }
dfafc897
FS
3721
3722 t = build (MODIFY_EXPR, TREE_TYPE (gpr), gpr, build_int_2 (n_gpr, 0));
3723 TREE_SIDE_EFFECTS (t) = 1;
3724 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3725
3726 t = build (MODIFY_EXPR, TREE_TYPE (fpr), fpr, build_int_2 (n_fpr, 0));
3727 TREE_SIDE_EFFECTS (t) = 1;
3728 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3729
3730 /* Find the overflow area. */
3731 t = make_tree (TREE_TYPE (ovf), virtual_incoming_args_rtx);
3732 if (words != 0)
3733 t = build (PLUS_EXPR, TREE_TYPE (ovf), t,
3734 build_int_2 (words * UNITS_PER_WORD, 0));
3735 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3736 TREE_SIDE_EFFECTS (t) = 1;
3737 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3738
3739 /* Find the register save area. */
3740 t = make_tree (TREE_TYPE (sav), virtual_stack_vars_rtx);
3741 t = build (PLUS_EXPR, TREE_TYPE (sav), t,
3742 build_int_2 (-RS6000_VARARGS_SIZE, -1));
3743 t = build (MODIFY_EXPR, TREE_TYPE (sav), sav, t);
3744 TREE_SIDE_EFFECTS (t) = 1;
3745 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3746}
3747
3748/* Implement va_arg. */
3749
3750rtx
3751rs6000_va_arg (valist, type)
3752 tree valist, type;
3753{
3754 tree f_gpr, f_fpr, f_ovf, f_sav;
3755 tree gpr, fpr, ovf, sav, reg, t, u;
3756 int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale;
3757 rtx lab_false, lab_over, addr_rtx, r;
3758
f607bc57 3759 if (DEFAULT_ABI != ABI_V4)
c8c99a68
DE
3760 {
3761 /* Variable sized types are passed by reference. */
3762 if (int_size_in_bytes (type) <= 0)
3763 {
3764 u = build_pointer_type (type);
3765
3766 /* Args grow upward. */
3767 t = build (POSTINCREMENT_EXPR, TREE_TYPE (valist), valist,
3768 build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0));
3769 TREE_SIDE_EFFECTS (t) = 1;
3770
3771 t = build1 (NOP_EXPR, build_pointer_type (u), t);
3772 TREE_SIDE_EFFECTS (t) = 1;
3773
3774 t = build1 (INDIRECT_REF, u, t);
3775 TREE_SIDE_EFFECTS (t) = 1;
3776
3777 return expand_expr (t, NULL_RTX, VOIDmode, EXPAND_NORMAL);
3778 }
3779 else
3780 return std_expand_builtin_va_arg (valist, type);
3781 }
dfafc897 3782
973a648b 3783 f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node));
dfafc897
FS
3784 f_fpr = TREE_CHAIN (f_gpr);
3785 f_ovf = TREE_CHAIN (f_fpr);
3786 f_sav = TREE_CHAIN (f_ovf);
3787
8ebecc3b 3788 valist = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)), valist);
dfafc897
FS
3789 gpr = build (COMPONENT_REF, TREE_TYPE (f_gpr), valist, f_gpr);
3790 fpr = build (COMPONENT_REF, TREE_TYPE (f_fpr), valist, f_fpr);
3791 ovf = build (COMPONENT_REF, TREE_TYPE (f_ovf), valist, f_ovf);
3792 sav = build (COMPONENT_REF, TREE_TYPE (f_sav), valist, f_sav);
3793
3794 size = int_size_in_bytes (type);
3795 rsize = (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
4cc833b7 3796
dfafc897 3797 if (AGGREGATE_TYPE_P (type) || TYPE_MODE (type) == TFmode)
4cc833b7 3798 {
dfafc897
FS
3799 /* Aggregates and long doubles are passed by reference. */
3800 indirect_p = 1;
3801 reg = gpr;
3802 n_reg = 1;
3803 sav_ofs = 0;
3804 sav_scale = 4;
d3294cd9
FS
3805 size = UNITS_PER_WORD;
3806 rsize = 1;
dfafc897 3807 }
a3170dc6 3808 else if (FLOAT_TYPE_P (type) && TARGET_HARD_FLOAT && TARGET_FPRS)
dfafc897
FS
3809 {
3810 /* FP args go in FP registers, if present. */
3811 indirect_p = 0;
3812 reg = fpr;
3813 n_reg = 1;
3814 sav_ofs = 8*4;
3815 sav_scale = 8;
4cc833b7 3816 }
dfafc897
FS
3817 else
3818 {
3819 /* Otherwise into GP registers. */
3820 indirect_p = 0;
3821 reg = gpr;
3822 n_reg = rsize;
3823 sav_ofs = 0;
3824 sav_scale = 4;
3825 }
3826
a4f6c312 3827 /* Pull the value out of the saved registers ... */
dfafc897
FS
3828
3829 lab_false = gen_label_rtx ();
3830 lab_over = gen_label_rtx ();
3831 addr_rtx = gen_reg_rtx (Pmode);
3832
16861f33
AH
3833 /* AltiVec vectors never go in registers. */
3834 if (!TARGET_ALTIVEC || TREE_CODE (type) != VECTOR_TYPE)
2c4974b7 3835 {
41daaf0e
AH
3836 TREE_THIS_VOLATILE (reg) = 1;
3837 emit_cmp_and_jump_insns
3838 (expand_expr (reg, NULL_RTX, QImode, EXPAND_NORMAL),
3839 GEN_INT (8 - n_reg + 1), GE, const1_rtx, QImode, 1,
3840 lab_false);
dfafc897 3841
41daaf0e
AH
3842 /* Long long is aligned in the registers. */
3843 if (n_reg > 1)
3844 {
3845 u = build (BIT_AND_EXPR, TREE_TYPE (reg), reg,
3846 build_int_2 (n_reg - 1, 0));
3847 u = build (PLUS_EXPR, TREE_TYPE (reg), reg, u);
3848 u = build (MODIFY_EXPR, TREE_TYPE (reg), reg, u);
3849 TREE_SIDE_EFFECTS (u) = 1;
3850 expand_expr (u, const0_rtx, VOIDmode, EXPAND_NORMAL);
3851 }
2c4974b7 3852
41daaf0e
AH
3853 if (sav_ofs)
3854 t = build (PLUS_EXPR, ptr_type_node, sav, build_int_2 (sav_ofs, 0));
3855 else
3856 t = sav;
2c4974b7 3857
41daaf0e
AH
3858 u = build (POSTINCREMENT_EXPR, TREE_TYPE (reg), reg,
3859 build_int_2 (n_reg, 0));
3860 TREE_SIDE_EFFECTS (u) = 1;
2c4974b7 3861
41daaf0e
AH
3862 u = build1 (CONVERT_EXPR, integer_type_node, u);
3863 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3864
41daaf0e
AH
3865 u = build (MULT_EXPR, integer_type_node, u, build_int_2 (sav_scale, 0));
3866 TREE_SIDE_EFFECTS (u) = 1;
dfafc897 3867
41daaf0e
AH
3868 t = build (PLUS_EXPR, ptr_type_node, t, u);
3869 TREE_SIDE_EFFECTS (t) = 1;
3870
3871 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3872 if (r != addr_rtx)
3873 emit_move_insn (addr_rtx, r);
3874
3875 emit_jump_insn (gen_jump (lab_over));
3876 emit_barrier ();
3877 }
dfafc897 3878
dfafc897
FS
3879 emit_label (lab_false);
3880
a4f6c312 3881 /* ... otherwise out of the overflow area. */
dfafc897 3882
41daaf0e
AH
3883 /* Make sure we don't find reg 7 for the next int arg.
3884
3885 All AltiVec vectors go in the overflow area. So in the AltiVec
3886 case we need to get the vectors from the overflow area, but
3887 remember where the GPRs and FPRs are. */
16861f33
AH
3888 if (n_reg > 1 && (TREE_CODE (type) != VECTOR_TYPE
3889 || !TARGET_ALTIVEC))
dfafc897
FS
3890 {
3891 t = build (MODIFY_EXPR, TREE_TYPE (reg), reg, build_int_2 (8, 0));
3892 TREE_SIDE_EFFECTS (t) = 1;
3893 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3894 }
3895
3896 /* Care for on-stack alignment if needed. */
3897 if (rsize <= 1)
3898 t = ovf;
3899 else
3900 {
41daaf0e
AH
3901 int align;
3902
16861f33
AH
3903 /* AltiVec vectors are 16 byte aligned. */
3904 if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
41daaf0e
AH
3905 align = 15;
3906 else
3907 align = 7;
3908
3909 t = build (PLUS_EXPR, TREE_TYPE (ovf), ovf, build_int_2 (align, 0));
3910 t = build (BIT_AND_EXPR, TREE_TYPE (t), t, build_int_2 (-align-1, -1));
dfafc897
FS
3911 }
3912 t = save_expr (t);
3913
3914 r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL);
3915 if (r != addr_rtx)
3916 emit_move_insn (addr_rtx, r);
3917
3918 t = build (PLUS_EXPR, TREE_TYPE (t), t, build_int_2 (size, 0));
3919 t = build (MODIFY_EXPR, TREE_TYPE (ovf), ovf, t);
3920 TREE_SIDE_EFFECTS (t) = 1;
3921 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3922
3923 emit_label (lab_over);
3924
3925 if (indirect_p)
3926 {
3927 r = gen_rtx_MEM (Pmode, addr_rtx);
ba4828e0 3928 set_mem_alias_set (r, get_varargs_alias_set ());
dfafc897
FS
3929 emit_move_insn (addr_rtx, r);
3930 }
3931
3932 return addr_rtx;
4697a36c 3933}
0ac081f6
AH
3934
3935/* Builtins. */
3936
6a2dd09a
RS
3937#define def_builtin(MASK, NAME, TYPE, CODE) \
3938do { \
3939 if ((MASK) & target_flags) \
3940 builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, \
3941 NULL, NULL_TREE); \
0ac081f6
AH
3942} while (0)
3943
24408032
AH
3944/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
3945
2212663f 3946static const struct builtin_description bdesc_3arg[] =
24408032
AH
3947{
3948 { MASK_ALTIVEC, CODE_FOR_altivec_vmaddfp, "__builtin_altivec_vmaddfp", ALTIVEC_BUILTIN_VMADDFP },
3949 { MASK_ALTIVEC, CODE_FOR_altivec_vmhaddshs, "__builtin_altivec_vmhaddshs", ALTIVEC_BUILTIN_VMHADDSHS },
3950 { MASK_ALTIVEC, CODE_FOR_altivec_vmhraddshs, "__builtin_altivec_vmhraddshs", ALTIVEC_BUILTIN_VMHRADDSHS },
3951 { MASK_ALTIVEC, CODE_FOR_altivec_vmladduhm, "__builtin_altivec_vmladduhm", ALTIVEC_BUILTIN_VMLADDUHM},
3952 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumubm, "__builtin_altivec_vmsumubm", ALTIVEC_BUILTIN_VMSUMUBM },
3953 { MASK_ALTIVEC, CODE_FOR_altivec_vmsummbm, "__builtin_altivec_vmsummbm", ALTIVEC_BUILTIN_VMSUMMBM },
3954 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhm, "__builtin_altivec_vmsumuhm", ALTIVEC_BUILTIN_VMSUMUHM },
3955 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshm, "__builtin_altivec_vmsumshm", ALTIVEC_BUILTIN_VMSUMSHM },
3956 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumuhs, "__builtin_altivec_vmsumuhs", ALTIVEC_BUILTIN_VMSUMUHS },
3957 { MASK_ALTIVEC, CODE_FOR_altivec_vmsumshs, "__builtin_altivec_vmsumshs", ALTIVEC_BUILTIN_VMSUMSHS },
3958 { MASK_ALTIVEC, CODE_FOR_altivec_vnmsubfp, "__builtin_altivec_vnmsubfp", ALTIVEC_BUILTIN_VNMSUBFP },
3959 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4sf, "__builtin_altivec_vperm_4sf", ALTIVEC_BUILTIN_VPERM_4SF },
3960 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_4si, "__builtin_altivec_vperm_4si", ALTIVEC_BUILTIN_VPERM_4SI },
3961 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_8hi, "__builtin_altivec_vperm_8hi", ALTIVEC_BUILTIN_VPERM_8HI },
3962 { MASK_ALTIVEC, CODE_FOR_altivec_vperm_16qi, "__builtin_altivec_vperm_16qi", ALTIVEC_BUILTIN_VPERM_16QI },
3963 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4sf, "__builtin_altivec_vsel_4sf", ALTIVEC_BUILTIN_VSEL_4SF },
3964 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_4si, "__builtin_altivec_vsel_4si", ALTIVEC_BUILTIN_VSEL_4SI },
3965 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_8hi, "__builtin_altivec_vsel_8hi", ALTIVEC_BUILTIN_VSEL_8HI },
3966 { MASK_ALTIVEC, CODE_FOR_altivec_vsel_16qi, "__builtin_altivec_vsel_16qi", ALTIVEC_BUILTIN_VSEL_16QI },
3967 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_16qi, "__builtin_altivec_vsldoi_16qi", ALTIVEC_BUILTIN_VSLDOI_16QI },
3968 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_8hi, "__builtin_altivec_vsldoi_8hi", ALTIVEC_BUILTIN_VSLDOI_8HI },
3969 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4si, "__builtin_altivec_vsldoi_4si", ALTIVEC_BUILTIN_VSLDOI_4SI },
3970 { MASK_ALTIVEC, CODE_FOR_altivec_vsldoi_4sf, "__builtin_altivec_vsldoi_4sf", ALTIVEC_BUILTIN_VSLDOI_4SF },
3971};
2212663f 3972
95385cbb
AH
3973/* DST operations: void foo (void *, const int, const char). */
3974
3975static const struct builtin_description bdesc_dst[] =
3976{
3977 { MASK_ALTIVEC, CODE_FOR_altivec_dst, "__builtin_altivec_dst", ALTIVEC_BUILTIN_DST },
3978 { MASK_ALTIVEC, CODE_FOR_altivec_dstt, "__builtin_altivec_dstt", ALTIVEC_BUILTIN_DSTT },
3979 { MASK_ALTIVEC, CODE_FOR_altivec_dstst, "__builtin_altivec_dstst", ALTIVEC_BUILTIN_DSTST },
3980 { MASK_ALTIVEC, CODE_FOR_altivec_dststt, "__builtin_altivec_dststt", ALTIVEC_BUILTIN_DSTSTT }
3981};
3982
2212663f 3983/* Simple binary operations: VECc = foo (VECa, VECb). */
24408032 3984
a3170dc6 3985static struct builtin_description bdesc_2arg[] =
0ac081f6 3986{
f18c054f
DB
3987 { MASK_ALTIVEC, CODE_FOR_addv16qi3, "__builtin_altivec_vaddubm", ALTIVEC_BUILTIN_VADDUBM },
3988 { MASK_ALTIVEC, CODE_FOR_addv8hi3, "__builtin_altivec_vadduhm", ALTIVEC_BUILTIN_VADDUHM },
3989 { MASK_ALTIVEC, CODE_FOR_addv4si3, "__builtin_altivec_vadduwm", ALTIVEC_BUILTIN_VADDUWM },
3990 { MASK_ALTIVEC, CODE_FOR_addv4sf3, "__builtin_altivec_vaddfp", ALTIVEC_BUILTIN_VADDFP },
0ac081f6
AH
3991 { MASK_ALTIVEC, CODE_FOR_altivec_vaddcuw, "__builtin_altivec_vaddcuw", ALTIVEC_BUILTIN_VADDCUW },
3992 { MASK_ALTIVEC, CODE_FOR_altivec_vaddubs, "__builtin_altivec_vaddubs", ALTIVEC_BUILTIN_VADDUBS },
3993 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsbs, "__builtin_altivec_vaddsbs", ALTIVEC_BUILTIN_VADDSBS },
3994 { MASK_ALTIVEC, CODE_FOR_altivec_vadduhs, "__builtin_altivec_vadduhs", ALTIVEC_BUILTIN_VADDUHS },
3995 { MASK_ALTIVEC, CODE_FOR_altivec_vaddshs, "__builtin_altivec_vaddshs", ALTIVEC_BUILTIN_VADDSHS },
3996 { MASK_ALTIVEC, CODE_FOR_altivec_vadduws, "__builtin_altivec_vadduws", ALTIVEC_BUILTIN_VADDUWS },
3997 { MASK_ALTIVEC, CODE_FOR_altivec_vaddsws, "__builtin_altivec_vaddsws", ALTIVEC_BUILTIN_VADDSWS },
f18c054f 3998 { MASK_ALTIVEC, CODE_FOR_andv4si3, "__builtin_altivec_vand", ALTIVEC_BUILTIN_VAND },
0ac081f6
AH
3999 { MASK_ALTIVEC, CODE_FOR_altivec_vandc, "__builtin_altivec_vandc", ALTIVEC_BUILTIN_VANDC },
4000 { MASK_ALTIVEC, CODE_FOR_altivec_vavgub, "__builtin_altivec_vavgub", ALTIVEC_BUILTIN_VAVGUB },
4001 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsb, "__builtin_altivec_vavgsb", ALTIVEC_BUILTIN_VAVGSB },
4002 { MASK_ALTIVEC, CODE_FOR_altivec_vavguh, "__builtin_altivec_vavguh", ALTIVEC_BUILTIN_VAVGUH },
4003 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsh, "__builtin_altivec_vavgsh", ALTIVEC_BUILTIN_VAVGSH },
4004 { MASK_ALTIVEC, CODE_FOR_altivec_vavguw, "__builtin_altivec_vavguw", ALTIVEC_BUILTIN_VAVGUW },
4005 { MASK_ALTIVEC, CODE_FOR_altivec_vavgsw, "__builtin_altivec_vavgsw", ALTIVEC_BUILTIN_VAVGSW },
617e0e1d
DB
4006 { MASK_ALTIVEC, CODE_FOR_altivec_vcfux, "__builtin_altivec_vcfux", ALTIVEC_BUILTIN_VCFUX },
4007 { MASK_ALTIVEC, CODE_FOR_altivec_vcfsx, "__builtin_altivec_vcfsx", ALTIVEC_BUILTIN_VCFSX },
0ac081f6
AH
4008 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpbfp, "__builtin_altivec_vcmpbfp", ALTIVEC_BUILTIN_VCMPBFP },
4009 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequb, "__builtin_altivec_vcmpequb", ALTIVEC_BUILTIN_VCMPEQUB },
4010 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequh, "__builtin_altivec_vcmpequh", ALTIVEC_BUILTIN_VCMPEQUH },
4011 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpequw, "__builtin_altivec_vcmpequw", ALTIVEC_BUILTIN_VCMPEQUW },
4012 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpeqfp, "__builtin_altivec_vcmpeqfp", ALTIVEC_BUILTIN_VCMPEQFP },
4013 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgefp, "__builtin_altivec_vcmpgefp", ALTIVEC_BUILTIN_VCMPGEFP },
4014 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtub, "__builtin_altivec_vcmpgtub", ALTIVEC_BUILTIN_VCMPGTUB },
4015 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsb, "__builtin_altivec_vcmpgtsb", ALTIVEC_BUILTIN_VCMPGTSB },
4016 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuh, "__builtin_altivec_vcmpgtuh", ALTIVEC_BUILTIN_VCMPGTUH },
4017 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsh, "__builtin_altivec_vcmpgtsh", ALTIVEC_BUILTIN_VCMPGTSH },
4018 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtuw, "__builtin_altivec_vcmpgtuw", ALTIVEC_BUILTIN_VCMPGTUW },
4019 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtsw, "__builtin_altivec_vcmpgtsw", ALTIVEC_BUILTIN_VCMPGTSW },
4020 { MASK_ALTIVEC, CODE_FOR_altivec_vcmpgtfp, "__builtin_altivec_vcmpgtfp", ALTIVEC_BUILTIN_VCMPGTFP },
617e0e1d
DB
4021 { MASK_ALTIVEC, CODE_FOR_altivec_vctsxs, "__builtin_altivec_vctsxs", ALTIVEC_BUILTIN_VCTSXS },
4022 { MASK_ALTIVEC, CODE_FOR_altivec_vctuxs, "__builtin_altivec_vctuxs", ALTIVEC_BUILTIN_VCTUXS },
f18c054f
DB
4023 { MASK_ALTIVEC, CODE_FOR_umaxv16qi3, "__builtin_altivec_vmaxub", ALTIVEC_BUILTIN_VMAXUB },
4024 { MASK_ALTIVEC, CODE_FOR_smaxv16qi3, "__builtin_altivec_vmaxsb", ALTIVEC_BUILTIN_VMAXSB },
df966bff
AH
4025 { MASK_ALTIVEC, CODE_FOR_umaxv8hi3, "__builtin_altivec_vmaxuh", ALTIVEC_BUILTIN_VMAXUH },
4026 { MASK_ALTIVEC, CODE_FOR_smaxv8hi3, "__builtin_altivec_vmaxsh", ALTIVEC_BUILTIN_VMAXSH },
4027 { MASK_ALTIVEC, CODE_FOR_umaxv4si3, "__builtin_altivec_vmaxuw", ALTIVEC_BUILTIN_VMAXUW },
4028 { MASK_ALTIVEC, CODE_FOR_smaxv4si3, "__builtin_altivec_vmaxsw", ALTIVEC_BUILTIN_VMAXSW },
4029 { MASK_ALTIVEC, CODE_FOR_smaxv4sf3, "__builtin_altivec_vmaxfp", ALTIVEC_BUILTIN_VMAXFP },
0ac081f6
AH
4030 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghb, "__builtin_altivec_vmrghb", ALTIVEC_BUILTIN_VMRGHB },
4031 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghh, "__builtin_altivec_vmrghh", ALTIVEC_BUILTIN_VMRGHH },
4032 { MASK_ALTIVEC, CODE_FOR_altivec_vmrghw, "__builtin_altivec_vmrghw", ALTIVEC_BUILTIN_VMRGHW },
4033 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglb, "__builtin_altivec_vmrglb", ALTIVEC_BUILTIN_VMRGLB },
4034 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglh, "__builtin_altivec_vmrglh", ALTIVEC_BUILTIN_VMRGLH },
4035 { MASK_ALTIVEC, CODE_FOR_altivec_vmrglw, "__builtin_altivec_vmrglw", ALTIVEC_BUILTIN_VMRGLW },
f18c054f
DB
4036 { MASK_ALTIVEC, CODE_FOR_uminv16qi3, "__builtin_altivec_vminub", ALTIVEC_BUILTIN_VMINUB },
4037 { MASK_ALTIVEC, CODE_FOR_sminv16qi3, "__builtin_altivec_vminsb", ALTIVEC_BUILTIN_VMINSB },
4038 { MASK_ALTIVEC, CODE_FOR_uminv8hi3, "__builtin_altivec_vminuh", ALTIVEC_BUILTIN_VMINUH },
4039 { MASK_ALTIVEC, CODE_FOR_sminv8hi3, "__builtin_altivec_vminsh", ALTIVEC_BUILTIN_VMINSH },
4040 { MASK_ALTIVEC, CODE_FOR_uminv4si3, "__builtin_altivec_vminuw", ALTIVEC_BUILTIN_VMINUW },
4041 { MASK_ALTIVEC, CODE_FOR_sminv4si3, "__builtin_altivec_vminsw", ALTIVEC_BUILTIN_VMINSW },
4042 { MASK_ALTIVEC, CODE_FOR_sminv4sf3, "__builtin_altivec_vminfp", ALTIVEC_BUILTIN_VMINFP },
0ac081f6
AH
4043 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleub, "__builtin_altivec_vmuleub", ALTIVEC_BUILTIN_VMULEUB },
4044 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesb, "__builtin_altivec_vmulesb", ALTIVEC_BUILTIN_VMULESB },
4045 { MASK_ALTIVEC, CODE_FOR_altivec_vmuleuh, "__builtin_altivec_vmuleuh", ALTIVEC_BUILTIN_VMULEUH },
4046 { MASK_ALTIVEC, CODE_FOR_altivec_vmulesh, "__builtin_altivec_vmulesh", ALTIVEC_BUILTIN_VMULESH },
4047 { MASK_ALTIVEC, CODE_FOR_altivec_vmuloub, "__builtin_altivec_vmuloub", ALTIVEC_BUILTIN_VMULOUB },
4048 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosb, "__builtin_altivec_vmulosb", ALTIVEC_BUILTIN_VMULOSB },
4049 { MASK_ALTIVEC, CODE_FOR_altivec_vmulouh, "__builtin_altivec_vmulouh", ALTIVEC_BUILTIN_VMULOUH },
4050 { MASK_ALTIVEC, CODE_FOR_altivec_vmulosh, "__builtin_altivec_vmulosh", ALTIVEC_BUILTIN_VMULOSH },
4051 { MASK_ALTIVEC, CODE_FOR_altivec_vnor, "__builtin_altivec_vnor", ALTIVEC_BUILTIN_VNOR },
f18c054f 4052 { MASK_ALTIVEC, CODE_FOR_iorv4si3, "__builtin_altivec_vor", ALTIVEC_BUILTIN_VOR },
0ac081f6
AH
4053 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhum, "__builtin_altivec_vpkuhum", ALTIVEC_BUILTIN_VPKUHUM },
4054 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwum, "__builtin_altivec_vpkuwum", ALTIVEC_BUILTIN_VPKUWUM },
4055 { MASK_ALTIVEC, CODE_FOR_altivec_vpkpx, "__builtin_altivec_vpkpx", ALTIVEC_BUILTIN_VPKPX },
4056 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhss, "__builtin_altivec_vpkuhss", ALTIVEC_BUILTIN_VPKUHSS },
4057 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshss, "__builtin_altivec_vpkshss", ALTIVEC_BUILTIN_VPKSHSS },
4058 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwss, "__builtin_altivec_vpkuwss", ALTIVEC_BUILTIN_VPKUWSS },
4059 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswss, "__builtin_altivec_vpkswss", ALTIVEC_BUILTIN_VPKSWSS },
4060 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuhus, "__builtin_altivec_vpkuhus", ALTIVEC_BUILTIN_VPKUHUS },
4061 { MASK_ALTIVEC, CODE_FOR_altivec_vpkshus, "__builtin_altivec_vpkshus", ALTIVEC_BUILTIN_VPKSHUS },
4062 { MASK_ALTIVEC, CODE_FOR_altivec_vpkuwus, "__builtin_altivec_vpkuwus", ALTIVEC_BUILTIN_VPKUWUS },
4063 { MASK_ALTIVEC, CODE_FOR_altivec_vpkswus, "__builtin_altivec_vpkswus", ALTIVEC_BUILTIN_VPKSWUS },
4064 { MASK_ALTIVEC, CODE_FOR_altivec_vrlb, "__builtin_altivec_vrlb", ALTIVEC_BUILTIN_VRLB },
4065 { MASK_ALTIVEC, CODE_FOR_altivec_vrlh, "__builtin_altivec_vrlh", ALTIVEC_BUILTIN_VRLH },
4066 { MASK_ALTIVEC, CODE_FOR_altivec_vrlw, "__builtin_altivec_vrlw", ALTIVEC_BUILTIN_VRLW },
4067 { MASK_ALTIVEC, CODE_FOR_altivec_vslb, "__builtin_altivec_vslb", ALTIVEC_BUILTIN_VSLB },
4068 { MASK_ALTIVEC, CODE_FOR_altivec_vslh, "__builtin_altivec_vslh", ALTIVEC_BUILTIN_VSLH },
4069 { MASK_ALTIVEC, CODE_FOR_altivec_vslw, "__builtin_altivec_vslw", ALTIVEC_BUILTIN_VSLW },
4070 { MASK_ALTIVEC, CODE_FOR_altivec_vsl, "__builtin_altivec_vsl", ALTIVEC_BUILTIN_VSL },
4071 { MASK_ALTIVEC, CODE_FOR_altivec_vslo, "__builtin_altivec_vslo", ALTIVEC_BUILTIN_VSLO },
2212663f
DB
4072 { MASK_ALTIVEC, CODE_FOR_altivec_vspltb, "__builtin_altivec_vspltb", ALTIVEC_BUILTIN_VSPLTB },
4073 { MASK_ALTIVEC, CODE_FOR_altivec_vsplth, "__builtin_altivec_vsplth", ALTIVEC_BUILTIN_VSPLTH },
4074 { MASK_ALTIVEC, CODE_FOR_altivec_vspltw, "__builtin_altivec_vspltw", ALTIVEC_BUILTIN_VSPLTW },
0ac081f6 4075 { MASK_ALTIVEC, CODE_FOR_altivec_vsrb, "__builtin_altivec_vsrb", ALTIVEC_BUILTIN_VSRB },
f18c054f
DB
4076 { MASK_ALTIVEC, CODE_FOR_altivec_vsrh, "__builtin_altivec_vsrh", ALTIVEC_BUILTIN_VSRH },
4077 { MASK_ALTIVEC, CODE_FOR_altivec_vsrw, "__builtin_altivec_vsrw", ALTIVEC_BUILTIN_VSRW },
0ac081f6
AH
4078 { MASK_ALTIVEC, CODE_FOR_altivec_vsrab, "__builtin_altivec_vsrab", ALTIVEC_BUILTIN_VSRAB },
4079 { MASK_ALTIVEC, CODE_FOR_altivec_vsrah, "__builtin_altivec_vsrah", ALTIVEC_BUILTIN_VSRAH },
4080 { MASK_ALTIVEC, CODE_FOR_altivec_vsraw, "__builtin_altivec_vsraw", ALTIVEC_BUILTIN_VSRAW },
4081 { MASK_ALTIVEC, CODE_FOR_altivec_vsr, "__builtin_altivec_vsr", ALTIVEC_BUILTIN_VSR },
4082 { MASK_ALTIVEC, CODE_FOR_altivec_vsro, "__builtin_altivec_vsro", ALTIVEC_BUILTIN_VSRO },
f18c054f
DB
4083 { MASK_ALTIVEC, CODE_FOR_subv16qi3, "__builtin_altivec_vsububm", ALTIVEC_BUILTIN_VSUBUBM },
4084 { MASK_ALTIVEC, CODE_FOR_subv8hi3, "__builtin_altivec_vsubuhm", ALTIVEC_BUILTIN_VSUBUHM },
4085 { MASK_ALTIVEC, CODE_FOR_subv4si3, "__builtin_altivec_vsubuwm", ALTIVEC_BUILTIN_VSUBUWM },
4086 { MASK_ALTIVEC, CODE_FOR_subv4sf3, "__builtin_altivec_vsubfp", ALTIVEC_BUILTIN_VSUBFP },
0ac081f6
AH
4087 { MASK_ALTIVEC, CODE_FOR_altivec_vsubcuw, "__builtin_altivec_vsubcuw", ALTIVEC_BUILTIN_VSUBCUW },
4088 { MASK_ALTIVEC, CODE_FOR_altivec_vsububs, "__builtin_altivec_vsububs", ALTIVEC_BUILTIN_VSUBUBS },
4089 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsbs, "__builtin_altivec_vsubsbs", ALTIVEC_BUILTIN_VSUBSBS },
4090 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuhs, "__builtin_altivec_vsubuhs", ALTIVEC_BUILTIN_VSUBUHS },
4091 { MASK_ALTIVEC, CODE_FOR_altivec_vsubshs, "__builtin_altivec_vsubshs", ALTIVEC_BUILTIN_VSUBSHS },
4092 { MASK_ALTIVEC, CODE_FOR_altivec_vsubuws, "__builtin_altivec_vsubuws", ALTIVEC_BUILTIN_VSUBUWS },
4093 { MASK_ALTIVEC, CODE_FOR_altivec_vsubsws, "__builtin_altivec_vsubsws", ALTIVEC_BUILTIN_VSUBSWS },
4094 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4ubs, "__builtin_altivec_vsum4ubs", ALTIVEC_BUILTIN_VSUM4UBS },
4095 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4sbs, "__builtin_altivec_vsum4sbs", ALTIVEC_BUILTIN_VSUM4SBS },
4096 { MASK_ALTIVEC, CODE_FOR_altivec_vsum4shs, "__builtin_altivec_vsum4shs", ALTIVEC_BUILTIN_VSUM4SHS },
4097 { MASK_ALTIVEC, CODE_FOR_altivec_vsum2sws, "__builtin_altivec_vsum2sws", ALTIVEC_BUILTIN_VSUM2SWS },
4098 { MASK_ALTIVEC, CODE_FOR_altivec_vsumsws, "__builtin_altivec_vsumsws", ALTIVEC_BUILTIN_VSUMSWS },
f18c054f 4099 { MASK_ALTIVEC, CODE_FOR_xorv4si3, "__builtin_altivec_vxor", ALTIVEC_BUILTIN_VXOR },
a3170dc6
AH
4100
4101 /* Place holder, leave as first spe builtin. */
4102 { 0, CODE_FOR_spe_evaddw, "__builtin_spe_evaddw", SPE_BUILTIN_EVADDW },
4103 { 0, CODE_FOR_spe_evand, "__builtin_spe_evand", SPE_BUILTIN_EVAND },
4104 { 0, CODE_FOR_spe_evandc, "__builtin_spe_evandc", SPE_BUILTIN_EVANDC },
4105 { 0, CODE_FOR_spe_evdivws, "__builtin_spe_evdivws", SPE_BUILTIN_EVDIVWS },
4106 { 0, CODE_FOR_spe_evdivwu, "__builtin_spe_evdivwu", SPE_BUILTIN_EVDIVWU },
4107 { 0, CODE_FOR_spe_eveqv, "__builtin_spe_eveqv", SPE_BUILTIN_EVEQV },
4108 { 0, CODE_FOR_spe_evfsadd, "__builtin_spe_evfsadd", SPE_BUILTIN_EVFSADD },
4109 { 0, CODE_FOR_spe_evfsdiv, "__builtin_spe_evfsdiv", SPE_BUILTIN_EVFSDIV },
4110 { 0, CODE_FOR_spe_evfsmul, "__builtin_spe_evfsmul", SPE_BUILTIN_EVFSMUL },
4111 { 0, CODE_FOR_spe_evfssub, "__builtin_spe_evfssub", SPE_BUILTIN_EVFSSUB },
4112 { 0, CODE_FOR_spe_evmergehi, "__builtin_spe_evmergehi", SPE_BUILTIN_EVMERGEHI },
4113 { 0, CODE_FOR_spe_evmergehilo, "__builtin_spe_evmergehilo", SPE_BUILTIN_EVMERGEHILO },
4114 { 0, CODE_FOR_spe_evmergelo, "__builtin_spe_evmergelo", SPE_BUILTIN_EVMERGELO },
4115 { 0, CODE_FOR_spe_evmergelohi, "__builtin_spe_evmergelohi", SPE_BUILTIN_EVMERGELOHI },
4116 { 0, CODE_FOR_spe_evmhegsmfaa, "__builtin_spe_evmhegsmfaa", SPE_BUILTIN_EVMHEGSMFAA },
4117 { 0, CODE_FOR_spe_evmhegsmfan, "__builtin_spe_evmhegsmfan", SPE_BUILTIN_EVMHEGSMFAN },
4118 { 0, CODE_FOR_spe_evmhegsmiaa, "__builtin_spe_evmhegsmiaa", SPE_BUILTIN_EVMHEGSMIAA },
4119 { 0, CODE_FOR_spe_evmhegsmian, "__builtin_spe_evmhegsmian", SPE_BUILTIN_EVMHEGSMIAN },
4120 { 0, CODE_FOR_spe_evmhegumiaa, "__builtin_spe_evmhegumiaa", SPE_BUILTIN_EVMHEGUMIAA },
4121 { 0, CODE_FOR_spe_evmhegumian, "__builtin_spe_evmhegumian", SPE_BUILTIN_EVMHEGUMIAN },
4122 { 0, CODE_FOR_spe_evmhesmf, "__builtin_spe_evmhesmf", SPE_BUILTIN_EVMHESMF },
4123 { 0, CODE_FOR_spe_evmhesmfa, "__builtin_spe_evmhesmfa", SPE_BUILTIN_EVMHESMFA },
4124 { 0, CODE_FOR_spe_evmhesmfaaw, "__builtin_spe_evmhesmfaaw", SPE_BUILTIN_EVMHESMFAAW },
4125 { 0, CODE_FOR_spe_evmhesmfanw, "__builtin_spe_evmhesmfanw", SPE_BUILTIN_EVMHESMFANW },
4126 { 0, CODE_FOR_spe_evmhesmi, "__builtin_spe_evmhesmi", SPE_BUILTIN_EVMHESMI },
4127 { 0, CODE_FOR_spe_evmhesmia, "__builtin_spe_evmhesmia", SPE_BUILTIN_EVMHESMIA },
4128 { 0, CODE_FOR_spe_evmhesmiaaw, "__builtin_spe_evmhesmiaaw", SPE_BUILTIN_EVMHESMIAAW },
4129 { 0, CODE_FOR_spe_evmhesmianw, "__builtin_spe_evmhesmianw", SPE_BUILTIN_EVMHESMIANW },
4130 { 0, CODE_FOR_spe_evmhessf, "__builtin_spe_evmhessf", SPE_BUILTIN_EVMHESSF },
4131 { 0, CODE_FOR_spe_evmhessfa, "__builtin_spe_evmhessfa", SPE_BUILTIN_EVMHESSFA },
4132 { 0, CODE_FOR_spe_evmhessfaaw, "__builtin_spe_evmhessfaaw", SPE_BUILTIN_EVMHESSFAAW },
4133 { 0, CODE_FOR_spe_evmhessfanw, "__builtin_spe_evmhessfanw", SPE_BUILTIN_EVMHESSFANW },
4134 { 0, CODE_FOR_spe_evmhessiaaw, "__builtin_spe_evmhessiaaw", SPE_BUILTIN_EVMHESSIAAW },
4135 { 0, CODE_FOR_spe_evmhessianw, "__builtin_spe_evmhessianw", SPE_BUILTIN_EVMHESSIANW },
4136 { 0, CODE_FOR_spe_evmheumi, "__builtin_spe_evmheumi", SPE_BUILTIN_EVMHEUMI },
4137 { 0, CODE_FOR_spe_evmheumia, "__builtin_spe_evmheumia", SPE_BUILTIN_EVMHEUMIA },
4138 { 0, CODE_FOR_spe_evmheumiaaw, "__builtin_spe_evmheumiaaw", SPE_BUILTIN_EVMHEUMIAAW },
4139 { 0, CODE_FOR_spe_evmheumianw, "__builtin_spe_evmheumianw", SPE_BUILTIN_EVMHEUMIANW },
4140 { 0, CODE_FOR_spe_evmheusiaaw, "__builtin_spe_evmheusiaaw", SPE_BUILTIN_EVMHEUSIAAW },
4141 { 0, CODE_FOR_spe_evmheusianw, "__builtin_spe_evmheusianw", SPE_BUILTIN_EVMHEUSIANW },
4142 { 0, CODE_FOR_spe_evmhogsmfaa, "__builtin_spe_evmhogsmfaa", SPE_BUILTIN_EVMHOGSMFAA },
4143 { 0, CODE_FOR_spe_evmhogsmfan, "__builtin_spe_evmhogsmfan", SPE_BUILTIN_EVMHOGSMFAN },
4144 { 0, CODE_FOR_spe_evmhogsmiaa, "__builtin_spe_evmhogsmiaa", SPE_BUILTIN_EVMHOGSMIAA },
4145 { 0, CODE_FOR_spe_evmhogsmian, "__builtin_spe_evmhogsmian", SPE_BUILTIN_EVMHOGSMIAN },
4146 { 0, CODE_FOR_spe_evmhogumiaa, "__builtin_spe_evmhogumiaa", SPE_BUILTIN_EVMHOGUMIAA },
4147 { 0, CODE_FOR_spe_evmhogumian, "__builtin_spe_evmhogumian", SPE_BUILTIN_EVMHOGUMIAN },
4148 { 0, CODE_FOR_spe_evmhosmf, "__builtin_spe_evmhosmf", SPE_BUILTIN_EVMHOSMF },
4149 { 0, CODE_FOR_spe_evmhosmfa, "__builtin_spe_evmhosmfa", SPE_BUILTIN_EVMHOSMFA },
4150 { 0, CODE_FOR_spe_evmhosmfaaw, "__builtin_spe_evmhosmfaaw", SPE_BUILTIN_EVMHOSMFAAW },
4151 { 0, CODE_FOR_spe_evmhosmfanw, "__builtin_spe_evmhosmfanw", SPE_BUILTIN_EVMHOSMFANW },
4152 { 0, CODE_FOR_spe_evmhosmi, "__builtin_spe_evmhosmi", SPE_BUILTIN_EVMHOSMI },
4153 { 0, CODE_FOR_spe_evmhosmia, "__builtin_spe_evmhosmia", SPE_BUILTIN_EVMHOSMIA },
4154 { 0, CODE_FOR_spe_evmhosmiaaw, "__builtin_spe_evmhosmiaaw", SPE_BUILTIN_EVMHOSMIAAW },
4155 { 0, CODE_FOR_spe_evmhosmianw, "__builtin_spe_evmhosmianw", SPE_BUILTIN_EVMHOSMIANW },
4156 { 0, CODE_FOR_spe_evmhossf, "__builtin_spe_evmhossf", SPE_BUILTIN_EVMHOSSF },
4157 { 0, CODE_FOR_spe_evmhossfa, "__builtin_spe_evmhossfa", SPE_BUILTIN_EVMHOSSFA },
4158 { 0, CODE_FOR_spe_evmhossfaaw, "__builtin_spe_evmhossfaaw", SPE_BUILTIN_EVMHOSSFAAW },
4159 { 0, CODE_FOR_spe_evmhossfanw, "__builtin_spe_evmhossfanw", SPE_BUILTIN_EVMHOSSFANW },
4160 { 0, CODE_FOR_spe_evmhossiaaw, "__builtin_spe_evmhossiaaw", SPE_BUILTIN_EVMHOSSIAAW },
4161 { 0, CODE_FOR_spe_evmhossianw, "__builtin_spe_evmhossianw", SPE_BUILTIN_EVMHOSSIANW },
4162 { 0, CODE_FOR_spe_evmhoumi, "__builtin_spe_evmhoumi", SPE_BUILTIN_EVMHOUMI },
4163 { 0, CODE_FOR_spe_evmhoumia, "__builtin_spe_evmhoumia", SPE_BUILTIN_EVMHOUMIA },
4164 { 0, CODE_FOR_spe_evmhoumiaaw, "__builtin_spe_evmhoumiaaw", SPE_BUILTIN_EVMHOUMIAAW },
4165 { 0, CODE_FOR_spe_evmhoumianw, "__builtin_spe_evmhoumianw", SPE_BUILTIN_EVMHOUMIANW },
4166 { 0, CODE_FOR_spe_evmhousiaaw, "__builtin_spe_evmhousiaaw", SPE_BUILTIN_EVMHOUSIAAW },
4167 { 0, CODE_FOR_spe_evmhousianw, "__builtin_spe_evmhousianw", SPE_BUILTIN_EVMHOUSIANW },
4168 { 0, CODE_FOR_spe_evmwhsmf, "__builtin_spe_evmwhsmf", SPE_BUILTIN_EVMWHSMF },
4169 { 0, CODE_FOR_spe_evmwhsmfa, "__builtin_spe_evmwhsmfa", SPE_BUILTIN_EVMWHSMFA },
4170 { 0, CODE_FOR_spe_evmwhsmi, "__builtin_spe_evmwhsmi", SPE_BUILTIN_EVMWHSMI },
4171 { 0, CODE_FOR_spe_evmwhsmia, "__builtin_spe_evmwhsmia", SPE_BUILTIN_EVMWHSMIA },
4172 { 0, CODE_FOR_spe_evmwhssf, "__builtin_spe_evmwhssf", SPE_BUILTIN_EVMWHSSF },
4173 { 0, CODE_FOR_spe_evmwhssfa, "__builtin_spe_evmwhssfa", SPE_BUILTIN_EVMWHSSFA },
4174 { 0, CODE_FOR_spe_evmwhumi, "__builtin_spe_evmwhumi", SPE_BUILTIN_EVMWHUMI },
4175 { 0, CODE_FOR_spe_evmwhumia, "__builtin_spe_evmwhumia", SPE_BUILTIN_EVMWHUMIA },
a3170dc6
AH
4176 { 0, CODE_FOR_spe_evmwlsmiaaw, "__builtin_spe_evmwlsmiaaw", SPE_BUILTIN_EVMWLSMIAAW },
4177 { 0, CODE_FOR_spe_evmwlsmianw, "__builtin_spe_evmwlsmianw", SPE_BUILTIN_EVMWLSMIANW },
a3170dc6
AH
4178 { 0, CODE_FOR_spe_evmwlssiaaw, "__builtin_spe_evmwlssiaaw", SPE_BUILTIN_EVMWLSSIAAW },
4179 { 0, CODE_FOR_spe_evmwlssianw, "__builtin_spe_evmwlssianw", SPE_BUILTIN_EVMWLSSIANW },
4180 { 0, CODE_FOR_spe_evmwlumi, "__builtin_spe_evmwlumi", SPE_BUILTIN_EVMWLUMI },
4181 { 0, CODE_FOR_spe_evmwlumia, "__builtin_spe_evmwlumia", SPE_BUILTIN_EVMWLUMIA },
4182 { 0, CODE_FOR_spe_evmwlumiaaw, "__builtin_spe_evmwlumiaaw", SPE_BUILTIN_EVMWLUMIAAW },
4183 { 0, CODE_FOR_spe_evmwlumianw, "__builtin_spe_evmwlumianw", SPE_BUILTIN_EVMWLUMIANW },
4184 { 0, CODE_FOR_spe_evmwlusiaaw, "__builtin_spe_evmwlusiaaw", SPE_BUILTIN_EVMWLUSIAAW },
4185 { 0, CODE_FOR_spe_evmwlusianw, "__builtin_spe_evmwlusianw", SPE_BUILTIN_EVMWLUSIANW },
4186 { 0, CODE_FOR_spe_evmwsmf, "__builtin_spe_evmwsmf", SPE_BUILTIN_EVMWSMF },
4187 { 0, CODE_FOR_spe_evmwsmfa, "__builtin_spe_evmwsmfa", SPE_BUILTIN_EVMWSMFA },
4188 { 0, CODE_FOR_spe_evmwsmfaa, "__builtin_spe_evmwsmfaa", SPE_BUILTIN_EVMWSMFAA },
4189 { 0, CODE_FOR_spe_evmwsmfan, "__builtin_spe_evmwsmfan", SPE_BUILTIN_EVMWSMFAN },
4190 { 0, CODE_FOR_spe_evmwsmi, "__builtin_spe_evmwsmi", SPE_BUILTIN_EVMWSMI },
4191 { 0, CODE_FOR_spe_evmwsmia, "__builtin_spe_evmwsmia", SPE_BUILTIN_EVMWSMIA },
4192 { 0, CODE_FOR_spe_evmwsmiaa, "__builtin_spe_evmwsmiaa", SPE_BUILTIN_EVMWSMIAA },
4193 { 0, CODE_FOR_spe_evmwsmian, "__builtin_spe_evmwsmian", SPE_BUILTIN_EVMWSMIAN },
4194 { 0, CODE_FOR_spe_evmwssf, "__builtin_spe_evmwssf", SPE_BUILTIN_EVMWSSF },
4195 { 0, CODE_FOR_spe_evmwssfa, "__builtin_spe_evmwssfa", SPE_BUILTIN_EVMWSSFA },
4196 { 0, CODE_FOR_spe_evmwssfaa, "__builtin_spe_evmwssfaa", SPE_BUILTIN_EVMWSSFAA },
4197 { 0, CODE_FOR_spe_evmwssfan, "__builtin_spe_evmwssfan", SPE_BUILTIN_EVMWSSFAN },
4198 { 0, CODE_FOR_spe_evmwumi, "__builtin_spe_evmwumi", SPE_BUILTIN_EVMWUMI },
4199 { 0, CODE_FOR_spe_evmwumia, "__builtin_spe_evmwumia", SPE_BUILTIN_EVMWUMIA },
4200 { 0, CODE_FOR_spe_evmwumiaa, "__builtin_spe_evmwumiaa", SPE_BUILTIN_EVMWUMIAA },
4201 { 0, CODE_FOR_spe_evmwumian, "__builtin_spe_evmwumian", SPE_BUILTIN_EVMWUMIAN },
4202 { 0, CODE_FOR_spe_evnand, "__builtin_spe_evnand", SPE_BUILTIN_EVNAND },
4203 { 0, CODE_FOR_spe_evnor, "__builtin_spe_evnor", SPE_BUILTIN_EVNOR },
4204 { 0, CODE_FOR_spe_evor, "__builtin_spe_evor", SPE_BUILTIN_EVOR },
4205 { 0, CODE_FOR_spe_evorc, "__builtin_spe_evorc", SPE_BUILTIN_EVORC },
4206 { 0, CODE_FOR_spe_evrlw, "__builtin_spe_evrlw", SPE_BUILTIN_EVRLW },
4207 { 0, CODE_FOR_spe_evslw, "__builtin_spe_evslw", SPE_BUILTIN_EVSLW },
4208 { 0, CODE_FOR_spe_evsrws, "__builtin_spe_evsrws", SPE_BUILTIN_EVSRWS },
4209 { 0, CODE_FOR_spe_evsrwu, "__builtin_spe_evsrwu", SPE_BUILTIN_EVSRWU },
4210 { 0, CODE_FOR_spe_evsubfw, "__builtin_spe_evsubfw", SPE_BUILTIN_EVSUBFW },
4211
4212 /* SPE binary operations expecting a 5-bit unsigned literal. */
4213 { 0, CODE_FOR_spe_evaddiw, "__builtin_spe_evaddiw", SPE_BUILTIN_EVADDIW },
4214
4215 { 0, CODE_FOR_spe_evrlwi, "__builtin_spe_evrlwi", SPE_BUILTIN_EVRLWI },
4216 { 0, CODE_FOR_spe_evslwi, "__builtin_spe_evslwi", SPE_BUILTIN_EVSLWI },
4217 { 0, CODE_FOR_spe_evsrwis, "__builtin_spe_evsrwis", SPE_BUILTIN_EVSRWIS },
4218 { 0, CODE_FOR_spe_evsrwiu, "__builtin_spe_evsrwiu", SPE_BUILTIN_EVSRWIU },
4219 { 0, CODE_FOR_spe_evsubifw, "__builtin_spe_evsubifw", SPE_BUILTIN_EVSUBIFW },
4220 { 0, CODE_FOR_spe_evmwhssfaa, "__builtin_spe_evmwhssfaa", SPE_BUILTIN_EVMWHSSFAA },
4221 { 0, CODE_FOR_spe_evmwhssmaa, "__builtin_spe_evmwhssmaa", SPE_BUILTIN_EVMWHSSMAA },
4222 { 0, CODE_FOR_spe_evmwhsmfaa, "__builtin_spe_evmwhsmfaa", SPE_BUILTIN_EVMWHSMFAA },
4223 { 0, CODE_FOR_spe_evmwhsmiaa, "__builtin_spe_evmwhsmiaa", SPE_BUILTIN_EVMWHSMIAA },
4224 { 0, CODE_FOR_spe_evmwhusiaa, "__builtin_spe_evmwhusiaa", SPE_BUILTIN_EVMWHUSIAA },
4225 { 0, CODE_FOR_spe_evmwhumiaa, "__builtin_spe_evmwhumiaa", SPE_BUILTIN_EVMWHUMIAA },
4226 { 0, CODE_FOR_spe_evmwhssfan, "__builtin_spe_evmwhssfan", SPE_BUILTIN_EVMWHSSFAN },
4227 { 0, CODE_FOR_spe_evmwhssian, "__builtin_spe_evmwhssian", SPE_BUILTIN_EVMWHSSIAN },
4228 { 0, CODE_FOR_spe_evmwhsmfan, "__builtin_spe_evmwhsmfan", SPE_BUILTIN_EVMWHSMFAN },
4229 { 0, CODE_FOR_spe_evmwhsmian, "__builtin_spe_evmwhsmian", SPE_BUILTIN_EVMWHSMIAN },
4230 { 0, CODE_FOR_spe_evmwhusian, "__builtin_spe_evmwhusian", SPE_BUILTIN_EVMWHUSIAN },
4231 { 0, CODE_FOR_spe_evmwhumian, "__builtin_spe_evmwhumian", SPE_BUILTIN_EVMWHUMIAN },
4232 { 0, CODE_FOR_spe_evmwhgssfaa, "__builtin_spe_evmwhgssfaa", SPE_BUILTIN_EVMWHGSSFAA },
4233 { 0, CODE_FOR_spe_evmwhgsmfaa, "__builtin_spe_evmwhgsmfaa", SPE_BUILTIN_EVMWHGSMFAA },
4234 { 0, CODE_FOR_spe_evmwhgsmiaa, "__builtin_spe_evmwhgsmiaa", SPE_BUILTIN_EVMWHGSMIAA },
4235 { 0, CODE_FOR_spe_evmwhgumiaa, "__builtin_spe_evmwhgumiaa", SPE_BUILTIN_EVMWHGUMIAA },
4236 { 0, CODE_FOR_spe_evmwhgssfan, "__builtin_spe_evmwhgssfan", SPE_BUILTIN_EVMWHGSSFAN },
4237 { 0, CODE_FOR_spe_evmwhgsmfan, "__builtin_spe_evmwhgsmfan", SPE_BUILTIN_EVMWHGSMFAN },
4238 { 0, CODE_FOR_spe_evmwhgsmian, "__builtin_spe_evmwhgsmian", SPE_BUILTIN_EVMWHGSMIAN },
4239 { 0, CODE_FOR_spe_evmwhgumian, "__builtin_spe_evmwhgumian", SPE_BUILTIN_EVMWHGUMIAN },
4240 { 0, CODE_FOR_spe_brinc, "__builtin_spe_brinc", SPE_BUILTIN_BRINC },
4241
4242 /* Place-holder. Leave as last binary SPE builtin. */
17edbda5 4243 { 0, CODE_FOR_xorv2si3, "__builtin_spe_evxor", SPE_BUILTIN_EVXOR },
ae4b4a02
AH
4244};
4245
4246/* AltiVec predicates. */
4247
4248struct builtin_description_predicates
4249{
4250 const unsigned int mask;
4251 const enum insn_code icode;
4252 const char *opcode;
4253 const char *const name;
4254 const enum rs6000_builtins code;
4255};
4256
4257static const struct builtin_description_predicates bdesc_altivec_preds[] =
4258{
4259 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpbfp.", "__builtin_altivec_vcmpbfp_p", ALTIVEC_BUILTIN_VCMPBFP_P },
4260 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpeqfp.", "__builtin_altivec_vcmpeqfp_p", ALTIVEC_BUILTIN_VCMPEQFP_P },
4261 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgefp.", "__builtin_altivec_vcmpgefp_p", ALTIVEC_BUILTIN_VCMPGEFP_P },
4262 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4sf, "*vcmpgtfp.", "__builtin_altivec_vcmpgtfp_p", ALTIVEC_BUILTIN_VCMPGTFP_P },
4263 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpequw.", "__builtin_altivec_vcmpequw_p", ALTIVEC_BUILTIN_VCMPEQUW_P },
4264 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtsw.", "__builtin_altivec_vcmpgtsw_p", ALTIVEC_BUILTIN_VCMPGTSW_P },
4265 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v4si, "*vcmpgtuw.", "__builtin_altivec_vcmpgtuw_p", ALTIVEC_BUILTIN_VCMPGTUW_P },
4266 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtuh.", "__builtin_altivec_vcmpgtuh_p", ALTIVEC_BUILTIN_VCMPGTUH_P },
4267 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpgtsh.", "__builtin_altivec_vcmpgtsh_p", ALTIVEC_BUILTIN_VCMPGTSH_P },
4268 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v8hi, "*vcmpequh.", "__builtin_altivec_vcmpequh_p", ALTIVEC_BUILTIN_VCMPEQUH_P },
4269 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpequb.", "__builtin_altivec_vcmpequb_p", ALTIVEC_BUILTIN_VCMPEQUB_P },
4270 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtsb.", "__builtin_altivec_vcmpgtsb_p", ALTIVEC_BUILTIN_VCMPGTSB_P },
4271 { MASK_ALTIVEC, CODE_FOR_altivec_predicate_v16qi, "*vcmpgtub.", "__builtin_altivec_vcmpgtub_p", ALTIVEC_BUILTIN_VCMPGTUB_P }
0ac081f6 4272};
24408032 4273
a3170dc6
AH
4274/* SPE predicates. */
4275static struct builtin_description bdesc_spe_predicates[] =
4276{
4277 /* Place-holder. Leave as first. */
4278 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evcmpeq", SPE_BUILTIN_EVCMPEQ },
4279 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evcmpgts", SPE_BUILTIN_EVCMPGTS },
4280 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evcmpgtu", SPE_BUILTIN_EVCMPGTU },
4281 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evcmplts", SPE_BUILTIN_EVCMPLTS },
4282 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evcmpltu", SPE_BUILTIN_EVCMPLTU },
4283 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evfscmpeq", SPE_BUILTIN_EVFSCMPEQ },
4284 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evfscmpgt", SPE_BUILTIN_EVFSCMPGT },
4285 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evfscmplt", SPE_BUILTIN_EVFSCMPLT },
4286 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evfststeq", SPE_BUILTIN_EVFSTSTEQ },
4287 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evfststgt", SPE_BUILTIN_EVFSTSTGT },
4288 /* Place-holder. Leave as last. */
4289 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evfststlt", SPE_BUILTIN_EVFSTSTLT },
4290};
4291
4292/* SPE evsel predicates. */
4293static struct builtin_description bdesc_spe_evsel[] =
4294{
4295 /* Place-holder. Leave as first. */
4296 { 0, CODE_FOR_spe_evcmpgts, "__builtin_spe_evsel_gts", SPE_BUILTIN_EVSEL_CMPGTS },
4297 { 0, CODE_FOR_spe_evcmpgtu, "__builtin_spe_evsel_gtu", SPE_BUILTIN_EVSEL_CMPGTU },
4298 { 0, CODE_FOR_spe_evcmplts, "__builtin_spe_evsel_lts", SPE_BUILTIN_EVSEL_CMPLTS },
4299 { 0, CODE_FOR_spe_evcmpltu, "__builtin_spe_evsel_ltu", SPE_BUILTIN_EVSEL_CMPLTU },
4300 { 0, CODE_FOR_spe_evcmpeq, "__builtin_spe_evsel_eq", SPE_BUILTIN_EVSEL_CMPEQ },
4301 { 0, CODE_FOR_spe_evfscmpgt, "__builtin_spe_evsel_fsgt", SPE_BUILTIN_EVSEL_FSCMPGT },
4302 { 0, CODE_FOR_spe_evfscmplt, "__builtin_spe_evsel_fslt", SPE_BUILTIN_EVSEL_FSCMPLT },
4303 { 0, CODE_FOR_spe_evfscmpeq, "__builtin_spe_evsel_fseq", SPE_BUILTIN_EVSEL_FSCMPEQ },
4304 { 0, CODE_FOR_spe_evfststgt, "__builtin_spe_evsel_fststgt", SPE_BUILTIN_EVSEL_FSTSTGT },
4305 { 0, CODE_FOR_spe_evfststlt, "__builtin_spe_evsel_fststlt", SPE_BUILTIN_EVSEL_FSTSTLT },
4306 /* Place-holder. Leave as last. */
4307 { 0, CODE_FOR_spe_evfststeq, "__builtin_spe_evsel_fststeq", SPE_BUILTIN_EVSEL_FSTSTEQ },
4308};
4309
b6d08ca1 4310/* ABS* operations. */
100c4561
AH
4311
4312static const struct builtin_description bdesc_abs[] =
4313{
4314 { MASK_ALTIVEC, CODE_FOR_absv4si2, "__builtin_altivec_abs_v4si", ALTIVEC_BUILTIN_ABS_V4SI },
4315 { MASK_ALTIVEC, CODE_FOR_absv8hi2, "__builtin_altivec_abs_v8hi", ALTIVEC_BUILTIN_ABS_V8HI },
4316 { MASK_ALTIVEC, CODE_FOR_absv4sf2, "__builtin_altivec_abs_v4sf", ALTIVEC_BUILTIN_ABS_V4SF },
4317 { MASK_ALTIVEC, CODE_FOR_absv16qi2, "__builtin_altivec_abs_v16qi", ALTIVEC_BUILTIN_ABS_V16QI },
4318 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v4si, "__builtin_altivec_abss_v4si", ALTIVEC_BUILTIN_ABSS_V4SI },
4319 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v8hi, "__builtin_altivec_abss_v8hi", ALTIVEC_BUILTIN_ABSS_V8HI },
4320 { MASK_ALTIVEC, CODE_FOR_altivec_abss_v16qi, "__builtin_altivec_abss_v16qi", ALTIVEC_BUILTIN_ABSS_V16QI }
4321};
4322
617e0e1d
DB
4323/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
4324 foo (VECa). */
24408032 4325
a3170dc6 4326static struct builtin_description bdesc_1arg[] =
2212663f 4327{
617e0e1d
DB
4328 { MASK_ALTIVEC, CODE_FOR_altivec_vexptefp, "__builtin_altivec_vexptefp", ALTIVEC_BUILTIN_VEXPTEFP },
4329 { MASK_ALTIVEC, CODE_FOR_altivec_vlogefp, "__builtin_altivec_vlogefp", ALTIVEC_BUILTIN_VLOGEFP },
4330 { MASK_ALTIVEC, CODE_FOR_altivec_vrefp, "__builtin_altivec_vrefp", ALTIVEC_BUILTIN_VREFP },
4331 { MASK_ALTIVEC, CODE_FOR_altivec_vrfim, "__builtin_altivec_vrfim", ALTIVEC_BUILTIN_VRFIM },
4332 { MASK_ALTIVEC, CODE_FOR_altivec_vrfin, "__builtin_altivec_vrfin", ALTIVEC_BUILTIN_VRFIN },
4333 { MASK_ALTIVEC, CODE_FOR_altivec_vrfip, "__builtin_altivec_vrfip", ALTIVEC_BUILTIN_VRFIP },
4334 { MASK_ALTIVEC, CODE_FOR_ftruncv4sf2, "__builtin_altivec_vrfiz", ALTIVEC_BUILTIN_VRFIZ },
4335 { MASK_ALTIVEC, CODE_FOR_altivec_vrsqrtefp, "__builtin_altivec_vrsqrtefp", ALTIVEC_BUILTIN_VRSQRTEFP },
2212663f
DB
4336 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisb, "__builtin_altivec_vspltisb", ALTIVEC_BUILTIN_VSPLTISB },
4337 { MASK_ALTIVEC, CODE_FOR_altivec_vspltish, "__builtin_altivec_vspltish", ALTIVEC_BUILTIN_VSPLTISH },
4338 { MASK_ALTIVEC, CODE_FOR_altivec_vspltisw, "__builtin_altivec_vspltisw", ALTIVEC_BUILTIN_VSPLTISW },
20e26713
AH
4339 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsb, "__builtin_altivec_vupkhsb", ALTIVEC_BUILTIN_VUPKHSB },
4340 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhpx, "__builtin_altivec_vupkhpx", ALTIVEC_BUILTIN_VUPKHPX },
4341 { MASK_ALTIVEC, CODE_FOR_altivec_vupkhsh, "__builtin_altivec_vupkhsh", ALTIVEC_BUILTIN_VUPKHSH },
4342 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsb, "__builtin_altivec_vupklsb", ALTIVEC_BUILTIN_VUPKLSB },
4343 { MASK_ALTIVEC, CODE_FOR_altivec_vupklpx, "__builtin_altivec_vupklpx", ALTIVEC_BUILTIN_VUPKLPX },
4344 { MASK_ALTIVEC, CODE_FOR_altivec_vupklsh, "__builtin_altivec_vupklsh", ALTIVEC_BUILTIN_VUPKLSH },
a3170dc6
AH
4345
4346 /* The SPE unary builtins must start with SPE_BUILTIN_EVABS and
4347 end with SPE_BUILTIN_EVSUBFUSIAAW. */
4348 { 0, CODE_FOR_spe_evabs, "__builtin_spe_evabs", SPE_BUILTIN_EVABS },
4349 { 0, CODE_FOR_spe_evaddsmiaaw, "__builtin_spe_evaddsmiaaw", SPE_BUILTIN_EVADDSMIAAW },
4350 { 0, CODE_FOR_spe_evaddssiaaw, "__builtin_spe_evaddssiaaw", SPE_BUILTIN_EVADDSSIAAW },
4351 { 0, CODE_FOR_spe_evaddumiaaw, "__builtin_spe_evaddumiaaw", SPE_BUILTIN_EVADDUMIAAW },
4352 { 0, CODE_FOR_spe_evaddusiaaw, "__builtin_spe_evaddusiaaw", SPE_BUILTIN_EVADDUSIAAW },
4353 { 0, CODE_FOR_spe_evcntlsw, "__builtin_spe_evcntlsw", SPE_BUILTIN_EVCNTLSW },
4354 { 0, CODE_FOR_spe_evcntlzw, "__builtin_spe_evcntlzw", SPE_BUILTIN_EVCNTLZW },
4355 { 0, CODE_FOR_spe_evextsb, "__builtin_spe_evextsb", SPE_BUILTIN_EVEXTSB },
4356 { 0, CODE_FOR_spe_evextsh, "__builtin_spe_evextsh", SPE_BUILTIN_EVEXTSH },
4357 { 0, CODE_FOR_spe_evfsabs, "__builtin_spe_evfsabs", SPE_BUILTIN_EVFSABS },
4358 { 0, CODE_FOR_spe_evfscfsf, "__builtin_spe_evfscfsf", SPE_BUILTIN_EVFSCFSF },
4359 { 0, CODE_FOR_spe_evfscfsi, "__builtin_spe_evfscfsi", SPE_BUILTIN_EVFSCFSI },
4360 { 0, CODE_FOR_spe_evfscfuf, "__builtin_spe_evfscfuf", SPE_BUILTIN_EVFSCFUF },
4361 { 0, CODE_FOR_spe_evfscfui, "__builtin_spe_evfscfui", SPE_BUILTIN_EVFSCFUI },
4362 { 0, CODE_FOR_spe_evfsctsf, "__builtin_spe_evfsctsf", SPE_BUILTIN_EVFSCTSF },
4363 { 0, CODE_FOR_spe_evfsctsi, "__builtin_spe_evfsctsi", SPE_BUILTIN_EVFSCTSI },
4364 { 0, CODE_FOR_spe_evfsctsiz, "__builtin_spe_evfsctsiz", SPE_BUILTIN_EVFSCTSIZ },
4365 { 0, CODE_FOR_spe_evfsctuf, "__builtin_spe_evfsctuf", SPE_BUILTIN_EVFSCTUF },
4366 { 0, CODE_FOR_spe_evfsctui, "__builtin_spe_evfsctui", SPE_BUILTIN_EVFSCTUI },
4367 { 0, CODE_FOR_spe_evfsctuiz, "__builtin_spe_evfsctuiz", SPE_BUILTIN_EVFSCTUIZ },
4368 { 0, CODE_FOR_spe_evfsnabs, "__builtin_spe_evfsnabs", SPE_BUILTIN_EVFSNABS },
4369 { 0, CODE_FOR_spe_evfsneg, "__builtin_spe_evfsneg", SPE_BUILTIN_EVFSNEG },
4370 { 0, CODE_FOR_spe_evmra, "__builtin_spe_evmra", SPE_BUILTIN_EVMRA },
4371 { 0, CODE_FOR_spe_evneg, "__builtin_spe_evneg", SPE_BUILTIN_EVNEG },
4372 { 0, CODE_FOR_spe_evrndw, "__builtin_spe_evrndw", SPE_BUILTIN_EVRNDW },
4373 { 0, CODE_FOR_spe_evsubfsmiaaw, "__builtin_spe_evsubfsmiaaw", SPE_BUILTIN_EVSUBFSMIAAW },
4374 { 0, CODE_FOR_spe_evsubfssiaaw, "__builtin_spe_evsubfssiaaw", SPE_BUILTIN_EVSUBFSSIAAW },
4375 { 0, CODE_FOR_spe_evsubfumiaaw, "__builtin_spe_evsubfumiaaw", SPE_BUILTIN_EVSUBFUMIAAW },
4376 { 0, CODE_FOR_spe_evsplatfi, "__builtin_spe_evsplatfi", SPE_BUILTIN_EVSPLATFI },
4377 { 0, CODE_FOR_spe_evsplati, "__builtin_spe_evsplati", SPE_BUILTIN_EVSPLATI },
4378
4379 /* Place-holder. Leave as last unary SPE builtin. */
4380 { 0, CODE_FOR_spe_evsubfusiaaw, "__builtin_spe_evsubfusiaaw", SPE_BUILTIN_EVSUBFUSIAAW },
2212663f
DB
4381};
4382
4383static rtx
92898235 4384rs6000_expand_unop_builtin (icode, arglist, target)
2212663f
DB
4385 enum insn_code icode;
4386 tree arglist;
4387 rtx target;
4388{
4389 rtx pat;
4390 tree arg0 = TREE_VALUE (arglist);
4391 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4392 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4393 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4394
0559cc77
DE
4395 if (icode == CODE_FOR_nothing)
4396 /* Builtin not supported on this processor. */
4397 return 0;
4398
20e26713
AH
4399 /* If we got invalid arguments bail out before generating bad rtl. */
4400 if (arg0 == error_mark_node)
9a171fcd 4401 return const0_rtx;
20e26713 4402
0559cc77
DE
4403 if (icode == CODE_FOR_altivec_vspltisb
4404 || icode == CODE_FOR_altivec_vspltish
4405 || icode == CODE_FOR_altivec_vspltisw
4406 || icode == CODE_FOR_spe_evsplatfi
4407 || icode == CODE_FOR_spe_evsplati)
b44140e7
AH
4408 {
4409 /* Only allow 5-bit *signed* literals. */
b44140e7
AH
4410 if (GET_CODE (op0) != CONST_INT
4411 || INTVAL (op0) > 0x1f
4412 || INTVAL (op0) < -0x1f)
4413 {
4414 error ("argument 1 must be a 5-bit signed literal");
9a171fcd 4415 return const0_rtx;
b44140e7 4416 }
b44140e7
AH
4417 }
4418
c62f2db5 4419 if (target == 0
2212663f
DB
4420 || GET_MODE (target) != tmode
4421 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4422 target = gen_reg_rtx (tmode);
4423
4424 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4425 op0 = copy_to_mode_reg (mode0, op0);
4426
4427 pat = GEN_FCN (icode) (target, op0);
4428 if (! pat)
4429 return 0;
4430 emit_insn (pat);
0ac081f6 4431
2212663f
DB
4432 return target;
4433}
ae4b4a02 4434
100c4561
AH
4435static rtx
4436altivec_expand_abs_builtin (icode, arglist, target)
4437 enum insn_code icode;
4438 tree arglist;
4439 rtx target;
4440{
4441 rtx pat, scratch1, scratch2;
4442 tree arg0 = TREE_VALUE (arglist);
4443 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4444 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4445 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4446
4447 /* If we have invalid arguments, bail out before generating bad rtl. */
4448 if (arg0 == error_mark_node)
9a171fcd 4449 return const0_rtx;
100c4561
AH
4450
4451 if (target == 0
4452 || GET_MODE (target) != tmode
4453 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4454 target = gen_reg_rtx (tmode);
4455
4456 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4457 op0 = copy_to_mode_reg (mode0, op0);
4458
4459 scratch1 = gen_reg_rtx (mode0);
4460 scratch2 = gen_reg_rtx (mode0);
4461
4462 pat = GEN_FCN (icode) (target, op0, scratch1, scratch2);
4463 if (! pat)
4464 return 0;
4465 emit_insn (pat);
4466
4467 return target;
4468}
4469
0ac081f6 4470static rtx
92898235 4471rs6000_expand_binop_builtin (icode, arglist, target)
0ac081f6
AH
4472 enum insn_code icode;
4473 tree arglist;
4474 rtx target;
4475{
4476 rtx pat;
4477 tree arg0 = TREE_VALUE (arglist);
4478 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4479 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4480 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4481 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4482 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4483 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4484
0559cc77
DE
4485 if (icode == CODE_FOR_nothing)
4486 /* Builtin not supported on this processor. */
4487 return 0;
4488
20e26713
AH
4489 /* If we got invalid arguments bail out before generating bad rtl. */
4490 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4491 return const0_rtx;
20e26713 4492
0559cc77
DE
4493 if (icode == CODE_FOR_altivec_vcfux
4494 || icode == CODE_FOR_altivec_vcfsx
4495 || icode == CODE_FOR_altivec_vctsxs
4496 || icode == CODE_FOR_altivec_vctuxs
4497 || icode == CODE_FOR_altivec_vspltb
4498 || icode == CODE_FOR_altivec_vsplth
4499 || icode == CODE_FOR_altivec_vspltw
4500 || icode == CODE_FOR_spe_evaddiw
4501 || icode == CODE_FOR_spe_evldd
4502 || icode == CODE_FOR_spe_evldh
4503 || icode == CODE_FOR_spe_evldw
4504 || icode == CODE_FOR_spe_evlhhesplat
4505 || icode == CODE_FOR_spe_evlhhossplat
4506 || icode == CODE_FOR_spe_evlhhousplat
4507 || icode == CODE_FOR_spe_evlwhe
4508 || icode == CODE_FOR_spe_evlwhos
4509 || icode == CODE_FOR_spe_evlwhou
4510 || icode == CODE_FOR_spe_evlwhsplat
4511 || icode == CODE_FOR_spe_evlwwsplat
4512 || icode == CODE_FOR_spe_evrlwi
4513 || icode == CODE_FOR_spe_evslwi
4514 || icode == CODE_FOR_spe_evsrwis
4515 || icode == CODE_FOR_spe_evsrwiu)
b44140e7
AH
4516 {
4517 /* Only allow 5-bit unsigned literals. */
b44140e7
AH
4518 if (TREE_CODE (arg1) != INTEGER_CST
4519 || TREE_INT_CST_LOW (arg1) & ~0x1f)
4520 {
4521 error ("argument 2 must be a 5-bit unsigned literal");
9a171fcd 4522 return const0_rtx;
b44140e7 4523 }
b44140e7
AH
4524 }
4525
c62f2db5 4526 if (target == 0
0ac081f6
AH
4527 || GET_MODE (target) != tmode
4528 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4529 target = gen_reg_rtx (tmode);
4530
4531 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4532 op0 = copy_to_mode_reg (mode0, op0);
4533 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4534 op1 = copy_to_mode_reg (mode1, op1);
4535
4536 pat = GEN_FCN (icode) (target, op0, op1);
4537 if (! pat)
4538 return 0;
4539 emit_insn (pat);
4540
4541 return target;
4542}
6525c0e7 4543
ae4b4a02
AH
4544static rtx
4545altivec_expand_predicate_builtin (icode, opcode, arglist, target)
4546 enum insn_code icode;
4547 const char *opcode;
4548 tree arglist;
4549 rtx target;
4550{
4551 rtx pat, scratch;
4552 tree cr6_form = TREE_VALUE (arglist);
4553 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
4554 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4555 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4556 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4557 enum machine_mode tmode = SImode;
4558 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4559 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4560 int cr6_form_int;
4561
4562 if (TREE_CODE (cr6_form) != INTEGER_CST)
4563 {
4564 error ("argument 1 of __builtin_altivec_predicate must be a constant");
9a171fcd 4565 return const0_rtx;
ae4b4a02
AH
4566 }
4567 else
4568 cr6_form_int = TREE_INT_CST_LOW (cr6_form);
4569
4570 if (mode0 != mode1)
4571 abort ();
4572
4573 /* If we have invalid arguments, bail out before generating bad rtl. */
4574 if (arg0 == error_mark_node || arg1 == error_mark_node)
9a171fcd 4575 return const0_rtx;
ae4b4a02
AH
4576
4577 if (target == 0
4578 || GET_MODE (target) != tmode
4579 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4580 target = gen_reg_rtx (tmode);
4581
4582 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4583 op0 = copy_to_mode_reg (mode0, op0);
4584 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4585 op1 = copy_to_mode_reg (mode1, op1);
4586
4587 scratch = gen_reg_rtx (mode0);
4588
4589 pat = GEN_FCN (icode) (scratch, op0, op1,
4590 gen_rtx (SYMBOL_REF, Pmode, opcode));
4591 if (! pat)
4592 return 0;
4593 emit_insn (pat);
4594
4595 /* The vec_any* and vec_all* predicates use the same opcodes for two
4596 different operations, but the bits in CR6 will be different
4597 depending on what information we want. So we have to play tricks
4598 with CR6 to get the right bits out.
4599
4600 If you think this is disgusting, look at the specs for the
4601 AltiVec predicates. */
4602
4603 switch (cr6_form_int)
4604 {
4605 case 0:
4606 emit_insn (gen_cr6_test_for_zero (target));
4607 break;
4608 case 1:
4609 emit_insn (gen_cr6_test_for_zero_reverse (target));
4610 break;
4611 case 2:
4612 emit_insn (gen_cr6_test_for_lt (target));
4613 break;
4614 case 3:
4615 emit_insn (gen_cr6_test_for_lt_reverse (target));
4616 break;
4617 default:
4618 error ("argument 1 of __builtin_altivec_predicate is out of range");
4619 break;
4620 }
4621
4622 return target;
4623}
4624
6525c0e7
AH
4625static rtx
4626altivec_expand_stv_builtin (icode, arglist)
4627 enum insn_code icode;
4628 tree arglist;
4629{
4630 tree arg0 = TREE_VALUE (arglist);
4631 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4632 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4633 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4634 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4635 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4636 rtx pat;
4637 enum machine_mode mode0 = insn_data[icode].operand[0].mode;
4638 enum machine_mode mode1 = insn_data[icode].operand[1].mode;
4639 enum machine_mode mode2 = insn_data[icode].operand[2].mode;
4640
4641 /* Invalid arguments. Bail before doing anything stoopid! */
4642 if (arg0 == error_mark_node
4643 || arg1 == error_mark_node
4644 || arg2 == error_mark_node)
9a171fcd 4645 return const0_rtx;
6525c0e7
AH
4646
4647 if (! (*insn_data[icode].operand[2].predicate) (op0, mode2))
4648 op0 = copy_to_mode_reg (mode2, op0);
4649 if (! (*insn_data[icode].operand[0].predicate) (op1, mode0))
4650 op1 = copy_to_mode_reg (mode0, op1);
4651 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
4652 op2 = copy_to_mode_reg (mode1, op2);
4653
4654 pat = GEN_FCN (icode) (op1, op2, op0);
4655 if (pat)
4656 emit_insn (pat);
4657 return NULL_RTX;
4658}
4659
2212663f 4660static rtx
92898235 4661rs6000_expand_ternop_builtin (icode, arglist, target)
2212663f
DB
4662 enum insn_code icode;
4663 tree arglist;
4664 rtx target;
4665{
4666 rtx pat;
4667 tree arg0 = TREE_VALUE (arglist);
4668 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4669 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4670 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4671 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4672 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4673 enum machine_mode tmode = insn_data[icode].operand[0].mode;
4674 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
4675 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
4676 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
0ac081f6 4677
774b5662
DE
4678 if (icode == CODE_FOR_nothing)
4679 /* Builtin not supported on this processor. */
4680 return 0;
4681
20e26713
AH
4682 /* If we got invalid arguments bail out before generating bad rtl. */
4683 if (arg0 == error_mark_node
4684 || arg1 == error_mark_node
4685 || arg2 == error_mark_node)
9a171fcd 4686 return const0_rtx;
20e26713 4687
774b5662
DE
4688 if (icode == CODE_FOR_altivec_vsldoi_4sf
4689 || icode == CODE_FOR_altivec_vsldoi_4si
4690 || icode == CODE_FOR_altivec_vsldoi_8hi
4691 || icode == CODE_FOR_altivec_vsldoi_16qi)
b44140e7
AH
4692 {
4693 /* Only allow 4-bit unsigned literals. */
b44140e7
AH
4694 if (TREE_CODE (arg2) != INTEGER_CST
4695 || TREE_INT_CST_LOW (arg2) & ~0xf)
4696 {
4697 error ("argument 3 must be a 4-bit unsigned literal");
e3277ffb 4698 return const0_rtx;
b44140e7 4699 }
b44140e7
AH
4700 }
4701
c62f2db5 4702 if (target == 0
2212663f
DB
4703 || GET_MODE (target) != tmode
4704 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4705 target = gen_reg_rtx (tmode);
4706
4707 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4708 op0 = copy_to_mode_reg (mode0, op0);
4709 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
4710 op1 = copy_to_mode_reg (mode1, op1);
4711 if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
4712 op2 = copy_to_mode_reg (mode2, op2);
4713
4714 pat = GEN_FCN (icode) (target, op0, op1, op2);
4715 if (! pat)
4716 return 0;
4717 emit_insn (pat);
4718
4719 return target;
4720}
92898235 4721
3a9b8c7e 4722/* Expand the lvx builtins. */
0ac081f6 4723static rtx
3a9b8c7e 4724altivec_expand_ld_builtin (exp, target, expandedp)
0ac081f6
AH
4725 tree exp;
4726 rtx target;
92898235 4727 bool *expandedp;
0ac081f6 4728{
0ac081f6
AH
4729 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4730 tree arglist = TREE_OPERAND (exp, 1);
0ac081f6 4731 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3a9b8c7e
AH
4732 tree arg0;
4733 enum machine_mode tmode, mode0;
7c3abc73 4734 rtx pat, op0;
3a9b8c7e 4735 enum insn_code icode;
92898235 4736
0ac081f6
AH
4737 switch (fcode)
4738 {
f18c054f
DB
4739 case ALTIVEC_BUILTIN_LD_INTERNAL_16qi:
4740 icode = CODE_FOR_altivec_lvx_16qi;
3a9b8c7e 4741 break;
f18c054f
DB
4742 case ALTIVEC_BUILTIN_LD_INTERNAL_8hi:
4743 icode = CODE_FOR_altivec_lvx_8hi;
3a9b8c7e
AH
4744 break;
4745 case ALTIVEC_BUILTIN_LD_INTERNAL_4si:
4746 icode = CODE_FOR_altivec_lvx_4si;
4747 break;
4748 case ALTIVEC_BUILTIN_LD_INTERNAL_4sf:
4749 icode = CODE_FOR_altivec_lvx_4sf;
4750 break;
4751 default:
4752 *expandedp = false;
4753 return NULL_RTX;
4754 }
0ac081f6 4755
3a9b8c7e 4756 *expandedp = true;
f18c054f 4757
3a9b8c7e
AH
4758 arg0 = TREE_VALUE (arglist);
4759 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4760 tmode = insn_data[icode].operand[0].mode;
4761 mode0 = insn_data[icode].operand[1].mode;
f18c054f 4762
3a9b8c7e
AH
4763 if (target == 0
4764 || GET_MODE (target) != tmode
4765 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4766 target = gen_reg_rtx (tmode);
24408032 4767
3a9b8c7e
AH
4768 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
4769 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
f18c054f 4770
3a9b8c7e
AH
4771 pat = GEN_FCN (icode) (target, op0);
4772 if (! pat)
4773 return 0;
4774 emit_insn (pat);
4775 return target;
4776}
f18c054f 4777
3a9b8c7e
AH
4778/* Expand the stvx builtins. */
4779static rtx
4780altivec_expand_st_builtin (exp, target, expandedp)
4781 tree exp;
7c3abc73 4782 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4783 bool *expandedp;
4784{
4785 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4786 tree arglist = TREE_OPERAND (exp, 1);
4787 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4788 tree arg0, arg1;
4789 enum machine_mode mode0, mode1;
7c3abc73 4790 rtx pat, op0, op1;
3a9b8c7e 4791 enum insn_code icode;
f18c054f 4792
3a9b8c7e
AH
4793 switch (fcode)
4794 {
4795 case ALTIVEC_BUILTIN_ST_INTERNAL_16qi:
4796 icode = CODE_FOR_altivec_stvx_16qi;
4797 break;
4798 case ALTIVEC_BUILTIN_ST_INTERNAL_8hi:
4799 icode = CODE_FOR_altivec_stvx_8hi;
4800 break;
4801 case ALTIVEC_BUILTIN_ST_INTERNAL_4si:
4802 icode = CODE_FOR_altivec_stvx_4si;
4803 break;
4804 case ALTIVEC_BUILTIN_ST_INTERNAL_4sf:
4805 icode = CODE_FOR_altivec_stvx_4sf;
4806 break;
4807 default:
4808 *expandedp = false;
4809 return NULL_RTX;
4810 }
24408032 4811
3a9b8c7e
AH
4812 arg0 = TREE_VALUE (arglist);
4813 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4814 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4815 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4816 mode0 = insn_data[icode].operand[0].mode;
4817 mode1 = insn_data[icode].operand[1].mode;
f18c054f 4818
3a9b8c7e
AH
4819 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4820 op0 = gen_rtx_MEM (mode0, copy_to_mode_reg (Pmode, op0));
4821 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
4822 op1 = copy_to_mode_reg (mode1, op1);
f18c054f 4823
3a9b8c7e
AH
4824 pat = GEN_FCN (icode) (op0, op1);
4825 if (pat)
4826 emit_insn (pat);
f18c054f 4827
3a9b8c7e
AH
4828 *expandedp = true;
4829 return NULL_RTX;
4830}
f18c054f 4831
3a9b8c7e
AH
4832/* Expand the dst builtins. */
4833static rtx
4834altivec_expand_dst_builtin (exp, target, expandedp)
4835 tree exp;
7c3abc73 4836 rtx target ATTRIBUTE_UNUSED;
3a9b8c7e
AH
4837 bool *expandedp;
4838{
4839 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4840 tree arglist = TREE_OPERAND (exp, 1);
4841 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
4842 tree arg0, arg1, arg2;
4843 enum machine_mode mode0, mode1, mode2;
7c3abc73 4844 rtx pat, op0, op1, op2;
3a9b8c7e 4845 struct builtin_description *d;
a3170dc6 4846 size_t i;
f18c054f 4847
3a9b8c7e 4848 *expandedp = false;
f18c054f 4849
3a9b8c7e
AH
4850 /* Handle DST variants. */
4851 d = (struct builtin_description *) bdesc_dst;
4852 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
4853 if (d->code == fcode)
4854 {
4855 arg0 = TREE_VALUE (arglist);
4856 arg1 = TREE_VALUE (TREE_CHAIN (arglist));
4857 arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
4858 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4859 op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
4860 op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
4861 mode0 = insn_data[d->icode].operand[0].mode;
4862 mode1 = insn_data[d->icode].operand[1].mode;
4863 mode2 = insn_data[d->icode].operand[2].mode;
24408032 4864
3a9b8c7e
AH
4865 /* Invalid arguments, bail out before generating bad rtl. */
4866 if (arg0 == error_mark_node
4867 || arg1 == error_mark_node
4868 || arg2 == error_mark_node)
4869 return const0_rtx;
f18c054f 4870
3a9b8c7e
AH
4871 if (TREE_CODE (arg2) != INTEGER_CST
4872 || TREE_INT_CST_LOW (arg2) & ~0x3)
4873 {
4874 error ("argument to `%s' must be a 2-bit unsigned literal", d->name);
4875 return const0_rtx;
4876 }
f18c054f 4877
3a9b8c7e
AH
4878 if (! (*insn_data[d->icode].operand[0].predicate) (op0, mode0))
4879 op0 = copy_to_mode_reg (mode0, op0);
4880 if (! (*insn_data[d->icode].operand[1].predicate) (op1, mode1))
4881 op1 = copy_to_mode_reg (mode1, op1);
24408032 4882
3a9b8c7e
AH
4883 pat = GEN_FCN (d->icode) (op0, op1, op2);
4884 if (pat != 0)
4885 emit_insn (pat);
f18c054f 4886
3a9b8c7e
AH
4887 *expandedp = true;
4888 return NULL_RTX;
4889 }
f18c054f 4890
3a9b8c7e
AH
4891 return NULL_RTX;
4892}
24408032 4893
3a9b8c7e
AH
4894/* Expand the builtin in EXP and store the result in TARGET. Store
4895 true in *EXPANDEDP if we found a builtin to expand. */
4896static rtx
4897altivec_expand_builtin (exp, target, expandedp)
4898 tree exp;
4899 rtx target;
4900 bool *expandedp;
4901{
4902 struct builtin_description *d;
4903 struct builtin_description_predicates *dp;
4904 size_t i;
4905 enum insn_code icode;
4906 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
4907 tree arglist = TREE_OPERAND (exp, 1);
7c3abc73
AH
4908 tree arg0;
4909 rtx op0, pat;
4910 enum machine_mode tmode, mode0;
3a9b8c7e 4911 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
0ac081f6 4912
3a9b8c7e
AH
4913 target = altivec_expand_ld_builtin (exp, target, expandedp);
4914 if (*expandedp)
4915 return target;
0ac081f6 4916
3a9b8c7e
AH
4917 target = altivec_expand_st_builtin (exp, target, expandedp);
4918 if (*expandedp)
4919 return target;
4920
4921 target = altivec_expand_dst_builtin (exp, target, expandedp);
4922 if (*expandedp)
4923 return target;
4924
4925 *expandedp = true;
95385cbb 4926
3a9b8c7e
AH
4927 switch (fcode)
4928 {
6525c0e7
AH
4929 case ALTIVEC_BUILTIN_STVX:
4930 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvx, arglist);
4931 case ALTIVEC_BUILTIN_STVEBX:
4932 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvebx, arglist);
4933 case ALTIVEC_BUILTIN_STVEHX:
4934 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvehx, arglist);
4935 case ALTIVEC_BUILTIN_STVEWX:
4936 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvewx, arglist);
4937 case ALTIVEC_BUILTIN_STVXL:
4938 return altivec_expand_stv_builtin (CODE_FOR_altivec_stvxl, arglist);
3a9b8c7e 4939
95385cbb
AH
4940 case ALTIVEC_BUILTIN_MFVSCR:
4941 icode = CODE_FOR_altivec_mfvscr;
4942 tmode = insn_data[icode].operand[0].mode;
4943
4944 if (target == 0
4945 || GET_MODE (target) != tmode
4946 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
4947 target = gen_reg_rtx (tmode);
4948
4949 pat = GEN_FCN (icode) (target);
0ac081f6
AH
4950 if (! pat)
4951 return 0;
4952 emit_insn (pat);
95385cbb
AH
4953 return target;
4954
4955 case ALTIVEC_BUILTIN_MTVSCR:
4956 icode = CODE_FOR_altivec_mtvscr;
4957 arg0 = TREE_VALUE (arglist);
4958 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4959 mode0 = insn_data[icode].operand[0].mode;
4960
4961 /* If we got invalid arguments bail out before generating bad rtl. */
4962 if (arg0 == error_mark_node)
9a171fcd 4963 return const0_rtx;
95385cbb
AH
4964
4965 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4966 op0 = copy_to_mode_reg (mode0, op0);
4967
4968 pat = GEN_FCN (icode) (op0);
4969 if (pat)
4970 emit_insn (pat);
4971 return NULL_RTX;
3a9b8c7e 4972
95385cbb
AH
4973 case ALTIVEC_BUILTIN_DSSALL:
4974 emit_insn (gen_altivec_dssall ());
4975 return NULL_RTX;
4976
4977 case ALTIVEC_BUILTIN_DSS:
4978 icode = CODE_FOR_altivec_dss;
4979 arg0 = TREE_VALUE (arglist);
4980 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
4981 mode0 = insn_data[icode].operand[0].mode;
4982
4983 /* If we got invalid arguments bail out before generating bad rtl. */
4984 if (arg0 == error_mark_node)
9a171fcd 4985 return const0_rtx;
95385cbb 4986
b44140e7
AH
4987 if (TREE_CODE (arg0) != INTEGER_CST
4988 || TREE_INT_CST_LOW (arg0) & ~0x3)
4989 {
4990 error ("argument to dss must be a 2-bit unsigned literal");
9a171fcd 4991 return const0_rtx;
b44140e7
AH
4992 }
4993
95385cbb
AH
4994 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
4995 op0 = copy_to_mode_reg (mode0, op0);
4996
4997 emit_insn (gen_altivec_dss (op0));
0ac081f6
AH
4998 return NULL_RTX;
4999 }
24408032 5000
100c4561
AH
5001 /* Expand abs* operations. */
5002 d = (struct builtin_description *) bdesc_abs;
ca7558fc 5003 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
100c4561
AH
5004 if (d->code == fcode)
5005 return altivec_expand_abs_builtin (d->icode, arglist, target);
5006
ae4b4a02
AH
5007 /* Expand the AltiVec predicates. */
5008 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
ca7558fc 5009 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
ae4b4a02
AH
5010 if (dp->code == fcode)
5011 return altivec_expand_predicate_builtin (dp->icode, dp->opcode, arglist, target);
5012
6525c0e7
AH
5013 /* LV* are funky. We initialized them differently. */
5014 switch (fcode)
5015 {
5016 case ALTIVEC_BUILTIN_LVSL:
92898235 5017 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsl,
6525c0e7
AH
5018 arglist, target);
5019 case ALTIVEC_BUILTIN_LVSR:
92898235
AH
5020 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvsr,
5021 arglist, target);
6525c0e7 5022 case ALTIVEC_BUILTIN_LVEBX:
92898235
AH
5023 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvebx,
5024 arglist, target);
6525c0e7 5025 case ALTIVEC_BUILTIN_LVEHX:
92898235
AH
5026 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvehx,
5027 arglist, target);
6525c0e7 5028 case ALTIVEC_BUILTIN_LVEWX:
92898235
AH
5029 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvewx,
5030 arglist, target);
6525c0e7 5031 case ALTIVEC_BUILTIN_LVXL:
92898235
AH
5032 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvxl,
5033 arglist, target);
6525c0e7 5034 case ALTIVEC_BUILTIN_LVX:
92898235
AH
5035 return rs6000_expand_binop_builtin (CODE_FOR_altivec_lvx,
5036 arglist, target);
6525c0e7
AH
5037 default:
5038 break;
5039 /* Fall through. */
5040 }
95385cbb 5041
92898235 5042 *expandedp = false;
0ac081f6
AH
5043 return NULL_RTX;
5044}
5045
a3170dc6
AH
5046/* Binops that need to be initialized manually, but can be expanded
5047 automagically by rs6000_expand_binop_builtin. */
5048static struct builtin_description bdesc_2arg_spe[] =
5049{
5050 { 0, CODE_FOR_spe_evlddx, "__builtin_spe_evlddx", SPE_BUILTIN_EVLDDX },
5051 { 0, CODE_FOR_spe_evldwx, "__builtin_spe_evldwx", SPE_BUILTIN_EVLDWX },
5052 { 0, CODE_FOR_spe_evldhx, "__builtin_spe_evldhx", SPE_BUILTIN_EVLDHX },
5053 { 0, CODE_FOR_spe_evlwhex, "__builtin_spe_evlwhex", SPE_BUILTIN_EVLWHEX },
5054 { 0, CODE_FOR_spe_evlwhoux, "__builtin_spe_evlwhoux", SPE_BUILTIN_EVLWHOUX },
5055 { 0, CODE_FOR_spe_evlwhosx, "__builtin_spe_evlwhosx", SPE_BUILTIN_EVLWHOSX },
5056 { 0, CODE_FOR_spe_evlwwsplatx, "__builtin_spe_evlwwsplatx", SPE_BUILTIN_EVLWWSPLATX },
5057 { 0, CODE_FOR_spe_evlwhsplatx, "__builtin_spe_evlwhsplatx", SPE_BUILTIN_EVLWHSPLATX },
5058 { 0, CODE_FOR_spe_evlhhesplatx, "__builtin_spe_evlhhesplatx", SPE_BUILTIN_EVLHHESPLATX },
5059 { 0, CODE_FOR_spe_evlhhousplatx, "__builtin_spe_evlhhousplatx", SPE_BUILTIN_EVLHHOUSPLATX },
5060 { 0, CODE_FOR_spe_evlhhossplatx, "__builtin_spe_evlhhossplatx", SPE_BUILTIN_EVLHHOSSPLATX },
5061 { 0, CODE_FOR_spe_evldd, "__builtin_spe_evldd", SPE_BUILTIN_EVLDD },
5062 { 0, CODE_FOR_spe_evldw, "__builtin_spe_evldw", SPE_BUILTIN_EVLDW },
5063 { 0, CODE_FOR_spe_evldh, "__builtin_spe_evldh", SPE_BUILTIN_EVLDH },
5064 { 0, CODE_FOR_spe_evlwhe, "__builtin_spe_evlwhe", SPE_BUILTIN_EVLWHE },
5065 { 0, CODE_FOR_spe_evlwhou, "__builtin_spe_evlwhou", SPE_BUILTIN_EVLWHOU },
5066 { 0, CODE_FOR_spe_evlwhos, "__builtin_spe_evlwhos", SPE_BUILTIN_EVLWHOS },
5067 { 0, CODE_FOR_spe_evlwwsplat, "__builtin_spe_evlwwsplat", SPE_BUILTIN_EVLWWSPLAT },
5068 { 0, CODE_FOR_spe_evlwhsplat, "__builtin_spe_evlwhsplat", SPE_BUILTIN_EVLWHSPLAT },
5069 { 0, CODE_FOR_spe_evlhhesplat, "__builtin_spe_evlhhesplat", SPE_BUILTIN_EVLHHESPLAT },
5070 { 0, CODE_FOR_spe_evlhhousplat, "__builtin_spe_evlhhousplat", SPE_BUILTIN_EVLHHOUSPLAT },
5071 { 0, CODE_FOR_spe_evlhhossplat, "__builtin_spe_evlhhossplat", SPE_BUILTIN_EVLHHOSSPLAT }
5072};
5073
5074/* Expand the builtin in EXP and store the result in TARGET. Store
5075 true in *EXPANDEDP if we found a builtin to expand.
5076
5077 This expands the SPE builtins that are not simple unary and binary
5078 operations. */
5079static rtx
5080spe_expand_builtin (exp, target, expandedp)
5081 tree exp;
5082 rtx target;
5083 bool *expandedp;
5084{
5085 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5086 tree arglist = TREE_OPERAND (exp, 1);
5087 tree arg1, arg0;
5088 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5089 enum insn_code icode;
5090 enum machine_mode tmode, mode0;
5091 rtx pat, op0;
5092 struct builtin_description *d;
5093 size_t i;
5094
5095 *expandedp = true;
5096
5097 /* Syntax check for a 5-bit unsigned immediate. */
5098 switch (fcode)
5099 {
5100 case SPE_BUILTIN_EVSTDD:
5101 case SPE_BUILTIN_EVSTDH:
5102 case SPE_BUILTIN_EVSTDW:
5103 case SPE_BUILTIN_EVSTWHE:
5104 case SPE_BUILTIN_EVSTWHO:
5105 case SPE_BUILTIN_EVSTWWE:
5106 case SPE_BUILTIN_EVSTWWO:
5107 arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5108 if (TREE_CODE (arg1) != INTEGER_CST
5109 || TREE_INT_CST_LOW (arg1) & ~0x1f)
5110 {
5111 error ("argument 2 must be a 5-bit unsigned literal");
5112 return const0_rtx;
5113 }
5114 break;
5115 default:
5116 break;
5117 }
5118
5119 d = (struct builtin_description *) bdesc_2arg_spe;
5120 for (i = 0; i < ARRAY_SIZE (bdesc_2arg_spe); ++i, ++d)
5121 if (d->code == fcode)
5122 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5123
5124 d = (struct builtin_description *) bdesc_spe_predicates;
5125 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, ++d)
5126 if (d->code == fcode)
5127 return spe_expand_predicate_builtin (d->icode, arglist, target);
5128
5129 d = (struct builtin_description *) bdesc_spe_evsel;
5130 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, ++d)
5131 if (d->code == fcode)
5132 return spe_expand_evsel_builtin (d->icode, arglist, target);
5133
5134 switch (fcode)
5135 {
5136 case SPE_BUILTIN_EVSTDDX:
5137 return altivec_expand_stv_builtin (CODE_FOR_spe_evstddx, arglist);
5138 case SPE_BUILTIN_EVSTDHX:
5139 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdhx, arglist);
5140 case SPE_BUILTIN_EVSTDWX:
5141 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdwx, arglist);
5142 case SPE_BUILTIN_EVSTWHEX:
5143 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhex, arglist);
5144 case SPE_BUILTIN_EVSTWHOX:
5145 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhox, arglist);
5146 case SPE_BUILTIN_EVSTWWEX:
5147 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwex, arglist);
5148 case SPE_BUILTIN_EVSTWWOX:
5149 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwox, arglist);
5150 case SPE_BUILTIN_EVSTDD:
5151 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdd, arglist);
5152 case SPE_BUILTIN_EVSTDH:
5153 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdh, arglist);
5154 case SPE_BUILTIN_EVSTDW:
5155 return altivec_expand_stv_builtin (CODE_FOR_spe_evstdw, arglist);
5156 case SPE_BUILTIN_EVSTWHE:
5157 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwhe, arglist);
5158 case SPE_BUILTIN_EVSTWHO:
5159 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwho, arglist);
5160 case SPE_BUILTIN_EVSTWWE:
5161 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwe, arglist);
5162 case SPE_BUILTIN_EVSTWWO:
5163 return altivec_expand_stv_builtin (CODE_FOR_spe_evstwwo, arglist);
5164 case SPE_BUILTIN_MFSPEFSCR:
5165 icode = CODE_FOR_spe_mfspefscr;
5166 tmode = insn_data[icode].operand[0].mode;
5167
5168 if (target == 0
5169 || GET_MODE (target) != tmode
5170 || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
5171 target = gen_reg_rtx (tmode);
5172
5173 pat = GEN_FCN (icode) (target);
5174 if (! pat)
5175 return 0;
5176 emit_insn (pat);
5177 return target;
5178 case SPE_BUILTIN_MTSPEFSCR:
5179 icode = CODE_FOR_spe_mtspefscr;
5180 arg0 = TREE_VALUE (arglist);
5181 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5182 mode0 = insn_data[icode].operand[0].mode;
5183
5184 if (arg0 == error_mark_node)
5185 return const0_rtx;
5186
5187 if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
5188 op0 = copy_to_mode_reg (mode0, op0);
5189
5190 pat = GEN_FCN (icode) (op0);
5191 if (pat)
5192 emit_insn (pat);
5193 return NULL_RTX;
5194 default:
5195 break;
5196 }
5197
5198 *expandedp = false;
5199 return NULL_RTX;
5200}
5201
5202static rtx
5203spe_expand_predicate_builtin (icode, arglist, target)
5204 enum insn_code icode;
5205 tree arglist;
5206 rtx target;
5207{
5208 rtx pat, scratch, tmp;
5209 tree form = TREE_VALUE (arglist);
5210 tree arg0 = TREE_VALUE (TREE_CHAIN (arglist));
5211 tree arg1 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5212 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5213 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5214 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5215 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5216 int form_int;
5217 enum rtx_code code;
5218
5219 if (TREE_CODE (form) != INTEGER_CST)
5220 {
5221 error ("argument 1 of __builtin_spe_predicate must be a constant");
5222 return const0_rtx;
5223 }
5224 else
5225 form_int = TREE_INT_CST_LOW (form);
5226
5227 if (mode0 != mode1)
5228 abort ();
5229
5230 if (arg0 == error_mark_node || arg1 == error_mark_node)
5231 return const0_rtx;
5232
5233 if (target == 0
5234 || GET_MODE (target) != SImode
5235 || ! (*insn_data[icode].operand[0].predicate) (target, SImode))
5236 target = gen_reg_rtx (SImode);
5237
5238 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5239 op0 = copy_to_mode_reg (mode0, op0);
5240 if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
5241 op1 = copy_to_mode_reg (mode1, op1);
5242
5243 scratch = gen_reg_rtx (CCmode);
5244
5245 pat = GEN_FCN (icode) (scratch, op0, op1);
5246 if (! pat)
5247 return const0_rtx;
5248 emit_insn (pat);
5249
5250 /* There are 4 variants for each predicate: _any_, _all_, _upper_,
5251 _lower_. We use one compare, but look in different bits of the
5252 CR for each variant.
5253
5254 There are 2 elements in each SPE simd type (upper/lower). The CR
5255 bits are set as follows:
5256
5257 BIT0 | BIT 1 | BIT 2 | BIT 3
5258 U | L | (U | L) | (U & L)
5259
5260 So, for an "all" relationship, BIT 3 would be set.
5261 For an "any" relationship, BIT 2 would be set. Etc.
5262
5263 Following traditional nomenclature, these bits map to:
5264
5265 BIT0 | BIT 1 | BIT 2 | BIT 3
5266 LT | GT | EQ | OV
5267
5268 Later, we will generate rtl to look in the LT/EQ/EQ/OV bits.
5269 */
5270
5271 switch (form_int)
5272 {
5273 /* All variant. OV bit. */
5274 case 0:
5275 /* We need to get to the OV bit, which is the ORDERED bit. We
5276 could generate (ordered:SI (reg:CC xx) (const_int 0)), but
5277 that's ugly and will trigger a validate_condition_mode abort.
5278 So let's just use another pattern. */
5279 emit_insn (gen_move_from_CR_ov_bit (target, scratch));
5280 return target;
5281 /* Any variant. EQ bit. */
5282 case 1:
5283 code = EQ;
5284 break;
5285 /* Upper variant. LT bit. */
5286 case 2:
5287 code = LT;
5288 break;
5289 /* Lower variant. GT bit. */
5290 case 3:
5291 code = GT;
5292 break;
5293 default:
5294 error ("argument 1 of __builtin_spe_predicate is out of range");
5295 return const0_rtx;
5296 }
5297
5298 tmp = gen_rtx_fmt_ee (code, SImode, scratch, const0_rtx);
5299 emit_move_insn (target, tmp);
5300
5301 return target;
5302}
5303
5304/* The evsel builtins look like this:
5305
5306 e = __builtin_spe_evsel_OP (a, b, c, d);
5307
5308 and work like this:
5309
5310 e[upper] = a[upper] *OP* b[upper] ? c[upper] : d[upper];
5311 e[lower] = a[lower] *OP* b[lower] ? c[lower] : d[lower];
5312*/
5313
5314static rtx
5315spe_expand_evsel_builtin (icode, arglist, target)
5316 enum insn_code icode;
5317 tree arglist;
5318 rtx target;
5319{
5320 rtx pat, scratch;
5321 tree arg0 = TREE_VALUE (arglist);
5322 tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
5323 tree arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
5324 tree arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
5325 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
5326 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
5327 rtx op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
5328 rtx op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
5329 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
5330 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
5331
5332 if (mode0 != mode1)
5333 abort ();
5334
5335 if (arg0 == error_mark_node || arg1 == error_mark_node
5336 || arg2 == error_mark_node || arg3 == error_mark_node)
5337 return const0_rtx;
5338
5339 if (target == 0
5340 || GET_MODE (target) != mode0
5341 || ! (*insn_data[icode].operand[0].predicate) (target, mode0))
5342 target = gen_reg_rtx (mode0);
5343
5344 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
5345 op0 = copy_to_mode_reg (mode0, op0);
5346 if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
5347 op1 = copy_to_mode_reg (mode0, op1);
5348 if (! (*insn_data[icode].operand[1].predicate) (op2, mode1))
5349 op2 = copy_to_mode_reg (mode0, op2);
5350 if (! (*insn_data[icode].operand[1].predicate) (op3, mode1))
5351 op3 = copy_to_mode_reg (mode0, op3);
5352
5353 /* Generate the compare. */
5354 scratch = gen_reg_rtx (CCmode);
5355 pat = GEN_FCN (icode) (scratch, op0, op1);
5356 if (! pat)
5357 return const0_rtx;
5358 emit_insn (pat);
5359
5360 if (mode0 == V2SImode)
5361 emit_insn (gen_spe_evsel (target, op2, op3, scratch));
5362 else
5363 emit_insn (gen_spe_evsel_fs (target, op2, op3, scratch));
5364
5365 return target;
5366}
5367
0ac081f6
AH
5368/* Expand an expression EXP that calls a built-in function,
5369 with result going to TARGET if that's convenient
5370 (and in mode MODE if that's convenient).
5371 SUBTARGET may be used as the target for computing one of EXP's operands.
5372 IGNORE is nonzero if the value is to be ignored. */
5373
5374static rtx
5375rs6000_expand_builtin (exp, target, subtarget, mode, ignore)
5376 tree exp;
5377 rtx target;
00b960c7
AH
5378 rtx subtarget ATTRIBUTE_UNUSED;
5379 enum machine_mode mode ATTRIBUTE_UNUSED;
5380 int ignore ATTRIBUTE_UNUSED;
0ac081f6 5381{
92898235
AH
5382 tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
5383 tree arglist = TREE_OPERAND (exp, 1);
5384 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
5385 struct builtin_description *d;
5386 size_t i;
5387 rtx ret;
5388 bool success;
5389
0ac081f6 5390 if (TARGET_ALTIVEC)
92898235
AH
5391 {
5392 ret = altivec_expand_builtin (exp, target, &success);
5393
a3170dc6
AH
5394 if (success)
5395 return ret;
5396 }
5397 if (TARGET_SPE)
5398 {
5399 ret = spe_expand_builtin (exp, target, &success);
5400
92898235
AH
5401 if (success)
5402 return ret;
5403 }
5404
0559cc77
DE
5405 if (TARGET_ALTIVEC || TARGET_SPE)
5406 {
5407 /* Handle simple unary operations. */
5408 d = (struct builtin_description *) bdesc_1arg;
5409 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
5410 if (d->code == fcode)
5411 return rs6000_expand_unop_builtin (d->icode, arglist, target);
5412
5413 /* Handle simple binary operations. */
5414 d = (struct builtin_description *) bdesc_2arg;
5415 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
5416 if (d->code == fcode)
5417 return rs6000_expand_binop_builtin (d->icode, arglist, target);
5418
5419 /* Handle simple ternary operations. */
5420 d = (struct builtin_description *) bdesc_3arg;
5421 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
5422 if (d->code == fcode)
5423 return rs6000_expand_ternop_builtin (d->icode, arglist, target);
5424 }
0ac081f6
AH
5425
5426 abort ();
92898235 5427 return NULL_RTX;
0ac081f6
AH
5428}
5429
5430static void
6fa3f289 5431rs6000_init_builtins ()
0ac081f6 5432{
a3170dc6
AH
5433 if (TARGET_SPE)
5434 spe_init_builtins ();
0ac081f6
AH
5435 if (TARGET_ALTIVEC)
5436 altivec_init_builtins ();
0559cc77
DE
5437 if (TARGET_ALTIVEC || TARGET_SPE)
5438 rs6000_common_init_builtins ();
0ac081f6
AH
5439}
5440
a3170dc6
AH
5441/* Search through a set of builtins and enable the mask bits.
5442 DESC is an array of builtins.
b6d08ca1 5443 SIZE is the total number of builtins.
a3170dc6
AH
5444 START is the builtin enum at which to start.
5445 END is the builtin enum at which to end. */
0ac081f6 5446static void
a3170dc6
AH
5447enable_mask_for_builtins (desc, size, start, end)
5448 struct builtin_description *desc;
5449 int size;
5450 enum rs6000_builtins start, end;
5451{
5452 int i;
5453
5454 for (i = 0; i < size; ++i)
5455 if (desc[i].code == start)
5456 break;
5457
5458 if (i == size)
5459 return;
5460
5461 for (; i < size; ++i)
5462 {
5463 /* Flip all the bits on. */
5464 desc[i].mask = target_flags;
5465 if (desc[i].code == end)
5466 break;
5467 }
5468}
5469
5470static void
b24c9d35 5471spe_init_builtins ()
0ac081f6 5472{
a3170dc6
AH
5473 tree endlink = void_list_node;
5474 tree puint_type_node = build_pointer_type (unsigned_type_node);
5475 tree pushort_type_node = build_pointer_type (short_unsigned_type_node);
5476 tree pv2si_type_node = build_pointer_type (V2SI_type_node);
ae4b4a02 5477 struct builtin_description *d;
0ac081f6
AH
5478 size_t i;
5479
a3170dc6
AH
5480 tree v2si_ftype_4_v2si
5481 = build_function_type
5482 (V2SI_type_node,
5483 tree_cons (NULL_TREE, V2SI_type_node,
5484 tree_cons (NULL_TREE, V2SI_type_node,
5485 tree_cons (NULL_TREE, V2SI_type_node,
5486 tree_cons (NULL_TREE, V2SI_type_node,
5487 endlink)))));
5488
5489 tree v2sf_ftype_4_v2sf
5490 = build_function_type
5491 (V2SF_type_node,
5492 tree_cons (NULL_TREE, V2SF_type_node,
5493 tree_cons (NULL_TREE, V2SF_type_node,
5494 tree_cons (NULL_TREE, V2SF_type_node,
5495 tree_cons (NULL_TREE, V2SF_type_node,
5496 endlink)))));
5497
5498 tree int_ftype_int_v2si_v2si
5499 = build_function_type
5500 (integer_type_node,
5501 tree_cons (NULL_TREE, integer_type_node,
5502 tree_cons (NULL_TREE, V2SI_type_node,
5503 tree_cons (NULL_TREE, V2SI_type_node,
5504 endlink))));
5505
5506 tree int_ftype_int_v2sf_v2sf
5507 = build_function_type
5508 (integer_type_node,
5509 tree_cons (NULL_TREE, integer_type_node,
5510 tree_cons (NULL_TREE, V2SF_type_node,
5511 tree_cons (NULL_TREE, V2SF_type_node,
5512 endlink))));
5513
5514 tree void_ftype_v2si_puint_int
5515 = build_function_type (void_type_node,
5516 tree_cons (NULL_TREE, V2SI_type_node,
5517 tree_cons (NULL_TREE, puint_type_node,
5518 tree_cons (NULL_TREE,
5519 integer_type_node,
5520 endlink))));
5521
5522 tree void_ftype_v2si_puint_char
5523 = build_function_type (void_type_node,
5524 tree_cons (NULL_TREE, V2SI_type_node,
5525 tree_cons (NULL_TREE, puint_type_node,
5526 tree_cons (NULL_TREE,
5527 char_type_node,
5528 endlink))));
5529
5530 tree void_ftype_v2si_pv2si_int
5531 = build_function_type (void_type_node,
5532 tree_cons (NULL_TREE, V2SI_type_node,
5533 tree_cons (NULL_TREE, pv2si_type_node,
5534 tree_cons (NULL_TREE,
5535 integer_type_node,
5536 endlink))));
5537
5538 tree void_ftype_v2si_pv2si_char
5539 = build_function_type (void_type_node,
5540 tree_cons (NULL_TREE, V2SI_type_node,
5541 tree_cons (NULL_TREE, pv2si_type_node,
5542 tree_cons (NULL_TREE,
5543 char_type_node,
5544 endlink))));
5545
5546 tree void_ftype_int
5547 = build_function_type (void_type_node,
5548 tree_cons (NULL_TREE, integer_type_node, endlink));
5549
5550 tree int_ftype_void
5551 = build_function_type (integer_type_node,
5552 tree_cons (NULL_TREE, void_type_node, endlink));
5553
5554 tree v2si_ftype_pv2si_int
5555 = build_function_type (V2SI_type_node,
5556 tree_cons (NULL_TREE, pv2si_type_node,
5557 tree_cons (NULL_TREE, integer_type_node,
5558 endlink)));
5559
5560 tree v2si_ftype_puint_int
5561 = build_function_type (V2SI_type_node,
5562 tree_cons (NULL_TREE, puint_type_node,
5563 tree_cons (NULL_TREE, integer_type_node,
5564 endlink)));
5565
5566 tree v2si_ftype_pushort_int
5567 = build_function_type (V2SI_type_node,
5568 tree_cons (NULL_TREE, pushort_type_node,
5569 tree_cons (NULL_TREE, integer_type_node,
5570 endlink)));
5571
5572 /* The initialization of the simple binary and unary builtins is
5573 done in rs6000_common_init_builtins, but we have to enable the
5574 mask bits here manually because we have run out of `target_flags'
5575 bits. We really need to redesign this mask business. */
5576
5577 enable_mask_for_builtins ((struct builtin_description *) bdesc_2arg,
5578 ARRAY_SIZE (bdesc_2arg),
5579 SPE_BUILTIN_EVADDW,
5580 SPE_BUILTIN_EVXOR);
5581 enable_mask_for_builtins ((struct builtin_description *) bdesc_1arg,
5582 ARRAY_SIZE (bdesc_1arg),
5583 SPE_BUILTIN_EVABS,
5584 SPE_BUILTIN_EVSUBFUSIAAW);
5585 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_predicates,
5586 ARRAY_SIZE (bdesc_spe_predicates),
5587 SPE_BUILTIN_EVCMPEQ,
5588 SPE_BUILTIN_EVFSTSTLT);
5589 enable_mask_for_builtins ((struct builtin_description *) bdesc_spe_evsel,
5590 ARRAY_SIZE (bdesc_spe_evsel),
5591 SPE_BUILTIN_EVSEL_CMPGTS,
5592 SPE_BUILTIN_EVSEL_FSTSTEQ);
5593
5594 /* Initialize irregular SPE builtins. */
5595
5596 def_builtin (target_flags, "__builtin_spe_mtspefscr", void_ftype_int, SPE_BUILTIN_MTSPEFSCR);
5597 def_builtin (target_flags, "__builtin_spe_mfspefscr", int_ftype_void, SPE_BUILTIN_MFSPEFSCR);
5598 def_builtin (target_flags, "__builtin_spe_evstddx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDDX);
5599 def_builtin (target_flags, "__builtin_spe_evstdhx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDHX);
5600 def_builtin (target_flags, "__builtin_spe_evstdwx", void_ftype_v2si_pv2si_int, SPE_BUILTIN_EVSTDWX);
5601 def_builtin (target_flags, "__builtin_spe_evstwhex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHEX);
5602 def_builtin (target_flags, "__builtin_spe_evstwhox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWHOX);
5603 def_builtin (target_flags, "__builtin_spe_evstwwex", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWEX);
5604 def_builtin (target_flags, "__builtin_spe_evstwwox", void_ftype_v2si_puint_int, SPE_BUILTIN_EVSTWWOX);
5605 def_builtin (target_flags, "__builtin_spe_evstdd", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDD);
5606 def_builtin (target_flags, "__builtin_spe_evstdh", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDH);
5607 def_builtin (target_flags, "__builtin_spe_evstdw", void_ftype_v2si_pv2si_char, SPE_BUILTIN_EVSTDW);
5608 def_builtin (target_flags, "__builtin_spe_evstwhe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHE);
5609 def_builtin (target_flags, "__builtin_spe_evstwho", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWHO);
5610 def_builtin (target_flags, "__builtin_spe_evstwwe", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWE);
5611 def_builtin (target_flags, "__builtin_spe_evstwwo", void_ftype_v2si_puint_char, SPE_BUILTIN_EVSTWWO);
5612
5613 /* Loads. */
5614 def_builtin (target_flags, "__builtin_spe_evlddx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDDX);
5615 def_builtin (target_flags, "__builtin_spe_evldwx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDWX);
5616 def_builtin (target_flags, "__builtin_spe_evldhx", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDHX);
5617 def_builtin (target_flags, "__builtin_spe_evlwhex", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHEX);
5618 def_builtin (target_flags, "__builtin_spe_evlwhoux", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOUX);
5619 def_builtin (target_flags, "__builtin_spe_evlwhosx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOSX);
5620 def_builtin (target_flags, "__builtin_spe_evlwwsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLATX);
5621 def_builtin (target_flags, "__builtin_spe_evlwhsplatx", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLATX);
5622 def_builtin (target_flags, "__builtin_spe_evlhhesplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLATX);
5623 def_builtin (target_flags, "__builtin_spe_evlhhousplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLATX);
5624 def_builtin (target_flags, "__builtin_spe_evlhhossplatx", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLATX);
5625 def_builtin (target_flags, "__builtin_spe_evldd", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDD);
5626 def_builtin (target_flags, "__builtin_spe_evldw", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDW);
5627 def_builtin (target_flags, "__builtin_spe_evldh", v2si_ftype_pv2si_int, SPE_BUILTIN_EVLDH);
5628 def_builtin (target_flags, "__builtin_spe_evlhhesplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHESPLAT);
5629 def_builtin (target_flags, "__builtin_spe_evlhhossplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOSSPLAT);
5630 def_builtin (target_flags, "__builtin_spe_evlhhousplat", v2si_ftype_pushort_int, SPE_BUILTIN_EVLHHOUSPLAT);
5631 def_builtin (target_flags, "__builtin_spe_evlwhe", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHE);
5632 def_builtin (target_flags, "__builtin_spe_evlwhos", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOS);
5633 def_builtin (target_flags, "__builtin_spe_evlwhou", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHOU);
5634 def_builtin (target_flags, "__builtin_spe_evlwhsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWHSPLAT);
5635 def_builtin (target_flags, "__builtin_spe_evlwwsplat", v2si_ftype_puint_int, SPE_BUILTIN_EVLWWSPLAT);
5636
5637 /* Predicates. */
5638 d = (struct builtin_description *) bdesc_spe_predicates;
5639 for (i = 0; i < ARRAY_SIZE (bdesc_spe_predicates); ++i, d++)
5640 {
5641 tree type;
5642
5643 switch (insn_data[d->icode].operand[1].mode)
5644 {
5645 case V2SImode:
5646 type = int_ftype_int_v2si_v2si;
5647 break;
5648 case V2SFmode:
5649 type = int_ftype_int_v2sf_v2sf;
5650 break;
5651 default:
5652 abort ();
5653 }
5654
5655 def_builtin (d->mask, d->name, type, d->code);
5656 }
5657
5658 /* Evsel predicates. */
5659 d = (struct builtin_description *) bdesc_spe_evsel;
5660 for (i = 0; i < ARRAY_SIZE (bdesc_spe_evsel); ++i, d++)
5661 {
5662 tree type;
5663
5664 switch (insn_data[d->icode].operand[1].mode)
5665 {
5666 case V2SImode:
5667 type = v2si_ftype_4_v2si;
5668 break;
5669 case V2SFmode:
5670 type = v2sf_ftype_4_v2sf;
5671 break;
5672 default:
5673 abort ();
5674 }
5675
5676 def_builtin (d->mask, d->name, type, d->code);
5677 }
5678}
5679
5680static void
b24c9d35 5681altivec_init_builtins ()
a3170dc6
AH
5682{
5683 struct builtin_description *d;
5684 struct builtin_description_predicates *dp;
5685 size_t i;
5686 tree pfloat_type_node = build_pointer_type (float_type_node);
5687 tree pint_type_node = build_pointer_type (integer_type_node);
5688 tree pshort_type_node = build_pointer_type (short_integer_type_node);
5689 tree pchar_type_node = build_pointer_type (char_type_node);
5690
5691 tree pvoid_type_node = build_pointer_type (void_type_node);
5692
0dbc3651
ZW
5693 tree pcfloat_type_node = build_pointer_type (build_qualified_type (float_type_node, TYPE_QUAL_CONST));
5694 tree pcint_type_node = build_pointer_type (build_qualified_type (integer_type_node, TYPE_QUAL_CONST));
5695 tree pcshort_type_node = build_pointer_type (build_qualified_type (short_integer_type_node, TYPE_QUAL_CONST));
5696 tree pcchar_type_node = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST));
5697
5698 tree pcvoid_type_node = build_pointer_type (build_qualified_type (void_type_node, TYPE_QUAL_CONST));
5699
a3170dc6
AH
5700 tree int_ftype_int_v4si_v4si
5701 = build_function_type_list (integer_type_node,
5702 integer_type_node, V4SI_type_node,
5703 V4SI_type_node, NULL_TREE);
0dbc3651
ZW
5704 tree v4sf_ftype_pcfloat
5705 = build_function_type_list (V4SF_type_node, pcfloat_type_node, NULL_TREE);
a3170dc6 5706 tree void_ftype_pfloat_v4sf
b4de2f7d 5707 = build_function_type_list (void_type_node,
a3170dc6 5708 pfloat_type_node, V4SF_type_node, NULL_TREE);
0dbc3651
ZW
5709 tree v4si_ftype_pcint
5710 = build_function_type_list (V4SI_type_node, pcint_type_node, NULL_TREE);
5711 tree void_ftype_pint_v4si
b4de2f7d
AH
5712 = build_function_type_list (void_type_node,
5713 pint_type_node, V4SI_type_node, NULL_TREE);
0dbc3651
ZW
5714 tree v8hi_ftype_pcshort
5715 = build_function_type_list (V8HI_type_node, pcshort_type_node, NULL_TREE);
f18c054f 5716 tree void_ftype_pshort_v8hi
b4de2f7d
AH
5717 = build_function_type_list (void_type_node,
5718 pshort_type_node, V8HI_type_node, NULL_TREE);
0dbc3651
ZW
5719 tree v16qi_ftype_pcchar
5720 = build_function_type_list (V16QI_type_node, pcchar_type_node, NULL_TREE);
f18c054f 5721 tree void_ftype_pchar_v16qi
b4de2f7d
AH
5722 = build_function_type_list (void_type_node,
5723 pchar_type_node, V16QI_type_node, NULL_TREE);
95385cbb 5724 tree void_ftype_v4si
b4de2f7d 5725 = build_function_type_list (void_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
5726 tree v8hi_ftype_void
5727 = build_function_type (V8HI_type_node, void_list_node);
5728 tree void_ftype_void
5729 = build_function_type (void_type_node, void_list_node);
5730 tree void_ftype_qi
5731 = build_function_type_list (void_type_node, char_type_node, NULL_TREE);
0dbc3651
ZW
5732
5733 tree v16qi_ftype_int_pcvoid
a3170dc6 5734 = build_function_type_list (V16QI_type_node,
0dbc3651
ZW
5735 integer_type_node, pcvoid_type_node, NULL_TREE);
5736 tree v8hi_ftype_int_pcvoid
a3170dc6 5737 = build_function_type_list (V8HI_type_node,
0dbc3651
ZW
5738 integer_type_node, pcvoid_type_node, NULL_TREE);
5739 tree v4si_ftype_int_pcvoid
a3170dc6 5740 = build_function_type_list (V4SI_type_node,
0dbc3651
ZW
5741 integer_type_node, pcvoid_type_node, NULL_TREE);
5742
14b32f4e 5743 tree void_ftype_v4si_int_pvoid
b4de2f7d
AH
5744 = build_function_type_list (void_type_node,
5745 V4SI_type_node, integer_type_node,
5746 pvoid_type_node, NULL_TREE);
6525c0e7 5747 tree void_ftype_v16qi_int_pvoid
b4de2f7d
AH
5748 = build_function_type_list (void_type_node,
5749 V16QI_type_node, integer_type_node,
5750 pvoid_type_node, NULL_TREE);
6525c0e7 5751 tree void_ftype_v8hi_int_pvoid
b4de2f7d
AH
5752 = build_function_type_list (void_type_node,
5753 V8HI_type_node, integer_type_node,
5754 pvoid_type_node, NULL_TREE);
a3170dc6
AH
5755 tree int_ftype_int_v8hi_v8hi
5756 = build_function_type_list (integer_type_node,
5757 integer_type_node, V8HI_type_node,
5758 V8HI_type_node, NULL_TREE);
5759 tree int_ftype_int_v16qi_v16qi
5760 = build_function_type_list (integer_type_node,
5761 integer_type_node, V16QI_type_node,
5762 V16QI_type_node, NULL_TREE);
5763 tree int_ftype_int_v4sf_v4sf
5764 = build_function_type_list (integer_type_node,
5765 integer_type_node, V4SF_type_node,
5766 V4SF_type_node, NULL_TREE);
5767 tree v4si_ftype_v4si
5768 = build_function_type_list (V4SI_type_node, V4SI_type_node, NULL_TREE);
5769 tree v8hi_ftype_v8hi
5770 = build_function_type_list (V8HI_type_node, V8HI_type_node, NULL_TREE);
5771 tree v16qi_ftype_v16qi
5772 = build_function_type_list (V16QI_type_node, V16QI_type_node, NULL_TREE);
5773 tree v4sf_ftype_v4sf
5774 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
0dbc3651 5775 tree void_ftype_pcvoid_int_char
a3170dc6 5776 = build_function_type_list (void_type_node,
0dbc3651 5777 pcvoid_type_node, integer_type_node,
a3170dc6 5778 char_type_node, NULL_TREE);
0dbc3651
ZW
5779
5780 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4sf", v4sf_ftype_pcfloat,
5781 ALTIVEC_BUILTIN_LD_INTERNAL_4sf);
5782 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4sf", void_ftype_pfloat_v4sf,
5783 ALTIVEC_BUILTIN_ST_INTERNAL_4sf);
5784 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_4si", v4si_ftype_pcint,
5785 ALTIVEC_BUILTIN_LD_INTERNAL_4si);
5786 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_4si", void_ftype_pint_v4si,
5787 ALTIVEC_BUILTIN_ST_INTERNAL_4si);
5788 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_8hi", v8hi_ftype_pcshort,
5789 ALTIVEC_BUILTIN_LD_INTERNAL_8hi);
5790 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_8hi", void_ftype_pshort_v8hi,
5791 ALTIVEC_BUILTIN_ST_INTERNAL_8hi);
5792 def_builtin (MASK_ALTIVEC, "__builtin_altivec_ld_internal_16qi", v16qi_ftype_pcchar,
5793 ALTIVEC_BUILTIN_LD_INTERNAL_16qi);
5794 def_builtin (MASK_ALTIVEC, "__builtin_altivec_st_internal_16qi", void_ftype_pchar_v16qi,
5795 ALTIVEC_BUILTIN_ST_INTERNAL_16qi);
a3170dc6
AH
5796 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mtvscr", void_ftype_v4si, ALTIVEC_BUILTIN_MTVSCR);
5797 def_builtin (MASK_ALTIVEC, "__builtin_altivec_mfvscr", v8hi_ftype_void, ALTIVEC_BUILTIN_MFVSCR);
5798 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dssall", void_ftype_void, ALTIVEC_BUILTIN_DSSALL);
5799 def_builtin (MASK_ALTIVEC, "__builtin_altivec_dss", void_ftype_qi, ALTIVEC_BUILTIN_DSS);
0dbc3651
ZW
5800 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsl", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSL);
5801 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvsr", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVSR);
5802 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvebx", v16qi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEBX);
5803 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvehx", v8hi_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEHX);
5804 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvewx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVEWX);
5805 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvxl", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVXL);
5806 def_builtin (MASK_ALTIVEC, "__builtin_altivec_lvx", v4si_ftype_int_pcvoid, ALTIVEC_BUILTIN_LVX);
a3170dc6
AH
5807 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVX);
5808 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvewx", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVEWX);
5809 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvxl", void_ftype_v4si_int_pvoid, ALTIVEC_BUILTIN_STVXL);
5810 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvebx", void_ftype_v16qi_int_pvoid, ALTIVEC_BUILTIN_STVEBX);
5811 def_builtin (MASK_ALTIVEC, "__builtin_altivec_stvehx", void_ftype_v8hi_int_pvoid, ALTIVEC_BUILTIN_STVEHX);
5812
5813 /* Add the DST variants. */
5814 d = (struct builtin_description *) bdesc_dst;
5815 for (i = 0; i < ARRAY_SIZE (bdesc_dst); i++, d++)
0dbc3651 5816 def_builtin (d->mask, d->name, void_ftype_pcvoid_int_char, d->code);
a3170dc6
AH
5817
5818 /* Initialize the predicates. */
5819 dp = (struct builtin_description_predicates *) bdesc_altivec_preds;
5820 for (i = 0; i < ARRAY_SIZE (bdesc_altivec_preds); i++, dp++)
5821 {
5822 enum machine_mode mode1;
5823 tree type;
5824
5825 mode1 = insn_data[dp->icode].operand[1].mode;
5826
5827 switch (mode1)
5828 {
5829 case V4SImode:
5830 type = int_ftype_int_v4si_v4si;
5831 break;
5832 case V8HImode:
5833 type = int_ftype_int_v8hi_v8hi;
5834 break;
5835 case V16QImode:
5836 type = int_ftype_int_v16qi_v16qi;
5837 break;
5838 case V4SFmode:
5839 type = int_ftype_int_v4sf_v4sf;
5840 break;
5841 default:
5842 abort ();
5843 }
5844
5845 def_builtin (dp->mask, dp->name, type, dp->code);
5846 }
5847
5848 /* Initialize the abs* operators. */
5849 d = (struct builtin_description *) bdesc_abs;
5850 for (i = 0; i < ARRAY_SIZE (bdesc_abs); i++, d++)
5851 {
5852 enum machine_mode mode0;
5853 tree type;
5854
5855 mode0 = insn_data[d->icode].operand[0].mode;
5856
5857 switch (mode0)
5858 {
5859 case V4SImode:
5860 type = v4si_ftype_v4si;
5861 break;
5862 case V8HImode:
5863 type = v8hi_ftype_v8hi;
5864 break;
5865 case V16QImode:
5866 type = v16qi_ftype_v16qi;
5867 break;
5868 case V4SFmode:
5869 type = v4sf_ftype_v4sf;
5870 break;
5871 default:
5872 abort ();
5873 }
5874
5875 def_builtin (d->mask, d->name, type, d->code);
5876 }
5877}
5878
5879static void
b24c9d35 5880rs6000_common_init_builtins ()
a3170dc6
AH
5881{
5882 struct builtin_description *d;
5883 size_t i;
5884
5885 tree v4sf_ftype_v4sf_v4sf_v16qi
5886 = build_function_type_list (V4SF_type_node,
5887 V4SF_type_node, V4SF_type_node,
5888 V16QI_type_node, NULL_TREE);
5889 tree v4si_ftype_v4si_v4si_v16qi
5890 = build_function_type_list (V4SI_type_node,
5891 V4SI_type_node, V4SI_type_node,
5892 V16QI_type_node, NULL_TREE);
5893 tree v8hi_ftype_v8hi_v8hi_v16qi
5894 = build_function_type_list (V8HI_type_node,
5895 V8HI_type_node, V8HI_type_node,
5896 V16QI_type_node, NULL_TREE);
5897 tree v16qi_ftype_v16qi_v16qi_v16qi
5898 = build_function_type_list (V16QI_type_node,
5899 V16QI_type_node, V16QI_type_node,
5900 V16QI_type_node, NULL_TREE);
5901 tree v4si_ftype_char
5902 = build_function_type_list (V4SI_type_node, char_type_node, NULL_TREE);
5903 tree v8hi_ftype_char
5904 = build_function_type_list (V8HI_type_node, char_type_node, NULL_TREE);
5905 tree v16qi_ftype_char
5906 = build_function_type_list (V16QI_type_node, char_type_node, NULL_TREE);
5907 tree v8hi_ftype_v16qi
5908 = build_function_type_list (V8HI_type_node, V16QI_type_node, NULL_TREE);
5909 tree v4sf_ftype_v4sf
5910 = build_function_type_list (V4SF_type_node, V4SF_type_node, NULL_TREE);
5911
5912 tree v2si_ftype_v2si_v2si
5913 = build_function_type_list (V2SI_type_node,
5914 V2SI_type_node, V2SI_type_node, NULL_TREE);
5915
5916 tree v2sf_ftype_v2sf_v2sf
5917 = build_function_type_list (V2SF_type_node,
5918 V2SF_type_node, V2SF_type_node, NULL_TREE);
5919
5920 tree v2si_ftype_int_int
5921 = build_function_type_list (V2SI_type_node,
5922 integer_type_node, integer_type_node,
5923 NULL_TREE);
5924
5925 tree v2si_ftype_v2si
5926 = build_function_type_list (V2SI_type_node, V2SI_type_node, NULL_TREE);
5927
5928 tree v2sf_ftype_v2sf
5929 = build_function_type_list (V2SF_type_node,
5930 V2SF_type_node, NULL_TREE);
5931
5932 tree v2sf_ftype_v2si
5933 = build_function_type_list (V2SF_type_node,
5934 V2SI_type_node, NULL_TREE);
5935
5936 tree v2si_ftype_v2sf
5937 = build_function_type_list (V2SI_type_node,
5938 V2SF_type_node, NULL_TREE);
5939
5940 tree v2si_ftype_v2si_char
5941 = build_function_type_list (V2SI_type_node,
5942 V2SI_type_node, char_type_node, NULL_TREE);
5943
5944 tree v2si_ftype_int_char
5945 = build_function_type_list (V2SI_type_node,
5946 integer_type_node, char_type_node, NULL_TREE);
5947
5948 tree v2si_ftype_char
5949 = build_function_type_list (V2SI_type_node, char_type_node, NULL_TREE);
5950
5951 tree int_ftype_int_int
5952 = build_function_type_list (integer_type_node,
5953 integer_type_node, integer_type_node,
5954 NULL_TREE);
95385cbb 5955
0ac081f6 5956 tree v4si_ftype_v4si_v4si
b4de2f7d
AH
5957 = build_function_type_list (V4SI_type_node,
5958 V4SI_type_node, V4SI_type_node, NULL_TREE);
617e0e1d 5959 tree v4sf_ftype_v4si_char
b4de2f7d
AH
5960 = build_function_type_list (V4SF_type_node,
5961 V4SI_type_node, char_type_node, NULL_TREE);
617e0e1d 5962 tree v4si_ftype_v4sf_char
b4de2f7d
AH
5963 = build_function_type_list (V4SI_type_node,
5964 V4SF_type_node, char_type_node, NULL_TREE);
2212663f 5965 tree v4si_ftype_v4si_char
b4de2f7d
AH
5966 = build_function_type_list (V4SI_type_node,
5967 V4SI_type_node, char_type_node, NULL_TREE);
2212663f 5968 tree v8hi_ftype_v8hi_char
b4de2f7d
AH
5969 = build_function_type_list (V8HI_type_node,
5970 V8HI_type_node, char_type_node, NULL_TREE);
2212663f 5971 tree v16qi_ftype_v16qi_char
b4de2f7d
AH
5972 = build_function_type_list (V16QI_type_node,
5973 V16QI_type_node, char_type_node, NULL_TREE);
24408032 5974 tree v16qi_ftype_v16qi_v16qi_char
b4de2f7d
AH
5975 = build_function_type_list (V16QI_type_node,
5976 V16QI_type_node, V16QI_type_node,
5977 char_type_node, NULL_TREE);
24408032 5978 tree v8hi_ftype_v8hi_v8hi_char
b4de2f7d
AH
5979 = build_function_type_list (V8HI_type_node,
5980 V8HI_type_node, V8HI_type_node,
5981 char_type_node, NULL_TREE);
24408032 5982 tree v4si_ftype_v4si_v4si_char
b4de2f7d
AH
5983 = build_function_type_list (V4SI_type_node,
5984 V4SI_type_node, V4SI_type_node,
5985 char_type_node, NULL_TREE);
24408032 5986 tree v4sf_ftype_v4sf_v4sf_char
b4de2f7d
AH
5987 = build_function_type_list (V4SF_type_node,
5988 V4SF_type_node, V4SF_type_node,
5989 char_type_node, NULL_TREE);
0ac081f6 5990 tree v4sf_ftype_v4sf_v4sf
b4de2f7d
AH
5991 = build_function_type_list (V4SF_type_node,
5992 V4SF_type_node, V4SF_type_node, NULL_TREE);
617e0e1d 5993 tree v4sf_ftype_v4sf_v4sf_v4si
b4de2f7d
AH
5994 = build_function_type_list (V4SF_type_node,
5995 V4SF_type_node, V4SF_type_node,
5996 V4SI_type_node, NULL_TREE);
2212663f 5997 tree v4sf_ftype_v4sf_v4sf_v4sf
b4de2f7d
AH
5998 = build_function_type_list (V4SF_type_node,
5999 V4SF_type_node, V4SF_type_node,
6000 V4SF_type_node, NULL_TREE);
617e0e1d 6001 tree v4si_ftype_v4si_v4si_v4si
b4de2f7d
AH
6002 = build_function_type_list (V4SI_type_node,
6003 V4SI_type_node, V4SI_type_node,
6004 V4SI_type_node, NULL_TREE);
0ac081f6 6005 tree v8hi_ftype_v8hi_v8hi
b4de2f7d
AH
6006 = build_function_type_list (V8HI_type_node,
6007 V8HI_type_node, V8HI_type_node, NULL_TREE);
2212663f 6008 tree v8hi_ftype_v8hi_v8hi_v8hi
b4de2f7d
AH
6009 = build_function_type_list (V8HI_type_node,
6010 V8HI_type_node, V8HI_type_node,
6011 V8HI_type_node, NULL_TREE);
2212663f 6012 tree v4si_ftype_v8hi_v8hi_v4si
b4de2f7d
AH
6013 = build_function_type_list (V4SI_type_node,
6014 V8HI_type_node, V8HI_type_node,
6015 V4SI_type_node, NULL_TREE);
2212663f 6016 tree v4si_ftype_v16qi_v16qi_v4si
b4de2f7d
AH
6017 = build_function_type_list (V4SI_type_node,
6018 V16QI_type_node, V16QI_type_node,
6019 V4SI_type_node, NULL_TREE);
0ac081f6 6020 tree v16qi_ftype_v16qi_v16qi
b4de2f7d
AH
6021 = build_function_type_list (V16QI_type_node,
6022 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 6023 tree v4si_ftype_v4sf_v4sf
b4de2f7d
AH
6024 = build_function_type_list (V4SI_type_node,
6025 V4SF_type_node, V4SF_type_node, NULL_TREE);
0ac081f6 6026 tree v8hi_ftype_v16qi_v16qi
b4de2f7d
AH
6027 = build_function_type_list (V8HI_type_node,
6028 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 6029 tree v4si_ftype_v8hi_v8hi
b4de2f7d
AH
6030 = build_function_type_list (V4SI_type_node,
6031 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 6032 tree v8hi_ftype_v4si_v4si
b4de2f7d
AH
6033 = build_function_type_list (V8HI_type_node,
6034 V4SI_type_node, V4SI_type_node, NULL_TREE);
0ac081f6 6035 tree v16qi_ftype_v8hi_v8hi
b4de2f7d
AH
6036 = build_function_type_list (V16QI_type_node,
6037 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 6038 tree v4si_ftype_v16qi_v4si
b4de2f7d
AH
6039 = build_function_type_list (V4SI_type_node,
6040 V16QI_type_node, V4SI_type_node, NULL_TREE);
fa066a23 6041 tree v4si_ftype_v16qi_v16qi
b4de2f7d
AH
6042 = build_function_type_list (V4SI_type_node,
6043 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 6044 tree v4si_ftype_v8hi_v4si
b4de2f7d
AH
6045 = build_function_type_list (V4SI_type_node,
6046 V8HI_type_node, V4SI_type_node, NULL_TREE);
a3170dc6
AH
6047 tree v4si_ftype_v8hi
6048 = build_function_type_list (V4SI_type_node, V8HI_type_node, NULL_TREE);
6049 tree int_ftype_v4si_v4si
6050 = build_function_type_list (integer_type_node,
6051 V4SI_type_node, V4SI_type_node, NULL_TREE);
6052 tree int_ftype_v4sf_v4sf
6053 = build_function_type_list (integer_type_node,
6054 V4SF_type_node, V4SF_type_node, NULL_TREE);
6055 tree int_ftype_v16qi_v16qi
6056 = build_function_type_list (integer_type_node,
6057 V16QI_type_node, V16QI_type_node, NULL_TREE);
0ac081f6 6058 tree int_ftype_v8hi_v8hi
b4de2f7d
AH
6059 = build_function_type_list (integer_type_node,
6060 V8HI_type_node, V8HI_type_node, NULL_TREE);
0ac081f6 6061
6f317ef3 6062 /* Add the simple ternary operators. */
2212663f 6063 d = (struct builtin_description *) bdesc_3arg;
ca7558fc 6064 for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)
2212663f
DB
6065 {
6066
6067 enum machine_mode mode0, mode1, mode2, mode3;
6068 tree type;
6069
0559cc77 6070 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
6071 continue;
6072
6073 mode0 = insn_data[d->icode].operand[0].mode;
6074 mode1 = insn_data[d->icode].operand[1].mode;
6075 mode2 = insn_data[d->icode].operand[2].mode;
6076 mode3 = insn_data[d->icode].operand[3].mode;
6077
6078 /* When all four are of the same mode. */
6079 if (mode0 == mode1 && mode1 == mode2 && mode2 == mode3)
6080 {
6081 switch (mode0)
6082 {
617e0e1d
DB
6083 case V4SImode:
6084 type = v4si_ftype_v4si_v4si_v4si;
6085 break;
2212663f
DB
6086 case V4SFmode:
6087 type = v4sf_ftype_v4sf_v4sf_v4sf;
6088 break;
6089 case V8HImode:
6090 type = v8hi_ftype_v8hi_v8hi_v8hi;
6091 break;
6092 case V16QImode:
6093 type = v16qi_ftype_v16qi_v16qi_v16qi;
6094 break;
6095 default:
6096 abort();
6097 }
6098 }
6099 else if (mode0 == mode1 && mode1 == mode2 && mode3 == V16QImode)
6100 {
6101 switch (mode0)
6102 {
6103 case V4SImode:
6104 type = v4si_ftype_v4si_v4si_v16qi;
6105 break;
6106 case V4SFmode:
6107 type = v4sf_ftype_v4sf_v4sf_v16qi;
6108 break;
6109 case V8HImode:
6110 type = v8hi_ftype_v8hi_v8hi_v16qi;
6111 break;
6112 case V16QImode:
6113 type = v16qi_ftype_v16qi_v16qi_v16qi;
6114 break;
6115 default:
6116 abort();
6117 }
6118 }
6119 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode
6120 && mode3 == V4SImode)
24408032 6121 type = v4si_ftype_v16qi_v16qi_v4si;
2212663f
DB
6122 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode
6123 && mode3 == V4SImode)
24408032 6124 type = v4si_ftype_v8hi_v8hi_v4si;
617e0e1d
DB
6125 else if (mode0 == V4SFmode && mode1 == V4SFmode && mode2 == V4SFmode
6126 && mode3 == V4SImode)
24408032
AH
6127 type = v4sf_ftype_v4sf_v4sf_v4si;
6128
6129 /* vchar, vchar, vchar, 4 bit literal. */
6130 else if (mode0 == V16QImode && mode1 == mode0 && mode2 == mode0
6131 && mode3 == QImode)
6132 type = v16qi_ftype_v16qi_v16qi_char;
6133
6134 /* vshort, vshort, vshort, 4 bit literal. */
6135 else if (mode0 == V8HImode && mode1 == mode0 && mode2 == mode0
6136 && mode3 == QImode)
6137 type = v8hi_ftype_v8hi_v8hi_char;
6138
6139 /* vint, vint, vint, 4 bit literal. */
6140 else if (mode0 == V4SImode && mode1 == mode0 && mode2 == mode0
6141 && mode3 == QImode)
6142 type = v4si_ftype_v4si_v4si_char;
6143
6144 /* vfloat, vfloat, vfloat, 4 bit literal. */
6145 else if (mode0 == V4SFmode && mode1 == mode0 && mode2 == mode0
6146 && mode3 == QImode)
6147 type = v4sf_ftype_v4sf_v4sf_char;
6148
2212663f
DB
6149 else
6150 abort ();
6151
6152 def_builtin (d->mask, d->name, type, d->code);
6153 }
6154
0ac081f6 6155 /* Add the simple binary operators. */
00b960c7 6156 d = (struct builtin_description *) bdesc_2arg;
ca7558fc 6157 for (i = 0; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
0ac081f6
AH
6158 {
6159 enum machine_mode mode0, mode1, mode2;
6160 tree type;
6161
0559cc77 6162 if (d->name == 0 || d->icode == CODE_FOR_nothing)
0ac081f6
AH
6163 continue;
6164
6165 mode0 = insn_data[d->icode].operand[0].mode;
6166 mode1 = insn_data[d->icode].operand[1].mode;
6167 mode2 = insn_data[d->icode].operand[2].mode;
6168
6169 /* When all three operands are of the same mode. */
6170 if (mode0 == mode1 && mode1 == mode2)
6171 {
6172 switch (mode0)
6173 {
6174 case V4SFmode:
6175 type = v4sf_ftype_v4sf_v4sf;
6176 break;
6177 case V4SImode:
6178 type = v4si_ftype_v4si_v4si;
6179 break;
6180 case V16QImode:
6181 type = v16qi_ftype_v16qi_v16qi;
6182 break;
6183 case V8HImode:
6184 type = v8hi_ftype_v8hi_v8hi;
6185 break;
a3170dc6
AH
6186 case V2SImode:
6187 type = v2si_ftype_v2si_v2si;
6188 break;
6189 case V2SFmode:
6190 type = v2sf_ftype_v2sf_v2sf;
6191 break;
6192 case SImode:
6193 type = int_ftype_int_int;
6194 break;
0ac081f6
AH
6195 default:
6196 abort ();
6197 }
6198 }
6199
6200 /* A few other combos we really don't want to do manually. */
6201
6202 /* vint, vfloat, vfloat. */
6203 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == V4SFmode)
6204 type = v4si_ftype_v4sf_v4sf;
6205
6206 /* vshort, vchar, vchar. */
6207 else if (mode0 == V8HImode && mode1 == V16QImode && mode2 == V16QImode)
6208 type = v8hi_ftype_v16qi_v16qi;
6209
6210 /* vint, vshort, vshort. */
6211 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V8HImode)
6212 type = v4si_ftype_v8hi_v8hi;
6213
6214 /* vshort, vint, vint. */
6215 else if (mode0 == V8HImode && mode1 == V4SImode && mode2 == V4SImode)
6216 type = v8hi_ftype_v4si_v4si;
6217
6218 /* vchar, vshort, vshort. */
6219 else if (mode0 == V16QImode && mode1 == V8HImode && mode2 == V8HImode)
6220 type = v16qi_ftype_v8hi_v8hi;
6221
6222 /* vint, vchar, vint. */
6223 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V4SImode)
6224 type = v4si_ftype_v16qi_v4si;
6225
fa066a23
AH
6226 /* vint, vchar, vchar. */
6227 else if (mode0 == V4SImode && mode1 == V16QImode && mode2 == V16QImode)
6228 type = v4si_ftype_v16qi_v16qi;
6229
0ac081f6
AH
6230 /* vint, vshort, vint. */
6231 else if (mode0 == V4SImode && mode1 == V8HImode && mode2 == V4SImode)
6232 type = v4si_ftype_v8hi_v4si;
2212663f
DB
6233
6234 /* vint, vint, 5 bit literal. */
6235 else if (mode0 == V4SImode && mode1 == V4SImode && mode2 == QImode)
6236 type = v4si_ftype_v4si_char;
6237
6238 /* vshort, vshort, 5 bit literal. */
6239 else if (mode0 == V8HImode && mode1 == V8HImode && mode2 == QImode)
6240 type = v8hi_ftype_v8hi_char;
6241
6242 /* vchar, vchar, 5 bit literal. */
6243 else if (mode0 == V16QImode && mode1 == V16QImode && mode2 == QImode)
6244 type = v16qi_ftype_v16qi_char;
0ac081f6 6245
617e0e1d
DB
6246 /* vfloat, vint, 5 bit literal. */
6247 else if (mode0 == V4SFmode && mode1 == V4SImode && mode2 == QImode)
6248 type = v4sf_ftype_v4si_char;
6249
6250 /* vint, vfloat, 5 bit literal. */
6251 else if (mode0 == V4SImode && mode1 == V4SFmode && mode2 == QImode)
6252 type = v4si_ftype_v4sf_char;
6253
a3170dc6
AH
6254 else if (mode0 == V2SImode && mode1 == SImode && mode2 == SImode)
6255 type = v2si_ftype_int_int;
6256
6257 else if (mode0 == V2SImode && mode1 == V2SImode && mode2 == QImode)
6258 type = v2si_ftype_v2si_char;
6259
6260 else if (mode0 == V2SImode && mode1 == SImode && mode2 == QImode)
6261 type = v2si_ftype_int_char;
6262
0ac081f6
AH
6263 /* int, x, x. */
6264 else if (mode0 == SImode)
6265 {
6266 switch (mode1)
6267 {
6268 case V4SImode:
6269 type = int_ftype_v4si_v4si;
6270 break;
6271 case V4SFmode:
6272 type = int_ftype_v4sf_v4sf;
6273 break;
6274 case V16QImode:
6275 type = int_ftype_v16qi_v16qi;
6276 break;
6277 case V8HImode:
6278 type = int_ftype_v8hi_v8hi;
6279 break;
6280 default:
6281 abort ();
6282 }
6283 }
6284
6285 else
6286 abort ();
6287
2212663f
DB
6288 def_builtin (d->mask, d->name, type, d->code);
6289 }
24408032 6290
2212663f
DB
6291 /* Add the simple unary operators. */
6292 d = (struct builtin_description *) bdesc_1arg;
ca7558fc 6293 for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
2212663f
DB
6294 {
6295 enum machine_mode mode0, mode1;
6296 tree type;
6297
0559cc77 6298 if (d->name == 0 || d->icode == CODE_FOR_nothing)
2212663f
DB
6299 continue;
6300
6301 mode0 = insn_data[d->icode].operand[0].mode;
6302 mode1 = insn_data[d->icode].operand[1].mode;
6303
6304 if (mode0 == V4SImode && mode1 == QImode)
6305 type = v4si_ftype_char;
6306 else if (mode0 == V8HImode && mode1 == QImode)
6307 type = v8hi_ftype_char;
6308 else if (mode0 == V16QImode && mode1 == QImode)
6309 type = v16qi_ftype_char;
617e0e1d
DB
6310 else if (mode0 == V4SFmode && mode1 == V4SFmode)
6311 type = v4sf_ftype_v4sf;
20e26713
AH
6312 else if (mode0 == V8HImode && mode1 == V16QImode)
6313 type = v8hi_ftype_v16qi;
6314 else if (mode0 == V4SImode && mode1 == V8HImode)
6315 type = v4si_ftype_v8hi;
a3170dc6
AH
6316 else if (mode0 == V2SImode && mode1 == V2SImode)
6317 type = v2si_ftype_v2si;
6318 else if (mode0 == V2SFmode && mode1 == V2SFmode)
6319 type = v2sf_ftype_v2sf;
6320 else if (mode0 == V2SFmode && mode1 == V2SImode)
6321 type = v2sf_ftype_v2si;
6322 else if (mode0 == V2SImode && mode1 == V2SFmode)
6323 type = v2si_ftype_v2sf;
6324 else if (mode0 == V2SImode && mode1 == QImode)
6325 type = v2si_ftype_char;
2212663f
DB
6326 else
6327 abort ();
6328
0ac081f6
AH
6329 def_builtin (d->mask, d->name, type, d->code);
6330 }
6331}
6332
35aff10b 6333\f
7e69e155
MM
6334/* Expand a block move operation, and return 1 if successful. Return 0
6335 if we should let the compiler generate normal code.
6336
6337 operands[0] is the destination
6338 operands[1] is the source
6339 operands[2] is the length
6340 operands[3] is the alignment */
6341
3933e0e1
MM
6342#define MAX_MOVE_REG 4
6343
7e69e155
MM
6344int
6345expand_block_move (operands)
6346 rtx operands[];
6347{
b6c9286a
MM
6348 rtx orig_dest = operands[0];
6349 rtx orig_src = operands[1];
7e69e155 6350 rtx bytes_rtx = operands[2];
7e69e155 6351 rtx align_rtx = operands[3];
3933e0e1 6352 int constp = (GET_CODE (bytes_rtx) == CONST_INT);
5ee95df6 6353 int align;
3933e0e1
MM
6354 int bytes;
6355 int offset;
7e69e155
MM
6356 int move_bytes;
6357
3933e0e1 6358 /* If this is not a fixed size move, just call memcpy */
cc0d9ba8 6359 if (! constp)
3933e0e1
MM
6360 return 0;
6361
5ee95df6
FS
6362 /* If this is not a fixed size alignment, abort */
6363 if (GET_CODE (align_rtx) != CONST_INT)
6364 abort ();
6365 align = INTVAL (align_rtx);
6366
7e69e155 6367 /* Anything to move? */
3933e0e1
MM
6368 bytes = INTVAL (bytes_rtx);
6369 if (bytes <= 0)
7e69e155
MM
6370 return 1;
6371
ea9982a8 6372 /* store_one_arg depends on expand_block_move to handle at least the size of
6f317ef3 6373 reg_parm_stack_space. */
ea9982a8 6374 if (bytes > (TARGET_POWERPC64 ? 64 : 32))
7e69e155
MM
6375 return 0;
6376
3933e0e1 6377 if (TARGET_STRING) /* string instructions are available */
7e69e155 6378 {
35aff10b 6379 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6380 {
35aff10b
AM
6381 union {
6382 rtx (*movstrsi) PARAMS ((rtx, rtx, rtx, rtx));
6383 rtx (*mov) PARAMS ((rtx, rtx));
6384 } gen_func;
6385 enum machine_mode mode = BLKmode;
6386 rtx src, dest;
6387
3933e0e1 6388 if (bytes > 24 /* move up to 32 bytes at a time */
cc0d9ba8
DE
6389 && ! fixed_regs[5]
6390 && ! fixed_regs[6]
6391 && ! fixed_regs[7]
6392 && ! fixed_regs[8]
6393 && ! fixed_regs[9]
6394 && ! fixed_regs[10]
6395 && ! fixed_regs[11]
6396 && ! fixed_regs[12])
3933e0e1
MM
6397 {
6398 move_bytes = (bytes > 32) ? 32 : bytes;
35aff10b 6399 gen_func.movstrsi = gen_movstrsi_8reg;
3933e0e1
MM
6400 }
6401 else if (bytes > 16 /* move up to 24 bytes at a time */
f9562f27
DE
6402 && ! fixed_regs[5]
6403 && ! fixed_regs[6]
cc0d9ba8
DE
6404 && ! fixed_regs[7]
6405 && ! fixed_regs[8]
6406 && ! fixed_regs[9]
f9562f27 6407 && ! fixed_regs[10])
3933e0e1
MM
6408 {
6409 move_bytes = (bytes > 24) ? 24 : bytes;
35aff10b 6410 gen_func.movstrsi = gen_movstrsi_6reg;
3933e0e1
MM
6411 }
6412 else if (bytes > 8 /* move up to 16 bytes at a time */
f9562f27
DE
6413 && ! fixed_regs[5]
6414 && ! fixed_regs[6]
6415 && ! fixed_regs[7]
6416 && ! fixed_regs[8])
3933e0e1
MM
6417 {
6418 move_bytes = (bytes > 16) ? 16 : bytes;
35aff10b 6419 gen_func.movstrsi = gen_movstrsi_4reg;
3933e0e1 6420 }
acad7ed3 6421 else if (bytes >= 8 && TARGET_POWERPC64
a4f6c312 6422 /* 64-bit loads and stores require word-aligned
82e41834 6423 displacements. */
a4f6c312 6424 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
acad7ed3
DE
6425 {
6426 move_bytes = 8;
35aff10b
AM
6427 mode = DImode;
6428 gen_func.mov = gen_movdi;
acad7ed3 6429 }
09a625f7 6430 else if (bytes > 4 && !TARGET_POWERPC64)
3933e0e1
MM
6431 { /* move up to 8 bytes at a time */
6432 move_bytes = (bytes > 8) ? 8 : bytes;
35aff10b 6433 gen_func.movstrsi = gen_movstrsi_2reg;
3933e0e1 6434 }
cc0d9ba8 6435 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6436 { /* move 4 bytes */
6437 move_bytes = 4;
35aff10b
AM
6438 mode = SImode;
6439 gen_func.mov = gen_movsi;
3933e0e1 6440 }
cc0d9ba8 6441 else if (bytes == 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6442 { /* move 2 bytes */
6443 move_bytes = 2;
35aff10b
AM
6444 mode = HImode;
6445 gen_func.mov = gen_movhi;
3933e0e1
MM
6446 }
6447 else if (bytes == 1) /* move 1 byte */
6448 {
6449 move_bytes = 1;
35aff10b
AM
6450 mode = QImode;
6451 gen_func.mov = gen_movqi;
3933e0e1
MM
6452 }
6453 else
6454 { /* move up to 4 bytes at a time */
6455 move_bytes = (bytes > 4) ? 4 : bytes;
35aff10b 6456 gen_func.movstrsi = gen_movstrsi_1reg;
3933e0e1 6457 }
4c64a852 6458
35aff10b
AM
6459 src = adjust_address (orig_src, mode, offset);
6460 dest = adjust_address (orig_dest, mode, offset);
6461
6462 if (mode == BLKmode)
015892ee 6463 {
35aff10b
AM
6464 /* Move the address into scratch registers. The movstrsi
6465 patterns require zero offset. */
6466 if (!REG_P (XEXP (src, 0)))
cc0d9ba8 6467 {
35aff10b
AM
6468 rtx src_reg = copy_addr_to_reg (XEXP (src, 0));
6469 src = replace_equiv_address (src, src_reg);
cc0d9ba8 6470 }
35aff10b
AM
6471 set_mem_size (src, GEN_INT (move_bytes));
6472
6473 if (!REG_P (XEXP (dest, 0)))
cc0d9ba8 6474 {
35aff10b
AM
6475 rtx dest_reg = copy_addr_to_reg (XEXP (dest, 0));
6476 dest = replace_equiv_address (dest, dest_reg);
cc0d9ba8 6477 }
35aff10b
AM
6478 set_mem_size (dest, GEN_INT (move_bytes));
6479
6480 emit_insn ((*gen_func.movstrsi) (dest, src,
6481 GEN_INT (move_bytes & 31),
6482 align_rtx));
6483 }
6484 else
6485 {
6486 rtx tmp_reg = gen_reg_rtx (mode);
6487
6488 emit_insn ((*gen_func.mov) (tmp_reg, src));
6489 emit_insn ((*gen_func.mov) (dest, tmp_reg));
015892ee 6490 }
4c64a852 6491 }
3933e0e1
MM
6492 }
6493
6494 else /* string instructions not available */
6495 {
35aff10b
AM
6496 rtx stores[MAX_MOVE_REG];
6497 int num_reg = 0;
6498 int i;
6499
6500 for (offset = 0; bytes > 0; offset += move_bytes, bytes -= move_bytes)
7e69e155 6501 {
35aff10b
AM
6502 rtx (*gen_mov_func) PARAMS ((rtx, rtx));
6503 enum machine_mode mode;
6504 rtx src, dest, tmp_reg;
3933e0e1 6505
cc0d9ba8
DE
6506 /* Generate the appropriate load and store, saving the stores
6507 for later. */
6508 if (bytes >= 8 && TARGET_POWERPC64
a4f6c312
SS
6509 /* 64-bit loads and stores require word-aligned
6510 displacements. */
cc0d9ba8 6511 && (align >= 8 || (! STRICT_ALIGNMENT && align >= 4)))
b6c9286a
MM
6512 {
6513 move_bytes = 8;
35aff10b
AM
6514 mode = DImode;
6515 gen_mov_func = gen_movdi;
b6c9286a 6516 }
cc0d9ba8 6517 else if (bytes >= 4 && (align >= 4 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6518 {
6519 move_bytes = 4;
35aff10b
AM
6520 mode = SImode;
6521 gen_mov_func = gen_movsi;
3933e0e1 6522 }
cc0d9ba8 6523 else if (bytes >= 2 && (align >= 2 || ! STRICT_ALIGNMENT))
3933e0e1
MM
6524 {
6525 move_bytes = 2;
35aff10b
AM
6526 mode = HImode;
6527 gen_mov_func = gen_movhi;
3933e0e1
MM
6528 }
6529 else
6530 {
6531 move_bytes = 1;
35aff10b
AM
6532 mode = QImode;
6533 gen_mov_func = gen_movqi;
3933e0e1
MM
6534 }
6535
35aff10b
AM
6536 src = adjust_address (orig_src, mode, offset);
6537 dest = adjust_address (orig_dest, mode, offset);
6538 tmp_reg = gen_reg_rtx (mode);
6539
6540 emit_insn ((*gen_mov_func) (tmp_reg, src));
6541 stores[num_reg++] = (*gen_mov_func) (dest, tmp_reg);
6542
3933e0e1
MM
6543 if (num_reg >= MAX_MOVE_REG)
6544 {
6545 for (i = 0; i < num_reg; i++)
6546 emit_insn (stores[i]);
6547 num_reg = 0;
7e69e155
MM
6548 }
6549 }
3933e0e1 6550
b6c9286a
MM
6551 for (i = 0; i < num_reg; i++)
6552 emit_insn (stores[i]);
7e69e155
MM
6553 }
6554
6555 return 1;
6556}
6557
9878760c
RK
6558\f
6559/* Return 1 if OP is a load multiple operation. It is known to be a
6560 PARALLEL and the first section will be tested. */
6561
6562int
6563load_multiple_operation (op, mode)
6564 rtx op;
296b8152 6565 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6566{
6567 int count = XVECLEN (op, 0);
e2c953b6 6568 unsigned int dest_regno;
9878760c
RK
6569 rtx src_addr;
6570 int i;
6571
6572 /* Perform a quick check so we don't blow up below. */
6573 if (count <= 1
6574 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6575 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6576 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6577 return 0;
6578
6579 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6580 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6581
6582 for (i = 1; i < count; i++)
6583 {
6584 rtx elt = XVECEXP (op, 0, i);
6585
6586 if (GET_CODE (elt) != SET
6587 || GET_CODE (SET_DEST (elt)) != REG
6588 || GET_MODE (SET_DEST (elt)) != SImode
6589 || REGNO (SET_DEST (elt)) != dest_regno + i
6590 || GET_CODE (SET_SRC (elt)) != MEM
6591 || GET_MODE (SET_SRC (elt)) != SImode
6592 || GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
6593 || ! rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
6594 || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
6595 || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != i * 4)
6596 return 0;
6597 }
6598
6599 return 1;
6600}
6601
6602/* Similar, but tests for store multiple. Here, the second vector element
6603 is a CLOBBER. It will be tested later. */
6604
6605int
6606store_multiple_operation (op, mode)
6607 rtx op;
296b8152 6608 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6609{
6610 int count = XVECLEN (op, 0) - 1;
e2c953b6 6611 unsigned int src_regno;
9878760c
RK
6612 rtx dest_addr;
6613 int i;
6614
6615 /* Perform a quick check so we don't blow up below. */
6616 if (count <= 1
6617 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6618 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6619 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6620 return 0;
6621
6622 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6623 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6624
6625 for (i = 1; i < count; i++)
6626 {
6627 rtx elt = XVECEXP (op, 0, i + 1);
6628
6629 if (GET_CODE (elt) != SET
6630 || GET_CODE (SET_SRC (elt)) != REG
6631 || GET_MODE (SET_SRC (elt)) != SImode
6632 || REGNO (SET_SRC (elt)) != src_regno + i
6633 || GET_CODE (SET_DEST (elt)) != MEM
6634 || GET_MODE (SET_DEST (elt)) != SImode
6635 || GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
6636 || ! rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
6637 || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
6638 || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != i * 4)
6639 return 0;
6640 }
6641
6642 return 1;
6643}
9ebbca7d 6644
9caa3eb2
DE
6645/* Return a string to perform a load_multiple operation.
6646 operands[0] is the vector.
6647 operands[1] is the source address.
6648 operands[2] is the first destination register. */
6649
6650const char *
6651rs6000_output_load_multiple (operands)
ebe637e3 6652 rtx operands[3];
9caa3eb2
DE
6653{
6654 /* We have to handle the case where the pseudo used to contain the address
6655 is assigned to one of the output registers. */
6656 int i, j;
6657 int words = XVECLEN (operands[0], 0);
6658 rtx xop[10];
6659
6660 if (XVECLEN (operands[0], 0) == 1)
6661 return "{l|lwz} %2,0(%1)";
6662
6663 for (i = 0; i < words; i++)
6664 if (refers_to_regno_p (REGNO (operands[2]) + i,
6665 REGNO (operands[2]) + i + 1, operands[1], 0))
6666 {
6667 if (i == words-1)
6668 {
6669 xop[0] = GEN_INT (4 * (words-1));
6670 xop[1] = operands[1];
6671 xop[2] = operands[2];
6672 output_asm_insn ("{lsi|lswi} %2,%1,%0\n\t{l|lwz} %1,%0(%1)", xop);
6673 return "";
6674 }
6675 else if (i == 0)
6676 {
6677 xop[0] = GEN_INT (4 * (words-1));
6678 xop[1] = operands[1];
6679 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
6680 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);
6681 return "";
6682 }
6683 else
6684 {
6685 for (j = 0; j < words; j++)
6686 if (j != i)
6687 {
6688 xop[0] = GEN_INT (j * 4);
6689 xop[1] = operands[1];
6690 xop[2] = gen_rtx_REG (SImode, REGNO (operands[2]) + j);
6691 output_asm_insn ("{l|lwz} %2,%0(%1)", xop);
6692 }
6693 xop[0] = GEN_INT (i * 4);
6694 xop[1] = operands[1];
6695 output_asm_insn ("{l|lwz} %1,%0(%1)", xop);
6696 return "";
6697 }
6698 }
6699
6700 return "{lsi|lswi} %2,%1,%N0";
6701}
6702
00b960c7
AH
6703/* Return 1 for a parallel vrsave operation. */
6704
6705int
6706vrsave_operation (op, mode)
6707 rtx op;
6708 enum machine_mode mode ATTRIBUTE_UNUSED;
6709{
6710 int count = XVECLEN (op, 0);
6711 unsigned int dest_regno, src_regno;
6712 int i;
6713
6714 if (count <= 1
6715 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6716 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
a004eb82 6717 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC_VOLATILE)
00b960c7
AH
6718 return 0;
6719
6720 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6721 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6722
6723 if (dest_regno != VRSAVE_REGNO
6724 && src_regno != VRSAVE_REGNO)
6725 return 0;
6726
6727 for (i = 1; i < count; i++)
6728 {
6729 rtx elt = XVECEXP (op, 0, i);
6730
9aa86737
AH
6731 if (GET_CODE (elt) != CLOBBER
6732 && GET_CODE (elt) != SET)
00b960c7
AH
6733 return 0;
6734 }
6735
6736 return 1;
6737}
6738
a4f6c312 6739/* Return 1 for an PARALLEL suitable for mtcrf. */
9ebbca7d
GK
6740
6741int
6742mtcrf_operation (op, mode)
6743 rtx op;
6744 enum machine_mode mode ATTRIBUTE_UNUSED;
6745{
6746 int count = XVECLEN (op, 0);
6747 int i;
9ebbca7d
GK
6748 rtx src_reg;
6749
6750 /* Perform a quick check so we don't blow up below. */
e35b9579
GK
6751 if (count < 1
6752 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6753 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != UNSPEC
6754 || XVECLEN (SET_SRC (XVECEXP (op, 0, 0)), 0) != 2)
9ebbca7d 6755 return 0;
e35b9579 6756 src_reg = XVECEXP (SET_SRC (XVECEXP (op, 0, 0)), 0, 0);
9ebbca7d
GK
6757
6758 if (GET_CODE (src_reg) != REG
6759 || GET_MODE (src_reg) != SImode
6760 || ! INT_REGNO_P (REGNO (src_reg)))
6761 return 0;
6762
e35b9579 6763 for (i = 0; i < count; i++)
9ebbca7d
GK
6764 {
6765 rtx exp = XVECEXP (op, 0, i);
6766 rtx unspec;
6767 int maskval;
6768
6769 if (GET_CODE (exp) != SET
6770 || GET_CODE (SET_DEST (exp)) != REG
6771 || GET_MODE (SET_DEST (exp)) != CCmode
6772 || ! CR_REGNO_P (REGNO (SET_DEST (exp))))
6773 return 0;
6774 unspec = SET_SRC (exp);
6775 maskval = 1 << (MAX_CR_REGNO - REGNO (SET_DEST (exp)));
9ebbca7d
GK
6776
6777 if (GET_CODE (unspec) != UNSPEC
6778 || XINT (unspec, 1) != 20
6779 || XVECLEN (unspec, 0) != 2
6780 || XVECEXP (unspec, 0, 0) != src_reg
6781 || GET_CODE (XVECEXP (unspec, 0, 1)) != CONST_INT
6782 || INTVAL (XVECEXP (unspec, 0, 1)) != maskval)
6783 return 0;
6784 }
e35b9579 6785 return 1;
9ebbca7d
GK
6786}
6787
a4f6c312 6788/* Return 1 for an PARALLEL suitable for lmw. */
9ebbca7d
GK
6789
6790int
6791lmw_operation (op, mode)
6792 rtx op;
6793 enum machine_mode mode ATTRIBUTE_UNUSED;
6794{
6795 int count = XVECLEN (op, 0);
e2c953b6 6796 unsigned int dest_regno;
9ebbca7d 6797 rtx src_addr;
e2c953b6 6798 unsigned int base_regno;
9ebbca7d
GK
6799 HOST_WIDE_INT offset;
6800 int i;
6801
6802 /* Perform a quick check so we don't blow up below. */
6803 if (count <= 1
6804 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6805 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != REG
6806 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != MEM)
6807 return 0;
6808
6809 dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, 0)));
6810 src_addr = XEXP (SET_SRC (XVECEXP (op, 0, 0)), 0);
6811
6812 if (dest_regno > 31
e2c953b6 6813 || count != 32 - (int) dest_regno)
9ebbca7d
GK
6814 return 0;
6815
258bfae2 6816 if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
9ebbca7d
GK
6817 {
6818 offset = 0;
6819 base_regno = REGNO (src_addr);
6820 if (base_regno == 0)
6821 return 0;
6822 }
258bfae2 6823 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
9ebbca7d
GK
6824 {
6825 offset = INTVAL (XEXP (src_addr, 1));
6826 base_regno = REGNO (XEXP (src_addr, 0));
6827 }
6828 else
6829 return 0;
6830
6831 for (i = 0; i < count; i++)
6832 {
6833 rtx elt = XVECEXP (op, 0, i);
6834 rtx newaddr;
6835 rtx addr_reg;
6836 HOST_WIDE_INT newoffset;
6837
6838 if (GET_CODE (elt) != SET
6839 || GET_CODE (SET_DEST (elt)) != REG
6840 || GET_MODE (SET_DEST (elt)) != SImode
6841 || REGNO (SET_DEST (elt)) != dest_regno + i
6842 || GET_CODE (SET_SRC (elt)) != MEM
6843 || GET_MODE (SET_SRC (elt)) != SImode)
6844 return 0;
6845 newaddr = XEXP (SET_SRC (elt), 0);
258bfae2 6846 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6847 {
6848 newoffset = 0;
6849 addr_reg = newaddr;
6850 }
258bfae2 6851 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6852 {
6853 addr_reg = XEXP (newaddr, 0);
6854 newoffset = INTVAL (XEXP (newaddr, 1));
6855 }
6856 else
6857 return 0;
6858 if (REGNO (addr_reg) != base_regno
6859 || newoffset != offset + 4 * i)
6860 return 0;
6861 }
6862
6863 return 1;
6864}
6865
a4f6c312 6866/* Return 1 for an PARALLEL suitable for stmw. */
9ebbca7d
GK
6867
6868int
6869stmw_operation (op, mode)
6870 rtx op;
6871 enum machine_mode mode ATTRIBUTE_UNUSED;
6872{
6873 int count = XVECLEN (op, 0);
e2c953b6 6874 unsigned int src_regno;
9ebbca7d 6875 rtx dest_addr;
e2c953b6 6876 unsigned int base_regno;
9ebbca7d
GK
6877 HOST_WIDE_INT offset;
6878 int i;
6879
6880 /* Perform a quick check so we don't blow up below. */
6881 if (count <= 1
6882 || GET_CODE (XVECEXP (op, 0, 0)) != SET
6883 || GET_CODE (SET_DEST (XVECEXP (op, 0, 0))) != MEM
6884 || GET_CODE (SET_SRC (XVECEXP (op, 0, 0))) != REG)
6885 return 0;
6886
6887 src_regno = REGNO (SET_SRC (XVECEXP (op, 0, 0)));
6888 dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, 0)), 0);
6889
6890 if (src_regno > 31
e2c953b6 6891 || count != 32 - (int) src_regno)
9ebbca7d
GK
6892 return 0;
6893
258bfae2 6894 if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
9ebbca7d
GK
6895 {
6896 offset = 0;
6897 base_regno = REGNO (dest_addr);
6898 if (base_regno == 0)
6899 return 0;
6900 }
258bfae2 6901 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
9ebbca7d
GK
6902 {
6903 offset = INTVAL (XEXP (dest_addr, 1));
6904 base_regno = REGNO (XEXP (dest_addr, 0));
6905 }
6906 else
6907 return 0;
6908
6909 for (i = 0; i < count; i++)
6910 {
6911 rtx elt = XVECEXP (op, 0, i);
6912 rtx newaddr;
6913 rtx addr_reg;
6914 HOST_WIDE_INT newoffset;
6915
6916 if (GET_CODE (elt) != SET
6917 || GET_CODE (SET_SRC (elt)) != REG
6918 || GET_MODE (SET_SRC (elt)) != SImode
6919 || REGNO (SET_SRC (elt)) != src_regno + i
6920 || GET_CODE (SET_DEST (elt)) != MEM
6921 || GET_MODE (SET_DEST (elt)) != SImode)
6922 return 0;
6923 newaddr = XEXP (SET_DEST (elt), 0);
258bfae2 6924 if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
9ebbca7d
GK
6925 {
6926 newoffset = 0;
6927 addr_reg = newaddr;
6928 }
258bfae2 6929 else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
9ebbca7d
GK
6930 {
6931 addr_reg = XEXP (newaddr, 0);
6932 newoffset = INTVAL (XEXP (newaddr, 1));
6933 }
6934 else
6935 return 0;
6936 if (REGNO (addr_reg) != base_regno
6937 || newoffset != offset + 4 * i)
6938 return 0;
6939 }
6940
6941 return 1;
6942}
9878760c 6943\f
a4f6c312
SS
6944/* A validation routine: say whether CODE, a condition code, and MODE
6945 match. The other alternatives either don't make sense or should
6946 never be generated. */
39a10a29 6947
39a10a29
GK
6948static void
6949validate_condition_mode (code, mode)
6950 enum rtx_code code;
6951 enum machine_mode mode;
6952{
6953 if (GET_RTX_CLASS (code) != '<'
6954 || GET_MODE_CLASS (mode) != MODE_CC)
6955 abort ();
6956
6957 /* These don't make sense. */
6958 if ((code == GT || code == LT || code == GE || code == LE)
6959 && mode == CCUNSmode)
6960 abort ();
6961
6962 if ((code == GTU || code == LTU || code == GEU || code == LEU)
6963 && mode != CCUNSmode)
6964 abort ();
6965
6966 if (mode != CCFPmode
6967 && (code == ORDERED || code == UNORDERED
6968 || code == UNEQ || code == LTGT
6969 || code == UNGT || code == UNLT
6970 || code == UNGE || code == UNLE))
a4f6c312 6971 abort ();
39a10a29 6972
de6c5979 6973 /* These should never be generated except for
ad72b533 6974 flag_unsafe_math_optimizations and flag_finite_math_only. */
39a10a29 6975 if (mode == CCFPmode
de6c5979 6976 && ! flag_unsafe_math_optimizations
ad72b533 6977 && ! flag_finite_math_only
39a10a29
GK
6978 && (code == LE || code == GE
6979 || code == UNEQ || code == LTGT
6980 || code == UNGT || code == UNLT))
6981 abort ();
6982
6983 /* These are invalid; the information is not there. */
6984 if (mode == CCEQmode
6985 && code != EQ && code != NE)
6986 abort ();
6987}
6988
9878760c
RK
6989/* Return 1 if OP is a comparison operation that is valid for a branch insn.
6990 We only check the opcode against the mode of the CC value here. */
6991
6992int
6993branch_comparison_operator (op, mode)
592696dd 6994 rtx op;
296b8152 6995 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
6996{
6997 enum rtx_code code = GET_CODE (op);
6998 enum machine_mode cc_mode;
6999
7000 if (GET_RTX_CLASS (code) != '<')
7001 return 0;
7002
7003 cc_mode = GET_MODE (XEXP (op, 0));
7004 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
7005 return 0;
7006
39a10a29 7007 validate_condition_mode (code, cc_mode);
9878760c 7008
39a10a29
GK
7009 return 1;
7010}
7011
7012/* Return 1 if OP is a comparison operation that is valid for a branch
7013 insn and which is true if the corresponding bit in the CC register
7014 is set. */
7015
7016int
7017branch_positive_comparison_operator (op, mode)
592696dd 7018 rtx op;
39a10a29
GK
7019 enum machine_mode mode;
7020{
7021 enum rtx_code code;
7022
7023 if (! branch_comparison_operator (op, mode))
9878760c
RK
7024 return 0;
7025
39a10a29
GK
7026 code = GET_CODE (op);
7027 return (code == EQ || code == LT || code == GT
993f19a8 7028 || (TARGET_E500 && TARGET_HARD_FLOAT && !TARGET_FPRS && code == NE)
39a10a29
GK
7029 || code == LTU || code == GTU
7030 || code == UNORDERED);
9878760c
RK
7031}
7032
7033/* Return 1 if OP is a comparison operation that is valid for an scc insn.
7034 We check the opcode against the mode of the CC value and disallow EQ or
7035 NE comparisons for integers. */
7036
7037int
7038scc_comparison_operator (op, mode)
592696dd 7039 rtx op;
9878760c
RK
7040 enum machine_mode mode;
7041{
7042 enum rtx_code code = GET_CODE (op);
7043 enum machine_mode cc_mode;
7044
7045 if (GET_MODE (op) != mode && mode != VOIDmode)
7046 return 0;
7047
7048 if (GET_RTX_CLASS (code) != '<')
7049 return 0;
7050
7051 cc_mode = GET_MODE (XEXP (op, 0));
7052 if (GET_MODE_CLASS (cc_mode) != MODE_CC)
7053 return 0;
7054
39a10a29 7055 validate_condition_mode (code, cc_mode);
9878760c 7056
39a10a29 7057 if (code == NE && cc_mode != CCFPmode)
c5defebb
RK
7058 return 0;
7059
9878760c
RK
7060 return 1;
7061}
e0cd0770
JC
7062
7063int
7064trap_comparison_operator (op, mode)
7065 rtx op;
7066 enum machine_mode mode;
7067{
7068 if (mode != VOIDmode && mode != GET_MODE (op))
7069 return 0;
39a10a29 7070 return GET_RTX_CLASS (GET_CODE (op)) == '<';
e0cd0770 7071}
dfbdccdb
GK
7072
7073int
7074boolean_operator (op, mode)
7075 rtx op;
7076 enum machine_mode mode ATTRIBUTE_UNUSED;
7077{
7078 enum rtx_code code = GET_CODE (op);
7079 return (code == AND || code == IOR || code == XOR);
7080}
1d328b19
GK
7081
7082int
7083boolean_or_operator (op, mode)
7084 rtx op;
7085 enum machine_mode mode ATTRIBUTE_UNUSED;
7086{
7087 enum rtx_code code = GET_CODE (op);
7088 return (code == IOR || code == XOR);
7089}
50a0b056
GK
7090
7091int
7092min_max_operator (op, mode)
7093 rtx op;
7094 enum machine_mode mode ATTRIBUTE_UNUSED;
7095{
7096 enum rtx_code code = GET_CODE (op);
7097 return (code == SMIN || code == SMAX || code == UMIN || code == UMAX);
7098}
9878760c
RK
7099\f
7100/* Return 1 if ANDOP is a mask that has no bits on that are not in the
7101 mask required to convert the result of a rotate insn into a shift
b1765bde 7102 left insn of SHIFTOP bits. Both are known to be SImode CONST_INT. */
9878760c
RK
7103
7104int
7105includes_lshift_p (shiftop, andop)
592696dd
SS
7106 rtx shiftop;
7107 rtx andop;
9878760c 7108{
e2c953b6
DE
7109 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
7110
7111 shift_mask <<= INTVAL (shiftop);
9878760c 7112
b1765bde 7113 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
9878760c
RK
7114}
7115
7116/* Similar, but for right shift. */
7117
7118int
7119includes_rshift_p (shiftop, andop)
592696dd
SS
7120 rtx shiftop;
7121 rtx andop;
9878760c 7122{
a7653a2c 7123 unsigned HOST_WIDE_INT shift_mask = ~(unsigned HOST_WIDE_INT) 0;
9878760c
RK
7124
7125 shift_mask >>= INTVAL (shiftop);
7126
b1765bde 7127 return (INTVAL (andop) & 0xffffffff & ~shift_mask) == 0;
e2c953b6
DE
7128}
7129
c5059423
AM
7130/* Return 1 if ANDOP is a mask suitable for use with an rldic insn
7131 to perform a left shift. It must have exactly SHIFTOP least
b6d08ca1 7132 significant 0's, then one or more 1's, then zero or more 0's. */
e2c953b6
DE
7133
7134int
c5059423 7135includes_rldic_lshift_p (shiftop, andop)
592696dd
SS
7136 rtx shiftop;
7137 rtx andop;
e2c953b6 7138{
c5059423
AM
7139 if (GET_CODE (andop) == CONST_INT)
7140 {
02071907 7141 HOST_WIDE_INT c, lsb, shift_mask;
e2c953b6 7142
c5059423 7143 c = INTVAL (andop);
02071907 7144 if (c == 0 || c == ~0)
c5059423 7145 return 0;
e2c953b6 7146
02071907 7147 shift_mask = ~0;
c5059423
AM
7148 shift_mask <<= INTVAL (shiftop);
7149
b6d08ca1 7150 /* Find the least significant one bit. */
c5059423
AM
7151 lsb = c & -c;
7152
7153 /* It must coincide with the LSB of the shift mask. */
7154 if (-lsb != shift_mask)
7155 return 0;
e2c953b6 7156
c5059423
AM
7157 /* Invert to look for the next transition (if any). */
7158 c = ~c;
7159
7160 /* Remove the low group of ones (originally low group of zeros). */
7161 c &= -lsb;
7162
7163 /* Again find the lsb, and check we have all 1's above. */
7164 lsb = c & -c;
7165 return c == -lsb;
7166 }
7167 else if (GET_CODE (andop) == CONST_DOUBLE
7168 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
7169 {
02071907
AM
7170 HOST_WIDE_INT low, high, lsb;
7171 HOST_WIDE_INT shift_mask_low, shift_mask_high;
c5059423
AM
7172
7173 low = CONST_DOUBLE_LOW (andop);
7174 if (HOST_BITS_PER_WIDE_INT < 64)
7175 high = CONST_DOUBLE_HIGH (andop);
7176
7177 if ((low == 0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == 0))
02071907 7178 || (low == ~0 && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0)))
c5059423
AM
7179 return 0;
7180
7181 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
7182 {
02071907 7183 shift_mask_high = ~0;
c5059423
AM
7184 if (INTVAL (shiftop) > 32)
7185 shift_mask_high <<= INTVAL (shiftop) - 32;
7186
7187 lsb = high & -high;
7188
7189 if (-lsb != shift_mask_high || INTVAL (shiftop) < 32)
7190 return 0;
7191
7192 high = ~high;
7193 high &= -lsb;
7194
7195 lsb = high & -high;
7196 return high == -lsb;
7197 }
7198
02071907 7199 shift_mask_low = ~0;
c5059423
AM
7200 shift_mask_low <<= INTVAL (shiftop);
7201
7202 lsb = low & -low;
7203
7204 if (-lsb != shift_mask_low)
7205 return 0;
7206
7207 if (HOST_BITS_PER_WIDE_INT < 64)
7208 high = ~high;
7209 low = ~low;
7210 low &= -lsb;
7211
7212 if (HOST_BITS_PER_WIDE_INT < 64 && low == 0)
7213 {
7214 lsb = high & -high;
7215 return high == -lsb;
7216 }
7217
7218 lsb = low & -low;
7219 return low == -lsb && (HOST_BITS_PER_WIDE_INT >= 64 || high == ~0);
7220 }
7221 else
7222 return 0;
7223}
e2c953b6 7224
c5059423
AM
7225/* Return 1 if ANDOP is a mask suitable for use with an rldicr insn
7226 to perform a left shift. It must have SHIFTOP or more least
7227 signifigant 0's, with the remainder of the word 1's. */
e2c953b6 7228
c5059423
AM
7229int
7230includes_rldicr_lshift_p (shiftop, andop)
592696dd
SS
7231 rtx shiftop;
7232 rtx andop;
c5059423 7233{
e2c953b6 7234 if (GET_CODE (andop) == CONST_INT)
c5059423 7235 {
02071907 7236 HOST_WIDE_INT c, lsb, shift_mask;
c5059423 7237
02071907 7238 shift_mask = ~0;
c5059423
AM
7239 shift_mask <<= INTVAL (shiftop);
7240 c = INTVAL (andop);
7241
7242 /* Find the least signifigant one bit. */
7243 lsb = c & -c;
7244
7245 /* It must be covered by the shift mask.
a4f6c312 7246 This test also rejects c == 0. */
c5059423
AM
7247 if ((lsb & shift_mask) == 0)
7248 return 0;
7249
7250 /* Check we have all 1's above the transition, and reject all 1's. */
7251 return c == -lsb && lsb != 1;
7252 }
7253 else if (GET_CODE (andop) == CONST_DOUBLE
7254 && (GET_MODE (andop) == VOIDmode || GET_MODE (andop) == DImode))
7255 {
02071907 7256 HOST_WIDE_INT low, lsb, shift_mask_low;
c5059423
AM
7257
7258 low = CONST_DOUBLE_LOW (andop);
7259
7260 if (HOST_BITS_PER_WIDE_INT < 64)
7261 {
02071907 7262 HOST_WIDE_INT high, shift_mask_high;
c5059423
AM
7263
7264 high = CONST_DOUBLE_HIGH (andop);
7265
7266 if (low == 0)
7267 {
02071907 7268 shift_mask_high = ~0;
c5059423
AM
7269 if (INTVAL (shiftop) > 32)
7270 shift_mask_high <<= INTVAL (shiftop) - 32;
7271
7272 lsb = high & -high;
7273
7274 if ((lsb & shift_mask_high) == 0)
7275 return 0;
7276
7277 return high == -lsb;
7278 }
7279 if (high != ~0)
7280 return 0;
7281 }
7282
02071907 7283 shift_mask_low = ~0;
c5059423
AM
7284 shift_mask_low <<= INTVAL (shiftop);
7285
7286 lsb = low & -low;
7287
7288 if ((lsb & shift_mask_low) == 0)
7289 return 0;
7290
7291 return low == -lsb && lsb != 1;
7292 }
e2c953b6 7293 else
c5059423 7294 return 0;
9878760c 7295}
35068b43
RK
7296
7297/* Return 1 if REGNO (reg1) == REGNO (reg2) - 1 making them candidates
7298 for lfq and stfq insns.
7299
7300 Note reg1 and reg2 *must* be hard registers. To be sure we will
7301 abort if we are passed pseudo registers. */
7302
7303int
7304registers_ok_for_quad_peep (reg1, reg2)
7305 rtx reg1, reg2;
7306{
7307 /* We might have been passed a SUBREG. */
7308 if (GET_CODE (reg1) != REG || GET_CODE (reg2) != REG)
7309 return 0;
7310
7311 return (REGNO (reg1) == REGNO (reg2) - 1);
7312}
7313
a4f6c312
SS
7314/* Return 1 if addr1 and addr2 are suitable for lfq or stfq insn.
7315 addr1 and addr2 must be in consecutive memory locations
7316 (addr2 == addr1 + 8). */
35068b43
RK
7317
7318int
7319addrs_ok_for_quad_peep (addr1, addr2)
592696dd
SS
7320 rtx addr1;
7321 rtx addr2;
35068b43 7322{
e2c953b6 7323 unsigned int reg1;
35068b43
RK
7324 int offset1;
7325
7326 /* Extract an offset (if used) from the first addr. */
7327 if (GET_CODE (addr1) == PLUS)
7328 {
7329 /* If not a REG, return zero. */
7330 if (GET_CODE (XEXP (addr1, 0)) != REG)
7331 return 0;
7332 else
7333 {
7334 reg1 = REGNO (XEXP (addr1, 0));
7335 /* The offset must be constant! */
7336 if (GET_CODE (XEXP (addr1, 1)) != CONST_INT)
7337 return 0;
7338 offset1 = INTVAL (XEXP (addr1, 1));
7339 }
7340 }
7341 else if (GET_CODE (addr1) != REG)
7342 return 0;
7343 else
7344 {
7345 reg1 = REGNO (addr1);
7346 /* This was a simple (mem (reg)) expression. Offset is 0. */
7347 offset1 = 0;
7348 }
7349
984e25ac
DE
7350/* Make sure the second address is a (mem (plus (reg) (const_int)))
7351 or if it is (mem (reg)) then make sure that offset1 is -8 and the same
7352 register as addr1. */
7353 if (offset1 == -8 && GET_CODE (addr2) == REG && reg1 == REGNO (addr2))
7354 return 1;
35068b43
RK
7355 if (GET_CODE (addr2) != PLUS)
7356 return 0;
7357
7358 if (GET_CODE (XEXP (addr2, 0)) != REG
7359 || GET_CODE (XEXP (addr2, 1)) != CONST_INT)
7360 return 0;
7361
7362 if (reg1 != REGNO (XEXP (addr2, 0)))
7363 return 0;
7364
7365 /* The offset for the second addr must be 8 more than the first addr. */
7366 if (INTVAL (XEXP (addr2, 1)) != offset1 + 8)
7367 return 0;
7368
7369 /* All the tests passed. addr1 and addr2 are valid for lfq or stfq
7370 instructions. */
7371 return 1;
7372}
9878760c
RK
7373\f
7374/* Return the register class of a scratch register needed to copy IN into
7375 or out of a register in CLASS in MODE. If it can be done directly,
7376 NO_REGS is returned. */
7377
7378enum reg_class
7379secondary_reload_class (class, mode, in)
7380 enum reg_class class;
296b8152 7381 enum machine_mode mode ATTRIBUTE_UNUSED;
9878760c
RK
7382 rtx in;
7383{
5accd822 7384 int regno;
9878760c 7385
ab82a49f
AP
7386 if (TARGET_ELF || (DEFAULT_ABI == ABI_DARWIN
7387#if TARGET_MACHO
7388 && MACHOPIC_INDIRECT
7389#endif
7390 ))
46fad5b7
DJ
7391 {
7392 /* We cannot copy a symbolic operand directly into anything
7393 other than BASE_REGS for TARGET_ELF. So indicate that a
7394 register from BASE_REGS is needed as an intermediate
7395 register.
7396
7397 On Darwin, pic addresses require a load from memory, which
7398 needs a base register. */
7399 if (class != BASE_REGS
7400 && (GET_CODE (in) == SYMBOL_REF
7401 || GET_CODE (in) == HIGH
7402 || GET_CODE (in) == LABEL_REF
7403 || GET_CODE (in) == CONST))
7404 return BASE_REGS;
7405 }
e7b7998a 7406
5accd822
DE
7407 if (GET_CODE (in) == REG)
7408 {
7409 regno = REGNO (in);
7410 if (regno >= FIRST_PSEUDO_REGISTER)
7411 {
7412 regno = true_regnum (in);
7413 if (regno >= FIRST_PSEUDO_REGISTER)
7414 regno = -1;
7415 }
7416 }
7417 else if (GET_CODE (in) == SUBREG)
7418 {
7419 regno = true_regnum (in);
7420 if (regno >= FIRST_PSEUDO_REGISTER)
7421 regno = -1;
7422 }
7423 else
7424 regno = -1;
7425
9878760c
RK
7426 /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
7427 into anything. */
7428 if (class == GENERAL_REGS || class == BASE_REGS
7429 || (regno >= 0 && INT_REGNO_P (regno)))
7430 return NO_REGS;
7431
7432 /* Constants, memory, and FP registers can go into FP registers. */
7433 if ((regno == -1 || FP_REGNO_P (regno))
7434 && (class == FLOAT_REGS || class == NON_SPECIAL_REGS))
7435 return NO_REGS;
7436
0ac081f6
AH
7437 /* Memory, and AltiVec registers can go into AltiVec registers. */
7438 if ((regno == -1 || ALTIVEC_REGNO_P (regno))
7439 && class == ALTIVEC_REGS)
7440 return NO_REGS;
7441
9878760c
RK
7442 /* We can copy among the CR registers. */
7443 if ((class == CR_REGS || class == CR0_REGS)
7444 && regno >= 0 && CR_REGNO_P (regno))
7445 return NO_REGS;
7446
7447 /* Otherwise, we need GENERAL_REGS. */
7448 return GENERAL_REGS;
7449}
7450\f
7451/* Given a comparison operation, return the bit number in CCR to test. We
7452 know this is a valid comparison.
7453
7454 SCC_P is 1 if this is for an scc. That means that %D will have been
7455 used instead of %C, so the bits will be in different places.
7456
b4ac57ab 7457 Return -1 if OP isn't a valid comparison for some reason. */
9878760c
RK
7458
7459int
7460ccr_bit (op, scc_p)
592696dd 7461 rtx op;
9878760c
RK
7462 int scc_p;
7463{
7464 enum rtx_code code = GET_CODE (op);
7465 enum machine_mode cc_mode;
7466 int cc_regnum;
7467 int base_bit;
9ebbca7d 7468 rtx reg;
9878760c
RK
7469
7470 if (GET_RTX_CLASS (code) != '<')
7471 return -1;
7472
9ebbca7d
GK
7473 reg = XEXP (op, 0);
7474
7475 if (GET_CODE (reg) != REG
7476 || ! CR_REGNO_P (REGNO (reg)))
7477 abort ();
7478
7479 cc_mode = GET_MODE (reg);
7480 cc_regnum = REGNO (reg);
7481 base_bit = 4 * (cc_regnum - CR0_REGNO);
9878760c 7482
39a10a29 7483 validate_condition_mode (code, cc_mode);
c5defebb 7484
9878760c
RK
7485 switch (code)
7486 {
7487 case NE:
993f19a8
AH
7488 if (TARGET_E500 && !TARGET_FPRS
7489 && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
a3170dc6 7490 return base_bit + 1;
9878760c
RK
7491 return scc_p ? base_bit + 3 : base_bit + 2;
7492 case EQ:
993f19a8
AH
7493 if (TARGET_E500 && !TARGET_FPRS
7494 && TARGET_HARD_FLOAT && cc_mode == CCFPmode)
a3170dc6 7495 return base_bit + 1;
9878760c 7496 return base_bit + 2;
1c882ea4 7497 case GT: case GTU: case UNLE:
9878760c 7498 return base_bit + 1;
1c882ea4 7499 case LT: case LTU: case UNGE:
9878760c 7500 return base_bit;
1c882ea4
GK
7501 case ORDERED: case UNORDERED:
7502 return base_bit + 3;
9878760c
RK
7503
7504 case GE: case GEU:
39a10a29 7505 /* If scc, we will have done a cror to put the bit in the
9878760c
RK
7506 unordered position. So test that bit. For integer, this is ! LT
7507 unless this is an scc insn. */
39a10a29 7508 return scc_p ? base_bit + 3 : base_bit;
9878760c
RK
7509
7510 case LE: case LEU:
39a10a29 7511 return scc_p ? base_bit + 3 : base_bit + 1;
1c882ea4 7512
9878760c
RK
7513 default:
7514 abort ();
7515 }
7516}
1ff7789b 7517\f
8d30c4ee 7518/* Return the GOT register. */
1ff7789b
MM
7519
7520struct rtx_def *
7521rs6000_got_register (value)
5f59ecb7 7522 rtx value ATTRIBUTE_UNUSED;
1ff7789b 7523{
a4f6c312
SS
7524 /* The second flow pass currently (June 1999) can't update
7525 regs_ever_live without disturbing other parts of the compiler, so
7526 update it here to make the prolog/epilogue code happy. */
1db02437
FS
7527 if (no_new_pseudos && ! regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM])
7528 regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM] = 1;
1ff7789b 7529
8d30c4ee 7530 current_function_uses_pic_offset_table = 1;
3cb999d8 7531
1ff7789b
MM
7532 return pic_offset_table_rtx;
7533}
a7df97e6 7534\f
e2500fed
GK
7535/* Function to init struct machine_function.
7536 This will be called, via a pointer variable,
7537 from push_function_context. */
a7df97e6 7538
e2500fed
GK
7539static struct machine_function *
7540rs6000_init_machine_status ()
a7df97e6 7541{
e2500fed 7542 return ggc_alloc_cleared (sizeof (machine_function));
a7df97e6 7543}
9878760c 7544\f
0ba1b2ff
AM
7545/* These macros test for integers and extract the low-order bits. */
7546#define INT_P(X) \
7547((GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE) \
7548 && GET_MODE (X) == VOIDmode)
7549
7550#define INT_LOWPART(X) \
7551 (GET_CODE (X) == CONST_INT ? INTVAL (X) : CONST_DOUBLE_LOW (X))
7552
7553int
7554extract_MB (op)
7555 rtx op;
7556{
7557 int i;
7558 unsigned long val = INT_LOWPART (op);
7559
7560 /* If the high bit is zero, the value is the first 1 bit we find
7561 from the left. */
7562 if ((val & 0x80000000) == 0)
7563 {
7564 if ((val & 0xffffffff) == 0)
7565 abort ();
7566
7567 i = 1;
7568 while (((val <<= 1) & 0x80000000) == 0)
7569 ++i;
7570 return i;
7571 }
7572
7573 /* If the high bit is set and the low bit is not, or the mask is all
7574 1's, the value is zero. */
7575 if ((val & 1) == 0 || (val & 0xffffffff) == 0xffffffff)
7576 return 0;
7577
7578 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7579 from the right. */
7580 i = 31;
7581 while (((val >>= 1) & 1) != 0)
7582 --i;
7583
7584 return i;
7585}
7586
7587int
7588extract_ME (op)
7589 rtx op;
7590{
7591 int i;
7592 unsigned long val = INT_LOWPART (op);
7593
7594 /* If the low bit is zero, the value is the first 1 bit we find from
7595 the right. */
7596 if ((val & 1) == 0)
7597 {
7598 if ((val & 0xffffffff) == 0)
7599 abort ();
7600
7601 i = 30;
7602 while (((val >>= 1) & 1) == 0)
7603 --i;
7604
7605 return i;
7606 }
7607
7608 /* If the low bit is set and the high bit is not, or the mask is all
7609 1's, the value is 31. */
7610 if ((val & 0x80000000) == 0 || (val & 0xffffffff) == 0xffffffff)
7611 return 31;
7612
7613 /* Otherwise we have a wrap-around mask. Look for the first 0 bit
7614 from the left. */
7615 i = 0;
7616 while (((val <<= 1) & 0x80000000) != 0)
7617 ++i;
7618
7619 return i;
7620}
7621
9878760c
RK
7622/* Print an operand. Recognize special options, documented below. */
7623
38c1f2d7 7624#if TARGET_ELF
d9407988 7625#define SMALL_DATA_RELOC ((rs6000_sdata == SDATA_EABI) ? "sda21" : "sdarel")
8fbd2dc7 7626#define SMALL_DATA_REG ((rs6000_sdata == SDATA_EABI) ? 0 : 13)
ba5e43aa
MM
7627#else
7628#define SMALL_DATA_RELOC "sda21"
8fbd2dc7 7629#define SMALL_DATA_REG 0
ba5e43aa
MM
7630#endif
7631
9878760c
RK
7632void
7633print_operand (file, x, code)
7634 FILE *file;
7635 rtx x;
9ebbca7d 7636 int code;
9878760c
RK
7637{
7638 int i;
a260abc9 7639 HOST_WIDE_INT val;
0ba1b2ff 7640 unsigned HOST_WIDE_INT uval;
9878760c
RK
7641
7642 switch (code)
7643 {
a8b3aeda 7644 case '.':
a85d226b
RK
7645 /* Write out an instruction after the call which may be replaced
7646 with glue code by the loader. This depends on the AIX version. */
7647 asm_fprintf (file, RS6000_CALL_GLUE);
a8b3aeda
RK
7648 return;
7649
81eace42
GK
7650 /* %a is output_address. */
7651
9854d9ed
RK
7652 case 'A':
7653 /* If X is a constant integer whose low-order 5 bits are zero,
7654 write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
76229ac8 7655 in the AIX assembler where "sri" with a zero shift count
20e26713 7656 writes a trash instruction. */
9854d9ed 7657 if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
76229ac8 7658 putc ('l', file);
9854d9ed 7659 else
76229ac8 7660 putc ('r', file);
9854d9ed
RK
7661 return;
7662
7663 case 'b':
e2c953b6
DE
7664 /* If constant, low-order 16 bits of constant, unsigned.
7665 Otherwise, write normally. */
7666 if (INT_P (x))
7667 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 0xffff);
7668 else
7669 print_operand (file, x, 0);
cad12a8d
RK
7670 return;
7671
a260abc9
DE
7672 case 'B':
7673 /* If the low-order bit is zero, write 'r'; otherwise, write 'l'
7674 for 64-bit mask direction. */
296b8152 7675 putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
a238cd8b 7676 return;
a260abc9 7677
81eace42
GK
7678 /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
7679 output_operand. */
7680
9854d9ed 7681 case 'D':
39a10a29
GK
7682 /* There used to be a comment for 'C' reading "This is an
7683 optional cror needed for certain floating-point
7684 comparisons. Otherwise write nothing." */
7685
9854d9ed
RK
7686 /* Similar, except that this is for an scc, so we must be able to
7687 encode the test in a single bit that is one. We do the above
7688 for any LE, GE, GEU, or LEU and invert the bit for NE. */
7689 if (GET_CODE (x) == LE || GET_CODE (x) == GE
7690 || GET_CODE (x) == LEU || GET_CODE (x) == GEU)
7691 {
9ebbca7d 7692 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7693
7694 fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
7695 base_bit + 2,
7696 base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
7697 }
7698
7699 else if (GET_CODE (x) == NE)
7700 {
9ebbca7d 7701 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
9854d9ed
RK
7702
7703 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
7704 base_bit + 2, base_bit + 2);
7705 }
993f19a8 7706 else if (TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT
a3170dc6
AH
7707 && GET_CODE (x) == EQ
7708 && GET_MODE (XEXP (x, 0)) == CCFPmode)
7709 {
7710 int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
7711
7712 fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
7713 base_bit + 1, base_bit + 1);
7714 }
9854d9ed
RK
7715 return;
7716
7717 case 'E':
39a10a29 7718 /* X is a CR register. Print the number of the EQ bit of the CR */
9854d9ed
RK
7719 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7720 output_operand_lossage ("invalid %%E value");
78fbdbf7 7721 else
39a10a29 7722 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO) + 2);
a85d226b 7723 return;
9854d9ed
RK
7724
7725 case 'f':
7726 /* X is a CR register. Print the shift count needed to move it
7727 to the high-order four bits. */
7728 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7729 output_operand_lossage ("invalid %%f value");
7730 else
9ebbca7d 7731 fprintf (file, "%d", 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7732 return;
7733
7734 case 'F':
7735 /* Similar, but print the count for the rotate in the opposite
7736 direction. */
7737 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7738 output_operand_lossage ("invalid %%F value");
7739 else
9ebbca7d 7740 fprintf (file, "%d", 32 - 4 * (REGNO (x) - CR0_REGNO));
9854d9ed
RK
7741 return;
7742
7743 case 'G':
7744 /* X is a constant integer. If it is negative, print "m",
43aa4e05 7745 otherwise print "z". This is to make an aze or ame insn. */
9854d9ed
RK
7746 if (GET_CODE (x) != CONST_INT)
7747 output_operand_lossage ("invalid %%G value");
7748 else if (INTVAL (x) >= 0)
76229ac8 7749 putc ('z', file);
9854d9ed 7750 else
76229ac8 7751 putc ('m', file);
9854d9ed 7752 return;
e2c953b6 7753
9878760c 7754 case 'h':
a4f6c312
SS
7755 /* If constant, output low-order five bits. Otherwise, write
7756 normally. */
9878760c 7757 if (INT_P (x))
5f59ecb7 7758 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 31);
9878760c
RK
7759 else
7760 print_operand (file, x, 0);
7761 return;
7762
64305719 7763 case 'H':
a4f6c312
SS
7764 /* If constant, output low-order six bits. Otherwise, write
7765 normally. */
64305719 7766 if (INT_P (x))
5f59ecb7 7767 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INT_LOWPART (x) & 63);
64305719
DE
7768 else
7769 print_operand (file, x, 0);
7770 return;
7771
9854d9ed
RK
7772 case 'I':
7773 /* Print `i' if this is a constant, else nothing. */
9878760c 7774 if (INT_P (x))
76229ac8 7775 putc ('i', file);
9878760c
RK
7776 return;
7777
9854d9ed
RK
7778 case 'j':
7779 /* Write the bit number in CCR for jump. */
7780 i = ccr_bit (x, 0);
7781 if (i == -1)
7782 output_operand_lossage ("invalid %%j code");
9878760c 7783 else
9854d9ed 7784 fprintf (file, "%d", i);
9878760c
RK
7785 return;
7786
9854d9ed
RK
7787 case 'J':
7788 /* Similar, but add one for shift count in rlinm for scc and pass
7789 scc flag to `ccr_bit'. */
7790 i = ccr_bit (x, 1);
7791 if (i == -1)
7792 output_operand_lossage ("invalid %%J code");
7793 else
a0466a68
RK
7794 /* If we want bit 31, write a shift count of zero, not 32. */
7795 fprintf (file, "%d", i == 31 ? 0 : i + 1);
9878760c
RK
7796 return;
7797
9854d9ed
RK
7798 case 'k':
7799 /* X must be a constant. Write the 1's complement of the
7800 constant. */
9878760c 7801 if (! INT_P (x))
9854d9ed 7802 output_operand_lossage ("invalid %%k value");
e2c953b6
DE
7803 else
7804 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
9878760c
RK
7805 return;
7806
81eace42 7807 case 'K':
9ebbca7d
GK
7808 /* X must be a symbolic constant on ELF. Write an
7809 expression suitable for an 'addi' that adds in the low 16
7810 bits of the MEM. */
7811 if (GET_CODE (x) != CONST)
7812 {
7813 print_operand_address (file, x);
7814 fputs ("@l", file);
7815 }
7816 else
7817 {
7818 if (GET_CODE (XEXP (x, 0)) != PLUS
7819 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
7820 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
7821 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
53cd5d6c 7822 output_operand_lossage ("invalid %%K value");
9ebbca7d
GK
7823 print_operand_address (file, XEXP (XEXP (x, 0), 0));
7824 fputs ("@l", file);
ed8d2920
MM
7825 /* For GNU as, there must be a non-alphanumeric character
7826 between 'l' and the number. The '-' is added by
7827 print_operand() already. */
7828 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
7829 fputs ("+", file);
9ebbca7d
GK
7830 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
7831 }
81eace42
GK
7832 return;
7833
7834 /* %l is output_asm_label. */
9ebbca7d 7835
9854d9ed
RK
7836 case 'L':
7837 /* Write second word of DImode or DFmode reference. Works on register
7838 or non-indexed memory only. */
7839 if (GET_CODE (x) == REG)
5ebfb2ba 7840 fprintf (file, "%s", reg_names[REGNO (x) + 1]);
9854d9ed
RK
7841 else if (GET_CODE (x) == MEM)
7842 {
7843 /* Handle possible auto-increment. Since it is pre-increment and
1427100a 7844 we have already done it, we can just use an offset of word. */
9854d9ed
RK
7845 if (GET_CODE (XEXP (x, 0)) == PRE_INC
7846 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
ed8908e7
RK
7847 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
7848 UNITS_PER_WORD));
9854d9ed 7849 else
d7624dc0
RK
7850 output_address (XEXP (adjust_address_nv (x, SImode,
7851 UNITS_PER_WORD),
7852 0));
ed8908e7 7853
ba5e43aa 7854 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
7855 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
7856 reg_names[SMALL_DATA_REG]);
9854d9ed 7857 }
9878760c 7858 return;
9854d9ed 7859
9878760c
RK
7860 case 'm':
7861 /* MB value for a mask operand. */
b1765bde 7862 if (! mask_operand (x, SImode))
9878760c
RK
7863 output_operand_lossage ("invalid %%m value");
7864
0ba1b2ff 7865 fprintf (file, "%d", extract_MB (x));
9878760c
RK
7866 return;
7867
7868 case 'M':
7869 /* ME value for a mask operand. */
b1765bde 7870 if (! mask_operand (x, SImode))
a260abc9 7871 output_operand_lossage ("invalid %%M value");
9878760c 7872
0ba1b2ff 7873 fprintf (file, "%d", extract_ME (x));
9878760c
RK
7874 return;
7875
81eace42
GK
7876 /* %n outputs the negative of its operand. */
7877
9878760c
RK
7878 case 'N':
7879 /* Write the number of elements in the vector times 4. */
7880 if (GET_CODE (x) != PARALLEL)
7881 output_operand_lossage ("invalid %%N value");
e2c953b6
DE
7882 else
7883 fprintf (file, "%d", XVECLEN (x, 0) * 4);
9878760c
RK
7884 return;
7885
7886 case 'O':
7887 /* Similar, but subtract 1 first. */
7888 if (GET_CODE (x) != PARALLEL)
1427100a 7889 output_operand_lossage ("invalid %%O value");
e2c953b6
DE
7890 else
7891 fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
9878760c
RK
7892 return;
7893
9854d9ed
RK
7894 case 'p':
7895 /* X is a CONST_INT that is a power of two. Output the logarithm. */
7896 if (! INT_P (x)
2bfcf297 7897 || INT_LOWPART (x) < 0
9854d9ed
RK
7898 || (i = exact_log2 (INT_LOWPART (x))) < 0)
7899 output_operand_lossage ("invalid %%p value");
e2c953b6
DE
7900 else
7901 fprintf (file, "%d", i);
9854d9ed
RK
7902 return;
7903
9878760c
RK
7904 case 'P':
7905 /* The operand must be an indirect memory reference. The result
a4f6c312 7906 is the register number. */
9878760c
RK
7907 if (GET_CODE (x) != MEM || GET_CODE (XEXP (x, 0)) != REG
7908 || REGNO (XEXP (x, 0)) >= 32)
7909 output_operand_lossage ("invalid %%P value");
e2c953b6
DE
7910 else
7911 fprintf (file, "%d", REGNO (XEXP (x, 0)));
9878760c
RK
7912 return;
7913
dfbdccdb
GK
7914 case 'q':
7915 /* This outputs the logical code corresponding to a boolean
7916 expression. The expression may have one or both operands
39a10a29
GK
7917 negated (if one, only the first one). For condition register
7918 logical operations, it will also treat the negated
7919 CR codes as NOTs, but not handle NOTs of them. */
dfbdccdb 7920 {
63bc1d05 7921 const char *const *t = 0;
dfbdccdb
GK
7922 const char *s;
7923 enum rtx_code code = GET_CODE (x);
7924 static const char * const tbl[3][3] = {
7925 { "and", "andc", "nor" },
7926 { "or", "orc", "nand" },
7927 { "xor", "eqv", "xor" } };
7928
7929 if (code == AND)
7930 t = tbl[0];
7931 else if (code == IOR)
7932 t = tbl[1];
7933 else if (code == XOR)
7934 t = tbl[2];
7935 else
7936 output_operand_lossage ("invalid %%q value");
7937
7938 if (GET_CODE (XEXP (x, 0)) != NOT)
7939 s = t[0];
7940 else
7941 {
7942 if (GET_CODE (XEXP (x, 1)) == NOT)
7943 s = t[2];
7944 else
7945 s = t[1];
7946 }
7947
7948 fputs (s, file);
7949 }
7950 return;
7951
9854d9ed
RK
7952 case 'R':
7953 /* X is a CR register. Print the mask for `mtcrf'. */
7954 if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
7955 output_operand_lossage ("invalid %%R value");
7956 else
9ebbca7d 7957 fprintf (file, "%d", 128 >> (REGNO (x) - CR0_REGNO));
9878760c 7958 return;
9854d9ed
RK
7959
7960 case 's':
7961 /* Low 5 bits of 32 - value */
7962 if (! INT_P (x))
7963 output_operand_lossage ("invalid %%s value");
e2c953b6
DE
7964 else
7965 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INT_LOWPART (x)) & 31);
9878760c 7966 return;
9854d9ed 7967
a260abc9 7968 case 'S':
0ba1b2ff 7969 /* PowerPC64 mask position. All 0's is excluded.
a260abc9
DE
7970 CONST_INT 32-bit mask is considered sign-extended so any
7971 transition must occur within the CONST_INT, not on the boundary. */
b1765bde 7972 if (! mask64_operand (x, DImode))
a260abc9
DE
7973 output_operand_lossage ("invalid %%S value");
7974
0ba1b2ff 7975 uval = INT_LOWPART (x);
a260abc9 7976
0ba1b2ff 7977 if (uval & 1) /* Clear Left */
a260abc9 7978 {
f099d360
GK
7979#if HOST_BITS_PER_WIDE_INT > 64
7980 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
7981#endif
0ba1b2ff 7982 i = 64;
a260abc9 7983 }
0ba1b2ff 7984 else /* Clear Right */
a260abc9 7985 {
0ba1b2ff 7986 uval = ~uval;
f099d360
GK
7987#if HOST_BITS_PER_WIDE_INT > 64
7988 uval &= ((unsigned HOST_WIDE_INT) 1 << 64) - 1;
7989#endif
0ba1b2ff 7990 i = 63;
a260abc9 7991 }
0ba1b2ff
AM
7992 while (uval != 0)
7993 --i, uval >>= 1;
7994 if (i < 0)
7995 abort ();
7996 fprintf (file, "%d", i);
7997 return;
a260abc9 7998
a3170dc6
AH
7999 case 't':
8000 /* Like 'J' but get to the OVERFLOW/UNORDERED bit. */
8001 if (GET_CODE (x) != REG || GET_MODE (x) != CCmode)
8002 abort ();
8003
8004 /* Bit 3 is OV bit. */
8005 i = 4 * (REGNO (x) - CR0_REGNO) + 3;
8006
8007 /* If we want bit 31, write a shift count of zero, not 32. */
8008 fprintf (file, "%d", i == 31 ? 0 : i + 1);
8009 return;
8010
cccf3bdc
DE
8011 case 'T':
8012 /* Print the symbolic name of a branch target register. */
8013 if (GET_CODE (x) != REG || (REGNO (x) != LINK_REGISTER_REGNUM
8014 && REGNO (x) != COUNT_REGISTER_REGNUM))
8015 output_operand_lossage ("invalid %%T value");
e2c953b6 8016 else if (REGNO (x) == LINK_REGISTER_REGNUM)
cccf3bdc
DE
8017 fputs (TARGET_NEW_MNEMONICS ? "lr" : "r", file);
8018 else
8019 fputs ("ctr", file);
8020 return;
8021
9854d9ed 8022 case 'u':
802a0058 8023 /* High-order 16 bits of constant for use in unsigned operand. */
9854d9ed
RK
8024 if (! INT_P (x))
8025 output_operand_lossage ("invalid %%u value");
e2c953b6
DE
8026 else
8027 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
8028 (INT_LOWPART (x) >> 16) & 0xffff);
9878760c
RK
8029 return;
8030
802a0058
MM
8031 case 'v':
8032 /* High-order 16 bits of constant for use in signed operand. */
8033 if (! INT_P (x))
8034 output_operand_lossage ("invalid %%v value");
e2c953b6 8035 else
134c32f6
DE
8036 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
8037 (INT_LOWPART (x) >> 16) & 0xffff);
8038 return;
802a0058 8039
9854d9ed
RK
8040 case 'U':
8041 /* Print `u' if this has an auto-increment or auto-decrement. */
8042 if (GET_CODE (x) == MEM
8043 && (GET_CODE (XEXP (x, 0)) == PRE_INC
8044 || GET_CODE (XEXP (x, 0)) == PRE_DEC))
76229ac8 8045 putc ('u', file);
9854d9ed 8046 return;
9878760c 8047
e0cd0770
JC
8048 case 'V':
8049 /* Print the trap code for this operand. */
8050 switch (GET_CODE (x))
8051 {
8052 case EQ:
8053 fputs ("eq", file); /* 4 */
8054 break;
8055 case NE:
8056 fputs ("ne", file); /* 24 */
8057 break;
8058 case LT:
8059 fputs ("lt", file); /* 16 */
8060 break;
8061 case LE:
8062 fputs ("le", file); /* 20 */
8063 break;
8064 case GT:
8065 fputs ("gt", file); /* 8 */
8066 break;
8067 case GE:
8068 fputs ("ge", file); /* 12 */
8069 break;
8070 case LTU:
8071 fputs ("llt", file); /* 2 */
8072 break;
8073 case LEU:
8074 fputs ("lle", file); /* 6 */
8075 break;
8076 case GTU:
8077 fputs ("lgt", file); /* 1 */
8078 break;
8079 case GEU:
8080 fputs ("lge", file); /* 5 */
8081 break;
8082 default:
8083 abort ();
8084 }
8085 break;
8086
9854d9ed
RK
8087 case 'w':
8088 /* If constant, low-order 16 bits of constant, signed. Otherwise, write
8089 normally. */
8090 if (INT_P (x))
5f59ecb7
DE
8091 fprintf (file, HOST_WIDE_INT_PRINT_DEC,
8092 ((INT_LOWPART (x) & 0xffff) ^ 0x8000) - 0x8000);
9854d9ed
RK
8093 else
8094 print_operand (file, x, 0);
9878760c
RK
8095 return;
8096
9854d9ed 8097 case 'W':
e2c953b6 8098 /* MB value for a PowerPC64 rldic operand. */
e2c953b6
DE
8099 val = (GET_CODE (x) == CONST_INT
8100 ? INTVAL (x) : CONST_DOUBLE_HIGH (x));
8101
8102 if (val < 0)
8103 i = -1;
9854d9ed 8104 else
e2c953b6
DE
8105 for (i = 0; i < HOST_BITS_PER_WIDE_INT; i++)
8106 if ((val <<= 1) < 0)
8107 break;
8108
8109#if HOST_BITS_PER_WIDE_INT == 32
8110 if (GET_CODE (x) == CONST_INT && i >= 0)
8111 i += 32; /* zero-extend high-part was all 0's */
8112 else if (GET_CODE (x) == CONST_DOUBLE && i == 32)
8113 {
8114 val = CONST_DOUBLE_LOW (x);
8115
8116 if (val == 0)
a4f6c312 8117 abort ();
e2c953b6
DE
8118 else if (val < 0)
8119 --i;
8120 else
8121 for ( ; i < 64; i++)
8122 if ((val <<= 1) < 0)
8123 break;
8124 }
8125#endif
8126
8127 fprintf (file, "%d", i + 1);
9854d9ed 8128 return;
9878760c 8129
9854d9ed
RK
8130 case 'X':
8131 if (GET_CODE (x) == MEM
258bfae2 8132 && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
76229ac8 8133 putc ('x', file);
9854d9ed 8134 return;
9878760c 8135
9854d9ed
RK
8136 case 'Y':
8137 /* Like 'L', for third word of TImode */
8138 if (GET_CODE (x) == REG)
5ebfb2ba 8139 fprintf (file, "%s", reg_names[REGNO (x) + 2]);
9854d9ed 8140 else if (GET_CODE (x) == MEM)
9878760c 8141 {
9854d9ed
RK
8142 if (GET_CODE (XEXP (x, 0)) == PRE_INC
8143 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 8144 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
9854d9ed 8145 else
d7624dc0 8146 output_address (XEXP (adjust_address_nv (x, SImode, 8), 0));
ba5e43aa 8147 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8148 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8149 reg_names[SMALL_DATA_REG]);
9878760c
RK
8150 }
8151 return;
9854d9ed 8152
9878760c 8153 case 'z':
b4ac57ab
RS
8154 /* X is a SYMBOL_REF. Write out the name preceded by a
8155 period and without any trailing data in brackets. Used for function
4d30c363
MM
8156 names. If we are configured for System V (or the embedded ABI) on
8157 the PowerPC, do not emit the period, since those systems do not use
8158 TOCs and the like. */
9878760c
RK
8159 if (GET_CODE (x) != SYMBOL_REF)
8160 abort ();
8161
b6c9286a
MM
8162 if (XSTR (x, 0)[0] != '.')
8163 {
8164 switch (DEFAULT_ABI)
8165 {
8166 default:
8167 abort ();
8168
8169 case ABI_AIX:
8170 putc ('.', file);
8171 break;
8172
8173 case ABI_V4:
8174 case ABI_AIX_NODESC:
ee890fe2 8175 case ABI_DARWIN:
b6c9286a 8176 break;
b6c9286a
MM
8177 }
8178 }
54ee9799
DE
8179#if TARGET_AIX
8180 RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
8181#else
9ebbca7d 8182 assemble_name (file, XSTR (x, 0));
54ee9799 8183#endif
9878760c
RK
8184 return;
8185
9854d9ed
RK
8186 case 'Z':
8187 /* Like 'L', for last word of TImode. */
8188 if (GET_CODE (x) == REG)
5ebfb2ba 8189 fprintf (file, "%s", reg_names[REGNO (x) + 3]);
9854d9ed
RK
8190 else if (GET_CODE (x) == MEM)
8191 {
8192 if (GET_CODE (XEXP (x, 0)) == PRE_INC
8193 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
a54d04b7 8194 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
9854d9ed 8195 else
d7624dc0 8196 output_address (XEXP (adjust_address_nv (x, SImode, 12), 0));
ba5e43aa 8197 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8198 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8199 reg_names[SMALL_DATA_REG]);
9854d9ed 8200 }
5c23c401 8201 return;
0ac081f6 8202
a3170dc6 8203 /* Print AltiVec or SPE memory operand. */
0ac081f6
AH
8204 case 'y':
8205 {
8206 rtx tmp;
8207
8208 if (GET_CODE (x) != MEM)
8209 abort ();
8210
8211 tmp = XEXP (x, 0);
8212
993f19a8 8213 if (TARGET_E500)
a3170dc6
AH
8214 {
8215 /* Handle [reg]. */
8216 if (GET_CODE (tmp) == REG)
8217 {
8218 fprintf (file, "0(%s)", reg_names[REGNO (tmp)]);
8219 break;
8220 }
8221 /* Handle [reg+UIMM]. */
8222 else if (GET_CODE (tmp) == PLUS &&
8223 GET_CODE (XEXP (tmp, 1)) == CONST_INT)
8224 {
8225 int x;
8226
8227 if (GET_CODE (XEXP (tmp, 0)) != REG)
8228 abort ();
8229
8230 x = INTVAL (XEXP (tmp, 1));
8231 fprintf (file, "%d(%s)", x, reg_names[REGNO (XEXP (tmp, 0))]);
8232 break;
8233 }
8234
8235 /* Fall through. Must be [reg+reg]. */
8236 }
0ac081f6 8237 if (GET_CODE (tmp) == REG)
c62f2db5 8238 fprintf (file, "0,%s", reg_names[REGNO (tmp)]);
0ac081f6
AH
8239 else if (GET_CODE (tmp) == PLUS && GET_CODE (XEXP (tmp, 1)) == REG)
8240 {
8241 if (REGNO (XEXP (tmp, 0)) == 0)
8242 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 1)) ],
8243 reg_names[ REGNO (XEXP (tmp, 0)) ]);
8244 else
8245 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (tmp, 0)) ],
8246 reg_names[ REGNO (XEXP (tmp, 1)) ]);
8247 }
8248 else
8249 abort ();
8250 break;
8251 }
9854d9ed 8252
9878760c
RK
8253 case 0:
8254 if (GET_CODE (x) == REG)
8255 fprintf (file, "%s", reg_names[REGNO (x)]);
8256 else if (GET_CODE (x) == MEM)
8257 {
8258 /* We need to handle PRE_INC and PRE_DEC here, since we need to
8259 know the width from the mode. */
8260 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
79ba6d34
MM
8261 fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
8262 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 8263 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
79ba6d34
MM
8264 fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
8265 reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
9878760c 8266 else
a54d04b7 8267 output_address (XEXP (x, 0));
9878760c
RK
8268 }
8269 else
a54d04b7 8270 output_addr_const (file, x);
a85d226b 8271 return;
9878760c
RK
8272
8273 default:
8274 output_operand_lossage ("invalid %%xn code");
8275 }
8276}
8277\f
8278/* Print the address of an operand. */
8279
8280void
8281print_operand_address (file, x)
8282 FILE *file;
592696dd 8283 rtx x;
9878760c
RK
8284{
8285 if (GET_CODE (x) == REG)
4697a36c 8286 fprintf (file, "0(%s)", reg_names[ REGNO (x) ]);
9ebbca7d
GK
8287 else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == CONST
8288 || GET_CODE (x) == LABEL_REF)
9878760c
RK
8289 {
8290 output_addr_const (file, x);
ba5e43aa 8291 if (small_data_operand (x, GET_MODE (x)))
8fbd2dc7
MM
8292 fprintf (file, "@%s(%s)", SMALL_DATA_RELOC,
8293 reg_names[SMALL_DATA_REG]);
9ebbca7d 8294 else if (TARGET_TOC)
a4f6c312 8295 abort ();
9878760c
RK
8296 }
8297 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == REG)
8298 {
8299 if (REGNO (XEXP (x, 0)) == 0)
4697a36c
MM
8300 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 1)) ],
8301 reg_names[ REGNO (XEXP (x, 0)) ]);
9878760c 8302 else
4697a36c
MM
8303 fprintf (file, "%s,%s", reg_names[ REGNO (XEXP (x, 0)) ],
8304 reg_names[ REGNO (XEXP (x, 1)) ]);
9878760c
RK
8305 }
8306 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
5f59ecb7
DE
8307 {
8308 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (XEXP (x, 1)));
8309 fprintf (file, "(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8310 }
3cb999d8
DE
8311#if TARGET_ELF
8312 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8313 && CONSTANT_P (XEXP (x, 1)))
4697a36c
MM
8314 {
8315 output_addr_const (file, XEXP (x, 1));
8316 fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8317 }
c859cda6
DJ
8318#endif
8319#if TARGET_MACHO
8320 else if (GET_CODE (x) == LO_SUM && GET_CODE (XEXP (x, 0)) == REG
8321 && CONSTANT_P (XEXP (x, 1)))
8322 {
8323 fprintf (file, "lo16(");
8324 output_addr_const (file, XEXP (x, 1));
8325 fprintf (file, ")(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
8326 }
3cb999d8 8327#endif
9ebbca7d
GK
8328 else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
8329 {
2bfcf297 8330 if (TARGET_AIX && (!TARGET_ELF || !TARGET_MINIMAL_TOC))
9ebbca7d 8331 {
2bfcf297
DB
8332 rtx contains_minus = XEXP (x, 1);
8333 rtx minus, symref;
8334 const char *name;
9ebbca7d
GK
8335
8336 /* Find the (minus (sym) (toc)) buried in X, and temporarily
a4f6c312 8337 turn it into (sym) for output_addr_const. */
9ebbca7d
GK
8338 while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
8339 contains_minus = XEXP (contains_minus, 0);
8340
2bfcf297
DB
8341 minus = XEXP (contains_minus, 0);
8342 symref = XEXP (minus, 0);
8343 XEXP (contains_minus, 0) = symref;
8344 if (TARGET_ELF)
8345 {
8346 char *newname;
8347
8348 name = XSTR (symref, 0);
8349 newname = alloca (strlen (name) + sizeof ("@toc"));
8350 strcpy (newname, name);
8351 strcat (newname, "@toc");
8352 XSTR (symref, 0) = newname;
8353 }
8354 output_addr_const (file, XEXP (x, 1));
8355 if (TARGET_ELF)
8356 XSTR (symref, 0) = name;
9ebbca7d
GK
8357 XEXP (contains_minus, 0) = minus;
8358 }
8359 else
8360 output_addr_const (file, XEXP (x, 1));
8361
8362 fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
8363 }
9878760c
RK
8364 else
8365 abort ();
8366}
8367\f
88cad84b 8368/* Target hook for assembling integer objects. The PowerPC version has
301d03af
RS
8369 to handle fixup entries for relocatable code if RELOCATABLE_NEEDS_FIXUP
8370 is defined. It also needs to handle DI-mode objects on 64-bit
8371 targets. */
8372
8373static bool
8374rs6000_assemble_integer (x, size, aligned_p)
8375 rtx x;
8376 unsigned int size;
8377 int aligned_p;
8378{
8379#ifdef RELOCATABLE_NEEDS_FIXUP
8380 /* Special handling for SI values. */
8381 if (size == 4 && aligned_p)
8382 {
8383 extern int in_toc_section PARAMS ((void));
8384 static int recurse = 0;
8385
8386 /* For -mrelocatable, we mark all addresses that need to be fixed up
8387 in the .fixup section. */
8388 if (TARGET_RELOCATABLE
8389 && !in_toc_section ()
8390 && !in_text_section ()
8391 && !recurse
8392 && GET_CODE (x) != CONST_INT
8393 && GET_CODE (x) != CONST_DOUBLE
8394 && CONSTANT_P (x))
8395 {
8396 char buf[256];
8397
8398 recurse = 1;
8399 ASM_GENERATE_INTERNAL_LABEL (buf, "LCP", fixuplabelno);
8400 fixuplabelno++;
8401 ASM_OUTPUT_LABEL (asm_out_file, buf);
8402 fprintf (asm_out_file, "\t.long\t(");
8403 output_addr_const (asm_out_file, x);
8404 fprintf (asm_out_file, ")@fixup\n");
8405 fprintf (asm_out_file, "\t.section\t\".fixup\",\"aw\"\n");
8406 ASM_OUTPUT_ALIGN (asm_out_file, 2);
8407 fprintf (asm_out_file, "\t.long\t");
8408 assemble_name (asm_out_file, buf);
8409 fprintf (asm_out_file, "\n\t.previous\n");
8410 recurse = 0;
8411 return true;
8412 }
8413 /* Remove initial .'s to turn a -mcall-aixdesc function
8414 address into the address of the descriptor, not the function
8415 itself. */
8416 else if (GET_CODE (x) == SYMBOL_REF
8417 && XSTR (x, 0)[0] == '.'
8418 && DEFAULT_ABI == ABI_AIX)
8419 {
8420 const char *name = XSTR (x, 0);
8421 while (*name == '.')
8422 name++;
8423
8424 fprintf (asm_out_file, "\t.long\t%s\n", name);
8425 return true;
8426 }
8427 }
8428#endif /* RELOCATABLE_NEEDS_FIXUP */
8429 return default_assemble_integer (x, size, aligned_p);
8430}
93638d7a
AM
8431
8432#ifdef HAVE_GAS_HIDDEN
8433/* Emit an assembler directive to set symbol visibility for DECL to
8434 VISIBILITY_TYPE. */
8435
5add3202 8436static void
25fdb4dc 8437rs6000_assemble_visibility (decl, vis)
93638d7a 8438 tree decl;
25fdb4dc 8439 int vis;
93638d7a 8440{
93638d7a
AM
8441 /* Functions need to have their entry point symbol visibility set as
8442 well as their descriptor symbol visibility. */
8443 if (DEFAULT_ABI == ABI_AIX && TREE_CODE (decl) == FUNCTION_DECL)
8444 {
25fdb4dc
RH
8445 static const char * const visibility_types[] = {
8446 NULL, "internal", "hidden", "protected"
8447 };
8448
8449 const char *name, *type;
93638d7a
AM
8450
8451 name = ((* targetm.strip_name_encoding)
8452 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
25fdb4dc 8453 type = visibility_types[vis];
93638d7a 8454
25fdb4dc
RH
8455 fprintf (asm_out_file, "\t.%s\t%s\n", type, name);
8456 fprintf (asm_out_file, "\t.%s\t.%s\n", type, name);
93638d7a 8457 }
25fdb4dc
RH
8458 else
8459 default_assemble_visibility (decl, vis);
93638d7a
AM
8460}
8461#endif
301d03af 8462\f
39a10a29
GK
8463enum rtx_code
8464rs6000_reverse_condition (mode, code)
8465 enum machine_mode mode;
8466 enum rtx_code code;
8467{
8468 /* Reversal of FP compares takes care -- an ordered compare
8469 becomes an unordered compare and vice versa. */
de40e1df 8470 if (mode == CCFPmode && !flag_unsafe_math_optimizations)
bab6226b 8471 return reverse_condition_maybe_unordered (code);
39a10a29 8472 else
bab6226b 8473 return reverse_condition (code);
39a10a29
GK
8474}
8475
39a10a29
GK
8476/* Generate a compare for CODE. Return a brand-new rtx that
8477 represents the result of the compare. */
a4f6c312 8478
39a10a29
GK
8479static rtx
8480rs6000_generate_compare (code)
8481 enum rtx_code code;
8482{
8483 enum machine_mode comp_mode;
8484 rtx compare_result;
8485
8486 if (rs6000_compare_fp_p)
8487 comp_mode = CCFPmode;
8488 else if (code == GTU || code == LTU
8489 || code == GEU || code == LEU)
8490 comp_mode = CCUNSmode;
8491 else
8492 comp_mode = CCmode;
8493
8494 /* First, the compare. */
8495 compare_result = gen_reg_rtx (comp_mode);
a3170dc6
AH
8496
8497 /* SPE FP compare instructions on the GPRs. Yuck! */
993f19a8
AH
8498 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT)
8499 && rs6000_compare_fp_p)
a3170dc6
AH
8500 {
8501 rtx cmp, or1, or2, or_result, compare_result2;
8502
8503 switch (code)
8504 {
8505 case EQ:
8506 case UNEQ:
8507 case NE:
8508 case LTGT:
8509 cmp = flag_unsafe_math_optimizations
8510 ? gen_tstsfeq_gpr (compare_result, rs6000_compare_op0,
8511 rs6000_compare_op1)
8512 : gen_cmpsfeq_gpr (compare_result, rs6000_compare_op0,
8513 rs6000_compare_op1);
8514 break;
8515 case GT:
8516 case GTU:
8517 case UNGT:
8518 case UNGE:
8519 case GE:
8520 case GEU:
8521 cmp = flag_unsafe_math_optimizations
8522 ? gen_tstsfgt_gpr (compare_result, rs6000_compare_op0,
8523 rs6000_compare_op1)
8524 : gen_cmpsfgt_gpr (compare_result, rs6000_compare_op0,
8525 rs6000_compare_op1);
8526 break;
8527 case LT:
8528 case LTU:
8529 case UNLT:
8530 case UNLE:
8531 case LE:
8532 case LEU:
8533 cmp = flag_unsafe_math_optimizations
8534 ? gen_tstsflt_gpr (compare_result, rs6000_compare_op0,
8535 rs6000_compare_op1)
8536 : gen_cmpsflt_gpr (compare_result, rs6000_compare_op0,
8537 rs6000_compare_op1);
8538 break;
8539 default:
8540 abort ();
8541 }
8542
8543 /* Synthesize LE and GE from LT/GT || EQ. */
8544 if (code == LE || code == GE || code == LEU || code == GEU)
8545 {
8546 /* Synthesize GE/LE frome GT/LT || EQ. */
8547
8548 emit_insn (cmp);
8549
8550 switch (code)
8551 {
8552 case LE: code = LT; break;
8553 case GE: code = GT; break;
8554 case LEU: code = LT; break;
8555 case GEU: code = GT; break;
8556 default: abort ();
8557 }
8558
8559 or1 = gen_reg_rtx (SImode);
8560 or2 = gen_reg_rtx (SImode);
8561 or_result = gen_reg_rtx (CCEQmode);
8562 compare_result2 = gen_reg_rtx (CCFPmode);
8563
8564 /* Do the EQ. */
8565 cmp = flag_unsafe_math_optimizations
8566 ? gen_tstsfeq_gpr (compare_result2, rs6000_compare_op0,
8567 rs6000_compare_op1)
8568 : gen_cmpsfeq_gpr (compare_result2, rs6000_compare_op0,
8569 rs6000_compare_op1);
8570 emit_insn (cmp);
8571
8572 /* The MC8540 FP compare instructions set the CR bits
8573 differently than other PPC compare instructions. For
8574 that matter, there is no generic test instruction, but a
8575 testgt, testlt, and testeq. For a true condition, bit 2
8576 is set (x1xx) in the CR. Following the traditional CR
8577 values:
8578
8579 LT GT EQ OV
8580 bit3 bit2 bit1 bit0
8581
8582 ... bit 2 would be a GT CR alias, so later on we
b6d08ca1 8583 look in the GT bits for the branch instructions.
a3170dc6
AH
8584 However, we must be careful to emit correct RTL in
8585 the meantime, so optimizations don't get confused. */
8586
8587 or1 = gen_rtx (NE, SImode, compare_result, const0_rtx);
8588 or2 = gen_rtx (NE, SImode, compare_result2, const0_rtx);
8589
8590 /* OR them together. */
8591 cmp = gen_rtx_SET (VOIDmode, or_result,
8592 gen_rtx_COMPARE (CCEQmode,
8593 gen_rtx_IOR (SImode, or1, or2),
8594 const_true_rtx));
8595 compare_result = or_result;
8596 code = EQ;
8597 }
8598 else
8599 {
8600 /* We only care about 1 bit (x1xx), so map everything to NE to
8601 maintain rtl sanity. We'll get to the right bit (x1xx) at
8602 code output time. */
8603 if (code == NE || code == LTGT)
8604 /* Do the inverse here because we have no cmpne
8605 instruction. We use the cmpeq instruction and expect
8606 to get a 0 instead. */
8607 code = EQ;
8608 else
8609 code = NE;
8610 }
8611
8612 emit_insn (cmp);
8613 }
8614 else
8615 emit_insn (gen_rtx_SET (VOIDmode, compare_result,
8616 gen_rtx_COMPARE (comp_mode,
8617 rs6000_compare_op0,
8618 rs6000_compare_op1)));
39a10a29 8619
ca5adc63 8620 /* Some kinds of FP comparisons need an OR operation;
de6c5979 8621 except for flag_unsafe_math_optimizations we don't bother. */
39a10a29 8622 if (rs6000_compare_fp_p
de6c5979 8623 && ! flag_unsafe_math_optimizations
993f19a8 8624 && ! (TARGET_HARD_FLOAT && TARGET_E500 && !TARGET_FPRS)
39a10a29
GK
8625 && (code == LE || code == GE
8626 || code == UNEQ || code == LTGT
8627 || code == UNGT || code == UNLT))
8628 {
8629 enum rtx_code or1, or2;
8630 rtx or1_rtx, or2_rtx, compare2_rtx;
8631 rtx or_result = gen_reg_rtx (CCEQmode);
8632
8633 switch (code)
8634 {
8635 case LE: or1 = LT; or2 = EQ; break;
8636 case GE: or1 = GT; or2 = EQ; break;
8637 case UNEQ: or1 = UNORDERED; or2 = EQ; break;
8638 case LTGT: or1 = LT; or2 = GT; break;
8639 case UNGT: or1 = UNORDERED; or2 = GT; break;
8640 case UNLT: or1 = UNORDERED; or2 = LT; break;
8641 default: abort ();
8642 }
8643 validate_condition_mode (or1, comp_mode);
8644 validate_condition_mode (or2, comp_mode);
8645 or1_rtx = gen_rtx (or1, SImode, compare_result, const0_rtx);
8646 or2_rtx = gen_rtx (or2, SImode, compare_result, const0_rtx);
8647 compare2_rtx = gen_rtx_COMPARE (CCEQmode,
8648 gen_rtx_IOR (SImode, or1_rtx, or2_rtx),
8649 const_true_rtx);
8650 emit_insn (gen_rtx_SET (VOIDmode, or_result, compare2_rtx));
8651
8652 compare_result = or_result;
8653 code = EQ;
8654 }
8655
8656 validate_condition_mode (code, GET_MODE (compare_result));
8657
8658 return gen_rtx (code, VOIDmode, compare_result, const0_rtx);
8659}
8660
8661
8662/* Emit the RTL for an sCOND pattern. */
8663
8664void
8665rs6000_emit_sCOND (code, result)
8666 enum rtx_code code;
8667 rtx result;
8668{
8669 rtx condition_rtx;
8670 enum machine_mode op_mode;
8671
8672 condition_rtx = rs6000_generate_compare (code);
8673
8674 op_mode = GET_MODE (rs6000_compare_op0);
8675 if (op_mode == VOIDmode)
8676 op_mode = GET_MODE (rs6000_compare_op1);
8677
8678 if (TARGET_POWERPC64 && (op_mode == DImode || rs6000_compare_fp_p))
8679 {
8680 PUT_MODE (condition_rtx, DImode);
8681 convert_move (result, condition_rtx, 0);
8682 }
8683 else
8684 {
8685 PUT_MODE (condition_rtx, SImode);
8686 emit_insn (gen_rtx_SET (VOIDmode, result, condition_rtx));
8687 }
8688}
8689
39a10a29
GK
8690/* Emit a branch of kind CODE to location LOC. */
8691
8692void
8693rs6000_emit_cbranch (code, loc)
8694 enum rtx_code code;
8695 rtx loc;
8696{
8697 rtx condition_rtx, loc_ref;
8698
8699 condition_rtx = rs6000_generate_compare (code);
8700 loc_ref = gen_rtx_LABEL_REF (VOIDmode, loc);
8701 emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
8702 gen_rtx_IF_THEN_ELSE (VOIDmode, condition_rtx,
8703 loc_ref, pc_rtx)));
8704}
8705
12a4e8c5
GK
8706/* Return the string to output a conditional branch to LABEL, which is
8707 the operand number of the label, or -1 if the branch is really a
8708 conditional return.
8709
8710 OP is the conditional expression. XEXP (OP, 0) is assumed to be a
8711 condition code register and its mode specifies what kind of
8712 comparison we made.
8713
a0ab749a 8714 REVERSED is nonzero if we should reverse the sense of the comparison.
12a4e8c5
GK
8715
8716 INSN is the insn. */
8717
8718char *
8719output_cbranch (op, label, reversed, insn)
8720 rtx op;
8721 const char * label;
8722 int reversed;
8723 rtx insn;
8724{
8725 static char string[64];
8726 enum rtx_code code = GET_CODE (op);
8727 rtx cc_reg = XEXP (op, 0);
8728 enum machine_mode mode = GET_MODE (cc_reg);
8729 int cc_regno = REGNO (cc_reg) - CR0_REGNO;
39a10a29 8730 int need_longbranch = label != NULL && get_attr_length (insn) == 8;
12a4e8c5
GK
8731 int really_reversed = reversed ^ need_longbranch;
8732 char *s = string;
8733 const char *ccode;
8734 const char *pred;
8735 rtx note;
8736
39a10a29
GK
8737 validate_condition_mode (code, mode);
8738
8739 /* Work out which way this really branches. We could use
8740 reverse_condition_maybe_unordered here always but this
8741 makes the resulting assembler clearer. */
12a4e8c5 8742 if (really_reversed)
de40e1df
DJ
8743 {
8744 /* Reversal of FP compares takes care -- an ordered compare
8745 becomes an unordered compare and vice versa. */
8746 if (mode == CCFPmode)
8747 code = reverse_condition_maybe_unordered (code);
8748 else
8749 code = reverse_condition (code);
8750 }
12a4e8c5 8751
993f19a8 8752 if ((TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT) && mode == CCFPmode)
a3170dc6
AH
8753 {
8754 /* The efscmp/tst* instructions twiddle bit 2, which maps nicely
8755 to the GT bit. */
8756 if (code == EQ)
8757 /* Opposite of GT. */
8758 code = UNLE;
8759 else if (code == NE)
8760 code = GT;
8761 else
8762 abort ();
8763 }
8764
39a10a29 8765 switch (code)
12a4e8c5
GK
8766 {
8767 /* Not all of these are actually distinct opcodes, but
8768 we distinguish them for clarity of the resulting assembler. */
50a0b056
GK
8769 case NE: case LTGT:
8770 ccode = "ne"; break;
8771 case EQ: case UNEQ:
8772 ccode = "eq"; break;
8773 case GE: case GEU:
8774 ccode = "ge"; break;
8775 case GT: case GTU: case UNGT:
8776 ccode = "gt"; break;
8777 case LE: case LEU:
8778 ccode = "le"; break;
8779 case LT: case LTU: case UNLT:
8780 ccode = "lt"; break;
12a4e8c5
GK
8781 case UNORDERED: ccode = "un"; break;
8782 case ORDERED: ccode = "nu"; break;
8783 case UNGE: ccode = "nl"; break;
8784 case UNLE: ccode = "ng"; break;
8785 default:
a4f6c312 8786 abort ();
12a4e8c5
GK
8787 }
8788
94a54f47
GK
8789 /* Maybe we have a guess as to how likely the branch is.
8790 The old mnemonics don't have a way to specify this information. */
f4857b9b 8791 pred = "";
12a4e8c5
GK
8792 note = find_reg_note (insn, REG_BR_PROB, NULL_RTX);
8793 if (note != NULL_RTX)
8794 {
8795 /* PROB is the difference from 50%. */
8796 int prob = INTVAL (XEXP (note, 0)) - REG_BR_PROB_BASE / 2;
f4857b9b
AM
8797 bool always_hint = rs6000_cpu != PROCESSOR_POWER4;
8798
8799 /* Only hint for highly probable/improbable branches on newer
8800 cpus as static prediction overrides processor dynamic
8801 prediction. For older cpus we may as well always hint, but
8802 assume not taken for branches that are very close to 50% as a
8803 mispredicted taken branch is more expensive than a
8804 mispredicted not-taken branch. */
8805 if (always_hint
8806 || abs (prob) > REG_BR_PROB_BASE / 100 * 48)
8807 {
8808 if (abs (prob) > REG_BR_PROB_BASE / 20
8809 && ((prob > 0) ^ need_longbranch))
7f3d8013 8810 pred = "+";
f4857b9b
AM
8811 else
8812 pred = "-";
8813 }
12a4e8c5 8814 }
12a4e8c5
GK
8815
8816 if (label == NULL)
94a54f47 8817 s += sprintf (s, "{b%sr|b%slr%s} ", ccode, ccode, pred);
12a4e8c5 8818 else
94a54f47 8819 s += sprintf (s, "{b%s|b%s%s} ", ccode, ccode, pred);
12a4e8c5 8820
37c67319
GK
8821 /* We need to escape any '%' characters in the reg_names string.
8822 Assume they'd only be the first character... */
8823 if (reg_names[cc_regno + CR0_REGNO][0] == '%')
8824 *s++ = '%';
94a54f47 8825 s += sprintf (s, "%s", reg_names[cc_regno + CR0_REGNO]);
12a4e8c5
GK
8826
8827 if (label != NULL)
8828 {
8829 /* If the branch distance was too far, we may have to use an
8830 unconditional branch to go the distance. */
8831 if (need_longbranch)
44518ddd 8832 s += sprintf (s, ",$+8\n\tb %s", label);
12a4e8c5
GK
8833 else
8834 s += sprintf (s, ",%s", label);
8835 }
8836
8837 return string;
8838}
50a0b056
GK
8839
8840/* Emit a conditional move: move TRUE_COND to DEST if OP of the
8841 operands of the last comparison is nonzero/true, FALSE_COND if it
8842 is zero/false. Return 0 if the hardware has no such operation. */
a4f6c312 8843
50a0b056
GK
8844int
8845rs6000_emit_cmove (dest, op, true_cond, false_cond)
8846 rtx dest;
8847 rtx op;
8848 rtx true_cond;
8849 rtx false_cond;
8850{
8851 enum rtx_code code = GET_CODE (op);
8852 rtx op0 = rs6000_compare_op0;
8853 rtx op1 = rs6000_compare_op1;
8854 REAL_VALUE_TYPE c1;
3148ad6d
DJ
8855 enum machine_mode compare_mode = GET_MODE (op0);
8856 enum machine_mode result_mode = GET_MODE (dest);
50a0b056
GK
8857 rtx temp;
8858
3148ad6d 8859 /* These modes should always match. */
a3170dc6
AH
8860 if (GET_MODE (op1) != compare_mode
8861 /* In the isel case however, we can use a compare immediate, so
8862 op1 may be a small constant. */
8863 && (!TARGET_ISEL || !short_cint_operand (op1, VOIDmode)))
3148ad6d 8864 return 0;
178c3eff 8865 if (GET_MODE (true_cond) != result_mode)
3148ad6d 8866 return 0;
178c3eff 8867 if (GET_MODE (false_cond) != result_mode)
3148ad6d
DJ
8868 return 0;
8869
50a0b056
GK
8870 /* First, work out if the hardware can do this at all, or
8871 if it's too slow... */
50a0b056 8872 if (! rs6000_compare_fp_p)
a3170dc6
AH
8873 {
8874 if (TARGET_ISEL)
8875 return rs6000_emit_int_cmove (dest, op, true_cond, false_cond);
8876 return 0;
8877 }
50a0b056
GK
8878
8879 /* Eliminate half of the comparisons by switching operands, this
8880 makes the remaining code simpler. */
8881 if (code == UNLT || code == UNGT || code == UNORDERED || code == NE
8882 || code == LTGT || code == LT)
8883 {
8884 code = reverse_condition_maybe_unordered (code);
8885 temp = true_cond;
8886 true_cond = false_cond;
8887 false_cond = temp;
8888 }
8889
8890 /* UNEQ and LTGT take four instructions for a comparison with zero,
8891 it'll probably be faster to use a branch here too. */
8892 if (code == UNEQ)
8893 return 0;
8894
8895 if (GET_CODE (op1) == CONST_DOUBLE)
8896 REAL_VALUE_FROM_CONST_DOUBLE (c1, op1);
8897
b6d08ca1 8898 /* We're going to try to implement comparisons by performing
50a0b056
GK
8899 a subtract, then comparing against zero. Unfortunately,
8900 Inf - Inf is NaN which is not zero, and so if we don't
27d30956 8901 know that the operand is finite and the comparison
50a0b056
GK
8902 would treat EQ different to UNORDERED, we can't do it. */
8903 if (! flag_unsafe_math_optimizations
8904 && code != GT && code != UNGE
045572c7 8905 && (GET_CODE (op1) != CONST_DOUBLE || real_isinf (&c1))
50a0b056
GK
8906 /* Constructs of the form (a OP b ? a : b) are safe. */
8907 && ((! rtx_equal_p (op0, false_cond) && ! rtx_equal_p (op1, false_cond))
8908 || (! rtx_equal_p (op0, true_cond)
8909 && ! rtx_equal_p (op1, true_cond))))
8910 return 0;
8911 /* At this point we know we can use fsel. */
8912
8913 /* Reduce the comparison to a comparison against zero. */
3148ad6d 8914 temp = gen_reg_rtx (compare_mode);
50a0b056 8915 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8916 gen_rtx_MINUS (compare_mode, op0, op1)));
50a0b056 8917 op0 = temp;
3148ad6d 8918 op1 = CONST0_RTX (compare_mode);
50a0b056
GK
8919
8920 /* If we don't care about NaNs we can reduce some of the comparisons
8921 down to faster ones. */
8922 if (flag_unsafe_math_optimizations)
8923 switch (code)
8924 {
8925 case GT:
8926 code = LE;
8927 temp = true_cond;
8928 true_cond = false_cond;
8929 false_cond = temp;
8930 break;
8931 case UNGE:
8932 code = GE;
8933 break;
8934 case UNEQ:
8935 code = EQ;
8936 break;
8937 default:
8938 break;
8939 }
8940
8941 /* Now, reduce everything down to a GE. */
8942 switch (code)
8943 {
8944 case GE:
8945 break;
8946
8947 case LE:
3148ad6d
DJ
8948 temp = gen_reg_rtx (compare_mode);
8949 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8950 op0 = temp;
8951 break;
8952
8953 case ORDERED:
3148ad6d
DJ
8954 temp = gen_reg_rtx (compare_mode);
8955 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_ABS (compare_mode, op0)));
50a0b056
GK
8956 op0 = temp;
8957 break;
8958
8959 case EQ:
3148ad6d 8960 temp = gen_reg_rtx (compare_mode);
50a0b056 8961 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d
DJ
8962 gen_rtx_NEG (compare_mode,
8963 gen_rtx_ABS (compare_mode, op0))));
50a0b056
GK
8964 op0 = temp;
8965 break;
8966
8967 case UNGE:
3148ad6d 8968 temp = gen_reg_rtx (result_mode);
50a0b056 8969 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8970 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8971 gen_rtx_GE (VOIDmode,
8972 op0, op1),
8973 true_cond, false_cond)));
8974 false_cond = temp;
8975 true_cond = false_cond;
8976
3148ad6d
DJ
8977 temp = gen_reg_rtx (compare_mode);
8978 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8979 op0 = temp;
8980 break;
8981
8982 case GT:
3148ad6d 8983 temp = gen_reg_rtx (result_mode);
50a0b056 8984 emit_insn (gen_rtx_SET (VOIDmode, temp,
3148ad6d 8985 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
8986 gen_rtx_GE (VOIDmode,
8987 op0, op1),
8988 true_cond, false_cond)));
8989 true_cond = temp;
8990 false_cond = true_cond;
8991
3148ad6d
DJ
8992 temp = gen_reg_rtx (compare_mode);
8993 emit_insn (gen_rtx_SET (VOIDmode, temp, gen_rtx_NEG (compare_mode, op0)));
50a0b056
GK
8994 op0 = temp;
8995 break;
8996
8997 default:
8998 abort ();
8999 }
9000
9001 emit_insn (gen_rtx_SET (VOIDmode, dest,
3148ad6d 9002 gen_rtx_IF_THEN_ELSE (result_mode,
50a0b056
GK
9003 gen_rtx_GE (VOIDmode,
9004 op0, op1),
9005 true_cond, false_cond)));
9006 return 1;
9007}
9008
a3170dc6
AH
9009/* Same as above, but for ints (isel). */
9010
9011static int
9012rs6000_emit_int_cmove (dest, op, true_cond, false_cond)
9013 rtx dest;
9014 rtx op;
9015 rtx true_cond;
9016 rtx false_cond;
9017{
9018 rtx condition_rtx, cr;
9019
9020 /* All isel implementations thus far are 32-bits. */
9021 if (GET_MODE (rs6000_compare_op0) != SImode)
9022 return 0;
9023
9024 /* We still have to do the compare, because isel doesn't do a
9025 compare, it just looks at the CRx bits set by a previous compare
9026 instruction. */
9027 condition_rtx = rs6000_generate_compare (GET_CODE (op));
9028 cr = XEXP (condition_rtx, 0);
9029
9030 if (GET_MODE (cr) == CCmode)
9031 emit_insn (gen_isel_signed (dest, condition_rtx,
9032 true_cond, false_cond, cr));
9033 else
9034 emit_insn (gen_isel_unsigned (dest, condition_rtx,
9035 true_cond, false_cond, cr));
9036
9037 return 1;
9038}
9039
9040const char *
9041output_isel (operands)
9042 rtx *operands;
9043{
9044 enum rtx_code code;
9045
9046 code = GET_CODE (operands[1]);
9047 if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
9048 {
9049 PUT_CODE (operands[1], reverse_condition (code));
9050 return "isel %0,%3,%2,%j1";
9051 }
9052 else
9053 return "isel %0,%2,%3,%j1";
9054}
9055
50a0b056
GK
9056void
9057rs6000_emit_minmax (dest, code, op0, op1)
9058 rtx dest;
9059 enum rtx_code code;
9060 rtx op0;
9061 rtx op1;
9062{
9063 enum machine_mode mode = GET_MODE (op0);
5dc8d536 9064 enum rtx_code c;
50a0b056 9065 rtx target;
5dc8d536
AH
9066
9067 if (code == SMAX || code == SMIN)
9068 c = GE;
9069 else
9070 c = GEU;
9071
50a0b056 9072 if (code == SMAX || code == UMAX)
5dc8d536 9073 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
9074 op0, op1, mode, 0);
9075 else
5dc8d536 9076 target = emit_conditional_move (dest, c, op0, op1, mode,
50a0b056
GK
9077 op1, op0, mode, 0);
9078 if (target == NULL_RTX)
9079 abort ();
9080 if (target != dest)
9081 emit_move_insn (dest, target);
9082}
12a4e8c5 9083\f
a4f6c312
SS
9084/* This page contains routines that are used to determine what the
9085 function prologue and epilogue code will do and write them out. */
9878760c 9086
a4f6c312
SS
9087/* Return the first fixed-point register that is required to be
9088 saved. 32 if none. */
9878760c
RK
9089
9090int
9091first_reg_to_save ()
9092{
9093 int first_reg;
9094
9095 /* Find lowest numbered live register. */
9096 for (first_reg = 13; first_reg <= 31; first_reg++)
a38d360d
GK
9097 if (regs_ever_live[first_reg]
9098 && (! call_used_regs[first_reg]
1db02437 9099 || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 9100 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 9101 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
9878760c
RK
9102 break;
9103
ee890fe2 9104#if TARGET_MACHO
93638d7a
AM
9105 if (flag_pic
9106 && current_function_uses_pic_offset_table
9107 && first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM)
1db02437 9108 return RS6000_PIC_OFFSET_TABLE_REGNUM;
ee890fe2
SS
9109#endif
9110
9878760c
RK
9111 return first_reg;
9112}
9113
9114/* Similar, for FP regs. */
9115
9116int
9117first_fp_reg_to_save ()
9118{
9119 int first_reg;
9120
9121 /* Find lowest numbered live register. */
9122 for (first_reg = 14 + 32; first_reg <= 63; first_reg++)
9123 if (regs_ever_live[first_reg])
9124 break;
9125
9126 return first_reg;
9127}
00b960c7
AH
9128
9129/* Similar, for AltiVec regs. */
9130
9131static int
9132first_altivec_reg_to_save ()
9133{
9134 int i;
9135
9136 /* Stack frame remains as is unless we are in AltiVec ABI. */
9137 if (! TARGET_ALTIVEC_ABI)
9138 return LAST_ALTIVEC_REGNO + 1;
9139
9140 /* Find lowest numbered live register. */
9141 for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i)
9142 if (regs_ever_live[i])
9143 break;
9144
9145 return i;
9146}
9147
9148/* Return a 32-bit mask of the AltiVec registers we need to set in
9149 VRSAVE. Bit n of the return value is 1 if Vn is live. The MSB in
9150 the 32-bit word is 0. */
9151
9152static unsigned int
9153compute_vrsave_mask ()
9154{
9155 unsigned int i, mask = 0;
9156
9157 /* First, find out if we use _any_ altivec registers. */
9158 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
9159 if (regs_ever_live[i])
9160 mask |= ALTIVEC_REG_BIT (i);
9161
9162 if (mask == 0)
9163 return mask;
9164
00b960c7
AH
9165 /* Next, remove the argument registers from the set. These must
9166 be in the VRSAVE mask set by the caller, so we don't need to add
9167 them in again. More importantly, the mask we compute here is
9168 used to generate CLOBBERs in the set_vrsave insn, and we do not
9169 wish the argument registers to die. */
9170 for (i = cfun->args_info.vregno; i >= ALTIVEC_ARG_MIN_REG; --i)
9171 mask &= ~ALTIVEC_REG_BIT (i);
9172
9173 /* Similarly, remove the return value from the set. */
9174 {
9175 bool yes = false;
9176 diddle_return_value (is_altivec_return_reg, &yes);
9177 if (yes)
9178 mask &= ~ALTIVEC_REG_BIT (ALTIVEC_ARG_RETURN);
9179 }
9180
9181 return mask;
9182}
9183
9184static void
9185is_altivec_return_reg (reg, xyes)
9186 rtx reg;
9187 void *xyes;
9188{
9189 bool *yes = (bool *) xyes;
9190 if (REGNO (reg) == ALTIVEC_ARG_RETURN)
9191 *yes = true;
9192}
9193
4697a36c
MM
9194\f
9195/* Calculate the stack information for the current function. This is
9196 complicated by having two separate calling sequences, the AIX calling
9197 sequence and the V.4 calling sequence.
9198
592696dd 9199 AIX (and Darwin/Mac OS X) stack frames look like:
a260abc9 9200 32-bit 64-bit
4697a36c 9201 SP----> +---------------------------------------+
a260abc9 9202 | back chain to caller | 0 0
4697a36c 9203 +---------------------------------------+
a260abc9 9204 | saved CR | 4 8 (8-11)
4697a36c 9205 +---------------------------------------+
a260abc9 9206 | saved LR | 8 16
4697a36c 9207 +---------------------------------------+
a260abc9 9208 | reserved for compilers | 12 24
4697a36c 9209 +---------------------------------------+
a260abc9 9210 | reserved for binders | 16 32
4697a36c 9211 +---------------------------------------+
a260abc9 9212 | saved TOC pointer | 20 40
4697a36c 9213 +---------------------------------------+
a260abc9 9214 | Parameter save area (P) | 24 48
4697a36c 9215 +---------------------------------------+
a260abc9 9216 | Alloca space (A) | 24+P etc.
802a0058 9217 +---------------------------------------+
a7df97e6 9218 | Local variable space (L) | 24+P+A
4697a36c 9219 +---------------------------------------+
a7df97e6 9220 | Float/int conversion temporary (X) | 24+P+A+L
4697a36c 9221 +---------------------------------------+
00b960c7
AH
9222 | Save area for AltiVec registers (W) | 24+P+A+L+X
9223 +---------------------------------------+
9224 | AltiVec alignment padding (Y) | 24+P+A+L+X+W
9225 +---------------------------------------+
9226 | Save area for VRSAVE register (Z) | 24+P+A+L+X+W+Y
4697a36c 9227 +---------------------------------------+
00b960c7
AH
9228 | Save area for GP registers (G) | 24+P+A+X+L+X+W+Y+Z
9229 +---------------------------------------+
9230 | Save area for FP registers (F) | 24+P+A+X+L+X+W+Y+Z+G
4697a36c
MM
9231 +---------------------------------------+
9232 old SP->| back chain to caller's caller |
9233 +---------------------------------------+
9234
5376a30c
KR
9235 The required alignment for AIX configurations is two words (i.e., 8
9236 or 16 bytes).
9237
9238
4697a36c
MM
9239 V.4 stack frames look like:
9240
9241 SP----> +---------------------------------------+
9242 | back chain to caller | 0
9243 +---------------------------------------+
5eb387b8 9244 | caller's saved LR | 4
4697a36c
MM
9245 +---------------------------------------+
9246 | Parameter save area (P) | 8
9247 +---------------------------------------+
a7df97e6
MM
9248 | Alloca space (A) | 8+P
9249 +---------------------------------------+
9250 | Varargs save area (V) | 8+P+A
9251 +---------------------------------------+
9252 | Local variable space (L) | 8+P+A+V
9253 +---------------------------------------+
9254 | Float/int conversion temporary (X) | 8+P+A+V+L
4697a36c 9255 +---------------------------------------+
00b960c7
AH
9256 | Save area for AltiVec registers (W) | 8+P+A+V+L+X
9257 +---------------------------------------+
9258 | AltiVec alignment padding (Y) | 8+P+A+V+L+X+W
9259 +---------------------------------------+
9260 | Save area for VRSAVE register (Z) | 8+P+A+V+L+X+W+Y
9261 +---------------------------------------+
a3170dc6
AH
9262 | SPE: area for 64-bit GP registers |
9263 +---------------------------------------+
9264 | SPE alignment padding |
9265 +---------------------------------------+
00b960c7 9266 | saved CR (C) | 8+P+A+V+L+X+W+Y+Z
a7df97e6 9267 +---------------------------------------+
00b960c7 9268 | Save area for GP registers (G) | 8+P+A+V+L+X+W+Y+Z+C
a7df97e6 9269 +---------------------------------------+
00b960c7 9270 | Save area for FP registers (F) | 8+P+A+V+L+X+W+Y+Z+C+G
4697a36c
MM
9271 +---------------------------------------+
9272 old SP->| back chain to caller's caller |
9273 +---------------------------------------+
b6c9286a 9274
5376a30c
KR
9275 The required alignment for V.4 is 16 bytes, or 8 bytes if -meabi is
9276 given. (But note below and in sysv4.h that we require only 8 and
9277 may round up the size of our stack frame anyways. The historical
9278 reason is early versions of powerpc-linux which didn't properly
9279 align the stack at program startup. A happy side-effect is that
9280 -mno-eabi libraries can be used with -meabi programs.)
9281
5376a30c
KR
9282 The EABI configuration defaults to the V.4 layout, unless
9283 -mcall-aix is used, in which case the AIX layout is used. However,
9284 the stack alignment requirements may differ. If -mno-eabi is not
9285 given, the required stack alignment is 8 bytes; if -mno-eabi is
9286 given, the required alignment is 16 bytes. (But see V.4 comment
9287 above.) */
4697a36c 9288
61b2fbe7
MM
9289#ifndef ABI_STACK_BOUNDARY
9290#define ABI_STACK_BOUNDARY STACK_BOUNDARY
9291#endif
9292
4697a36c
MM
9293rs6000_stack_t *
9294rs6000_stack_info ()
9295{
9296 static rs6000_stack_t info, zero_info;
9297 rs6000_stack_t *info_ptr = &info;
9ebbca7d 9298 int reg_size = TARGET_POWERPC64 ? 8 : 4;
83720594 9299 int ehrd_size;
b6c9286a 9300 int total_raw_size;
4697a36c 9301
a4f6c312 9302 /* Zero all fields portably. */
4697a36c
MM
9303 info = zero_info;
9304
c19de7aa
AH
9305 if (TARGET_SPE)
9306 {
9307 /* Cache value so we don't rescan instruction chain over and over. */
9b7b447f
AH
9308 if (cfun->machine->insn_chain_scanned_p == 0)
9309 {
9310 cfun->machine->insn_chain_scanned_p = 1;
9311 info_ptr->spe_64bit_regs_used = (int) spe_func_has_64bit_regs_p ();
9312 }
c19de7aa
AH
9313 }
9314
a4f6c312 9315 /* Select which calling sequence. */
178274da 9316 info_ptr->abi = DEFAULT_ABI;
9878760c 9317
a4f6c312 9318 /* Calculate which registers need to be saved & save area size. */
4697a36c 9319 info_ptr->first_gp_reg_save = first_reg_to_save ();
1db02437 9320 /* Assume that we will have to save RS6000_PIC_OFFSET_TABLE_REGNUM,
906fb125 9321 even if it currently looks like we won't. */
2bfcf297 9322 if (((TARGET_TOC && TARGET_MINIMAL_TOC)
178274da
AM
9323 || (flag_pic == 1 && DEFAULT_ABI == ABI_V4)
9324 || (flag_pic && DEFAULT_ABI == ABI_DARWIN))
1db02437
FS
9325 && info_ptr->first_gp_reg_save > RS6000_PIC_OFFSET_TABLE_REGNUM)
9326 info_ptr->gp_size = reg_size * (32 - RS6000_PIC_OFFSET_TABLE_REGNUM);
906fb125
GK
9327 else
9328 info_ptr->gp_size = reg_size * (32 - info_ptr->first_gp_reg_save);
4697a36c 9329
a3170dc6
AH
9330 /* For the SPE, we have an additional upper 32-bits on each GPR.
9331 Ideally we should save the entire 64-bits only when the upper
9332 half is used in SIMD instructions. Since we only record
9333 registers live (not the size they are used in), this proves
9334 difficult because we'd have to traverse the instruction chain at
9335 the right time, taking reload into account. This is a real pain,
c19de7aa
AH
9336 so we opt to save the GPRs in 64-bits always if but one register
9337 gets used in 64-bits. Otherwise, all the registers in the frame
9338 get saved in 32-bits.
a3170dc6 9339
c19de7aa 9340 So... since when we save all GPRs (except the SP) in 64-bits, the
a3170dc6 9341 traditional GP save area will be empty. */
c19de7aa 9342 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
9343 info_ptr->gp_size = 0;
9344
4697a36c
MM
9345 info_ptr->first_fp_reg_save = first_fp_reg_to_save ();
9346 info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save);
9347
00b960c7
AH
9348 info_ptr->first_altivec_reg_save = first_altivec_reg_to_save ();
9349 info_ptr->altivec_size = 16 * (LAST_ALTIVEC_REGNO + 1
9350 - info_ptr->first_altivec_reg_save);
9351
592696dd 9352 /* Does this function call anything? */
71f123ca
FS
9353 info_ptr->calls_p = (! current_function_is_leaf
9354 || cfun->machine->ra_needs_full_frame);
b6c9286a 9355
a4f6c312 9356 /* Determine if we need to save the link register. */
71f123ca 9357 if (rs6000_ra_ever_killed ()
ffcfcb5f
AM
9358 || (DEFAULT_ABI == ABI_AIX
9359 && current_function_profile
9360 && !TARGET_PROFILE_KERNEL)
4697a36c
MM
9361#ifdef TARGET_RELOCATABLE
9362 || (TARGET_RELOCATABLE && (get_pool_size () != 0))
9363#endif
9364 || (info_ptr->first_fp_reg_save != 64
9365 && !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
00b960c7 9366 || info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
178274da 9367 || (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
a4f6c312
SS
9368 || (DEFAULT_ABI == ABI_DARWIN
9369 && flag_pic
9370 && current_function_uses_pic_offset_table)
4697a36c
MM
9371 || info_ptr->calls_p)
9372 {
9373 info_ptr->lr_save_p = 1;
9ebbca7d 9374 regs_ever_live[LINK_REGISTER_REGNUM] = 1;
4697a36c
MM
9375 }
9376
9ebbca7d
GK
9377 /* Determine if we need to save the condition code registers. */
9378 if (regs_ever_live[CR2_REGNO]
9379 || regs_ever_live[CR3_REGNO]
9380 || regs_ever_live[CR4_REGNO])
4697a36c
MM
9381 {
9382 info_ptr->cr_save_p = 1;
178274da 9383 if (DEFAULT_ABI == ABI_V4)
4697a36c
MM
9384 info_ptr->cr_size = reg_size;
9385 }
9386
83720594
RH
9387 /* If the current function calls __builtin_eh_return, then we need
9388 to allocate stack space for registers that will hold data for
9389 the exception handler. */
9390 if (current_function_calls_eh_return)
9391 {
9392 unsigned int i;
9393 for (i = 0; EH_RETURN_DATA_REGNO (i) != INVALID_REGNUM; ++i)
9394 continue;
a3170dc6
AH
9395
9396 /* SPE saves EH registers in 64-bits. */
c19de7aa
AH
9397 ehrd_size = i * (TARGET_SPE_ABI
9398 && info_ptr->spe_64bit_regs_used != 0
9399 ? UNITS_PER_SPE_WORD : UNITS_PER_WORD);
83720594
RH
9400 }
9401 else
9402 ehrd_size = 0;
9403
592696dd 9404 /* Determine various sizes. */
4697a36c
MM
9405 info_ptr->reg_size = reg_size;
9406 info_ptr->fixed_size = RS6000_SAVE_AREA;
9407 info_ptr->varargs_size = RS6000_VARARGS_AREA;
189e03e3 9408 info_ptr->vars_size = RS6000_ALIGN (get_frame_size (), 8);
a4f6c312
SS
9409 info_ptr->parm_size = RS6000_ALIGN (current_function_outgoing_args_size,
9410 8);
00b960c7 9411
c19de7aa 9412 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
9413 info_ptr->spe_gp_size = 8 * (32 - info_ptr->first_gp_reg_save);
9414 else
9415 info_ptr->spe_gp_size = 0;
9416
08b57fb3 9417 if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
00b960c7
AH
9418 {
9419 info_ptr->vrsave_mask = compute_vrsave_mask ();
9420 info_ptr->vrsave_size = info_ptr->vrsave_mask ? 4 : 0;
9421 }
9422 else
9423 {
9424 info_ptr->vrsave_mask = 0;
9425 info_ptr->vrsave_size = 0;
9426 }
b6c9286a 9427
592696dd 9428 /* Calculate the offsets. */
178274da 9429 switch (DEFAULT_ABI)
4697a36c 9430 {
b6c9286a 9431 case ABI_NONE:
24d304eb 9432 default:
b6c9286a
MM
9433 abort ();
9434
9435 case ABI_AIX:
9436 case ABI_AIX_NODESC:
ee890fe2 9437 case ABI_DARWIN:
b6c9286a
MM
9438 info_ptr->fp_save_offset = - info_ptr->fp_size;
9439 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
00b960c7
AH
9440
9441 if (TARGET_ALTIVEC_ABI)
9442 {
9443 info_ptr->vrsave_save_offset
9444 = info_ptr->gp_save_offset - info_ptr->vrsave_size;
9445
9446 /* Align stack so vector save area is on a quadword boundary. */
9447 if (info_ptr->altivec_size != 0)
9448 info_ptr->altivec_padding_size
9449 = 16 - (-info_ptr->vrsave_save_offset % 16);
9450 else
9451 info_ptr->altivec_padding_size = 0;
9452
9453 info_ptr->altivec_save_offset
9454 = info_ptr->vrsave_save_offset
9455 - info_ptr->altivec_padding_size
9456 - info_ptr->altivec_size;
9457
9458 /* Adjust for AltiVec case. */
9459 info_ptr->ehrd_offset = info_ptr->altivec_save_offset - ehrd_size;
9460 }
9461 else
9462 info_ptr->ehrd_offset = info_ptr->gp_save_offset - ehrd_size;
a260abc9
DE
9463 info_ptr->cr_save_offset = reg_size; /* first word when 64-bit. */
9464 info_ptr->lr_save_offset = 2*reg_size;
24d304eb
RK
9465 break;
9466
9467 case ABI_V4:
b6c9286a
MM
9468 info_ptr->fp_save_offset = - info_ptr->fp_size;
9469 info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
a7df97e6 9470 info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
00b960c7 9471
c19de7aa 9472 if (TARGET_SPE_ABI && info_ptr->spe_64bit_regs_used != 0)
a3170dc6
AH
9473 {
9474 /* Align stack so SPE GPR save area is aligned on a
9475 double-word boundary. */
9476 if (info_ptr->spe_gp_size != 0)
9477 info_ptr->spe_padding_size
9478 = 8 - (-info_ptr->cr_save_offset % 8);
9479 else
9480 info_ptr->spe_padding_size = 0;
9481
9482 info_ptr->spe_gp_save_offset
9483 = info_ptr->cr_save_offset
9484 - info_ptr->spe_padding_size
9485 - info_ptr->spe_gp_size;
9486
9487 /* Adjust for SPE case. */
9488 info_ptr->toc_save_offset
9489 = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
9490 }
9491 else if (TARGET_ALTIVEC_ABI)
00b960c7
AH
9492 {
9493 info_ptr->vrsave_save_offset
9494 = info_ptr->cr_save_offset - info_ptr->vrsave_size;
9495
9496 /* Align stack so vector save area is on a quadword boundary. */
9497 if (info_ptr->altivec_size != 0)
9498 info_ptr->altivec_padding_size
9499 = 16 - (-info_ptr->vrsave_save_offset % 16);
9500 else
9501 info_ptr->altivec_padding_size = 0;
9502
9503 info_ptr->altivec_save_offset
9504 = info_ptr->vrsave_save_offset
9505 - info_ptr->altivec_padding_size
9506 - info_ptr->altivec_size;
9507
9508 /* Adjust for AltiVec case. */
9509 info_ptr->toc_save_offset
9510 = info_ptr->altivec_save_offset - info_ptr->toc_size;
9511 }
9512 else
9513 info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
83720594 9514 info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
b6c9286a
MM
9515 info_ptr->lr_save_offset = reg_size;
9516 break;
4697a36c
MM
9517 }
9518
00b960c7
AH
9519 info_ptr->save_size = RS6000_ALIGN (info_ptr->fp_size
9520 + info_ptr->gp_size
9521 + info_ptr->altivec_size
9522 + info_ptr->altivec_padding_size
9523 + info_ptr->vrsave_size
a3170dc6
AH
9524 + info_ptr->spe_gp_size
9525 + info_ptr->spe_padding_size
00b960c7
AH
9526 + ehrd_size
9527 + info_ptr->cr_size
9528 + info_ptr->lr_size
9529 + info_ptr->vrsave_size
9530 + info_ptr->toc_size,
9531 (TARGET_ALTIVEC_ABI || ABI_DARWIN)
9532 ? 16 : 8);
9533
ff381587
MM
9534 total_raw_size = (info_ptr->vars_size
9535 + info_ptr->parm_size
ff381587
MM
9536 + info_ptr->save_size
9537 + info_ptr->varargs_size
9538 + info_ptr->fixed_size);
9539
a4f6c312
SS
9540 info_ptr->total_size =
9541 RS6000_ALIGN (total_raw_size, ABI_STACK_BOUNDARY / BITS_PER_UNIT);
ff381587
MM
9542
9543 /* Determine if we need to allocate any stack frame:
9544
a4f6c312
SS
9545 For AIX we need to push the stack if a frame pointer is needed
9546 (because the stack might be dynamically adjusted), if we are
9547 debugging, if we make calls, or if the sum of fp_save, gp_save,
9548 and local variables are more than the space needed to save all
9549 non-volatile registers: 32-bit: 18*8 + 19*4 = 220 or 64-bit: 18*8
9550 + 18*8 = 288 (GPR13 reserved).
ff381587 9551
a4f6c312
SS
9552 For V.4 we don't have the stack cushion that AIX uses, but assume
9553 that the debugger can handle stackless frames. */
ff381587
MM
9554
9555 if (info_ptr->calls_p)
9556 info_ptr->push_p = 1;
9557
178274da 9558 else if (DEFAULT_ABI == ABI_V4)
e72247f4 9559 info_ptr->push_p = total_raw_size > info_ptr->fixed_size;
ff381587 9560
178274da
AM
9561 else if (frame_pointer_needed)
9562 info_ptr->push_p = 1;
9563
9564 else if (TARGET_XCOFF && write_symbols != NO_DEBUG)
9565 info_ptr->push_p = 1;
9566
ff381587 9567 else
178274da
AM
9568 info_ptr->push_p
9569 = total_raw_size - info_ptr->fixed_size > (TARGET_32BIT ? 220 : 288);
ff381587 9570
a4f6c312 9571 /* Zero offsets if we're not saving those registers. */
8dda1a21 9572 if (info_ptr->fp_size == 0)
4697a36c
MM
9573 info_ptr->fp_save_offset = 0;
9574
8dda1a21 9575 if (info_ptr->gp_size == 0)
4697a36c
MM
9576 info_ptr->gp_save_offset = 0;
9577
00b960c7
AH
9578 if (! TARGET_ALTIVEC_ABI || info_ptr->altivec_size == 0)
9579 info_ptr->altivec_save_offset = 0;
9580
9581 if (! TARGET_ALTIVEC_ABI || info_ptr->vrsave_mask == 0)
9582 info_ptr->vrsave_save_offset = 0;
9583
c19de7aa
AH
9584 if (! TARGET_SPE_ABI
9585 || info_ptr->spe_64bit_regs_used == 0
9586 || info_ptr->spe_gp_size == 0)
a3170dc6
AH
9587 info_ptr->spe_gp_save_offset = 0;
9588
c81fc13e 9589 if (! info_ptr->lr_save_p)
4697a36c
MM
9590 info_ptr->lr_save_offset = 0;
9591
c81fc13e 9592 if (! info_ptr->cr_save_p)
4697a36c
MM
9593 info_ptr->cr_save_offset = 0;
9594
c81fc13e 9595 if (! info_ptr->toc_save_p)
b6c9286a
MM
9596 info_ptr->toc_save_offset = 0;
9597
4697a36c
MM
9598 return info_ptr;
9599}
9600
c19de7aa
AH
9601/* Return true if the current function uses any GPRs in 64-bit SIMD
9602 mode. */
9603
9604static bool
9605spe_func_has_64bit_regs_p ()
9606{
9607 rtx insns, insn;
9608
9609 /* Functions that save and restore all the call-saved registers will
9610 need to save/restore the registers in 64-bits. */
9611 if (current_function_calls_eh_return
9612 || current_function_calls_setjmp
9613 || current_function_has_nonlocal_goto)
9614 return true;
9615
9616 insns = get_insns ();
9617
9618 for (insn = NEXT_INSN (insns); insn != NULL_RTX; insn = NEXT_INSN (insn))
9619 {
9620 if (INSN_P (insn))
9621 {
9622 rtx i;
9623
9624 i = PATTERN (insn);
9625 if (GET_CODE (i) == SET
9626 && SPE_VECTOR_MODE (GET_MODE (SET_SRC (i))))
9627 return true;
9628 }
9629 }
9630
9631 return false;
9632}
9633
4697a36c
MM
9634void
9635debug_stack_info (info)
9636 rs6000_stack_t *info;
9878760c 9637{
d330fd93 9638 const char *abi_string;
24d304eb 9639
c81fc13e 9640 if (! info)
4697a36c
MM
9641 info = rs6000_stack_info ();
9642
9643 fprintf (stderr, "\nStack information for function %s:\n",
9644 ((current_function_decl && DECL_NAME (current_function_decl))
9645 ? IDENTIFIER_POINTER (DECL_NAME (current_function_decl))
9646 : "<unknown>"));
9647
24d304eb
RK
9648 switch (info->abi)
9649 {
b6c9286a
MM
9650 default: abi_string = "Unknown"; break;
9651 case ABI_NONE: abi_string = "NONE"; break;
f607bc57 9652 case ABI_AIX:
b6c9286a 9653 case ABI_AIX_NODESC: abi_string = "AIX"; break;
ee890fe2 9654 case ABI_DARWIN: abi_string = "Darwin"; break;
b6c9286a 9655 case ABI_V4: abi_string = "V.4"; break;
24d304eb
RK
9656 }
9657
9658 fprintf (stderr, "\tABI = %5s\n", abi_string);
9659
00b960c7
AH
9660 if (TARGET_ALTIVEC_ABI)
9661 fprintf (stderr, "\tALTIVEC ABI extensions enabled.\n");
9662
a3170dc6
AH
9663 if (TARGET_SPE_ABI)
9664 fprintf (stderr, "\tSPE ABI extensions enabled.\n");
9665
4697a36c
MM
9666 if (info->first_gp_reg_save != 32)
9667 fprintf (stderr, "\tfirst_gp_reg_save = %5d\n", info->first_gp_reg_save);
9668
9669 if (info->first_fp_reg_save != 64)
9670 fprintf (stderr, "\tfirst_fp_reg_save = %5d\n", info->first_fp_reg_save);
9878760c 9671
00b960c7
AH
9672 if (info->first_altivec_reg_save <= LAST_ALTIVEC_REGNO)
9673 fprintf (stderr, "\tfirst_altivec_reg_save = %5d\n",
9674 info->first_altivec_reg_save);
9675
4697a36c
MM
9676 if (info->lr_save_p)
9677 fprintf (stderr, "\tlr_save_p = %5d\n", info->lr_save_p);
9878760c 9678
4697a36c
MM
9679 if (info->cr_save_p)
9680 fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
9681
b6c9286a
MM
9682 if (info->toc_save_p)
9683 fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
9684
00b960c7
AH
9685 if (info->vrsave_mask)
9686 fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
9687
4697a36c
MM
9688 if (info->push_p)
9689 fprintf (stderr, "\tpush_p = %5d\n", info->push_p);
9690
9691 if (info->calls_p)
9692 fprintf (stderr, "\tcalls_p = %5d\n", info->calls_p);
9693
4697a36c
MM
9694 if (info->gp_save_offset)
9695 fprintf (stderr, "\tgp_save_offset = %5d\n", info->gp_save_offset);
9696
9697 if (info->fp_save_offset)
9698 fprintf (stderr, "\tfp_save_offset = %5d\n", info->fp_save_offset);
9699
00b960c7
AH
9700 if (info->altivec_save_offset)
9701 fprintf (stderr, "\taltivec_save_offset = %5d\n",
9702 info->altivec_save_offset);
9703
a3170dc6
AH
9704 if (info->spe_gp_save_offset)
9705 fprintf (stderr, "\tspe_gp_save_offset = %5d\n",
9706 info->spe_gp_save_offset);
9707
00b960c7
AH
9708 if (info->vrsave_save_offset)
9709 fprintf (stderr, "\tvrsave_save_offset = %5d\n",
9710 info->vrsave_save_offset);
9711
4697a36c
MM
9712 if (info->lr_save_offset)
9713 fprintf (stderr, "\tlr_save_offset = %5d\n", info->lr_save_offset);
9714
9715 if (info->cr_save_offset)
9716 fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
9717
b6c9286a
MM
9718 if (info->toc_save_offset)
9719 fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
9720
4697a36c
MM
9721 if (info->varargs_save_offset)
9722 fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
9723
9724 if (info->total_size)
9725 fprintf (stderr, "\ttotal_size = %5d\n", info->total_size);
9726
9727 if (info->varargs_size)
9728 fprintf (stderr, "\tvarargs_size = %5d\n", info->varargs_size);
9729
9730 if (info->vars_size)
9731 fprintf (stderr, "\tvars_size = %5d\n", info->vars_size);
9732
9733 if (info->parm_size)
9734 fprintf (stderr, "\tparm_size = %5d\n", info->parm_size);
9735
9736 if (info->fixed_size)
9737 fprintf (stderr, "\tfixed_size = %5d\n", info->fixed_size);
9738
9739 if (info->gp_size)
9740 fprintf (stderr, "\tgp_size = %5d\n", info->gp_size);
9741
a3170dc6
AH
9742 if (info->spe_gp_size)
9743 fprintf (stderr, "\tspe_gp_size = %5d\n", info->spe_gp_size);
9744
4697a36c
MM
9745 if (info->fp_size)
9746 fprintf (stderr, "\tfp_size = %5d\n", info->fp_size);
9747
00b960c7
AH
9748 if (info->altivec_size)
9749 fprintf (stderr, "\taltivec_size = %5d\n", info->altivec_size);
9750
9751 if (info->vrsave_size)
9752 fprintf (stderr, "\tvrsave_size = %5d\n", info->vrsave_size);
9753
9754 if (info->altivec_padding_size)
9755 fprintf (stderr, "\taltivec_padding_size= %5d\n",
9756 info->altivec_padding_size);
9757
a3170dc6
AH
9758 if (info->spe_padding_size)
9759 fprintf (stderr, "\tspe_padding_size = %5d\n",
9760 info->spe_padding_size);
9761
a4f6c312 9762 if (info->lr_size)
ed947a96 9763 fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
b6c9286a 9764
4697a36c
MM
9765 if (info->cr_size)
9766 fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
9767
a4f6c312 9768 if (info->toc_size)
b6c9286a
MM
9769 fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
9770
4697a36c
MM
9771 if (info->save_size)
9772 fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
9773
9774 if (info->reg_size != 4)
9775 fprintf (stderr, "\treg_size = %5d\n", info->reg_size);
9776
9777 fprintf (stderr, "\n");
9878760c 9778}
71f123ca
FS
9779
9780rtx
9781rs6000_return_addr (count, frame)
9782 int count;
9783 rtx frame;
9784{
a4f6c312
SS
9785 /* Currently we don't optimize very well between prolog and body
9786 code and for PIC code the code can be actually quite bad, so
9787 don't try to be too clever here. */
f1384257 9788 if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic))
71f123ca
FS
9789 {
9790 cfun->machine->ra_needs_full_frame = 1;
8ac61af7
RK
9791
9792 return
9793 gen_rtx_MEM
9794 (Pmode,
9795 memory_address
9796 (Pmode,
9797 plus_constant (copy_to_reg
9798 (gen_rtx_MEM (Pmode,
9799 memory_address (Pmode, frame))),
9800 RETURN_ADDRESS_OFFSET)));
71f123ca
FS
9801 }
9802
9e2f7ec7 9803 return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM);
71f123ca
FS
9804}
9805
5e1bf043
DJ
9806/* Say whether a function is a candidate for sibcall handling or not.
9807 We do not allow indirect calls to be optimized into sibling calls.
9808 Also, we can't do it if there are any vector parameters; there's
9809 nowhere to put the VRsave code so it works; note that functions with
9810 vector parameters are required to have a prototype, so the argument
9811 type info must be available here. (The tail recursion case can work
9812 with vector parameters, but there's no way to distinguish here.) */
4977bab6
ZW
9813static bool
9814rs6000_function_ok_for_sibcall (decl, exp)
9815 tree decl;
9816 tree exp ATTRIBUTE_UNUSED;
5e1bf043
DJ
9817{
9818 tree type;
4977bab6 9819 if (decl)
5e1bf043
DJ
9820 {
9821 if (TARGET_ALTIVEC_VRSAVE)
9822 {
4977bab6 9823 for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
5e1bf043
DJ
9824 type; type = TREE_CHAIN (type))
9825 {
c15b529f 9826 if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
4977bab6 9827 return false;
5e1bf043
DJ
9828 }
9829 }
9830 if (DEFAULT_ABI == ABI_DARWIN
4977bab6 9831 || (*targetm.binds_local_p) (decl))
2bcc50d0 9832 {
4977bab6 9833 tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
2bcc50d0
AM
9834
9835 if (!lookup_attribute ("longcall", attr_list)
9836 || lookup_attribute ("shortcall", attr_list))
4977bab6 9837 return true;
2bcc50d0 9838 }
5e1bf043 9839 }
4977bab6 9840 return false;
5e1bf043
DJ
9841}
9842
71f123ca
FS
9843static int
9844rs6000_ra_ever_killed ()
9845{
9846 rtx top;
5e1bf043
DJ
9847 rtx reg;
9848 rtx insn;
71f123ca 9849
3961e8fe
RH
9850 /* Irritatingly, there are two kinds of thunks -- those created with
9851 TARGET_ASM_OUTPUT_MI_THUNK and those with DECL_THUNK_P that go
9852 through the regular part of the compiler. This is a very hacky
9853 way to tell them apart. */
9854 if (current_function_is_thunk && !no_new_pseudos)
71f123ca 9855 return 0;
eb0424da 9856
36f7e964
AH
9857 /* regs_ever_live has LR marked as used if any sibcalls are present,
9858 but this should not force saving and restoring in the
9859 pro/epilogue. Likewise, reg_set_between_p thinks a sibcall
9860 clobbers LR, so that is inappropriate. */
9861
5e1bf043
DJ
9862 /* Also, the prologue can generate a store into LR that
9863 doesn't really count, like this:
36f7e964 9864
5e1bf043
DJ
9865 move LR->R0
9866 bcl to set PIC register
9867 move LR->R31
9868 move R0->LR
36f7e964
AH
9869
9870 When we're called from the epilogue, we need to avoid counting
9871 this as a store. */
5e1bf043 9872
71f123ca
FS
9873 push_topmost_sequence ();
9874 top = get_insns ();
9875 pop_topmost_sequence ();
5e1bf043 9876 reg = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
71f123ca 9877
5e1bf043
DJ
9878 for (insn = NEXT_INSN (top); insn != NULL_RTX; insn = NEXT_INSN (insn))
9879 {
9880 if (INSN_P (insn))
9881 {
9882 if (FIND_REG_INC_NOTE (insn, reg))
9883 return 1;
9884 else if (GET_CODE (insn) == CALL_INSN
c15b529f 9885 && !SIBLING_CALL_P (insn))
5e1bf043 9886 return 1;
36f7e964
AH
9887 else if (set_of (reg, insn) != NULL_RTX
9888 && !prologue_epilogue_contains (insn))
5e1bf043
DJ
9889 return 1;
9890 }
9891 }
9892 return 0;
71f123ca 9893}
4697a36c 9894\f
8cd8f856
GK
9895/* Add a REG_MAYBE_DEAD note to the insn. */
9896static void
9897rs6000_maybe_dead (insn)
9898 rtx insn;
9899{
9900 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD,
9901 const0_rtx,
9902 REG_NOTES (insn));
9903}
9904
9ebbca7d 9905/* Emit instructions needed to load the TOC register.
c7ca610e 9906 This is only needed when TARGET_TOC, TARGET_MINIMAL_TOC, and there is
9ebbca7d 9907 a constant pool; or for SVR4 -fpic. */
c7ca610e
RK
9908
9909void
9ebbca7d
GK
9910rs6000_emit_load_toc_table (fromprolog)
9911 int fromprolog;
c7ca610e 9912{
027fbf43 9913 rtx dest, insn;
1db02437 9914 dest = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
c7ca610e 9915
20b71b17
AM
9916 if (TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 1)
9917 {
9918 rtx temp = (fromprolog
9919 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9920 : gen_reg_rtx (Pmode));
027fbf43
JJ
9921 insn = emit_insn (gen_load_toc_v4_pic_si (temp));
9922 if (fromprolog)
9923 rs6000_maybe_dead (insn);
9924 insn = emit_move_insn (dest, temp);
9925 if (fromprolog)
9926 rs6000_maybe_dead (insn);
20b71b17
AM
9927 }
9928 else if (TARGET_ELF && DEFAULT_ABI != ABI_AIX && flag_pic == 2)
9929 {
9930 char buf[30];
9931 rtx tempLR = (fromprolog
9932 ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)
9933 : gen_reg_rtx (Pmode));
9934 rtx temp0 = (fromprolog
9935 ? gen_rtx_REG (Pmode, 0)
9936 : gen_reg_rtx (Pmode));
9937 rtx symF;
9938
9939 /* possibly create the toc section */
9940 if (! toc_initialized)
38c1f2d7 9941 {
20b71b17
AM
9942 toc_section ();
9943 function_section (current_function_decl);
38c1f2d7 9944 }
9ebbca7d 9945
20b71b17
AM
9946 if (fromprolog)
9947 {
9948 rtx symL;
38c1f2d7 9949
20b71b17
AM
9950 ASM_GENERATE_INTERNAL_LABEL (buf, "LCF", rs6000_pic_labelno);
9951 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9ebbca7d 9952
20b71b17
AM
9953 ASM_GENERATE_INTERNAL_LABEL (buf, "LCL", rs6000_pic_labelno);
9954 symL = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9955
9956 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_1 (tempLR,
9957 symF)));
9958 rs6000_maybe_dead (emit_move_insn (dest, tempLR));
9959 rs6000_maybe_dead (emit_insn (gen_load_toc_v4_PIC_2 (temp0, dest,
9960 symL,
9961 symF)));
9ebbca7d
GK
9962 }
9963 else
20b71b17
AM
9964 {
9965 rtx tocsym;
9966 static int reload_toc_labelno = 0;
9967
9968 tocsym = gen_rtx_SYMBOL_REF (Pmode, toc_label_name);
9969
9970 ASM_GENERATE_INTERNAL_LABEL (buf, "LCG", reload_toc_labelno++);
9971 symF = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9972
027fbf43
JJ
9973 emit_insn (gen_load_toc_v4_PIC_1b (tempLR, symF, tocsym));
9974 emit_move_insn (dest, tempLR);
9975 emit_move_insn (temp0, gen_rtx_MEM (Pmode, dest));
20b71b17 9976 }
027fbf43
JJ
9977 insn = emit_insn (gen_addsi3 (dest, temp0, dest));
9978 if (fromprolog)
9979 rs6000_maybe_dead (insn);
9ebbca7d 9980 }
20b71b17
AM
9981 else if (TARGET_ELF && !TARGET_AIX && flag_pic == 0 && TARGET_MINIMAL_TOC)
9982 {
9983 /* This is for AIX code running in non-PIC ELF32. */
9984 char buf[30];
9985 rtx realsym;
9986 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9987 realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9988
027fbf43
JJ
9989 insn = emit_insn (gen_elf_high (dest, realsym));
9990 if (fromprolog)
9991 rs6000_maybe_dead (insn);
9992 insn = emit_insn (gen_elf_low (dest, dest, realsym));
9993 if (fromprolog)
9994 rs6000_maybe_dead (insn);
20b71b17
AM
9995 }
9996 else if (DEFAULT_ABI == ABI_AIX)
9ebbca7d
GK
9997 {
9998 if (TARGET_32BIT)
027fbf43 9999 insn = emit_insn (gen_load_toc_aix_si (dest));
9ebbca7d 10000 else
027fbf43
JJ
10001 insn = emit_insn (gen_load_toc_aix_di (dest));
10002 if (fromprolog)
10003 rs6000_maybe_dead (insn);
9ebbca7d 10004 }
20b71b17
AM
10005 else
10006 abort ();
9ebbca7d
GK
10007}
10008
10009int
10010get_TOC_alias_set ()
10011{
10012 static int set = -1;
10013 if (set == -1)
10014 set = new_alias_set ();
10015 return set;
10016}
10017
10018/* This retuns nonzero if the current function uses the TOC. This is
10019 determined by the presence of (unspec ... 7), which is generated by
10020 the various load_toc_* patterns. */
a4f6c312 10021
9ebbca7d
GK
10022int
10023uses_TOC ()
10024{
10025 rtx insn;
38c1f2d7 10026
9ebbca7d 10027 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
2c3c49de 10028 if (INSN_P (insn))
9ebbca7d
GK
10029 {
10030 rtx pat = PATTERN (insn);
10031 int i;
10032
8cd8f856 10033 if (GET_CODE (pat) == PARALLEL)
9ebbca7d
GK
10034 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
10035 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == UNSPEC
10036 && XINT (XVECEXP (PATTERN (insn), 0, i), 1) == 7)
10037 return 1;
38c1f2d7 10038 }
9ebbca7d
GK
10039 return 0;
10040}
38c1f2d7 10041
9ebbca7d 10042rtx
a4f6c312 10043create_TOC_reference (symbol)
9ebbca7d
GK
10044 rtx symbol;
10045{
a8a05998
ZW
10046 return gen_rtx_PLUS (Pmode,
10047 gen_rtx_REG (Pmode, TOC_REGISTER),
10048 gen_rtx_CONST (Pmode,
10049 gen_rtx_MINUS (Pmode, symbol,
b999aaeb 10050 gen_rtx_SYMBOL_REF (Pmode, toc_label_name))));
9ebbca7d 10051}
38c1f2d7 10052
9ebbca7d
GK
10053#if TARGET_AIX
10054/* __throw will restore its own return address to be the same as the
10055 return address of the function that the throw is being made to.
10056 This is unfortunate, because we want to check the original
10057 return address to see if we need to restore the TOC.
10058 So we have to squirrel it away here.
10059 This is used only in compiling __throw and __rethrow.
c7ca610e 10060
9ebbca7d
GK
10061 Most of this code should be removed by CSE. */
10062static rtx insn_after_throw;
c7ca610e 10063
a4f6c312 10064/* This does the saving... */
9ebbca7d
GK
10065void
10066rs6000_aix_emit_builtin_unwind_init ()
10067{
10068 rtx mem;
10069 rtx stack_top = gen_reg_rtx (Pmode);
10070 rtx opcode_addr = gen_reg_rtx (Pmode);
10071
10072 insn_after_throw = gen_reg_rtx (SImode);
10073
10074 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
10075 emit_move_insn (stack_top, mem);
10076
10077 mem = gen_rtx_MEM (Pmode,
10078 gen_rtx_PLUS (Pmode, stack_top,
10079 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
10080 emit_move_insn (opcode_addr, mem);
10081 emit_move_insn (insn_after_throw, gen_rtx_MEM (SImode, opcode_addr));
c7ca610e
RK
10082}
10083
a4f6c312
SS
10084/* Emit insns to _restore_ the TOC register, at runtime (specifically
10085 in _eh.o). Only used on AIX.
9ebbca7d
GK
10086
10087 The idea is that on AIX, function calls look like this:
10088 bl somefunction-trampoline
10089 lwz r2,20(sp)
10090
a4f6c312 10091 and later,
9ebbca7d
GK
10092 somefunction-trampoline:
10093 stw r2,20(sp)
10094 ... load function address in the count register ...
10095 bctr
10096 or like this, if the linker determines that this is not a cross-module call
10097 and so the TOC need not be restored:
10098 bl somefunction
10099 nop
10100 or like this, if the compiler could determine that this is not a
10101 cross-module call:
10102 bl somefunction
10103 now, the tricky bit here is that register 2 is saved and restored
10104 by the _linker_, so we can't readily generate debugging information
10105 for it. So we need to go back up the call chain looking at the
10106 insns at return addresses to see which calls saved the TOC register
10107 and so see where it gets restored from.
10108
10109 Oh, and all this gets done in RTL inside the eh_epilogue pattern,
10110 just before the actual epilogue.
10111
10112 On the bright side, this incurs no space or time overhead unless an
10113 exception is thrown, except for the extra code in libgcc.a.
10114
10115 The parameter STACKSIZE is a register containing (at runtime)
10116 the amount to be popped off the stack in addition to the stack frame
10117 of this routine (which will be __throw or __rethrow, and so is
10118 guaranteed to have a stack frame). */
a4f6c312 10119
9ebbca7d
GK
10120void
10121rs6000_emit_eh_toc_restore (stacksize)
10122 rtx stacksize;
10123{
10124 rtx top_of_stack;
10125 rtx bottom_of_stack = gen_reg_rtx (Pmode);
10126 rtx tocompare = gen_reg_rtx (SImode);
10127 rtx opcode = gen_reg_rtx (SImode);
10128 rtx opcode_addr = gen_reg_rtx (Pmode);
10129 rtx mem;
10130 rtx loop_start = gen_label_rtx ();
10131 rtx no_toc_restore_needed = gen_label_rtx ();
10132 rtx loop_exit = gen_label_rtx ();
10133
10134 mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
ba4828e0 10135 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10136 emit_move_insn (bottom_of_stack, mem);
10137
10138 top_of_stack = expand_binop (Pmode, add_optab,
10139 bottom_of_stack, stacksize,
10140 NULL_RTX, 1, OPTAB_WIDEN);
10141
2496c7bd
LB
10142 emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
10143 : 0xE8410028, SImode));
9ebbca7d
GK
10144
10145 if (insn_after_throw == NULL_RTX)
a4f6c312 10146 abort ();
9ebbca7d
GK
10147 emit_move_insn (opcode, insn_after_throw);
10148
6496a589 10149 emit_note (NULL, NOTE_INSN_LOOP_BEG);
9ebbca7d
GK
10150 emit_label (loop_start);
10151
10152 do_compare_rtx_and_jump (opcode, tocompare, NE, 1,
06f4e019 10153 SImode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
10154 no_toc_restore_needed);
10155
10156 mem = gen_rtx_MEM (Pmode,
10157 gen_rtx_PLUS (Pmode, bottom_of_stack,
10158 GEN_INT (5 * GET_MODE_SIZE (Pmode))));
10159 emit_move_insn (gen_rtx_REG (Pmode, 2), mem);
10160
10161 emit_label (no_toc_restore_needed);
10162 do_compare_rtx_and_jump (top_of_stack, bottom_of_stack, EQ, 1,
06f4e019 10163 Pmode, NULL_RTX, NULL_RTX,
9ebbca7d
GK
10164 loop_exit);
10165
10166 mem = gen_rtx_MEM (Pmode, bottom_of_stack);
ba4828e0 10167 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10168 emit_move_insn (bottom_of_stack, mem);
10169
10170 mem = gen_rtx_MEM (Pmode,
10171 gen_rtx_PLUS (Pmode, bottom_of_stack,
10172 GEN_INT (2 * GET_MODE_SIZE (Pmode))));
10173 emit_move_insn (opcode_addr, mem);
10174 emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
10175
6496a589 10176 emit_note (NULL, NOTE_INSN_LOOP_CONT);
9ebbca7d 10177 emit_jump (loop_start);
6496a589 10178 emit_note (NULL, NOTE_INSN_LOOP_END);
9ebbca7d
GK
10179 emit_label (loop_exit);
10180}
10181#endif /* TARGET_AIX */
38c1f2d7 10182\f
ba4828e0
RK
10183/* This ties together stack memory (MEM with an alias set of
10184 rs6000_sr_alias_set) and the change to the stack pointer. */
10185
9ebbca7d
GK
10186static void
10187rs6000_emit_stack_tie ()
10188{
ba4828e0
RK
10189 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM));
10190
10191 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10192 emit_insn (gen_stack_tie (mem));
10193}
38c1f2d7 10194
9ebbca7d
GK
10195/* Emit the correct code for allocating stack space, as insns.
10196 If COPY_R12, make sure a copy of the old frame is left in r12.
10197 The generated code may use hard register 0 as a temporary. */
10198
10199static void
10200rs6000_emit_allocate_stack (size, copy_r12)
10201 HOST_WIDE_INT size;
38c1f2d7
MM
10202 int copy_r12;
10203{
9ebbca7d
GK
10204 rtx insn;
10205 rtx stack_reg = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10206 rtx tmp_reg = gen_rtx_REG (Pmode, 0);
10207 rtx todec = GEN_INT (-size);
a157febd
GK
10208
10209 if (current_function_limit_stack)
10210 {
10211 if (REG_P (stack_limit_rtx)
10212 && REGNO (stack_limit_rtx) > 1
10213 && REGNO (stack_limit_rtx) <= 31)
10214 {
5b71a4e7 10215 emit_insn (TARGET_32BIT
9ebbca7d
GK
10216 ? gen_addsi3 (tmp_reg,
10217 stack_limit_rtx,
10218 GEN_INT (size))
10219 : gen_adddi3 (tmp_reg,
10220 stack_limit_rtx,
10221 GEN_INT (size)));
5b71a4e7 10222
9ebbca7d
GK
10223 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
10224 const0_rtx));
a157febd
GK
10225 }
10226 else if (GET_CODE (stack_limit_rtx) == SYMBOL_REF
9ebbca7d 10227 && TARGET_32BIT
f607bc57 10228 && DEFAULT_ABI == ABI_V4)
a157febd 10229 {
9ebbca7d
GK
10230 rtx toload = gen_rtx_CONST (VOIDmode,
10231 gen_rtx_PLUS (Pmode,
10232 stack_limit_rtx,
10233 GEN_INT (size)));
5b71a4e7 10234
9ebbca7d
GK
10235 emit_insn (gen_elf_high (tmp_reg, toload));
10236 emit_insn (gen_elf_low (tmp_reg, tmp_reg, toload));
10237 emit_insn (gen_cond_trap (LTU, stack_reg, tmp_reg,
10238 const0_rtx));
a157febd
GK
10239 }
10240 else
10241 warning ("stack limit expression is not supported");
10242 }
10243
9ebbca7d
GK
10244 if (copy_r12 || ! TARGET_UPDATE)
10245 emit_move_insn (gen_rtx_REG (Pmode, 12), stack_reg);
10246
38c1f2d7
MM
10247 if (TARGET_UPDATE)
10248 {
9ebbca7d 10249 if (size > 32767)
38c1f2d7 10250 {
9ebbca7d
GK
10251 /* Need a note here so that try_split doesn't get confused. */
10252 if (get_last_insn() == NULL_RTX)
10253 emit_note (0, NOTE_INSN_DELETED);
10254 insn = emit_move_insn (tmp_reg, todec);
10255 try_split (PATTERN (insn), insn, 0);
10256 todec = tmp_reg;
38c1f2d7 10257 }
5b71a4e7
DE
10258
10259 insn = emit_insn (TARGET_32BIT
10260 ? gen_movsi_update (stack_reg, stack_reg,
10261 todec, stack_reg)
10262 : gen_movdi_update (stack_reg, stack_reg,
9ebbca7d 10263 todec, stack_reg));
38c1f2d7
MM
10264 }
10265 else
10266 {
5b71a4e7
DE
10267 insn = emit_insn (TARGET_32BIT
10268 ? gen_addsi3 (stack_reg, stack_reg, todec)
10269 : gen_adddi3 (stack_reg, stack_reg, todec));
9ebbca7d
GK
10270 emit_move_insn (gen_rtx_MEM (Pmode, stack_reg),
10271 gen_rtx_REG (Pmode, 12));
10272 }
5b71a4e7 10273
9ebbca7d
GK
10274 RTX_FRAME_RELATED_P (insn) = 1;
10275 REG_NOTES (insn) =
10276 gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10277 gen_rtx_SET (VOIDmode, stack_reg,
10278 gen_rtx_PLUS (Pmode, stack_reg,
10279 GEN_INT (-size))),
10280 REG_NOTES (insn));
10281}
10282
a4f6c312
SS
10283/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
10284 with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
10285 is not NULL. It would be nice if dwarf2out_frame_debug_expr could
10286 deduce these equivalences by itself so it wasn't necessary to hold
10287 its hand so much. */
9ebbca7d
GK
10288
10289static void
10290rs6000_frame_related (insn, reg, val, reg2, rreg)
10291 rtx insn;
10292 rtx reg;
10293 HOST_WIDE_INT val;
10294 rtx reg2;
10295 rtx rreg;
10296{
10297 rtx real, temp;
10298
e56c4463
JL
10299 /* copy_rtx will not make unique copies of registers, so we need to
10300 ensure we don't have unwanted sharing here. */
10301 if (reg == reg2)
10302 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10303
10304 if (reg == rreg)
10305 reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
10306
9ebbca7d
GK
10307 real = copy_rtx (PATTERN (insn));
10308
89e7058f
AH
10309 if (reg2 != NULL_RTX)
10310 real = replace_rtx (real, reg2, rreg);
10311
9ebbca7d
GK
10312 real = replace_rtx (real, reg,
10313 gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
10314 STACK_POINTER_REGNUM),
10315 GEN_INT (val)));
10316
10317 /* We expect that 'real' is either a SET or a PARALLEL containing
10318 SETs (and possibly other stuff). In a PARALLEL, all the SETs
10319 are important so they all have to be marked RTX_FRAME_RELATED_P. */
10320
10321 if (GET_CODE (real) == SET)
10322 {
10323 rtx set = real;
10324
10325 temp = simplify_rtx (SET_SRC (set));
10326 if (temp)
10327 SET_SRC (set) = temp;
10328 temp = simplify_rtx (SET_DEST (set));
10329 if (temp)
10330 SET_DEST (set) = temp;
10331 if (GET_CODE (SET_DEST (set)) == MEM)
38c1f2d7 10332 {
9ebbca7d
GK
10333 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10334 if (temp)
10335 XEXP (SET_DEST (set), 0) = temp;
38c1f2d7 10336 }
38c1f2d7 10337 }
9ebbca7d
GK
10338 else if (GET_CODE (real) == PARALLEL)
10339 {
10340 int i;
10341 for (i = 0; i < XVECLEN (real, 0); i++)
10342 if (GET_CODE (XVECEXP (real, 0, i)) == SET)
10343 {
10344 rtx set = XVECEXP (real, 0, i);
10345
10346 temp = simplify_rtx (SET_SRC (set));
10347 if (temp)
10348 SET_SRC (set) = temp;
10349 temp = simplify_rtx (SET_DEST (set));
10350 if (temp)
10351 SET_DEST (set) = temp;
10352 if (GET_CODE (SET_DEST (set)) == MEM)
10353 {
10354 temp = simplify_rtx (XEXP (SET_DEST (set), 0));
10355 if (temp)
10356 XEXP (SET_DEST (set), 0) = temp;
10357 }
10358 RTX_FRAME_RELATED_P (set) = 1;
10359 }
10360 }
10361 else
a4f6c312 10362 abort ();
c19de7aa
AH
10363
10364 if (TARGET_SPE)
10365 real = spe_synthesize_frame_save (real);
10366
9ebbca7d
GK
10367 RTX_FRAME_RELATED_P (insn) = 1;
10368 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
10369 real,
10370 REG_NOTES (insn));
38c1f2d7
MM
10371}
10372
c19de7aa
AH
10373/* Given an SPE frame note, return a PARALLEL of SETs with the
10374 original note, plus a synthetic register save. */
10375
10376static rtx
10377spe_synthesize_frame_save (real)
10378 rtx real;
10379{
10380 rtx synth, offset, reg, real2;
10381
10382 if (GET_CODE (real) != SET
10383 || GET_MODE (SET_SRC (real)) != V2SImode)
10384 return real;
10385
10386 /* For the SPE, registers saved in 64-bits, get a PARALLEL for their
10387 frame related note. The parallel contains a set of the register
41f3a930 10388 being saved, and another set to a synthetic register (n+1200).
c19de7aa
AH
10389 This is so we can differentiate between 64-bit and 32-bit saves.
10390 Words cannot describe this nastiness. */
10391
10392 if (GET_CODE (SET_DEST (real)) != MEM
10393 || GET_CODE (XEXP (SET_DEST (real), 0)) != PLUS
10394 || GET_CODE (SET_SRC (real)) != REG)
10395 abort ();
10396
10397 /* Transform:
10398 (set (mem (plus (reg x) (const y)))
10399 (reg z))
10400 into:
10401 (set (mem (plus (reg x) (const y+4)))
41f3a930 10402 (reg z+1200))
c19de7aa
AH
10403 */
10404
10405 real2 = copy_rtx (real);
10406 PUT_MODE (SET_DEST (real2), SImode);
10407 reg = SET_SRC (real2);
10408 real2 = replace_rtx (real2, reg, gen_rtx_REG (SImode, REGNO (reg)));
10409 synth = copy_rtx (real2);
10410
10411 if (BYTES_BIG_ENDIAN)
10412 {
10413 offset = XEXP (XEXP (SET_DEST (real2), 0), 1);
10414 real2 = replace_rtx (real2, offset, GEN_INT (INTVAL (offset) + 4));
10415 }
10416
10417 reg = SET_SRC (synth);
41f3a930 10418
c19de7aa 10419 synth = replace_rtx (synth, reg,
41f3a930 10420 gen_rtx_REG (SImode, REGNO (reg) + 1200));
c19de7aa
AH
10421
10422 offset = XEXP (XEXP (SET_DEST (synth), 0), 1);
10423 synth = replace_rtx (synth, offset,
10424 GEN_INT (INTVAL (offset)
10425 + (BYTES_BIG_ENDIAN ? 0 : 4)));
10426
10427 RTX_FRAME_RELATED_P (synth) = 1;
10428 RTX_FRAME_RELATED_P (real2) = 1;
10429 if (BYTES_BIG_ENDIAN)
10430 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, synth, real2));
10431 else
10432 real = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, real2, synth));
10433
10434 return real;
10435}
10436
00b960c7
AH
10437/* Returns an insn that has a vrsave set operation with the
10438 appropriate CLOBBERs. */
10439
10440static rtx
9aa86737 10441generate_set_vrsave (reg, info, epiloguep)
00b960c7
AH
10442 rtx reg;
10443 rs6000_stack_t *info;
9aa86737 10444 int epiloguep;
00b960c7
AH
10445{
10446 int nclobs, i;
10447 rtx insn, clobs[TOTAL_ALTIVEC_REGS + 1];
a004eb82 10448 rtx vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
00b960c7 10449
a004eb82
AH
10450 clobs[0]
10451 = gen_rtx_SET (VOIDmode,
10452 vrsave,
10453 gen_rtx_UNSPEC_VOLATILE (SImode,
10454 gen_rtvec (2, reg, vrsave),
10455 30));
00b960c7
AH
10456
10457 nclobs = 1;
10458
9aa86737
AH
10459 /* We need to clobber the registers in the mask so the scheduler
10460 does not move sets to VRSAVE before sets of AltiVec registers.
10461
10462 However, if the function receives nonlocal gotos, reload will set
10463 all call saved registers live. We will end up with:
10464
10465 (set (reg 999) (mem))
10466 (parallel [ (set (reg vrsave) (unspec blah))
10467 (clobber (reg 999))])
10468
10469 The clobber will cause the store into reg 999 to be dead, and
10470 flow will attempt to delete an epilogue insn. In this case, we
10471 need an unspec use/set of the register. */
00b960c7
AH
10472
10473 for (i = FIRST_ALTIVEC_REGNO; i <= LAST_ALTIVEC_REGNO; ++i)
10474 if (info->vrsave_mask != 0 && ALTIVEC_REG_BIT (i) != 0)
9aa86737
AH
10475 {
10476 if (!epiloguep || call_used_regs [i])
10477 clobs[nclobs++] = gen_rtx_CLOBBER (VOIDmode,
10478 gen_rtx_REG (V4SImode, i));
10479 else
10480 {
10481 rtx reg = gen_rtx_REG (V4SImode, i);
9aa86737
AH
10482
10483 clobs[nclobs++]
a004eb82
AH
10484 = gen_rtx_SET (VOIDmode,
10485 reg,
10486 gen_rtx_UNSPEC (V4SImode,
10487 gen_rtvec (1, reg), 27));
9aa86737
AH
10488 }
10489 }
00b960c7
AH
10490
10491 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nclobs));
10492
10493 for (i = 0; i < nclobs; ++i)
10494 XVECEXP (insn, 0, i) = clobs[i];
10495
10496 return insn;
10497}
10498
89e7058f
AH
10499/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
10500 Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */
10501
10502static void
10503emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
10504 rtx frame_reg;
10505 rtx frame_ptr;
10506 enum machine_mode mode;
10507 unsigned int regno;
10508 int offset;
10509 int total_size;
10510{
10511 rtx reg, offset_rtx, insn, mem, addr, int_rtx;
10512 rtx replacea, replaceb;
10513
10514 int_rtx = GEN_INT (offset);
10515
10516 /* Some cases that need register indexed addressing. */
10517 if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
a3170dc6
AH
10518 || (TARGET_SPE_ABI
10519 && SPE_VECTOR_MODE (mode)
10520 && !SPE_CONST_OFFSET_OK (offset)))
89e7058f
AH
10521 {
10522 /* Whomever calls us must make sure r11 is available in the
10523 flow path of instructions in the prologue. */
10524 offset_rtx = gen_rtx_REG (Pmode, 11);
10525 emit_move_insn (offset_rtx, int_rtx);
10526
10527 replacea = offset_rtx;
10528 replaceb = int_rtx;
10529 }
10530 else
10531 {
10532 offset_rtx = int_rtx;
10533 replacea = NULL_RTX;
10534 replaceb = NULL_RTX;
10535 }
10536
10537 reg = gen_rtx_REG (mode, regno);
10538 addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
10539 mem = gen_rtx_MEM (mode, addr);
10540 set_mem_alias_set (mem, rs6000_sr_alias_set);
10541
10542 insn = emit_move_insn (mem, reg);
10543
10544 rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
10545}
10546
a3170dc6
AH
10547/* Emit an offset memory reference suitable for a frame store, while
10548 converting to a valid addressing mode. */
10549
10550static rtx
10551gen_frame_mem_offset (mode, reg, offset)
10552 enum machine_mode mode;
10553 rtx reg;
10554 int offset;
10555{
10556 rtx int_rtx, offset_rtx;
10557
10558 int_rtx = GEN_INT (offset);
10559
10560 if (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
10561 {
10562 offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10563 emit_move_insn (offset_rtx, int_rtx);
10564 }
10565 else
10566 offset_rtx = int_rtx;
10567
10568 return gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, reg, offset_rtx));
10569}
10570
9ebbca7d
GK
10571/* Emit function prologue as insns. */
10572
9878760c 10573void
83720594 10574rs6000_emit_prologue ()
9878760c 10575{
4697a36c 10576 rs6000_stack_t *info = rs6000_stack_info ();
9ebbca7d
GK
10577 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
10578 int reg_size = TARGET_POWERPC64 ? 8 : 4;
10579 rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
10580 rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
10581 rtx frame_reg_rtx = sp_reg_rtx;
10582 rtx cr_save_rtx = NULL;
10583 rtx insn;
10584 int saving_FPRs_inline;
10585 int using_store_multiple;
10586 HOST_WIDE_INT sp_offset = 0;
10587
c19de7aa 10588 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
10589 {
10590 reg_mode = V2SImode;
10591 reg_size = 8;
10592 }
10593
9ebbca7d 10594 using_store_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
10595 && (!TARGET_SPE_ABI
10596 || info->spe_64bit_regs_used == 0)
9ebbca7d
GK
10597 && info->first_gp_reg_save < 31);
10598 saving_FPRs_inline = (info->first_fp_reg_save == 64
10599 || FP_SAVE_INLINE (info->first_fp_reg_save));
10600
10601 /* For V.4, update stack before we do any saving and set back pointer. */
f607bc57 10602 if (info->push_p && DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
10603 {
10604 if (info->total_size < 32767)
10605 sp_offset = info->total_size;
10606 else
10607 frame_reg_rtx = frame_ptr_rtx;
10608 rs6000_emit_allocate_stack (info->total_size,
10609 (frame_reg_rtx != sp_reg_rtx
10610 && (info->cr_save_p
10611 || info->lr_save_p
10612 || info->first_fp_reg_save < 64
10613 || info->first_gp_reg_save < 32
10614 )));
10615 if (frame_reg_rtx != sp_reg_rtx)
10616 rs6000_emit_stack_tie ();
10617 }
10618
9aa86737
AH
10619 /* Save AltiVec registers if needed. */
10620 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
10621 {
10622 int i;
10623
10624 /* There should be a non inline version of this, for when we
10625 are saving lots of vector registers. */
10626 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
10627 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
10628 {
10629 rtx areg, savereg, mem;
10630 int offset;
10631
10632 offset = info->altivec_save_offset + sp_offset
10633 + 16 * (i - info->first_altivec_reg_save);
10634
10635 savereg = gen_rtx_REG (V4SImode, i);
10636
10637 areg = gen_rtx_REG (Pmode, 0);
10638 emit_move_insn (areg, GEN_INT (offset));
10639
10640 /* AltiVec addressing mode is [reg+reg]. */
10641 mem = gen_rtx_MEM (V4SImode,
10642 gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
10643
10644 set_mem_alias_set (mem, rs6000_sr_alias_set);
10645
10646 insn = emit_move_insn (mem, savereg);
10647
5c242421
SB
10648 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10649 areg, GEN_INT (offset));
9aa86737
AH
10650 }
10651 }
10652
10653 /* VRSAVE is a bit vector representing which AltiVec registers
10654 are used. The OS uses this to determine which vector
10655 registers to save on a context switch. We need to save
10656 VRSAVE on the stack frame, add whatever AltiVec registers we
10657 used in this function, and do the corresponding magic in the
10658 epilogue. */
10659
10660 if (TARGET_ALTIVEC && info->vrsave_mask != 0)
10661 {
a004eb82 10662 rtx reg, mem, vrsave;
9aa86737
AH
10663 int offset;
10664
10665 /* Get VRSAVE onto a GPR. */
10666 reg = gen_rtx_REG (SImode, 12);
a004eb82 10667 vrsave = gen_rtx_REG (SImode, VRSAVE_REGNO);
b188f760
AH
10668 if (TARGET_MACHO)
10669 emit_insn (gen_get_vrsave_internal (reg));
10670 else
10671 emit_insn (gen_rtx_SET (VOIDmode, reg, vrsave));
9aa86737
AH
10672
10673 /* Save VRSAVE. */
10674 offset = info->vrsave_save_offset + sp_offset;
10675 mem
10676 = gen_rtx_MEM (SImode,
10677 gen_rtx_PLUS (Pmode, frame_reg_rtx, GEN_INT (offset)));
10678 set_mem_alias_set (mem, rs6000_sr_alias_set);
10679 insn = emit_move_insn (mem, reg);
10680
10681 /* Include the registers in the mask. */
10682 emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask)));
10683
10684 insn = emit_insn (generate_set_vrsave (reg, info, 0));
10685 }
10686
9ebbca7d
GK
10687 /* If we use the link register, get it into r0. */
10688 if (info->lr_save_p)
71f123ca 10689 emit_move_insn (gen_rtx_REG (Pmode, 0),
9ebbca7d
GK
10690 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10691
10692 /* If we need to save CR, put it into r12. */
10693 if (info->cr_save_p && frame_reg_rtx != frame_ptr_rtx)
10694 {
10695 cr_save_rtx = gen_rtx_REG (SImode, 12);
10696 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10697 }
10698
a4f6c312
SS
10699 /* Do any required saving of fpr's. If only one or two to save, do
10700 it ourselves. Otherwise, call function. */
9ebbca7d
GK
10701 if (saving_FPRs_inline)
10702 {
10703 int i;
10704 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10705 if ((regs_ever_live[info->first_fp_reg_save+i]
10706 && ! call_used_regs[info->first_fp_reg_save+i]))
89e7058f
AH
10707 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
10708 info->first_fp_reg_save + i,
10709 info->fp_save_offset + sp_offset + 8 * i,
10710 info->total_size);
9ebbca7d
GK
10711 }
10712 else if (info->first_fp_reg_save != 64)
10713 {
10714 int i;
10715 char rname[30];
520a57c8 10716 const char *alloc_rname;
9ebbca7d
GK
10717 rtvec p;
10718 p = rtvec_alloc (2 + 64 - info->first_fp_reg_save);
10719
10720 RTVEC_ELT (p, 0) = gen_rtx_CLOBBER (VOIDmode,
10721 gen_rtx_REG (Pmode,
10722 LINK_REGISTER_REGNUM));
10723 sprintf (rname, "%s%d%s", SAVE_FP_PREFIX,
10724 info->first_fp_reg_save - 32, SAVE_FP_SUFFIX);
a8a05998 10725 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
10726 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
10727 gen_rtx_SYMBOL_REF (Pmode,
10728 alloc_rname));
10729 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
10730 {
10731 rtx addr, reg, mem;
10732 reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
10733 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10734 GEN_INT (info->fp_save_offset
10735 + sp_offset + 8*i));
10736 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 10737 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10738
10739 RTVEC_ELT (p, i + 2) = gen_rtx_SET (VOIDmode, mem, reg);
10740 }
10741 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10742 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10743 NULL_RTX, NULL_RTX);
10744 }
b6c9286a 10745
9ebbca7d
GK
10746 /* Save GPRs. This is done as a PARALLEL if we are using
10747 the store-multiple instructions. */
10748 if (using_store_multiple)
b6c9286a 10749 {
308c142a 10750 rtvec p;
9ebbca7d
GK
10751 int i;
10752 p = rtvec_alloc (32 - info->first_gp_reg_save);
9ebbca7d
GK
10753 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10754 {
10755 rtx addr, reg, mem;
10756 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10757 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10758 GEN_INT (info->gp_save_offset
10759 + sp_offset
10760 + reg_size * i));
10761 mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 10762 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10763
10764 RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
10765 }
10766 insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
10767 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10768 NULL_RTX, NULL_RTX);
b6c9286a
MM
10769 }
10770 else
10771 {
9ebbca7d
GK
10772 int i;
10773 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
10774 if ((regs_ever_live[info->first_gp_reg_save+i]
10775 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 10776 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 10777 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 10778 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
a3170dc6
AH
10779 {
10780 rtx addr, reg, mem;
10781 reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
10782
c19de7aa 10783 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
10784 {
10785 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
10786 rtx b;
10787
10788 if (!SPE_CONST_OFFSET_OK (offset))
10789 {
10790 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
10791 emit_move_insn (b, GEN_INT (offset));
10792 }
10793 else
10794 b = GEN_INT (offset);
10795
10796 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
10797 mem = gen_rtx_MEM (V2SImode, addr);
10798 set_mem_alias_set (mem, rs6000_sr_alias_set);
10799 insn = emit_move_insn (mem, reg);
10800
10801 if (GET_CODE (b) == CONST_INT)
10802 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10803 NULL_RTX, NULL_RTX);
10804 else
10805 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10806 b, GEN_INT (offset));
10807 }
10808 else
10809 {
10810 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10811 GEN_INT (info->gp_save_offset
10812 + sp_offset
10813 + reg_size * i));
10814 mem = gen_rtx_MEM (reg_mode, addr);
10815 set_mem_alias_set (mem, rs6000_sr_alias_set);
10816
10817 insn = emit_move_insn (mem, reg);
10818 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10819 NULL_RTX, NULL_RTX);
10820 }
10821 }
9ebbca7d
GK
10822 }
10823
83720594
RH
10824 /* ??? There's no need to emit actual instructions here, but it's the
10825 easiest way to get the frame unwind information emitted. */
10826 if (current_function_calls_eh_return)
10827 {
78e1b90d
DE
10828 unsigned int i, regno;
10829
83720594
RH
10830 for (i = 0; ; ++i)
10831 {
83720594
RH
10832 regno = EH_RETURN_DATA_REGNO (i);
10833 if (regno == INVALID_REGNUM)
10834 break;
10835
89e7058f
AH
10836 emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
10837 info->ehrd_offset + sp_offset
10838 + reg_size * (int) i,
10839 info->total_size);
83720594
RH
10840 }
10841 }
10842
9ebbca7d
GK
10843 /* Save lr if we used it. */
10844 if (info->lr_save_p)
10845 {
10846 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10847 GEN_INT (info->lr_save_offset + sp_offset));
10848 rtx reg = gen_rtx_REG (Pmode, 0);
10849 rtx mem = gen_rtx_MEM (Pmode, addr);
10850 /* This should not be of rs6000_sr_alias_set, because of
10851 __builtin_return_address. */
10852
10853 insn = emit_move_insn (mem, reg);
10854 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
10855 reg, gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10856 }
10857
10858 /* Save CR if we use any that must be preserved. */
10859 if (info->cr_save_p)
10860 {
10861 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
10862 GEN_INT (info->cr_save_offset + sp_offset));
10863 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
10864
10865 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
10866
10867 /* If r12 was used to hold the original sp, copy cr into r0 now
10868 that it's free. */
10869 if (REGNO (frame_reg_rtx) == 12)
10870 {
10871 cr_save_rtx = gen_rtx_REG (SImode, 0);
10872 emit_insn (gen_movesi_from_cr (cr_save_rtx));
10873 }
10874 insn = emit_move_insn (mem, cr_save_rtx);
10875
10876 /* Now, there's no way that dwarf2out_frame_debug_expr is going
10877 to understand '(unspec:SI [(reg:CC 68) ...] 19)'. But that's
10878 OK. All we have to do is specify that _one_ condition code
10879 register is saved in this stack slot. The thrower's epilogue
a1dc9455
FS
10880 will then restore all the call-saved registers.
10881 We use CR2_REGNO (70) to be compatible with gcc-2.95 on Linux. */
9ebbca7d 10882 rs6000_frame_related (insn, frame_ptr_rtx, info->total_size,
a1dc9455 10883 cr_save_rtx, gen_rtx_REG (SImode, CR2_REGNO));
9ebbca7d
GK
10884 }
10885
10886 /* Update stack and set back pointer unless this is V.4,
10887 for which it was done previously. */
f607bc57 10888 if (info->push_p && DEFAULT_ABI != ABI_V4)
9ebbca7d
GK
10889 rs6000_emit_allocate_stack (info->total_size, FALSE);
10890
10891 /* Set frame pointer, if needed. */
10892 if (frame_pointer_needed)
10893 {
a3170dc6 10894 insn = emit_move_insn (gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM),
9ebbca7d
GK
10895 sp_reg_rtx);
10896 RTX_FRAME_RELATED_P (insn) = 1;
b6c9286a 10897 }
9878760c 10898
1db02437 10899 /* If we are using RS6000_PIC_OFFSET_TABLE_REGNUM, we need to set it up. */
9ebbca7d 10900 if ((TARGET_TOC && TARGET_MINIMAL_TOC && get_pool_size () != 0)
f607bc57 10901 || (DEFAULT_ABI == ABI_V4 && flag_pic == 1
1db02437 10902 && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
9ebbca7d
GK
10903 {
10904 /* If emit_load_toc_table will use the link register, we need to save
10905 it. We use R11 for this purpose because emit_load_toc_table
10906 can use register 0. This allows us to use a plain 'blr' to return
10907 from the procedure more often. */
f1384257
AM
10908 int save_LR_around_toc_setup = (TARGET_ELF
10909 && DEFAULT_ABI != ABI_AIX
10910 && flag_pic
d5fa86ba
GK
10911 && ! info->lr_save_p
10912 && EXIT_BLOCK_PTR->pred != NULL);
9ebbca7d
GK
10913 if (save_LR_around_toc_setup)
10914 emit_move_insn (gen_rtx_REG (Pmode, 11),
10915 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
10916
10917 rs6000_emit_load_toc_table (TRUE);
10918
10919 if (save_LR_around_toc_setup)
10920 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
10921 gen_rtx_REG (Pmode, 11));
10922 }
ee890fe2 10923
fcce224d 10924#if TARGET_MACHO
ee890fe2
SS
10925 if (DEFAULT_ABI == ABI_DARWIN
10926 && flag_pic && current_function_uses_pic_offset_table)
10927 {
10928 rtx dest = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
f099d360 10929 const char *picbase = machopic_function_base_name ();
6788f5ca 10930 rtx src = gen_rtx_SYMBOL_REF (Pmode, picbase);
ee890fe2 10931
f51eee6a 10932 rs6000_maybe_dead (emit_insn (gen_load_macho_picbase (dest, src)));
ee890fe2
SS
10933
10934 rs6000_maybe_dead (
1db02437 10935 emit_move_insn (gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM),
ee890fe2
SS
10936 gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)));
10937 }
fcce224d 10938#endif
9ebbca7d
GK
10939}
10940
9ebbca7d 10941/* Write function prologue. */
a4f6c312 10942
08c148a8
NB
10943static void
10944rs6000_output_function_prologue (file, size)
9ebbca7d 10945 FILE *file;
08c148a8 10946 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9ebbca7d
GK
10947{
10948 rs6000_stack_t *info = rs6000_stack_info ();
10949
4697a36c
MM
10950 if (TARGET_DEBUG_STACK)
10951 debug_stack_info (info);
9878760c 10952
a4f6c312
SS
10953 /* Write .extern for any function we will call to save and restore
10954 fp values. */
10955 if (info->first_fp_reg_save < 64
10956 && !FP_SAVE_INLINE (info->first_fp_reg_save))
4d30c363 10957 fprintf (file, "\t.extern %s%d%s\n\t.extern %s%d%s\n",
4697a36c 10958 SAVE_FP_PREFIX, info->first_fp_reg_save - 32, SAVE_FP_SUFFIX,
a4f6c312
SS
10959 RESTORE_FP_PREFIX, info->first_fp_reg_save - 32,
10960 RESTORE_FP_SUFFIX);
9878760c 10961
c764f757
RK
10962 /* Write .extern for AIX common mode routines, if needed. */
10963 if (! TARGET_POWER && ! TARGET_POWERPC && ! common_mode_defined)
10964 {
f6709c70
JW
10965 fputs ("\t.extern __mulh\n", file);
10966 fputs ("\t.extern __mull\n", file);
10967 fputs ("\t.extern __divss\n", file);
10968 fputs ("\t.extern __divus\n", file);
10969 fputs ("\t.extern __quoss\n", file);
10970 fputs ("\t.extern __quous\n", file);
c764f757
RK
10971 common_mode_defined = 1;
10972 }
9878760c 10973
9ebbca7d 10974 if (! HAVE_prologue)
979721f8 10975 {
9ebbca7d 10976 start_sequence ();
9dda4cc8 10977
a4f6c312
SS
10978 /* A NOTE_INSN_DELETED is supposed to be at the start and end of
10979 the "toplevel" insn chain. */
9ebbca7d
GK
10980 emit_note (0, NOTE_INSN_DELETED);
10981 rs6000_emit_prologue ();
10982 emit_note (0, NOTE_INSN_DELETED);
178c3eff
DJ
10983
10984 /* Expand INSN_ADDRESSES so final() doesn't crash. */
10985 {
10986 rtx insn;
10987 unsigned addr = 0;
10988 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
10989 {
10990 INSN_ADDRESSES_NEW (insn, addr);
10991 addr += 4;
10992 }
10993 }
9dda4cc8 10994
9ebbca7d 10995 if (TARGET_DEBUG_STACK)
a4f6c312
SS
10996 debug_rtx_list (get_insns (), 100);
10997 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 10998 end_sequence ();
979721f8
MM
10999 }
11000
9ebbca7d
GK
11001 rs6000_pic_labelno++;
11002}
11003
11004/* Emit function epilogue as insns.
9878760c 11005
9ebbca7d
GK
11006 At present, dwarf2out_frame_debug_expr doesn't understand
11007 register restores, so we don't bother setting RTX_FRAME_RELATED_P
11008 anywhere in the epilogue. Most of the insns below would in any case
11009 need special notes to explain where r11 is in relation to the stack. */
9878760c 11010
9ebbca7d 11011void
83720594 11012rs6000_emit_epilogue (sibcall)
9ebbca7d
GK
11013 int sibcall;
11014{
11015 rs6000_stack_t *info;
11016 int restoring_FPRs_inline;
11017 int using_load_multiple;
11018 int using_mfcr_multiple;
11019 int use_backchain_to_restore_sp;
11020 int sp_offset = 0;
11021 rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
11022 rtx frame_reg_rtx = sp_reg_rtx;
11023 enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
11024 int reg_size = TARGET_POWERPC64 ? 8 : 4;
11025 int i;
11026
c19de7aa
AH
11027 info = rs6000_stack_info ();
11028
11029 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
11030 {
11031 reg_mode = V2SImode;
11032 reg_size = 8;
11033 }
11034
9ebbca7d 11035 using_load_multiple = (TARGET_MULTIPLE && ! TARGET_POWERPC64
c19de7aa
AH
11036 && (!TARGET_SPE_ABI
11037 || info->spe_64bit_regs_used == 0)
9ebbca7d
GK
11038 && info->first_gp_reg_save < 31);
11039 restoring_FPRs_inline = (sibcall
83720594 11040 || current_function_calls_eh_return
9ebbca7d
GK
11041 || info->first_fp_reg_save == 64
11042 || FP_SAVE_INLINE (info->first_fp_reg_save));
11043 use_backchain_to_restore_sp = (frame_pointer_needed
11044 || current_function_calls_alloca
11045 || info->total_size > 32767);
11046 using_mfcr_multiple = (rs6000_cpu == PROCESSOR_PPC601
11047 || rs6000_cpu == PROCESSOR_PPC603
11048 || rs6000_cpu == PROCESSOR_PPC750
11049 || optimize_size);
11050
11051 /* If we have a frame pointer, a call to alloca, or a large stack
11052 frame, restore the old stack pointer using the backchain. Otherwise,
11053 we know what size to update it with. */
11054 if (use_backchain_to_restore_sp)
bacbde18 11055 {
9ebbca7d
GK
11056 /* Under V.4, don't reset the stack pointer until after we're done
11057 loading the saved registers. */
f607bc57 11058 if (DEFAULT_ABI == ABI_V4)
9ebbca7d 11059 frame_reg_rtx = gen_rtx_REG (Pmode, 11);
4697a36c 11060
9ebbca7d
GK
11061 emit_move_insn (frame_reg_rtx,
11062 gen_rtx_MEM (Pmode, sp_reg_rtx));
11063
bacbde18 11064 }
9ebbca7d 11065 else if (info->push_p)
85638c0d 11066 {
f607bc57 11067 if (DEFAULT_ABI == ABI_V4)
9ebbca7d
GK
11068 sp_offset = info->total_size;
11069 else
11070 {
11071 emit_insn (TARGET_32BIT
11072 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
11073 GEN_INT (info->total_size))
11074 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
11075 GEN_INT (info->total_size)));
11076 }
85638c0d 11077 }
9ebbca7d 11078
9aa86737
AH
11079 /* Restore AltiVec registers if needed. */
11080 if (TARGET_ALTIVEC_ABI && info->altivec_size != 0)
11081 {
11082 int i;
11083
11084 for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
11085 if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
11086 {
11087 rtx addr, areg, mem;
11088
11089 areg = gen_rtx_REG (Pmode, 0);
11090 emit_move_insn
11091 (areg, GEN_INT (info->altivec_save_offset
11092 + sp_offset
11093 + 16 * (i - info->first_altivec_reg_save)));
11094
11095 /* AltiVec addressing mode is [reg+reg]. */
11096 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
11097 mem = gen_rtx_MEM (V4SImode, addr);
11098 set_mem_alias_set (mem, rs6000_sr_alias_set);
11099
11100 emit_move_insn (gen_rtx_REG (V4SImode, i), mem);
11101 }
11102 }
11103
11104 /* Restore VRSAVE if needed. */
11105 if (TARGET_ALTIVEC_ABI && info->vrsave_mask != 0)
11106 {
11107 rtx addr, mem, reg;
11108
11109 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11110 GEN_INT (info->vrsave_save_offset + sp_offset));
11111 mem = gen_rtx_MEM (SImode, addr);
11112 set_mem_alias_set (mem, rs6000_sr_alias_set);
11113 reg = gen_rtx_REG (SImode, 12);
11114 emit_move_insn (reg, mem);
11115
11116 emit_insn (generate_set_vrsave (reg, info, 1));
11117 }
11118
9ebbca7d
GK
11119 /* Get the old lr if we saved it. */
11120 if (info->lr_save_p)
b6c9286a 11121 {
a3170dc6
AH
11122 rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
11123 info->lr_save_offset + sp_offset);
ba4828e0
RK
11124
11125 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 11126
9ebbca7d 11127 emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
b6c9286a 11128 }
9ebbca7d
GK
11129
11130 /* Get the old cr if we saved it. */
11131 if (info->cr_save_p)
11132 {
11133 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11134 GEN_INT (info->cr_save_offset + sp_offset));
11135 rtx mem = gen_rtx_MEM (SImode, addr);
ba4828e0
RK
11136
11137 set_mem_alias_set (mem, rs6000_sr_alias_set);
b6c9286a 11138
9ebbca7d
GK
11139 emit_move_insn (gen_rtx_REG (SImode, 12), mem);
11140 }
11141
11142 /* Set LR here to try to overlap restores below. */
4697a36c 11143 if (info->lr_save_p)
9ebbca7d
GK
11144 emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM),
11145 gen_rtx_REG (Pmode, 0));
11146
83720594
RH
11147 /* Load exception handler data registers, if needed. */
11148 if (current_function_calls_eh_return)
11149 {
78e1b90d
DE
11150 unsigned int i, regno;
11151
83720594
RH
11152 for (i = 0; ; ++i)
11153 {
a3170dc6 11154 rtx mem;
83720594
RH
11155
11156 regno = EH_RETURN_DATA_REGNO (i);
11157 if (regno == INVALID_REGNUM)
11158 break;
11159
a3170dc6
AH
11160 mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx,
11161 info->ehrd_offset + sp_offset
11162 + reg_size * (int) i);
ba4828e0 11163 set_mem_alias_set (mem, rs6000_sr_alias_set);
83720594
RH
11164
11165 emit_move_insn (gen_rtx_REG (reg_mode, regno), mem);
11166 }
11167 }
9ebbca7d
GK
11168
11169 /* Restore GPRs. This is done as a PARALLEL if we are using
11170 the load-multiple instructions. */
11171 if (using_load_multiple)
979721f8 11172 {
9ebbca7d
GK
11173 rtvec p;
11174 p = rtvec_alloc (32 - info->first_gp_reg_save);
11175 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
979721f8 11176 {
9ebbca7d
GK
11177 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11178 GEN_INT (info->gp_save_offset
11179 + sp_offset
11180 + reg_size * i));
11181 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0
RK
11182
11183 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11184
11185 RTVEC_ELT (p, i) =
11186 gen_rtx_SET (VOIDmode,
11187 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
11188 mem);
979721f8 11189 }
9ebbca7d 11190 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
979721f8 11191 }
9ebbca7d
GK
11192 else
11193 for (i = 0; i < 32 - info->first_gp_reg_save; i++)
11194 if ((regs_ever_live[info->first_gp_reg_save+i]
11195 && ! call_used_regs[info->first_gp_reg_save+i])
1db02437 11196 || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
14f00213 11197 && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0)
f607bc57 11198 || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
9ebbca7d
GK
11199 {
11200 rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11201 GEN_INT (info->gp_save_offset
11202 + sp_offset
11203 + reg_size * i));
11204 rtx mem = gen_rtx_MEM (reg_mode, addr);
ba4828e0 11205
a3170dc6 11206 /* Restore 64-bit quantities for SPE. */
c19de7aa 11207 if (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0)
a3170dc6
AH
11208 {
11209 int offset = info->spe_gp_save_offset + sp_offset + 8 * i;
11210 rtx b;
11211
11212 if (!SPE_CONST_OFFSET_OK (offset))
11213 {
11214 b = gen_rtx_REG (Pmode, FIXED_SCRATCH);
11215 emit_move_insn (b, GEN_INT (offset));
11216 }
11217 else
11218 b = GEN_INT (offset);
11219
11220 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, b);
11221 mem = gen_rtx_MEM (V2SImode, addr);
11222 }
11223
ba4828e0 11224 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11225
11226 emit_move_insn (gen_rtx_REG (reg_mode,
a3170dc6 11227 info->first_gp_reg_save + i), mem);
9ebbca7d 11228 }
9878760c 11229
9ebbca7d
GK
11230 /* Restore fpr's if we need to do it without calling a function. */
11231 if (restoring_FPRs_inline)
11232 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
11233 if ((regs_ever_live[info->first_fp_reg_save+i]
11234 && ! call_used_regs[info->first_fp_reg_save+i]))
11235 {
11236 rtx addr, mem;
11237 addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
11238 GEN_INT (info->fp_save_offset
11239 + sp_offset
a4f6c312 11240 + 8 * i));
9ebbca7d 11241 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 11242 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11243
11244 emit_move_insn (gen_rtx_REG (DFmode,
11245 info->first_fp_reg_save + i),
11246 mem);
11247 }
8d30c4ee 11248
9ebbca7d
GK
11249 /* If we saved cr, restore it here. Just those that were used. */
11250 if (info->cr_save_p)
979721f8 11251 {
9ebbca7d 11252 rtx r12_rtx = gen_rtx_REG (SImode, 12);
e35b9579 11253 int count = 0;
9ebbca7d
GK
11254
11255 if (using_mfcr_multiple)
979721f8 11256 {
9ebbca7d
GK
11257 for (i = 0; i < 8; i++)
11258 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
e35b9579 11259 count++;
9ebbca7d 11260 if (count == 0)
e35b9579
GK
11261 abort ();
11262 }
11263
11264 if (using_mfcr_multiple && count > 1)
11265 {
11266 rtvec p;
11267 int ndx;
9ebbca7d 11268
e35b9579 11269 p = rtvec_alloc (count);
9ebbca7d 11270
e35b9579 11271 ndx = 0;
9ebbca7d
GK
11272 for (i = 0; i < 8; i++)
11273 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
11274 {
11275 rtvec r = rtvec_alloc (2);
11276 RTVEC_ELT (r, 0) = r12_rtx;
11277 RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i));
e35b9579 11278 RTVEC_ELT (p, ndx) =
9ebbca7d
GK
11279 gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i),
11280 gen_rtx_UNSPEC (CCmode, r, 20));
e35b9579 11281 ndx++;
9ebbca7d
GK
11282 }
11283 emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
e35b9579
GK
11284 if (ndx != count)
11285 abort ();
979721f8
MM
11286 }
11287 else
9ebbca7d
GK
11288 for (i = 0; i < 8; i++)
11289 if (regs_ever_live[CR0_REGNO+i] && ! call_used_regs[CR0_REGNO+i])
979721f8 11290 {
9ebbca7d
GK
11291 emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode,
11292 CR0_REGNO+i),
11293 r12_rtx));
979721f8 11294 }
979721f8
MM
11295 }
11296
9ebbca7d
GK
11297 /* If this is V.4, unwind the stack pointer after all of the loads
11298 have been done. We need to emit a block here so that sched
11299 doesn't decide to move the sp change before the register restores
11300 (which may not have any obvious dependency on the stack). This
11301 doesn't hurt performance, because there is no scheduling that can
11302 be done after this point. */
f607bc57 11303 if (DEFAULT_ABI == ABI_V4)
b6c9286a 11304 {
9ebbca7d
GK
11305 if (frame_reg_rtx != sp_reg_rtx)
11306 rs6000_emit_stack_tie ();
b6c9286a 11307
9ebbca7d 11308 if (use_backchain_to_restore_sp)
b6c9286a 11309 {
9ebbca7d 11310 emit_move_insn (sp_reg_rtx, frame_reg_rtx);
b6c9286a 11311 }
9ebbca7d 11312 else if (sp_offset != 0)
13f1623b 11313 {
5b71a4e7 11314 emit_insn (TARGET_32BIT
9ebbca7d
GK
11315 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
11316 GEN_INT (sp_offset))
11317 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
11318 GEN_INT (sp_offset)));
13f1623b 11319 }
9ebbca7d 11320 }
b6c9286a 11321
83720594
RH
11322 if (current_function_calls_eh_return)
11323 {
11324 rtx sa = EH_RETURN_STACKADJ_RTX;
5b71a4e7 11325 emit_insn (TARGET_32BIT
83720594
RH
11326 ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx, sa)
11327 : gen_adddi3 (sp_reg_rtx, sp_reg_rtx, sa));
11328 }
11329
9ebbca7d
GK
11330 if (!sibcall)
11331 {
11332 rtvec p;
11333 if (! restoring_FPRs_inline)
11334 p = rtvec_alloc (3 + 64 - info->first_fp_reg_save);
11335 else
11336 p = rtvec_alloc (2);
b6c9286a 11337
e35b9579
GK
11338 RTVEC_ELT (p, 0) = gen_rtx_RETURN (VOIDmode);
11339 RTVEC_ELT (p, 1) = gen_rtx_USE (VOIDmode,
9ebbca7d
GK
11340 gen_rtx_REG (Pmode,
11341 LINK_REGISTER_REGNUM));
9ebbca7d
GK
11342
11343 /* If we have to restore more than two FP registers, branch to the
11344 restore function. It will return to our caller. */
11345 if (! restoring_FPRs_inline)
11346 {
11347 int i;
11348 char rname[30];
520a57c8 11349 const char *alloc_rname;
979721f8 11350
9ebbca7d
GK
11351 sprintf (rname, "%s%d%s", RESTORE_FP_PREFIX,
11352 info->first_fp_reg_save - 32, RESTORE_FP_SUFFIX);
a8a05998 11353 alloc_rname = ggc_strdup (rname);
9ebbca7d
GK
11354 RTVEC_ELT (p, 2) = gen_rtx_USE (VOIDmode,
11355 gen_rtx_SYMBOL_REF (Pmode,
11356 alloc_rname));
b6c9286a 11357
9ebbca7d
GK
11358 for (i = 0; i < 64 - info->first_fp_reg_save; i++)
11359 {
11360 rtx addr, mem;
11361 addr = gen_rtx_PLUS (Pmode, sp_reg_rtx,
11362 GEN_INT (info->fp_save_offset + 8*i));
11363 mem = gen_rtx_MEM (DFmode, addr);
ba4828e0 11364 set_mem_alias_set (mem, rs6000_sr_alias_set);
9ebbca7d
GK
11365
11366 RTVEC_ELT (p, i+3) =
11367 gen_rtx_SET (VOIDmode,
11368 gen_rtx_REG (DFmode, info->first_fp_reg_save + i),
11369 mem);
b6c9286a
MM
11370 }
11371 }
9ebbca7d
GK
11372
11373 emit_jump_insn (gen_rtx_PARALLEL (VOIDmode, p));
3daf36a4 11374 }
9878760c
RK
11375}
11376
11377/* Write function epilogue. */
11378
08c148a8
NB
11379static void
11380rs6000_output_function_epilogue (file, size)
9878760c 11381 FILE *file;
08c148a8 11382 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
9878760c 11383{
4697a36c 11384 rs6000_stack_t *info = rs6000_stack_info ();
9878760c 11385
9ebbca7d 11386 if (! HAVE_epilogue)
9878760c 11387 {
9ebbca7d
GK
11388 rtx insn = get_last_insn ();
11389 /* If the last insn was a BARRIER, we don't have to write anything except
11390 the trace table. */
11391 if (GET_CODE (insn) == NOTE)
11392 insn = prev_nonnote_insn (insn);
11393 if (insn == 0 || GET_CODE (insn) != BARRIER)
4697a36c 11394 {
9ebbca7d
GK
11395 /* This is slightly ugly, but at least we don't have two
11396 copies of the epilogue-emitting code. */
11397 start_sequence ();
11398
11399 /* A NOTE_INSN_DELETED is supposed to be at the start
11400 and end of the "toplevel" insn chain. */
11401 emit_note (0, NOTE_INSN_DELETED);
11402 rs6000_emit_epilogue (FALSE);
11403 emit_note (0, NOTE_INSN_DELETED);
11404
178c3eff
DJ
11405 /* Expand INSN_ADDRESSES so final() doesn't crash. */
11406 {
11407 rtx insn;
11408 unsigned addr = 0;
11409 for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
11410 {
11411 INSN_ADDRESSES_NEW (insn, addr);
11412 addr += 4;
11413 }
11414 }
11415
9ebbca7d 11416 if (TARGET_DEBUG_STACK)
a4f6c312
SS
11417 debug_rtx_list (get_insns (), 100);
11418 final (get_insns (), file, FALSE, FALSE);
9ebbca7d 11419 end_sequence ();
4697a36c 11420 }
9878760c 11421 }
b4ac57ab 11422
9b30bae2 11423 /* Output a traceback table here. See /usr/include/sys/debug.h for info
314fc5a9
ILT
11424 on its format.
11425
11426 We don't output a traceback table if -finhibit-size-directive was
11427 used. The documentation for -finhibit-size-directive reads
11428 ``don't output a @code{.size} assembler directive, or anything
11429 else that would cause trouble if the function is split in the
11430 middle, and the two halves are placed at locations far apart in
11431 memory.'' The traceback table has this property, since it
11432 includes the offset from the start of the function to the
4d30c363
MM
11433 traceback table itself.
11434
11435 System V.4 Powerpc's (and the embedded ABI derived from it) use a
b6c9286a 11436 different traceback table. */
57ac7be9
AM
11437 if (DEFAULT_ABI == ABI_AIX && ! flag_inhibit_size_directive
11438 && rs6000_traceback != traceback_none)
9b30bae2 11439 {
69c75916 11440 const char *fname = NULL;
3ac88239 11441 const char *language_string = lang_hooks.name;
6041bf2f 11442 int fixed_parms = 0, float_parms = 0, parm_info = 0;
314fc5a9 11443 int i;
57ac7be9
AM
11444 int optional_tbtab;
11445
11446 if (rs6000_traceback == traceback_full)
11447 optional_tbtab = 1;
11448 else if (rs6000_traceback == traceback_part)
11449 optional_tbtab = 0;
11450 else
11451 optional_tbtab = !optimize_size && !TARGET_ELF;
314fc5a9 11452
69c75916
AM
11453 if (optional_tbtab)
11454 {
11455 fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
11456 while (*fname == '.') /* V.4 encodes . in the name */
11457 fname++;
11458
11459 /* Need label immediately before tbtab, so we can compute
11460 its offset from the function start. */
11461 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
11462 ASM_OUTPUT_LABEL (file, fname);
11463 }
314fc5a9
ILT
11464
11465 /* The .tbtab pseudo-op can only be used for the first eight
11466 expressions, since it can't handle the possibly variable
11467 length fields that follow. However, if you omit the optional
11468 fields, the assembler outputs zeros for all optional fields
11469 anyways, giving each variable length field is minimum length
11470 (as defined in sys/debug.h). Thus we can not use the .tbtab
11471 pseudo-op at all. */
11472
11473 /* An all-zero word flags the start of the tbtab, for debuggers
11474 that have to find it by searching forward from the entry
11475 point or from the current pc. */
19d2d16f 11476 fputs ("\t.long 0\n", file);
314fc5a9
ILT
11477
11478 /* Tbtab format type. Use format type 0. */
19d2d16f 11479 fputs ("\t.byte 0,", file);
314fc5a9
ILT
11480
11481 /* Language type. Unfortunately, there doesn't seem to be any
11482 official way to get this info, so we use language_string. C
11483 is 0. C++ is 9. No number defined for Obj-C, so use the
9517ead8 11484 value for C for now. There is no official value for Java,
6f573ff9 11485 although IBM appears to be using 13. There is no official value
f710504c 11486 for Chill, so we've chosen 44 pseudo-randomly. */
314fc5a9 11487 if (! strcmp (language_string, "GNU C")
e2c953b6 11488 || ! strcmp (language_string, "GNU Objective-C"))
314fc5a9
ILT
11489 i = 0;
11490 else if (! strcmp (language_string, "GNU F77"))
11491 i = 1;
11492 else if (! strcmp (language_string, "GNU Ada"))
11493 i = 3;
8b83775b 11494 else if (! strcmp (language_string, "GNU Pascal"))
314fc5a9
ILT
11495 i = 2;
11496 else if (! strcmp (language_string, "GNU C++"))
11497 i = 9;
9517ead8
AG
11498 else if (! strcmp (language_string, "GNU Java"))
11499 i = 13;
6f573ff9
JL
11500 else if (! strcmp (language_string, "GNU CHILL"))
11501 i = 44;
314fc5a9
ILT
11502 else
11503 abort ();
11504 fprintf (file, "%d,", i);
11505
11506 /* 8 single bit fields: global linkage (not set for C extern linkage,
11507 apparently a PL/I convention?), out-of-line epilogue/prologue, offset
11508 from start of procedure stored in tbtab, internal function, function
11509 has controlled storage, function has no toc, function uses fp,
11510 function logs/aborts fp operations. */
11511 /* Assume that fp operations are used if any fp reg must be saved. */
6041bf2f
DE
11512 fprintf (file, "%d,",
11513 (optional_tbtab << 5) | ((info->first_fp_reg_save != 64) << 1));
314fc5a9
ILT
11514
11515 /* 6 bitfields: function is interrupt handler, name present in
11516 proc table, function calls alloca, on condition directives
11517 (controls stack walks, 3 bits), saves condition reg, saves
11518 link reg. */
11519 /* The `function calls alloca' bit seems to be set whenever reg 31 is
11520 set up as a frame pointer, even when there is no alloca call. */
11521 fprintf (file, "%d,",
6041bf2f
DE
11522 ((optional_tbtab << 6)
11523 | ((optional_tbtab & frame_pointer_needed) << 5)
11524 | (info->cr_save_p << 1)
11525 | (info->lr_save_p)));
314fc5a9 11526
6041bf2f 11527 /* 3 bitfields: saves backchain, fixup code, number of fpr saved
314fc5a9
ILT
11528 (6 bits). */
11529 fprintf (file, "%d,",
4697a36c 11530 (info->push_p << 7) | (64 - info->first_fp_reg_save));
314fc5a9
ILT
11531
11532 /* 2 bitfields: spare bits (2 bits), number of gpr saved (6 bits). */
11533 fprintf (file, "%d,", (32 - first_reg_to_save ()));
11534
6041bf2f
DE
11535 if (optional_tbtab)
11536 {
11537 /* Compute the parameter info from the function decl argument
11538 list. */
11539 tree decl;
11540 int next_parm_info_bit = 31;
314fc5a9 11541
6041bf2f
DE
11542 for (decl = DECL_ARGUMENTS (current_function_decl);
11543 decl; decl = TREE_CHAIN (decl))
11544 {
11545 rtx parameter = DECL_INCOMING_RTL (decl);
11546 enum machine_mode mode = GET_MODE (parameter);
314fc5a9 11547
6041bf2f
DE
11548 if (GET_CODE (parameter) == REG)
11549 {
11550 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
11551 {
11552 int bits;
11553
11554 float_parms++;
11555
11556 if (mode == SFmode)
11557 bits = 0x2;
fcce224d 11558 else if (mode == DFmode || mode == TFmode)
6041bf2f
DE
11559 bits = 0x3;
11560 else
11561 abort ();
11562
11563 /* If only one bit will fit, don't or in this entry. */
11564 if (next_parm_info_bit > 0)
11565 parm_info |= (bits << (next_parm_info_bit - 1));
11566 next_parm_info_bit -= 2;
11567 }
11568 else
11569 {
11570 fixed_parms += ((GET_MODE_SIZE (mode)
11571 + (UNITS_PER_WORD - 1))
11572 / UNITS_PER_WORD);
11573 next_parm_info_bit -= 1;
11574 }
11575 }
11576 }
11577 }
314fc5a9
ILT
11578
11579 /* Number of fixed point parameters. */
11580 /* This is actually the number of words of fixed point parameters; thus
11581 an 8 byte struct counts as 2; and thus the maximum value is 8. */
11582 fprintf (file, "%d,", fixed_parms);
11583
11584 /* 2 bitfields: number of floating point parameters (7 bits), parameters
11585 all on stack. */
11586 /* This is actually the number of fp registers that hold parameters;
11587 and thus the maximum value is 13. */
11588 /* Set parameters on stack bit if parameters are not in their original
11589 registers, regardless of whether they are on the stack? Xlc
11590 seems to set the bit when not optimizing. */
11591 fprintf (file, "%d\n", ((float_parms << 1) | (! optimize)));
11592
6041bf2f
DE
11593 if (! optional_tbtab)
11594 return;
11595
314fc5a9
ILT
11596 /* Optional fields follow. Some are variable length. */
11597
11598 /* Parameter types, left adjusted bit fields: 0 fixed, 10 single float,
11599 11 double float. */
11600 /* There is an entry for each parameter in a register, in the order that
11601 they occur in the parameter list. Any intervening arguments on the
11602 stack are ignored. If the list overflows a long (max possible length
11603 34 bits) then completely leave off all elements that don't fit. */
11604 /* Only emit this long if there was at least one parameter. */
11605 if (fixed_parms || float_parms)
11606 fprintf (file, "\t.long %d\n", parm_info);
11607
11608 /* Offset from start of code to tb table. */
19d2d16f 11609 fputs ("\t.long ", file);
314fc5a9 11610 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LT");
54ee9799
DE
11611#if TARGET_AIX
11612 RS6000_OUTPUT_BASENAME (file, fname);
11613#else
9ebbca7d 11614 assemble_name (file, fname);
54ee9799 11615#endif
19d2d16f 11616 fputs ("-.", file);
54ee9799
DE
11617#if TARGET_AIX
11618 RS6000_OUTPUT_BASENAME (file, fname);
11619#else
9ebbca7d 11620 assemble_name (file, fname);
54ee9799 11621#endif
19d2d16f 11622 putc ('\n', file);
314fc5a9
ILT
11623
11624 /* Interrupt handler mask. */
11625 /* Omit this long, since we never set the interrupt handler bit
11626 above. */
11627
11628 /* Number of CTL (controlled storage) anchors. */
11629 /* Omit this long, since the has_ctl bit is never set above. */
11630
11631 /* Displacement into stack of each CTL anchor. */
11632 /* Omit this list of longs, because there are no CTL anchors. */
11633
11634 /* Length of function name. */
69c75916
AM
11635 if (*fname == '*')
11636 ++fname;
296b8152 11637 fprintf (file, "\t.short %d\n", (int) strlen (fname));
314fc5a9
ILT
11638
11639 /* Function name. */
11640 assemble_string (fname, strlen (fname));
11641
11642 /* Register for alloca automatic storage; this is always reg 31.
11643 Only emit this if the alloca bit was set above. */
11644 if (frame_pointer_needed)
19d2d16f 11645 fputs ("\t.byte 31\n", file);
b1765bde
DE
11646
11647 fputs ("\t.align 2\n", file);
9b30bae2 11648 }
9878760c 11649}
17167fd8 11650\f
a4f6c312
SS
11651/* A C compound statement that outputs the assembler code for a thunk
11652 function, used to implement C++ virtual function calls with
11653 multiple inheritance. The thunk acts as a wrapper around a virtual
11654 function, adjusting the implicit object parameter before handing
11655 control off to the real function.
11656
11657 First, emit code to add the integer DELTA to the location that
11658 contains the incoming first argument. Assume that this argument
11659 contains a pointer, and is the one used to pass the `this' pointer
11660 in C++. This is the incoming argument *before* the function
11661 prologue, e.g. `%o0' on a sparc. The addition must preserve the
11662 values of all other incoming arguments.
17167fd8
MM
11663
11664 After the addition, emit code to jump to FUNCTION, which is a
a4f6c312
SS
11665 `FUNCTION_DECL'. This is a direct pure jump, not a call, and does
11666 not touch the return address. Hence returning from FUNCTION will
11667 return to whoever called the current `thunk'.
17167fd8 11668
a4f6c312
SS
11669 The effect must be as if FUNCTION had been called directly with the
11670 adjusted first argument. This macro is responsible for emitting
11671 all of the code for a thunk function; output_function_prologue()
11672 and output_function_epilogue() are not invoked.
17167fd8 11673
a4f6c312
SS
11674 The THUNK_FNDECL is redundant. (DELTA and FUNCTION have already
11675 been extracted from it.) It might possibly be useful on some
11676 targets, but probably not.
17167fd8 11677
a4f6c312
SS
11678 If you do not define this macro, the target-independent code in the
11679 C++ frontend will generate a less efficient heavyweight thunk that
11680 calls FUNCTION instead of jumping to it. The generic approach does
11681 not support varargs. */
17167fd8 11682
3961e8fe
RH
11683static void
11684rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
17167fd8 11685 FILE *file;
d330fd93 11686 tree thunk_fndecl ATTRIBUTE_UNUSED;
eb0424da 11687 HOST_WIDE_INT delta;
5b71a4e7 11688 HOST_WIDE_INT vcall_offset;
17167fd8
MM
11689 tree function;
11690{
5b71a4e7 11691 rtx this, insn, funexp;
17167fd8 11692
5b71a4e7
DE
11693 reload_completed = 1;
11694 no_new_pseudos = 1;
56a7189a 11695
5b71a4e7
DE
11696 /* Mark the end of the (empty) prologue. */
11697 emit_note (NULL, NOTE_INSN_PROLOGUE_END);
17167fd8 11698
5b71a4e7
DE
11699 /* Find the "this" pointer. If the function returns a structure,
11700 the structure return pointer is in r3. */
11701 if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))
11702 this = gen_rtx_REG (Pmode, 4);
56a7189a 11703 else
5b71a4e7 11704 this = gen_rtx_REG (Pmode, 3);
17167fd8 11705
5b71a4e7
DE
11706 /* Apply the constant offset, if required. */
11707 if (delta)
11708 {
11709 rtx delta_rtx = GEN_INT (delta);
11710 emit_insn (TARGET_32BIT
11711 ? gen_addsi3 (this, this, delta_rtx)
11712 : gen_adddi3 (this, this, delta_rtx));
17167fd8
MM
11713 }
11714
5b71a4e7
DE
11715 /* Apply the offset from the vtable, if required. */
11716 if (vcall_offset)
17167fd8 11717 {
5b71a4e7
DE
11718 rtx vcall_offset_rtx = GEN_INT (vcall_offset);
11719 rtx tmp = gen_rtx_REG (Pmode, 12);
17167fd8 11720
5b71a4e7
DE
11721 emit_move_insn (tmp, gen_rtx_MEM (Pmode, this));
11722 emit_insn (TARGET_32BIT
11723 ? gen_addsi3 (tmp, tmp, vcall_offset_rtx)
11724 : gen_adddi3 (tmp, tmp, vcall_offset_rtx));
11725 emit_move_insn (tmp, gen_rtx_MEM (Pmode, tmp));
11726 emit_insn (TARGET_32BIT
11727 ? gen_addsi3 (this, this, tmp)
11728 : gen_adddi3 (this, this, tmp));
17167fd8
MM
11729 }
11730
5b71a4e7
DE
11731 /* Generate a tail call to the target function. */
11732 if (!TREE_USED (function))
11733 {
11734 assemble_external (function);
11735 TREE_USED (function) = 1;
11736 }
11737 funexp = XEXP (DECL_RTL (function), 0);
42820a49 11738
5b71a4e7
DE
11739 SYMBOL_REF_FLAG (funexp) = 0;
11740 if (current_file_function_operand (funexp, VOIDmode)
a5c76ee6
ZW
11741 && (! lookup_attribute ("longcall",
11742 TYPE_ATTRIBUTES (TREE_TYPE (function)))
11743 || lookup_attribute ("shortcall",
11744 TYPE_ATTRIBUTES (TREE_TYPE (function)))))
5b71a4e7 11745 SYMBOL_REF_FLAG (funexp) = 1;
17167fd8 11746
5b71a4e7 11747 funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
ee890fe2
SS
11748
11749#if TARGET_MACHO
ab82a49f 11750 if (MACHOPIC_INDIRECT)
5b71a4e7 11751 funexp = machopic_indirect_call_target (funexp);
ee890fe2 11752#endif
5b71a4e7
DE
11753
11754 /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
11755 generate sibcall RTL explicitly to avoid constraint abort. */
11756 insn = emit_call_insn (
11757 gen_rtx_PARALLEL (VOIDmode,
11758 gen_rtvec (4,
11759 gen_rtx_CALL (VOIDmode,
11760 funexp, const0_rtx),
11761 gen_rtx_USE (VOIDmode, const0_rtx),
11762 gen_rtx_USE (VOIDmode,
11763 gen_rtx_REG (SImode,
11764 LINK_REGISTER_REGNUM)),
11765 gen_rtx_RETURN (VOIDmode))));
11766 SIBLING_CALL_P (insn) = 1;
11767 emit_barrier ();
11768
11769 /* Run just enough of rest_of_compilation to get the insns emitted.
11770 There's not really enough bulk here to make other passes such as
11771 instruction scheduling worth while. Note that use_thunk calls
11772 assemble_start_function and assemble_end_function. */
11773 insn = get_insns ();
11774 shorten_branches (insn);
11775 final_start_function (insn, file, 1);
11776 final (insn, file, 1, 0);
11777 final_end_function ();
11778
11779 reload_completed = 0;
11780 no_new_pseudos = 0;
9ebbca7d 11781}
9ebbca7d
GK
11782\f
11783/* A quick summary of the various types of 'constant-pool tables'
11784 under PowerPC:
11785
11786 Target Flags Name One table per
11787 AIX (none) AIX TOC object file
11788 AIX -mfull-toc AIX TOC object file
11789 AIX -mminimal-toc AIX minimal TOC translation unit
11790 SVR4/EABI (none) SVR4 SDATA object file
11791 SVR4/EABI -fpic SVR4 pic object file
11792 SVR4/EABI -fPIC SVR4 PIC translation unit
11793 SVR4/EABI -mrelocatable EABI TOC function
11794 SVR4/EABI -maix AIX TOC object file
11795 SVR4/EABI -maix -mminimal-toc
11796 AIX minimal TOC translation unit
11797
11798 Name Reg. Set by entries contains:
11799 made by addrs? fp? sum?
11800
11801 AIX TOC 2 crt0 as Y option option
11802 AIX minimal TOC 30 prolog gcc Y Y option
11803 SVR4 SDATA 13 crt0 gcc N Y N
11804 SVR4 pic 30 prolog ld Y not yet N
11805 SVR4 PIC 30 prolog gcc Y option option
11806 EABI TOC 30 prolog gcc Y option option
11807
11808*/
11809
9ebbca7d
GK
11810/* Hash functions for the hash table. */
11811
11812static unsigned
11813rs6000_hash_constant (k)
11814 rtx k;
11815{
46b33600
RH
11816 enum rtx_code code = GET_CODE (k);
11817 enum machine_mode mode = GET_MODE (k);
11818 unsigned result = (code << 3) ^ mode;
11819 const char *format;
11820 int flen, fidx;
9ebbca7d 11821
46b33600
RH
11822 format = GET_RTX_FORMAT (code);
11823 flen = strlen (format);
11824 fidx = 0;
9ebbca7d 11825
46b33600
RH
11826 switch (code)
11827 {
11828 case LABEL_REF:
11829 return result * 1231 + (unsigned) INSN_UID (XEXP (k, 0));
11830
11831 case CONST_DOUBLE:
11832 if (mode != VOIDmode)
11833 return real_hash (CONST_DOUBLE_REAL_VALUE (k)) * result;
11834 flen = 2;
11835 break;
11836
11837 case CODE_LABEL:
11838 fidx = 3;
11839 break;
11840
11841 default:
11842 break;
11843 }
9ebbca7d
GK
11844
11845 for (; fidx < flen; fidx++)
11846 switch (format[fidx])
11847 {
11848 case 's':
11849 {
11850 unsigned i, len;
11851 const char *str = XSTR (k, fidx);
11852 len = strlen (str);
11853 result = result * 613 + len;
11854 for (i = 0; i < len; i++)
11855 result = result * 613 + (unsigned) str[i];
17167fd8
MM
11856 break;
11857 }
9ebbca7d
GK
11858 case 'u':
11859 case 'e':
11860 result = result * 1231 + rs6000_hash_constant (XEXP (k, fidx));
11861 break;
11862 case 'i':
11863 case 'n':
11864 result = result * 613 + (unsigned) XINT (k, fidx);
11865 break;
11866 case 'w':
11867 if (sizeof (unsigned) >= sizeof (HOST_WIDE_INT))
11868 result = result * 613 + (unsigned) XWINT (k, fidx);
11869 else
11870 {
11871 size_t i;
11872 for (i = 0; i < sizeof(HOST_WIDE_INT)/sizeof(unsigned); i++)
11873 result = result * 613 + (unsigned) (XWINT (k, fidx)
11874 >> CHAR_BIT * i);
11875 }
11876 break;
11877 default:
a4f6c312 11878 abort ();
9ebbca7d 11879 }
46b33600 11880
9ebbca7d
GK
11881 return result;
11882}
11883
11884static unsigned
11885toc_hash_function (hash_entry)
11886 const void * hash_entry;
11887{
a9098fd0
GK
11888 const struct toc_hash_struct *thc =
11889 (const struct toc_hash_struct *) hash_entry;
11890 return rs6000_hash_constant (thc->key) ^ thc->key_mode;
9ebbca7d
GK
11891}
11892
11893/* Compare H1 and H2 for equivalence. */
11894
11895static int
11896toc_hash_eq (h1, h2)
11897 const void * h1;
11898 const void * h2;
11899{
11900 rtx r1 = ((const struct toc_hash_struct *) h1)->key;
11901 rtx r2 = ((const struct toc_hash_struct *) h2)->key;
11902
a9098fd0
GK
11903 if (((const struct toc_hash_struct *) h1)->key_mode
11904 != ((const struct toc_hash_struct *) h2)->key_mode)
11905 return 0;
11906
5692c7bc 11907 return rtx_equal_p (r1, r2);
9ebbca7d
GK
11908}
11909
28e510bd
MM
11910/* These are the names given by the C++ front-end to vtables, and
11911 vtable-like objects. Ideally, this logic should not be here;
11912 instead, there should be some programmatic way of inquiring as
11913 to whether or not an object is a vtable. */
11914
11915#define VTABLE_NAME_P(NAME) \
11916 (strncmp ("_vt.", name, strlen("_vt.")) == 0 \
11917 || strncmp ("_ZTV", name, strlen ("_ZTV")) == 0 \
11918 || strncmp ("_ZTT", name, strlen ("_ZTT")) == 0 \
11919 || strncmp ("_ZTC", name, strlen ("_ZTC")) == 0)
11920
11921void
11922rs6000_output_symbol_ref (file, x)
11923 FILE *file;
11924 rtx x;
11925{
11926 /* Currently C++ toc references to vtables can be emitted before it
11927 is decided whether the vtable is public or private. If this is
11928 the case, then the linker will eventually complain that there is
11929 a reference to an unknown section. Thus, for vtables only,
11930 we emit the TOC reference to reference the symbol and not the
11931 section. */
11932 const char *name = XSTR (x, 0);
54ee9799
DE
11933
11934 if (VTABLE_NAME_P (name))
11935 {
11936 RS6000_OUTPUT_BASENAME (file, name);
11937 }
11938 else
11939 assemble_name (file, name);
28e510bd
MM
11940}
11941
a4f6c312
SS
11942/* Output a TOC entry. We derive the entry name from what is being
11943 written. */
9878760c
RK
11944
11945void
a9098fd0 11946output_toc (file, x, labelno, mode)
9878760c
RK
11947 FILE *file;
11948 rtx x;
11949 int labelno;
a9098fd0 11950 enum machine_mode mode;
9878760c
RK
11951{
11952 char buf[256];
3cce094d 11953 const char *name = buf;
ec940faa 11954 const char *real_name;
9878760c
RK
11955 rtx base = x;
11956 int offset = 0;
11957
4697a36c
MM
11958 if (TARGET_NO_TOC)
11959 abort ();
11960
9ebbca7d
GK
11961 /* When the linker won't eliminate them, don't output duplicate
11962 TOC entries (this happens on AIX if there is any kind of TOC,
17211ab5
GK
11963 and on SVR4 under -fPIC or -mrelocatable). Don't do this for
11964 CODE_LABELs. */
11965 if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
9ebbca7d
GK
11966 {
11967 struct toc_hash_struct *h;
11968 void * * found;
11969
17211ab5
GK
11970 /* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
11971 time because GGC is not initialised at that point. */
11972 if (toc_hash_table == NULL)
11973 toc_hash_table = htab_create_ggc (1021, toc_hash_function,
11974 toc_hash_eq, NULL);
11975
9ebbca7d
GK
11976 h = ggc_alloc (sizeof (*h));
11977 h->key = x;
a9098fd0 11978 h->key_mode = mode;
9ebbca7d
GK
11979 h->labelno = labelno;
11980
11981 found = htab_find_slot (toc_hash_table, h, 1);
11982 if (*found == NULL)
11983 *found = h;
11984 else /* This is indeed a duplicate.
11985 Set this label equal to that label. */
11986 {
11987 fputs ("\t.set ", file);
11988 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11989 fprintf (file, "%d,", labelno);
11990 ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
11991 fprintf (file, "%d\n", ((*(const struct toc_hash_struct **)
11992 found)->labelno));
11993 return;
11994 }
11995 }
11996
11997 /* If we're going to put a double constant in the TOC, make sure it's
11998 aligned properly when strict alignment is on. */
ff1720ed
RK
11999 if (GET_CODE (x) == CONST_DOUBLE
12000 && STRICT_ALIGNMENT
a9098fd0 12001 && GET_MODE_BITSIZE (mode) >= 64
ff1720ed
RK
12002 && ! (TARGET_NO_FP_IN_TOC && ! TARGET_MINIMAL_TOC)) {
12003 ASM_OUTPUT_ALIGN (file, 3);
12004 }
12005
4977bab6 12006 (*targetm.asm_out.internal_label) (file, "LC", labelno);
9878760c 12007
37c37a57
RK
12008 /* Handle FP constants specially. Note that if we have a minimal
12009 TOC, things we put here aren't actually in the TOC, so we can allow
12010 FP constants. */
fcce224d
DE
12011 if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == TFmode)
12012 {
12013 REAL_VALUE_TYPE rv;
12014 long k[4];
12015
12016 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
12017 REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
12018
12019 if (TARGET_64BIT)
12020 {
12021 if (TARGET_MINIMAL_TOC)
12022 fputs (DOUBLE_INT_ASM_OP, file);
12023 else
12024 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
12025 k[0] & 0xffffffff, k[1] & 0xffffffff,
12026 k[2] & 0xffffffff, k[3] & 0xffffffff);
12027 fprintf (file, "0x%lx%08lx,0x%lx%08lx\n",
12028 k[0] & 0xffffffff, k[1] & 0xffffffff,
12029 k[2] & 0xffffffff, k[3] & 0xffffffff);
12030 return;
12031 }
12032 else
12033 {
12034 if (TARGET_MINIMAL_TOC)
12035 fputs ("\t.long ", file);
12036 else
12037 fprintf (file, "\t.tc FT_%lx_%lx_%lx_%lx[TC],",
12038 k[0] & 0xffffffff, k[1] & 0xffffffff,
12039 k[2] & 0xffffffff, k[3] & 0xffffffff);
12040 fprintf (file, "0x%lx,0x%lx,0x%lx,0x%lx\n",
12041 k[0] & 0xffffffff, k[1] & 0xffffffff,
12042 k[2] & 0xffffffff, k[3] & 0xffffffff);
12043 return;
12044 }
12045 }
12046 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
9878760c 12047 {
042259f2
DE
12048 REAL_VALUE_TYPE rv;
12049 long k[2];
0adc764e 12050
042259f2
DE
12051 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
12052 REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
31bfaa0b 12053
13ded975
DE
12054 if (TARGET_64BIT)
12055 {
12056 if (TARGET_MINIMAL_TOC)
2bfcf297 12057 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 12058 else
2f0552b6
AM
12059 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
12060 k[0] & 0xffffffff, k[1] & 0xffffffff);
12061 fprintf (file, "0x%lx%08lx\n",
12062 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
12063 return;
12064 }
1875cc88 12065 else
13ded975
DE
12066 {
12067 if (TARGET_MINIMAL_TOC)
2bfcf297 12068 fputs ("\t.long ", file);
13ded975 12069 else
2f0552b6
AM
12070 fprintf (file, "\t.tc FD_%lx_%lx[TC],",
12071 k[0] & 0xffffffff, k[1] & 0xffffffff);
12072 fprintf (file, "0x%lx,0x%lx\n",
12073 k[0] & 0xffffffff, k[1] & 0xffffffff);
13ded975
DE
12074 return;
12075 }
9878760c 12076 }
a9098fd0 12077 else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
9878760c 12078 {
042259f2
DE
12079 REAL_VALUE_TYPE rv;
12080 long l;
9878760c 12081
042259f2
DE
12082 REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
12083 REAL_VALUE_TO_TARGET_SINGLE (rv, l);
12084
31bfaa0b
DE
12085 if (TARGET_64BIT)
12086 {
12087 if (TARGET_MINIMAL_TOC)
2bfcf297 12088 fputs (DOUBLE_INT_ASM_OP, file);
31bfaa0b 12089 else
2f0552b6
AM
12090 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
12091 fprintf (file, "0x%lx00000000\n", l & 0xffffffff);
31bfaa0b
DE
12092 return;
12093 }
042259f2 12094 else
31bfaa0b
DE
12095 {
12096 if (TARGET_MINIMAL_TOC)
2bfcf297 12097 fputs ("\t.long ", file);
31bfaa0b 12098 else
2f0552b6
AM
12099 fprintf (file, "\t.tc FS_%lx[TC],", l & 0xffffffff);
12100 fprintf (file, "0x%lx\n", l & 0xffffffff);
31bfaa0b
DE
12101 return;
12102 }
042259f2 12103 }
f176e826 12104 else if (GET_MODE (x) == VOIDmode
a9098fd0 12105 && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
042259f2 12106 {
e2c953b6 12107 unsigned HOST_WIDE_INT low;
042259f2
DE
12108 HOST_WIDE_INT high;
12109
12110 if (GET_CODE (x) == CONST_DOUBLE)
12111 {
12112 low = CONST_DOUBLE_LOW (x);
12113 high = CONST_DOUBLE_HIGH (x);
12114 }
12115 else
12116#if HOST_BITS_PER_WIDE_INT == 32
12117 {
12118 low = INTVAL (x);
0858c623 12119 high = (low & 0x80000000) ? ~0 : 0;
042259f2
DE
12120 }
12121#else
12122 {
0858c623 12123 low = INTVAL (x) & 0xffffffff;
042259f2
DE
12124 high = (HOST_WIDE_INT) INTVAL (x) >> 32;
12125 }
12126#endif
9878760c 12127
a9098fd0
GK
12128 /* TOC entries are always Pmode-sized, but since this
12129 is a bigendian machine then if we're putting smaller
12130 integer constants in the TOC we have to pad them.
12131 (This is still a win over putting the constants in
12132 a separate constant pool, because then we'd have
02a4ec28
FS
12133 to have both a TOC entry _and_ the actual constant.)
12134
12135 For a 32-bit target, CONST_INT values are loaded and shifted
12136 entirely within `low' and can be stored in one TOC entry. */
12137
12138 if (TARGET_64BIT && POINTER_SIZE < GET_MODE_BITSIZE (mode))
a9098fd0 12139 abort ();/* It would be easy to make this work, but it doesn't now. */
02a4ec28
FS
12140
12141 if (POINTER_SIZE > GET_MODE_BITSIZE (mode))
fb52d8de
AM
12142 {
12143#if HOST_BITS_PER_WIDE_INT == 32
12144 lshift_double (low, high, POINTER_SIZE - GET_MODE_BITSIZE (mode),
12145 POINTER_SIZE, &low, &high, 0);
12146#else
12147 low |= high << 32;
12148 low <<= POINTER_SIZE - GET_MODE_BITSIZE (mode);
12149 high = (HOST_WIDE_INT) low >> 32;
12150 low &= 0xffffffff;
12151#endif
12152 }
a9098fd0 12153
13ded975
DE
12154 if (TARGET_64BIT)
12155 {
12156 if (TARGET_MINIMAL_TOC)
2bfcf297 12157 fputs (DOUBLE_INT_ASM_OP, file);
13ded975 12158 else
2f0552b6
AM
12159 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
12160 (long) high & 0xffffffff, (long) low & 0xffffffff);
12161 fprintf (file, "0x%lx%08lx\n",
12162 (long) high & 0xffffffff, (long) low & 0xffffffff);
13ded975
DE
12163 return;
12164 }
1875cc88 12165 else
13ded975 12166 {
02a4ec28
FS
12167 if (POINTER_SIZE < GET_MODE_BITSIZE (mode))
12168 {
12169 if (TARGET_MINIMAL_TOC)
2bfcf297 12170 fputs ("\t.long ", file);
02a4ec28 12171 else
2bfcf297 12172 fprintf (file, "\t.tc ID_%lx_%lx[TC],",
2f0552b6
AM
12173 (long) high & 0xffffffff, (long) low & 0xffffffff);
12174 fprintf (file, "0x%lx,0x%lx\n",
12175 (long) high & 0xffffffff, (long) low & 0xffffffff);
02a4ec28 12176 }
13ded975 12177 else
02a4ec28
FS
12178 {
12179 if (TARGET_MINIMAL_TOC)
2bfcf297 12180 fputs ("\t.long ", file);
02a4ec28 12181 else
2f0552b6
AM
12182 fprintf (file, "\t.tc IS_%lx[TC],", (long) low & 0xffffffff);
12183 fprintf (file, "0x%lx\n", (long) low & 0xffffffff);
02a4ec28 12184 }
13ded975
DE
12185 return;
12186 }
9878760c
RK
12187 }
12188
12189 if (GET_CODE (x) == CONST)
12190 {
2bfcf297
DB
12191 if (GET_CODE (XEXP (x, 0)) != PLUS)
12192 abort ();
12193
9878760c
RK
12194 base = XEXP (XEXP (x, 0), 0);
12195 offset = INTVAL (XEXP (XEXP (x, 0), 1));
12196 }
12197
12198 if (GET_CODE (base) == SYMBOL_REF)
12199 name = XSTR (base, 0);
12200 else if (GET_CODE (base) == LABEL_REF)
12201 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (base, 0)));
12202 else if (GET_CODE (base) == CODE_LABEL)
12203 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (base));
12204 else
12205 abort ();
12206
772c5265 12207 real_name = (*targetm.strip_name_encoding) (name);
1875cc88 12208 if (TARGET_MINIMAL_TOC)
2bfcf297 12209 fputs (TARGET_32BIT ? "\t.long " : DOUBLE_INT_ASM_OP, file);
1875cc88
JW
12210 else
12211 {
b6c9286a 12212 fprintf (file, "\t.tc %s", real_name);
9878760c 12213
1875cc88
JW
12214 if (offset < 0)
12215 fprintf (file, ".N%d", - offset);
12216 else if (offset)
12217 fprintf (file, ".P%d", offset);
9878760c 12218
19d2d16f 12219 fputs ("[TC],", file);
1875cc88 12220 }
581bc4de
MM
12221
12222 /* Currently C++ toc references to vtables can be emitted before it
12223 is decided whether the vtable is public or private. If this is
12224 the case, then the linker will eventually complain that there is
12225 a TOC reference to an unknown section. Thus, for vtables only,
12226 we emit the TOC reference to reference the symbol and not the
12227 section. */
28e510bd 12228 if (VTABLE_NAME_P (name))
581bc4de 12229 {
54ee9799 12230 RS6000_OUTPUT_BASENAME (file, name);
581bc4de
MM
12231 if (offset < 0)
12232 fprintf (file, "%d", offset);
12233 else if (offset > 0)
12234 fprintf (file, "+%d", offset);
12235 }
12236 else
12237 output_addr_const (file, x);
19d2d16f 12238 putc ('\n', file);
9878760c
RK
12239}
12240\f
12241/* Output an assembler pseudo-op to write an ASCII string of N characters
12242 starting at P to FILE.
12243
12244 On the RS/6000, we have to do this using the .byte operation and
12245 write out special characters outside the quoted string.
12246 Also, the assembler is broken; very long strings are truncated,
a4f6c312 12247 so we must artificially break them up early. */
9878760c
RK
12248
12249void
12250output_ascii (file, p, n)
12251 FILE *file;
d330fd93 12252 const char *p;
9878760c
RK
12253 int n;
12254{
12255 char c;
12256 int i, count_string;
d330fd93
KG
12257 const char *for_string = "\t.byte \"";
12258 const char *for_decimal = "\t.byte ";
12259 const char *to_close = NULL;
9878760c
RK
12260
12261 count_string = 0;
12262 for (i = 0; i < n; i++)
12263 {
12264 c = *p++;
12265 if (c >= ' ' && c < 0177)
12266 {
12267 if (for_string)
12268 fputs (for_string, file);
12269 putc (c, file);
12270
12271 /* Write two quotes to get one. */
12272 if (c == '"')
12273 {
12274 putc (c, file);
12275 ++count_string;
12276 }
12277
12278 for_string = NULL;
12279 for_decimal = "\"\n\t.byte ";
12280 to_close = "\"\n";
12281 ++count_string;
12282
12283 if (count_string >= 512)
12284 {
12285 fputs (to_close, file);
12286
12287 for_string = "\t.byte \"";
12288 for_decimal = "\t.byte ";
12289 to_close = NULL;
12290 count_string = 0;
12291 }
12292 }
12293 else
12294 {
12295 if (for_decimal)
12296 fputs (for_decimal, file);
12297 fprintf (file, "%d", c);
12298
12299 for_string = "\n\t.byte \"";
12300 for_decimal = ", ";
12301 to_close = "\n";
12302 count_string = 0;
12303 }
12304 }
12305
12306 /* Now close the string if we have written one. Then end the line. */
12307 if (to_close)
9ebbca7d 12308 fputs (to_close, file);
9878760c
RK
12309}
12310\f
12311/* Generate a unique section name for FILENAME for a section type
12312 represented by SECTION_DESC. Output goes into BUF.
12313
12314 SECTION_DESC can be any string, as long as it is different for each
12315 possible section type.
12316
12317 We name the section in the same manner as xlc. The name begins with an
12318 underscore followed by the filename (after stripping any leading directory
11e5fe42
RK
12319 names) with the last period replaced by the string SECTION_DESC. If
12320 FILENAME does not contain a period, SECTION_DESC is appended to the end of
12321 the name. */
9878760c
RK
12322
12323void
12324rs6000_gen_section_name (buf, filename, section_desc)
12325 char **buf;
9ebbca7d
GK
12326 const char *filename;
12327 const char *section_desc;
9878760c 12328{
9ebbca7d 12329 const char *q, *after_last_slash, *last_period = 0;
9878760c
RK
12330 char *p;
12331 int len;
9878760c
RK
12332
12333 after_last_slash = filename;
12334 for (q = filename; *q; q++)
11e5fe42
RK
12335 {
12336 if (*q == '/')
12337 after_last_slash = q + 1;
12338 else if (*q == '.')
12339 last_period = q;
12340 }
9878760c 12341
11e5fe42 12342 len = strlen (after_last_slash) + strlen (section_desc) + 2;
6d9f628e 12343 *buf = (char *) xmalloc (len);
9878760c
RK
12344
12345 p = *buf;
12346 *p++ = '_';
12347
12348 for (q = after_last_slash; *q; q++)
12349 {
11e5fe42 12350 if (q == last_period)
9878760c
RK
12351 {
12352 strcpy (p, section_desc);
12353 p += strlen (section_desc);
e3981aab 12354 break;
9878760c
RK
12355 }
12356
e9a780ec 12357 else if (ISALNUM (*q))
9878760c
RK
12358 *p++ = *q;
12359 }
12360
11e5fe42 12361 if (last_period == 0)
9878760c
RK
12362 strcpy (p, section_desc);
12363 else
12364 *p = '\0';
12365}
e165f3f0 12366\f
a4f6c312 12367/* Emit profile function. */
411707f4 12368
411707f4
CC
12369void
12370output_profile_hook (labelno)
57ac7be9 12371 int labelno ATTRIBUTE_UNUSED;
411707f4 12372{
ffcfcb5f
AM
12373 if (TARGET_PROFILE_KERNEL)
12374 return;
12375
8480e480
CC
12376 if (DEFAULT_ABI == ABI_AIX)
12377 {
57ac7be9
AM
12378#ifdef NO_PROFILE_COUNTERS
12379 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 0);
12380#else
8480e480 12381 char buf[30];
40501e5f 12382 const char *label_name;
8480e480 12383 rtx fun;
411707f4 12384
8480e480 12385 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
772c5265 12386 label_name = (*targetm.strip_name_encoding) (ggc_strdup (buf));
8480e480 12387 fun = gen_rtx_SYMBOL_REF (Pmode, label_name);
411707f4 12388
8480e480
CC
12389 emit_library_call (init_one_libfunc (RS6000_MCOUNT), 0, VOIDmode, 1,
12390 fun, Pmode);
57ac7be9 12391#endif
8480e480 12392 }
ee890fe2
SS
12393 else if (DEFAULT_ABI == ABI_DARWIN)
12394 {
d5fa86ba 12395 const char *mcount_name = RS6000_MCOUNT;
ee890fe2
SS
12396 int caller_addr_regno = LINK_REGISTER_REGNUM;
12397
12398 /* Be conservative and always set this, at least for now. */
12399 current_function_uses_pic_offset_table = 1;
12400
12401#if TARGET_MACHO
12402 /* For PIC code, set up a stub and collect the caller's address
12403 from r0, which is where the prologue puts it. */
ab82a49f 12404 if (MACHOPIC_INDIRECT)
ee890fe2
SS
12405 {
12406 mcount_name = machopic_stub_name (mcount_name);
12407 if (current_function_uses_pic_offset_table)
12408 caller_addr_regno = 0;
12409 }
12410#endif
12411 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, mcount_name),
12412 0, VOIDmode, 1,
12413 gen_rtx_REG (Pmode, caller_addr_regno), Pmode);
12414 }
411707f4
CC
12415}
12416
a4f6c312 12417/* Write function profiler code. */
e165f3f0
RK
12418
12419void
12420output_function_profiler (file, labelno)
12421 FILE *file;
12422 int labelno;
12423{
3daf36a4 12424 char buf[100];
09eeeacb 12425 int save_lr = 8;
e165f3f0 12426
38c1f2d7 12427 switch (DEFAULT_ABI)
3daf36a4 12428 {
38c1f2d7
MM
12429 default:
12430 abort ();
12431
12432 case ABI_V4:
09eeeacb
AM
12433 save_lr = 4;
12434 /* Fall through. */
12435
38c1f2d7 12436 case ABI_AIX_NODESC:
09eeeacb
AM
12437 if (!TARGET_32BIT)
12438 {
12439 warning ("no profiling of 64-bit code for this ABI");
12440 return;
12441 }
ffcfcb5f 12442 ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
38c1f2d7
MM
12443 fprintf (file, "\tmflr %s\n", reg_names[0]);
12444 if (flag_pic == 1)
12445 {
dfdfa60f 12446 fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
09eeeacb
AM
12447 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12448 reg_names[0], save_lr, reg_names[1]);
17167fd8 12449 asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
dfdfa60f 12450 asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
38c1f2d7 12451 assemble_name (file, buf);
17167fd8 12452 asm_fprintf (file, "@got(%s)\n", reg_names[12]);
38c1f2d7 12453 }
9ebbca7d 12454 else if (flag_pic > 1)
38c1f2d7 12455 {
09eeeacb
AM
12456 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12457 reg_names[0], save_lr, reg_names[1]);
9ebbca7d
GK
12458 /* Now, we need to get the address of the label. */
12459 fputs ("\tbl 1f\n\t.long ", file);
034e84c4 12460 assemble_name (file, buf);
9ebbca7d
GK
12461 fputs ("-.\n1:", file);
12462 asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
12463 asm_fprintf (file, "\t{l|lwz} %s,0(%s)\n",
12464 reg_names[0], reg_names[11]);
12465 asm_fprintf (file, "\t{cax|add} %s,%s,%s\n",
12466 reg_names[0], reg_names[0], reg_names[11]);
38c1f2d7 12467 }
38c1f2d7
MM
12468 else
12469 {
17167fd8 12470 asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
38c1f2d7 12471 assemble_name (file, buf);
dfdfa60f 12472 fputs ("@ha\n", file);
09eeeacb
AM
12473 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12474 reg_names[0], save_lr, reg_names[1]);
a260abc9 12475 asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
38c1f2d7 12476 assemble_name (file, buf);
17167fd8 12477 asm_fprintf (file, "@l(%s)\n", reg_names[12]);
38c1f2d7
MM
12478 }
12479
09eeeacb
AM
12480 if (current_function_needs_context && DEFAULT_ABI == ABI_AIX_NODESC)
12481 {
12482 asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
12483 reg_names[STATIC_CHAIN_REGNUM],
12484 12, reg_names[1]);
12485 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12486 asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
12487 reg_names[STATIC_CHAIN_REGNUM],
12488 12, reg_names[1]);
12489 }
12490 else
12491 /* ABI_V4 saves the static chain reg with ASM_OUTPUT_REG_PUSH. */
12492 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
38c1f2d7
MM
12493 break;
12494
12495 case ABI_AIX:
ee890fe2 12496 case ABI_DARWIN:
ffcfcb5f
AM
12497 if (!TARGET_PROFILE_KERNEL)
12498 {
12499 /* Don't do anything, done in output_profile_hook (). */
12500 }
12501 else
12502 {
12503 if (TARGET_32BIT)
12504 abort ();
12505
12506 asm_fprintf (file, "\tmflr %s\n", reg_names[0]);
12507 asm_fprintf (file, "\tstd %s,16(%s)\n", reg_names[0], reg_names[1]);
12508
12509 if (current_function_needs_context)
12510 {
12511 asm_fprintf (file, "\tstd %s,24(%s)\n",
12512 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
12513 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12514 asm_fprintf (file, "\tld %s,24(%s)\n",
12515 reg_names[STATIC_CHAIN_REGNUM], reg_names[1]);
12516 }
12517 else
12518 fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
12519 }
38c1f2d7
MM
12520 break;
12521 }
e165f3f0 12522}
a251ffd0 12523
b54cf83a
DE
12524\f
12525static int
12526rs6000_use_dfa_pipeline_interface ()
12527{
12528 return 1;
12529}
12530
b54cf83a
DE
12531/* Power4 load update and store update instructions are cracked into a
12532 load or store and an integer insn which are executed in the same cycle.
12533 Branches have their own dispatch slot which does not count against the
12534 GCC issue rate, but it changes the program flow so there are no other
12535 instructions to issue in this cycle. */
12536
12537static int
12538rs6000_variable_issue (stream, verbose, insn, more)
12539 FILE *stream ATTRIBUTE_UNUSED;
12540 int verbose ATTRIBUTE_UNUSED;
12541 rtx insn;
12542 int more;
12543{
12544 if (GET_CODE (PATTERN (insn)) == USE
12545 || GET_CODE (PATTERN (insn)) == CLOBBER)
12546 return more;
12547
12548 if (rs6000_cpu == PROCESSOR_POWER4)
12549 {
12550 enum attr_type type = get_attr_type (insn);
12551 if (type == TYPE_LOAD_EXT_U || type == TYPE_LOAD_EXT_UX
9259f3b0 12552 || type == TYPE_LOAD_UX || type == TYPE_STORE_UX)
b54cf83a
DE
12553 return 0;
12554 else if (type == TYPE_LOAD_U || type == TYPE_STORE_U
12555 || type == TYPE_FPLOAD_U || type == TYPE_FPSTORE_U
9259f3b0
DE
12556 || type == TYPE_FPLOAD_UX || type == TYPE_FPSTORE_UX
12557 || type == TYPE_LOAD_EXT || type == TYPE_DELAYED_CR
12558 || type == TYPE_COMPARE || type == TYPE_DELAYED_COMPARE
12559 || type == TYPE_IMUL_COMPARE || type == TYPE_LMUL_COMPARE
12560 || type == TYPE_IDIV || type == TYPE_LDIV)
3317bab1 12561 return more > 2 ? more - 2 : 0;
b54cf83a 12562 }
165b263e
DE
12563
12564 return more - 1;
b54cf83a
DE
12565}
12566
a251ffd0
TG
12567/* Adjust the cost of a scheduling dependency. Return the new cost of
12568 a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
12569
c237e94a 12570static int
a06faf84 12571rs6000_adjust_cost (insn, link, dep_insn, cost)
a251ffd0
TG
12572 rtx insn;
12573 rtx link;
296b8152 12574 rtx dep_insn ATTRIBUTE_UNUSED;
a251ffd0
TG
12575 int cost;
12576{
12577 if (! recog_memoized (insn))
12578 return 0;
12579
12580 if (REG_NOTE_KIND (link) != 0)
12581 return 0;
12582
12583 if (REG_NOTE_KIND (link) == 0)
12584 {
ed947a96
DJ
12585 /* Data dependency; DEP_INSN writes a register that INSN reads
12586 some cycles later. */
12587 switch (get_attr_type (insn))
12588 {
12589 case TYPE_JMPREG:
309323c2 12590 /* Tell the first scheduling pass about the latency between
ed947a96
DJ
12591 a mtctr and bctr (and mtlr and br/blr). The first
12592 scheduling pass will not know about this latency since
12593 the mtctr instruction, which has the latency associated
12594 to it, will be generated by reload. */
309323c2 12595 return TARGET_POWER ? 5 : 4;
ed947a96
DJ
12596 case TYPE_BRANCH:
12597 /* Leave some extra cycles between a compare and its
12598 dependent branch, to inhibit expensive mispredicts. */
309323c2
DE
12599 if ((rs6000_cpu_attr == CPU_PPC603
12600 || rs6000_cpu_attr == CPU_PPC604
12601 || rs6000_cpu_attr == CPU_PPC604E
12602 || rs6000_cpu_attr == CPU_PPC620
12603 || rs6000_cpu_attr == CPU_PPC630
12604 || rs6000_cpu_attr == CPU_PPC750
12605 || rs6000_cpu_attr == CPU_PPC7400
12606 || rs6000_cpu_attr == CPU_PPC7450
12607 || rs6000_cpu_attr == CPU_POWER4)
ed947a96
DJ
12608 && recog_memoized (dep_insn)
12609 && (INSN_CODE (dep_insn) >= 0)
b54cf83a
DE
12610 && (get_attr_type (dep_insn) == TYPE_CMP
12611 || get_attr_type (dep_insn) == TYPE_COMPARE
ed947a96 12612 || get_attr_type (dep_insn) == TYPE_DELAYED_COMPARE
9259f3b0
DE
12613 || get_attr_type (dep_insn) == TYPE_IMUL_COMPARE
12614 || get_attr_type (dep_insn) == TYPE_LMUL_COMPARE
ed947a96 12615 || get_attr_type (dep_insn) == TYPE_FPCOMPARE
b54cf83a
DE
12616 || get_attr_type (dep_insn) == TYPE_CR_LOGICAL
12617 || get_attr_type (dep_insn) == TYPE_DELAYED_CR))
ed947a96
DJ
12618 return cost + 2;
12619 default:
12620 break;
12621 }
a251ffd0
TG
12622 /* Fall out to return default cost. */
12623 }
12624
12625 return cost;
12626}
b6c9286a 12627
a4f6c312
SS
12628/* A C statement (sans semicolon) to update the integer scheduling
12629 priority INSN_PRIORITY (INSN). Reduce the priority to execute the
12630 INSN earlier, increase the priority to execute INSN later. Do not
12631 define this macro if you do not need to adjust the scheduling
12632 priorities of insns. */
bef84347 12633
c237e94a 12634static int
bef84347 12635rs6000_adjust_priority (insn, priority)
d330fd93 12636 rtx insn ATTRIBUTE_UNUSED;
bef84347
VM
12637 int priority;
12638{
a4f6c312
SS
12639 /* On machines (like the 750) which have asymmetric integer units,
12640 where one integer unit can do multiply and divides and the other
12641 can't, reduce the priority of multiply/divide so it is scheduled
12642 before other integer operations. */
bef84347
VM
12643
12644#if 0
2c3c49de 12645 if (! INSN_P (insn))
bef84347
VM
12646 return priority;
12647
12648 if (GET_CODE (PATTERN (insn)) == USE)
12649 return priority;
12650
12651 switch (rs6000_cpu_attr) {
12652 case CPU_PPC750:
12653 switch (get_attr_type (insn))
12654 {
12655 default:
12656 break;
12657
12658 case TYPE_IMUL:
12659 case TYPE_IDIV:
3cb999d8
DE
12660 fprintf (stderr, "priority was %#x (%d) before adjustment\n",
12661 priority, priority);
bef84347
VM
12662 if (priority >= 0 && priority < 0x01000000)
12663 priority >>= 3;
12664 break;
12665 }
12666 }
12667#endif
12668
12669 return priority;
12670}
12671
a4f6c312
SS
12672/* Return how many instructions the machine can issue per cycle. */
12673
c237e94a
ZW
12674static int
12675rs6000_issue_rate ()
b6c9286a 12676{
3317bab1
DE
12677 /* Use issue rate of 1 for first scheduling pass to decrease degradation. */
12678 if (!reload_completed)
12679 return 1;
12680
b6c9286a 12681 switch (rs6000_cpu_attr) {
3cb999d8
DE
12682 case CPU_RIOS1: /* ? */
12683 case CPU_RS64A:
12684 case CPU_PPC601: /* ? */
ed947a96 12685 case CPU_PPC7450:
3cb999d8 12686 return 3;
b54cf83a 12687 case CPU_PPC440:
b6c9286a 12688 case CPU_PPC603:
bef84347 12689 case CPU_PPC750:
ed947a96 12690 case CPU_PPC7400:
be12c2b0 12691 case CPU_PPC8540:
bef84347 12692 return 2;
3cb999d8 12693 case CPU_RIOS2:
b6c9286a 12694 case CPU_PPC604:
19684119 12695 case CPU_PPC604E:
b6c9286a 12696 case CPU_PPC620:
3cb999d8 12697 case CPU_PPC630:
309323c2 12698 case CPU_POWER4:
b6c9286a
MM
12699 return 4;
12700 default:
12701 return 1;
12702 }
12703}
12704
be12c2b0
VM
12705/* Return how many instructions to look ahead for better insn
12706 scheduling. */
12707
12708static int
12709rs6000_use_sched_lookahead ()
12710{
12711 if (rs6000_cpu_attr == CPU_PPC8540)
12712 return 4;
12713 return 0;
12714}
12715
b6c9286a 12716\f
b6c9286a
MM
12717/* Length in units of the trampoline for entering a nested function. */
12718
12719int
12720rs6000_trampoline_size ()
12721{
12722 int ret = 0;
12723
12724 switch (DEFAULT_ABI)
12725 {
12726 default:
12727 abort ();
12728
12729 case ABI_AIX:
8f802bfb 12730 ret = (TARGET_32BIT) ? 12 : 24;
b6c9286a
MM
12731 break;
12732
4dabc42d 12733 case ABI_DARWIN:
b6c9286a
MM
12734 case ABI_V4:
12735 case ABI_AIX_NODESC:
03a7e1a5 12736 ret = (TARGET_32BIT) ? 40 : 48;
b6c9286a 12737 break;
b6c9286a
MM
12738 }
12739
12740 return ret;
12741}
12742
12743/* Emit RTL insns to initialize the variable parts of a trampoline.
12744 FNADDR is an RTX for the address of the function's pure code.
12745 CXT is an RTX for the static chain value for the function. */
12746
12747void
12748rs6000_initialize_trampoline (addr, fnaddr, cxt)
12749 rtx addr;
12750 rtx fnaddr;
12751 rtx cxt;
12752{
ac2a93a1 12753 enum machine_mode pmode = Pmode;
8bd04c56
MM
12754 int regsize = (TARGET_32BIT) ? 4 : 8;
12755 rtx ctx_reg = force_reg (pmode, cxt);
b6c9286a
MM
12756
12757 switch (DEFAULT_ABI)
12758 {
12759 default:
12760 abort ();
12761
8bd04c56 12762/* Macros to shorten the code expansions below. */
39403d82 12763#define MEM_DEREF(addr) gen_rtx_MEM (pmode, memory_address (pmode, addr))
c5c76735
JL
12764#define MEM_PLUS(addr,offset) \
12765 gen_rtx_MEM (pmode, memory_address (pmode, plus_constant (addr, offset)))
7c59dc5d 12766
b6c9286a
MM
12767 /* Under AIX, just build the 3 word function descriptor */
12768 case ABI_AIX:
8bd04c56
MM
12769 {
12770 rtx fn_reg = gen_reg_rtx (pmode);
12771 rtx toc_reg = gen_reg_rtx (pmode);
12772 emit_move_insn (fn_reg, MEM_DEREF (fnaddr));
1cb18e3c 12773 emit_move_insn (toc_reg, MEM_PLUS (fnaddr, regsize));
8bd04c56
MM
12774 emit_move_insn (MEM_DEREF (addr), fn_reg);
12775 emit_move_insn (MEM_PLUS (addr, regsize), toc_reg);
12776 emit_move_insn (MEM_PLUS (addr, 2*regsize), ctx_reg);
12777 }
b6c9286a
MM
12778 break;
12779
4dabc42d
TC
12780 /* Under V.4/eabi/darwin, __trampoline_setup does the real work. */
12781 case ABI_DARWIN:
b6c9286a
MM
12782 case ABI_V4:
12783 case ABI_AIX_NODESC:
39403d82 12784 emit_library_call (gen_rtx_SYMBOL_REF (SImode, "__trampoline_setup"),
eaf1bcf1
MM
12785 FALSE, VOIDmode, 4,
12786 addr, pmode,
12787 GEN_INT (rs6000_trampoline_size ()), SImode,
12788 fnaddr, pmode,
12789 ctx_reg, pmode);
b6c9286a 12790 break;
b6c9286a
MM
12791 }
12792
12793 return;
12794}
7509c759
MM
12795
12796\f
91d231cb 12797/* Table of valid machine attributes. */
a4f6c312 12798
91d231cb 12799const struct attribute_spec rs6000_attribute_table[] =
7509c759 12800{
91d231cb 12801 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
a5c76ee6
ZW
12802 { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12803 { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
12804 { NULL, 0, 0, false, false, false, NULL }
91d231cb 12805};
7509c759 12806
a5c76ee6
ZW
12807/* Handle a "longcall" or "shortcall" attribute; arguments as in
12808 struct attribute_spec.handler. */
a4f6c312 12809
91d231cb
JM
12810static tree
12811rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
12812 tree *node;
12813 tree name;
12814 tree args ATTRIBUTE_UNUSED;
12815 int flags ATTRIBUTE_UNUSED;
12816 bool *no_add_attrs;
12817{
12818 if (TREE_CODE (*node) != FUNCTION_TYPE
12819 && TREE_CODE (*node) != FIELD_DECL
12820 && TREE_CODE (*node) != TYPE_DECL)
12821 {
12822 warning ("`%s' attribute only applies to functions",
12823 IDENTIFIER_POINTER (name));
12824 *no_add_attrs = true;
12825 }
6a4cee5f 12826
91d231cb 12827 return NULL_TREE;
7509c759
MM
12828}
12829
a5c76ee6
ZW
12830/* Set longcall attributes on all functions declared when
12831 rs6000_default_long_calls is true. */
12832static void
12833rs6000_set_default_type_attributes (type)
12834 tree type;
12835{
12836 if (rs6000_default_long_calls
12837 && (TREE_CODE (type) == FUNCTION_TYPE
12838 || TREE_CODE (type) == METHOD_TYPE))
12839 TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
12840 NULL_TREE,
12841 TYPE_ATTRIBUTES (type));
12842}
12843
3cb999d8
DE
12844/* Return a reference suitable for calling a function with the
12845 longcall attribute. */
a4f6c312 12846
6a4cee5f
MM
12847struct rtx_def *
12848rs6000_longcall_ref (call_ref)
12849 rtx call_ref;
12850{
d330fd93 12851 const char *call_name;
6a4cee5f
MM
12852 tree node;
12853
12854 if (GET_CODE (call_ref) != SYMBOL_REF)
12855 return call_ref;
12856
12857 /* System V adds '.' to the internal name, so skip them. */
12858 call_name = XSTR (call_ref, 0);
12859 if (*call_name == '.')
12860 {
12861 while (*call_name == '.')
12862 call_name++;
12863
12864 node = get_identifier (call_name);
39403d82 12865 call_ref = gen_rtx_SYMBOL_REF (VOIDmode, IDENTIFIER_POINTER (node));
6a4cee5f
MM
12866 }
12867
12868 return force_reg (Pmode, call_ref);
12869}
12870
7509c759 12871\f
b64a1b53
RH
12872#ifdef USING_ELFOS_H
12873
7509c759
MM
12874/* A C statement or statements to switch to the appropriate section
12875 for output of RTX in mode MODE. You can assume that RTX is some
12876 kind of constant in RTL. The argument MODE is redundant except in
12877 the case of a `const_int' rtx. Select the section by calling
12878 `text_section' or one of the alternatives for other sections.
12879
12880 Do not define this macro if you put all constants in the read-only
12881 data section. */
12882
b64a1b53
RH
12883static void
12884rs6000_elf_select_rtx_section (mode, x, align)
a9098fd0 12885 enum machine_mode mode;
7509c759 12886 rtx x;
b64a1b53 12887 unsigned HOST_WIDE_INT align;
7509c759 12888{
a9098fd0 12889 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
7509c759 12890 toc_section ();
7509c759 12891 else
b64a1b53 12892 default_elf_select_rtx_section (mode, x, align);
7509c759
MM
12893}
12894
12895/* A C statement or statements to switch to the appropriate
12896 section for output of DECL. DECL is either a `VAR_DECL' node
12897 or a constant of some sort. RELOC indicates whether forming
12898 the initial value of DECL requires link-time relocations. */
12899
ae46c4e0
RH
12900static void
12901rs6000_elf_select_section (decl, reloc, align)
7509c759
MM
12902 tree decl;
12903 int reloc;
0e5dbd9b 12904 unsigned HOST_WIDE_INT align;
7509c759 12905{
f1384257
AM
12906 /* Pretend that we're always building for a shared library when
12907 ABI_AIX, because otherwise we end up with dynamic relocations
12908 in read-only sections. This happens for function pointers,
12909 references to vtables in typeinfo, and probably other cases. */
0e5dbd9b
DE
12910 default_elf_select_section_1 (decl, reloc, align,
12911 flag_pic || DEFAULT_ABI == ABI_AIX);
63019373
GK
12912}
12913
12914/* A C statement to build up a unique section name, expressed as a
12915 STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
12916 RELOC indicates whether the initial value of EXP requires
12917 link-time relocations. If you do not define this macro, GCC will use
12918 the symbol name prefixed by `.' as the section name. Note - this
f5143c46 12919 macro can now be called for uninitialized data items as well as
4912a07c 12920 initialized data and functions. */
63019373 12921
ae46c4e0
RH
12922static void
12923rs6000_elf_unique_section (decl, reloc)
63019373
GK
12924 tree decl;
12925 int reloc;
12926{
f1384257
AM
12927 /* As above, pretend that we're always building for a shared library
12928 when ABI_AIX, to avoid dynamic relocations in read-only sections. */
0e5dbd9b
DE
12929 default_unique_section_1 (decl, reloc,
12930 flag_pic || DEFAULT_ABI == ABI_AIX);
7509c759 12931}
d9407988 12932\f
d9407988
MM
12933/* If we are referencing a function that is static or is known to be
12934 in this file, make the SYMBOL_REF special. We can use this to indicate
12935 that we can branch to this function without emitting a no-op after the
9ebbca7d 12936 call. For real AIX calling sequences, we also replace the
d9407988
MM
12937 function name with the real name (1 or 2 leading .'s), rather than
12938 the function descriptor name. This saves a lot of overriding code
a260abc9 12939 to read the prefixes. */
d9407988 12940
fb49053f
RH
12941static void
12942rs6000_elf_encode_section_info (decl, first)
d9407988 12943 tree decl;
b2003250 12944 int first;
d9407988 12945{
b2003250
RH
12946 if (!first)
12947 return;
12948
d9407988
MM
12949 if (TREE_CODE (decl) == FUNCTION_DECL)
12950 {
12951 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
b629ba0c 12952 if ((*targetm.binds_local_p) (decl))
d9407988
MM
12953 SYMBOL_REF_FLAG (sym_ref) = 1;
12954
f1384257 12955 if (!TARGET_AIX && DEFAULT_ABI == ABI_AIX)
d9407988 12956 {
ff669a6c
RH
12957 size_t len1 = (DEFAULT_ABI == ABI_AIX) ? 1 : 2;
12958 size_t len2 = strlen (XSTR (sym_ref, 0));
520a57c8 12959 char *str = alloca (len1 + len2 + 1);
ff669a6c
RH
12960 str[0] = '.';
12961 str[1] = '.';
12962 memcpy (str + len1, XSTR (sym_ref, 0), len2 + 1);
12963
520a57c8 12964 XSTR (sym_ref, 0) = ggc_alloc_string (str, len1 + len2);
d9407988
MM
12965 }
12966 }
12967 else if (rs6000_sdata != SDATA_NONE
f607bc57 12968 && DEFAULT_ABI == ABI_V4
d9407988
MM
12969 && TREE_CODE (decl) == VAR_DECL)
12970 {
c40e5172 12971 rtx sym_ref = XEXP (DECL_RTL (decl), 0);
d9407988
MM
12972 int size = int_size_in_bytes (TREE_TYPE (decl));
12973 tree section_name = DECL_SECTION_NAME (decl);
d330fd93 12974 const char *name = (char *)0;
d9407988
MM
12975 int len = 0;
12976
c40e5172
JS
12977 if ((*targetm.binds_local_p) (decl))
12978 SYMBOL_REF_FLAG (sym_ref) = 1;
12979
d9407988
MM
12980 if (section_name)
12981 {
12982 if (TREE_CODE (section_name) == STRING_CST)
12983 {
12984 name = TREE_STRING_POINTER (section_name);
12985 len = TREE_STRING_LENGTH (section_name);
12986 }
12987 else
12988 abort ();
12989 }
12990
2792d578
DE
12991 if (name
12992 ? ((len == sizeof (".sdata") - 1
12993 && strcmp (name, ".sdata") == 0)
12994 || (len == sizeof (".sdata2") - 1
12995 && strcmp (name, ".sdata2") == 0)
12996 || (len == sizeof (".sbss") - 1
12997 && strcmp (name, ".sbss") == 0)
12998 || (len == sizeof (".sbss2") - 1
12999 && strcmp (name, ".sbss2") == 0)
13000 || (len == sizeof (".PPC.EMB.sdata0") - 1
13001 && strcmp (name, ".PPC.EMB.sdata0") == 0)
13002 || (len == sizeof (".PPC.EMB.sbss0") - 1
13003 && strcmp (name, ".PPC.EMB.sbss0") == 0))
13004 : (size > 0 && size <= g_switch_value))
d9407988 13005 {
ff669a6c 13006 size_t len = strlen (XSTR (sym_ref, 0));
88c1e412 13007 char *str = alloca (len + 2);
ff669a6c 13008
ff669a6c
RH
13009 str[0] = '@';
13010 memcpy (str + 1, XSTR (sym_ref, 0), len + 1);
88c1e412 13011 XSTR (sym_ref, 0) = ggc_alloc_string (str, len + 1);
d9407988
MM
13012 }
13013 }
13014}
13015
772c5265
RH
13016static const char *
13017rs6000_elf_strip_name_encoding (str)
13018 const char *str;
13019{
13020 while (*str == '*' || *str == '@')
13021 str++;
13022 return str;
13023}
13024
0e5dbd9b
DE
13025static bool
13026rs6000_elf_in_small_data_p (decl)
13027 tree decl;
13028{
13029 if (rs6000_sdata == SDATA_NONE)
13030 return false;
13031
13032 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl))
13033 {
13034 const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
13035 if (strcmp (section, ".sdata") == 0
13036 || strcmp (section, ".sdata2") == 0
13037 || strcmp (section, ".sbss") == 0)
13038 return true;
13039 }
13040 else
13041 {
13042 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
13043
13044 if (size > 0
13045 && size <= g_switch_value
13046 && (rs6000_sdata != SDATA_DATA || TREE_PUBLIC (decl)))
13047 return true;
13048 }
13049
13050 return false;
13051}
13052
b91da81f 13053#endif /* USING_ELFOS_H */
000034eb 13054
a6c2a102 13055\f
000034eb 13056/* Return a REG that occurs in ADDR with coefficient 1.
02441cd6
JL
13057 ADDR can be effectively incremented by incrementing REG.
13058
13059 r0 is special and we must not select it as an address
13060 register by this routine since our caller will try to
13061 increment the returned register via an "la" instruction. */
000034eb
DE
13062
13063struct rtx_def *
13064find_addr_reg (addr)
13065 rtx addr;
13066{
13067 while (GET_CODE (addr) == PLUS)
13068 {
02441cd6
JL
13069 if (GET_CODE (XEXP (addr, 0)) == REG
13070 && REGNO (XEXP (addr, 0)) != 0)
000034eb 13071 addr = XEXP (addr, 0);
02441cd6
JL
13072 else if (GET_CODE (XEXP (addr, 1)) == REG
13073 && REGNO (XEXP (addr, 1)) != 0)
000034eb
DE
13074 addr = XEXP (addr, 1);
13075 else if (CONSTANT_P (XEXP (addr, 0)))
13076 addr = XEXP (addr, 1);
13077 else if (CONSTANT_P (XEXP (addr, 1)))
13078 addr = XEXP (addr, 0);
13079 else
13080 abort ();
13081 }
02441cd6 13082 if (GET_CODE (addr) == REG && REGNO (addr) != 0)
000034eb
DE
13083 return addr;
13084 abort ();
13085}
13086
a6c2a102
DE
13087void
13088rs6000_fatal_bad_address (op)
13089 rtx op;
13090{
13091 fatal_insn ("bad address", op);
13092}
c8023011 13093
ee890fe2
SS
13094#if TARGET_MACHO
13095
13096#if 0
13097/* Returns 1 if OP is either a symbol reference or a sum of a symbol
13098 reference and a constant. */
13099
13100int
13101symbolic_operand (op)
592696dd 13102 rtx op;
ee890fe2
SS
13103{
13104 switch (GET_CODE (op))
13105 {
13106 case SYMBOL_REF:
13107 case LABEL_REF:
13108 return 1;
13109 case CONST:
13110 op = XEXP (op, 0);
13111 return (GET_CODE (op) == SYMBOL_REF ||
13112 (GET_CODE (XEXP (op, 0)) == SYMBOL_REF
13113 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
13114 && GET_CODE (XEXP (op, 1)) == CONST_INT);
13115 default:
13116 return 0;
13117 }
c8023011 13118}
ee890fe2
SS
13119#endif
13120
13121#ifdef RS6000_LONG_BRANCH
13122
13123static tree stub_list = 0;
13124
13125/* ADD_COMPILER_STUB adds the compiler generated stub for handling
13126 procedure calls to the linked list. */
13127
13128void
13129add_compiler_stub (label_name, function_name, line_number)
13130 tree label_name;
13131 tree function_name;
13132 int line_number;
13133{
13134 tree stub = build_tree_list (function_name, label_name);
13135 TREE_TYPE (stub) = build_int_2 (line_number, 0);
13136 TREE_CHAIN (stub) = stub_list;
13137 stub_list = stub;
13138}
13139
13140#define STUB_LABEL_NAME(STUB) TREE_VALUE (STUB)
13141#define STUB_FUNCTION_NAME(STUB) TREE_PURPOSE (STUB)
13142#define STUB_LINE_NUMBER(STUB) TREE_INT_CST_LOW (TREE_TYPE (STUB))
13143
a4f6c312
SS
13144/* OUTPUT_COMPILER_STUB outputs the compiler generated stub for
13145 handling procedure calls from the linked list and initializes the
13146 linked list. */
ee890fe2 13147
a4f6c312
SS
13148void
13149output_compiler_stub ()
ee890fe2
SS
13150{
13151 char tmp_buf[256];
13152 char label_buf[256];
308c142a 13153 tree stub;
ee890fe2
SS
13154
13155 if (!flag_pic)
13156 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
13157 {
13158 fprintf (asm_out_file,
13159 "%s:\n", IDENTIFIER_POINTER(STUB_LABEL_NAME(stub)));
13160
13161#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
13162 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
13163 fprintf (asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER(stub));
13164#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
13165
13166 if (IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))[0] == '*')
13167 strcpy (label_buf,
13168 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub))+1);
13169 else
13170 {
13171 label_buf[0] = '_';
13172 strcpy (label_buf+1,
13173 IDENTIFIER_POINTER (STUB_FUNCTION_NAME (stub)));
13174 }
13175
13176 strcpy (tmp_buf, "lis r12,hi16(");
13177 strcat (tmp_buf, label_buf);
13178 strcat (tmp_buf, ")\n\tori r12,r12,lo16(");
13179 strcat (tmp_buf, label_buf);
13180 strcat (tmp_buf, ")\n\tmtctr r12\n\tbctr");
13181 output_asm_insn (tmp_buf, 0);
13182
13183#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
13184 if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
13185 fprintf(asm_out_file, "\t.stabd 68,0,%d\n", STUB_LINE_NUMBER (stub));
13186#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
13187 }
13188
13189 stub_list = 0;
13190}
13191
13192/* NO_PREVIOUS_DEF checks in the link list whether the function name is
13193 already there or not. */
13194
a4f6c312
SS
13195int
13196no_previous_def (function_name)
ee890fe2
SS
13197 tree function_name;
13198{
13199 tree stub;
13200 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
13201 if (function_name == STUB_FUNCTION_NAME (stub))
13202 return 0;
13203 return 1;
13204}
13205
13206/* GET_PREV_LABEL gets the label name from the previous definition of
13207 the function. */
13208
a4f6c312
SS
13209tree
13210get_prev_label (function_name)
ee890fe2
SS
13211 tree function_name;
13212{
13213 tree stub;
13214 for (stub = stub_list; stub; stub = TREE_CHAIN (stub))
13215 if (function_name == STUB_FUNCTION_NAME (stub))
13216 return STUB_LABEL_NAME (stub);
13217 return 0;
13218}
13219
13220/* INSN is either a function call or a millicode call. It may have an
13221 unconditional jump in its delay slot.
13222
13223 CALL_DEST is the routine we are calling. */
13224
13225char *
13226output_call (insn, call_dest, operand_number)
13227 rtx insn;
13228 rtx call_dest;
13229 int operand_number;
13230{
13231 static char buf[256];
13232 if (GET_CODE (call_dest) == SYMBOL_REF && TARGET_LONG_BRANCH && !flag_pic)
13233 {
13234 tree labelname;
13235 tree funname = get_identifier (XSTR (call_dest, 0));
13236
13237 if (no_previous_def (funname))
13238 {
308c142a 13239 int line_number = 0;
ee890fe2
SS
13240 rtx label_rtx = gen_label_rtx ();
13241 char *label_buf, temp_buf[256];
13242 ASM_GENERATE_INTERNAL_LABEL (temp_buf, "L",
13243 CODE_LABEL_NUMBER (label_rtx));
13244 label_buf = temp_buf[0] == '*' ? temp_buf + 1 : temp_buf;
13245 labelname = get_identifier (label_buf);
13246 for (; insn && GET_CODE (insn) != NOTE; insn = PREV_INSN (insn));
13247 if (insn)
13248 line_number = NOTE_LINE_NUMBER (insn);
13249 add_compiler_stub (labelname, funname, line_number);
13250 }
13251 else
13252 labelname = get_prev_label (funname);
13253
13254 sprintf (buf, "jbsr %%z%d,%.246s",
13255 operand_number, IDENTIFIER_POINTER (labelname));
13256 return buf;
13257 }
13258 else
13259 {
13260 sprintf (buf, "bl %%z%d", operand_number);
13261 return buf;
13262 }
13263}
13264
13265#endif /* RS6000_LONG_BRANCH */
13266
13267#define GEN_LOCAL_LABEL_FOR_SYMBOL(BUF,SYMBOL,LENGTH,N) \
13268 do { \
83182544 13269 const char *const symbol_ = (SYMBOL); \
ee890fe2
SS
13270 char *buffer_ = (BUF); \
13271 if (symbol_[0] == '"') \
13272 { \
13273 sprintf(buffer_, "\"L%d$%s", (N), symbol_+1); \
13274 } \
13275 else if (name_needs_quotes(symbol_)) \
13276 { \
13277 sprintf(buffer_, "\"L%d$%s\"", (N), symbol_); \
13278 } \
13279 else \
13280 { \
13281 sprintf(buffer_, "L%d$%s", (N), symbol_); \
13282 } \
13283 } while (0)
13284
13285
13286/* Generate PIC and indirect symbol stubs. */
13287
13288void
13289machopic_output_stub (file, symb, stub)
13290 FILE *file;
13291 const char *symb, *stub;
13292{
13293 unsigned int length;
a4f6c312
SS
13294 char *symbol_name, *lazy_ptr_name;
13295 char *local_label_0;
ee890fe2
SS
13296 static int label = 0;
13297
df56a27f 13298 /* Lose our funky encoding stuff so it doesn't contaminate the stub. */
772c5265 13299 symb = (*targetm.strip_name_encoding) (symb);
df56a27f 13300
ee890fe2
SS
13301 label += 1;
13302
ee890fe2
SS
13303 length = strlen (symb);
13304 symbol_name = alloca (length + 32);
13305 GEN_SYMBOL_NAME_FOR_SYMBOL (symbol_name, symb, length);
13306
13307 lazy_ptr_name = alloca (length + 32);
13308 GEN_LAZY_PTR_NAME_FOR_SYMBOL (lazy_ptr_name, symb, length);
13309
13310 local_label_0 = alloca (length + 32);
13311 GEN_LOCAL_LABEL_FOR_SYMBOL (local_label_0, symb, length, 0);
13312
ee890fe2 13313 if (flag_pic == 2)
d3c300d2 13314 machopic_picsymbol_stub1_section ();
ee890fe2 13315 else
d3c300d2
DJ
13316 machopic_symbol_stub1_section ();
13317 fprintf (file, "\t.align 2\n");
ee890fe2
SS
13318
13319 fprintf (file, "%s:\n", stub);
13320 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
13321
13322 if (flag_pic == 2)
13323 {
13324 fprintf (file, "\tmflr r0\n");
13325 fprintf (file, "\tbcl 20,31,%s\n", local_label_0);
13326 fprintf (file, "%s:\n\tmflr r11\n", local_label_0);
13327 fprintf (file, "\taddis r11,r11,ha16(%s-%s)\n",
13328 lazy_ptr_name, local_label_0);
13329 fprintf (file, "\tmtlr r0\n");
d3c300d2 13330 fprintf (file, "\tlwzu r12,lo16(%s-%s)(r11)\n",
ee890fe2
SS
13331 lazy_ptr_name, local_label_0);
13332 fprintf (file, "\tmtctr r12\n");
ee890fe2
SS
13333 fprintf (file, "\tbctr\n");
13334 }
13335 else
ab82a49f
AP
13336 {
13337 fprintf (file, "\tlis r11,ha16(%s)\n", lazy_ptr_name);
13338 fprintf (file, "\tlwzu r12,lo16(%s)(r11)\n", lazy_ptr_name);
13339 fprintf (file, "\tmtctr r12\n");
13340 fprintf (file, "\tbctr\n");
13341 }
ee890fe2
SS
13342
13343 machopic_lazy_symbol_ptr_section ();
13344 fprintf (file, "%s:\n", lazy_ptr_name);
13345 fprintf (file, "\t.indirect_symbol %s\n", symbol_name);
13346 fprintf (file, "\t.long dyld_stub_binding_helper\n");
13347}
13348
13349/* Legitimize PIC addresses. If the address is already
13350 position-independent, we return ORIG. Newly generated
13351 position-independent addresses go into a reg. This is REG if non
13352 zero, otherwise we allocate register(s) as necessary. */
13353
c859cda6 13354#define SMALL_INT(X) ((unsigned) (INTVAL(X) + 0x8000) < 0x10000)
ee890fe2
SS
13355
13356rtx
13357rs6000_machopic_legitimize_pic_address (orig, mode, reg)
13358 rtx orig;
13359 enum machine_mode mode;
13360 rtx reg;
13361{
13362 rtx base, offset;
13363
13364 if (reg == NULL && ! reload_in_progress && ! reload_completed)
13365 reg = gen_reg_rtx (Pmode);
13366
13367 if (GET_CODE (orig) == CONST)
13368 {
13369 if (GET_CODE (XEXP (orig, 0)) == PLUS
13370 && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
13371 return orig;
13372
13373 if (GET_CODE (XEXP (orig, 0)) == PLUS)
13374 {
a4f6c312
SS
13375 base =
13376 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 0),
13377 Pmode, reg);
13378 offset =
13379 rs6000_machopic_legitimize_pic_address (XEXP (XEXP (orig, 0), 1),
13380 Pmode, reg);
ee890fe2
SS
13381 }
13382 else
13383 abort ();
13384
13385 if (GET_CODE (offset) == CONST_INT)
13386 {
13387 if (SMALL_INT (offset))
ed8908e7 13388 return plus_constant (base, INTVAL (offset));
ee890fe2
SS
13389 else if (! reload_in_progress && ! reload_completed)
13390 offset = force_reg (Pmode, offset);
13391 else
c859cda6
DJ
13392 {
13393 rtx mem = force_const_mem (Pmode, orig);
13394 return machopic_legitimize_pic_address (mem, Pmode, reg);
13395 }
ee890fe2
SS
13396 }
13397 return gen_rtx (PLUS, Pmode, base, offset);
13398 }
13399
13400 /* Fall back on generic machopic code. */
13401 return machopic_legitimize_pic_address (orig, mode, reg);
13402}
13403
13404/* This is just a placeholder to make linking work without having to
13405 add this to the generic Darwin EXTRA_SECTIONS. If -mcall-aix is
13406 ever needed for Darwin (not too likely!) this would have to get a
13407 real definition. */
13408
13409void
13410toc_section ()
13411{
13412}
13413
13414#endif /* TARGET_MACHO */
7c262518
RH
13415
13416#if TARGET_ELF
13417static unsigned int
13418rs6000_elf_section_type_flags (decl, name, reloc)
13419 tree decl;
13420 const char *name;
13421 int reloc;
13422{
5add3202
DE
13423 unsigned int flags
13424 = default_section_type_flags_1 (decl, name, reloc,
13425 flag_pic || DEFAULT_ABI == ABI_AIX);
7c262518 13426
270fc29b
RH
13427 if (TARGET_RELOCATABLE)
13428 flags |= SECTION_WRITE;
7c262518 13429
d0101753 13430 return flags;
7c262518 13431}
d9f6800d
RH
13432
13433/* Record an element in the table of global constructors. SYMBOL is
13434 a SYMBOL_REF of the function to be called; PRIORITY is a number
13435 between 0 and MAX_INIT_PRIORITY.
13436
13437 This differs from default_named_section_asm_out_constructor in
13438 that we have special handling for -mrelocatable. */
13439
13440static void
13441rs6000_elf_asm_out_constructor (symbol, priority)
13442 rtx symbol;
13443 int priority;
13444{
13445 const char *section = ".ctors";
13446 char buf[16];
13447
13448 if (priority != DEFAULT_INIT_PRIORITY)
13449 {
13450 sprintf (buf, ".ctors.%.5u",
13451 /* Invert the numbering so the linker puts us in the proper
13452 order; constructors are run from right to left, and the
13453 linker sorts in increasing order. */
13454 MAX_INIT_PRIORITY - priority);
13455 section = buf;
13456 }
13457
715bdd29
RH
13458 named_section_flags (section, SECTION_WRITE);
13459 assemble_align (POINTER_SIZE);
d9f6800d
RH
13460
13461 if (TARGET_RELOCATABLE)
13462 {
13463 fputs ("\t.long (", asm_out_file);
13464 output_addr_const (asm_out_file, symbol);
13465 fputs (")@fixup\n", asm_out_file);
13466 }
13467 else
c8af3574 13468 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d
RH
13469}
13470
13471static void
13472rs6000_elf_asm_out_destructor (symbol, priority)
13473 rtx symbol;
13474 int priority;
13475{
13476 const char *section = ".dtors";
13477 char buf[16];
13478
13479 if (priority != DEFAULT_INIT_PRIORITY)
13480 {
13481 sprintf (buf, ".dtors.%.5u",
13482 /* Invert the numbering so the linker puts us in the proper
13483 order; constructors are run from right to left, and the
13484 linker sorts in increasing order. */
13485 MAX_INIT_PRIORITY - priority);
13486 section = buf;
13487 }
13488
715bdd29
RH
13489 named_section_flags (section, SECTION_WRITE);
13490 assemble_align (POINTER_SIZE);
d9f6800d
RH
13491
13492 if (TARGET_RELOCATABLE)
13493 {
13494 fputs ("\t.long (", asm_out_file);
13495 output_addr_const (asm_out_file, symbol);
13496 fputs (")@fixup\n", asm_out_file);
13497 }
13498 else
c8af3574 13499 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
d9f6800d 13500}
7c262518
RH
13501#endif
13502
cbaaba19 13503#if TARGET_XCOFF
7c262518 13504static void
b275d088
DE
13505rs6000_xcoff_asm_globalize_label (stream, name)
13506 FILE *stream;
13507 const char *name;
13508{
13509 fputs (GLOBAL_ASM_OP, stream);
13510 RS6000_OUTPUT_BASENAME (stream, name);
13511 putc ('\n', stream);
13512}
13513
13514static void
13515rs6000_xcoff_asm_named_section (name, flags)
7c262518 13516 const char *name;
0e5dbd9b 13517 unsigned int flags;
7c262518 13518{
0e5dbd9b
DE
13519 int smclass;
13520 static const char * const suffix[3] = { "PR", "RO", "RW" };
13521
13522 if (flags & SECTION_CODE)
13523 smclass = 0;
13524 else if (flags & SECTION_WRITE)
13525 smclass = 2;
13526 else
13527 smclass = 1;
13528
5b5198f7 13529 fprintf (asm_out_file, "\t.csect %s%s[%s],%u\n",
0e5dbd9b 13530 (flags & SECTION_CODE) ? "." : "",
5b5198f7 13531 name, suffix[smclass], flags & SECTION_ENTSIZE);
7c262518 13532}
ae46c4e0
RH
13533
13534static void
0e5dbd9b
DE
13535rs6000_xcoff_select_section (decl, reloc, align)
13536 tree decl;
ae46c4e0
RH
13537 int reloc;
13538 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13539{
5add3202 13540 if (decl_readonly_section_1 (decl, reloc, 1))
ae46c4e0 13541 {
0e5dbd9b 13542 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13543 read_only_data_section ();
13544 else
13545 read_only_private_data_section ();
13546 }
13547 else
13548 {
0e5dbd9b 13549 if (TREE_PUBLIC (decl))
ae46c4e0
RH
13550 data_section ();
13551 else
13552 private_data_section ();
13553 }
13554}
13555
13556static void
13557rs6000_xcoff_unique_section (decl, reloc)
13558 tree decl;
772c5265 13559 int reloc ATTRIBUTE_UNUSED;
ae46c4e0
RH
13560{
13561 const char *name;
ae46c4e0 13562
5b5198f7
DE
13563 /* Use select_section for private and uninitialized data. */
13564 if (!TREE_PUBLIC (decl)
13565 || DECL_COMMON (decl)
0e5dbd9b
DE
13566 || DECL_INITIAL (decl) == NULL_TREE
13567 || DECL_INITIAL (decl) == error_mark_node
13568 || (flag_zero_initialized_in_bss
13569 && initializer_zerop (DECL_INITIAL (decl))))
13570 return;
13571
13572 name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13573 name = (*targetm.strip_name_encoding) (name);
13574 DECL_SECTION_NAME (decl) = build_string (strlen (name), name);
ae46c4e0 13575}
b64a1b53 13576
fb49053f
RH
13577/* Select section for constant in constant pool.
13578
13579 On RS/6000, all constants are in the private read-only data area.
13580 However, if this is being placed in the TOC it must be output as a
13581 toc entry. */
13582
b64a1b53
RH
13583static void
13584rs6000_xcoff_select_rtx_section (mode, x, align)
13585 enum machine_mode mode;
13586 rtx x;
13587 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED;
13588{
13589 if (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode))
13590 toc_section ();
13591 else
13592 read_only_private_data_section ();
13593}
772c5265
RH
13594
13595/* Remove any trailing [DS] or the like from the symbol name. */
13596
13597static const char *
13598rs6000_xcoff_strip_name_encoding (name)
13599 const char *name;
13600{
13601 size_t len;
13602 if (*name == '*')
13603 name++;
13604 len = strlen (name);
13605 if (name[len - 1] == ']')
13606 return ggc_alloc_string (name, len - 4);
13607 else
13608 return name;
13609}
13610
5add3202
DE
13611/* Section attributes. AIX is always PIC. */
13612
13613static unsigned int
13614rs6000_xcoff_section_type_flags (decl, name, reloc)
13615 tree decl;
13616 const char *name;
13617 int reloc;
13618{
5b5198f7
DE
13619 unsigned int align;
13620 unsigned int flags = default_section_type_flags_1 (decl, name, reloc, 1);
13621
13622 /* Align to at least UNIT size. */
13623 if (flags & SECTION_CODE)
13624 align = MIN_UNITS_PER_WORD;
13625 else
13626 /* Increase alignment of large objects if not already stricter. */
13627 align = MAX ((DECL_ALIGN (decl) / BITS_PER_UNIT),
13628 int_size_in_bytes (TREE_TYPE (decl)) > MIN_UNITS_PER_WORD
13629 ? UNITS_PER_FP_WORD : MIN_UNITS_PER_WORD);
13630
13631 return flags | (exact_log2 (align) & SECTION_ENTSIZE);
5add3202
DE
13632}
13633
fb49053f
RH
13634static void
13635rs6000_xcoff_encode_section_info (decl, first)
13636 tree decl;
13637 int first ATTRIBUTE_UNUSED;
13638{
13639 if (TREE_CODE (decl) == FUNCTION_DECL
b629ba0c 13640 && (*targetm.binds_local_p) (decl))
fb49053f
RH
13641 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
13642}
f1384257 13643#endif /* TARGET_XCOFF */
0e5dbd9b 13644
f1384257
AM
13645#if TARGET_MACHO
13646/* Cross-module name binding. Darwin does not support overriding
7f3d8013 13647 functions at dynamic-link time. */
0e5dbd9b 13648
2bcc50d0 13649static bool
0e5dbd9b
DE
13650rs6000_binds_local_p (decl)
13651 tree decl;
13652{
f1384257 13653 return default_binds_local_p_1 (decl, 0);
0e5dbd9b 13654}
f1384257 13655#endif
34bb030a 13656
3c50106f
RH
13657/* Compute a (partial) cost for rtx X. Return true if the complete
13658 cost has been computed, and false if subexpressions should be
13659 scanned. In either case, *TOTAL contains the cost result. */
13660
13661static bool
13662rs6000_rtx_costs (x, code, outer_code, total)
13663 rtx x;
13664 int code, outer_code ATTRIBUTE_UNUSED;
13665 int *total;
13666{
13667 switch (code)
13668 {
13669 /* On the RS/6000, if it is valid in the insn, it is free.
13670 So this always returns 0. */
13671 case CONST_INT:
13672 case CONST:
13673 case LABEL_REF:
13674 case SYMBOL_REF:
13675 case CONST_DOUBLE:
13676 case HIGH:
13677 *total = 0;
13678 return true;
13679
13680 case PLUS:
13681 *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
13682 && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1))
13683 + 0x8000) >= 0x10000)
13684 && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
13685 ? COSTS_N_INSNS (2)
13686 : COSTS_N_INSNS (1));
13687 return true;
13688
13689 case AND:
13690 case IOR:
13691 case XOR:
13692 *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT
13693 && (INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0
13694 && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
13695 ? COSTS_N_INSNS (2)
13696 : COSTS_N_INSNS (1));
13697 return true;
13698
13699 case MULT:
13700 if (optimize_size)
13701 {
13702 *total = COSTS_N_INSNS (2);
13703 return true;
13704 }
13705 switch (rs6000_cpu)
13706 {
13707 case PROCESSOR_RIOS1:
13708 case PROCESSOR_PPC405:
13709 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13710 ? COSTS_N_INSNS (5)
13711 : (INTVAL (XEXP (x, 1)) >= -256
13712 && INTVAL (XEXP (x, 1)) <= 255)
13713 ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
13714 return true;
13715
13716 case PROCESSOR_RS64A:
13717 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13718 ? GET_MODE (XEXP (x, 1)) != DImode
13719 ? COSTS_N_INSNS (20) : COSTS_N_INSNS (34)
13720 : (INTVAL (XEXP (x, 1)) >= -256
13721 && INTVAL (XEXP (x, 1)) <= 255)
13722 ? COSTS_N_INSNS (8) : COSTS_N_INSNS (12));
13723 return true;
13724
13725 case PROCESSOR_RIOS2:
13726 case PROCESSOR_MPCCORE:
13727 case PROCESSOR_PPC604e:
13728 *total = COSTS_N_INSNS (2);
13729 return true;
13730
13731 case PROCESSOR_PPC601:
13732 *total = COSTS_N_INSNS (5);
13733 return true;
13734
13735 case PROCESSOR_PPC603:
13736 case PROCESSOR_PPC7400:
13737 case PROCESSOR_PPC750:
13738 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13739 ? COSTS_N_INSNS (5)
13740 : (INTVAL (XEXP (x, 1)) >= -256
13741 && INTVAL (XEXP (x, 1)) <= 255)
13742 ? COSTS_N_INSNS (2) : COSTS_N_INSNS (3));
13743 return true;
13744
13745 case PROCESSOR_PPC7450:
13746 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13747 ? COSTS_N_INSNS (4)
13748 : COSTS_N_INSNS (3));
13749 return true;
13750
13751 case PROCESSOR_PPC403:
13752 case PROCESSOR_PPC604:
13753 case PROCESSOR_PPC8540:
13754 *total = COSTS_N_INSNS (4);
13755 return true;
13756
13757 case PROCESSOR_PPC620:
13758 case PROCESSOR_PPC630:
3c50106f
RH
13759 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13760 ? GET_MODE (XEXP (x, 1)) != DImode
13761 ? COSTS_N_INSNS (5) : COSTS_N_INSNS (7)
13762 : (INTVAL (XEXP (x, 1)) >= -256
13763 && INTVAL (XEXP (x, 1)) <= 255)
13764 ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4));
13765 return true;
13766
9259f3b0
DE
13767 case PROCESSOR_POWER4:
13768 *total = (GET_CODE (XEXP (x, 1)) != CONST_INT
13769 ? GET_MODE (XEXP (x, 1)) != DImode
984e25ac
DE
13770 ? COSTS_N_INSNS (3) : COSTS_N_INSNS (4)
13771 : COSTS_N_INSNS (2));
9259f3b0
DE
13772 return true;
13773
3c50106f
RH
13774 default:
13775 abort ();
13776 }
13777
13778 case DIV:
13779 case MOD:
13780 if (GET_CODE (XEXP (x, 1)) == CONST_INT
13781 && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
13782 {
13783 *total = COSTS_N_INSNS (2);
13784 return true;
13785 }
13786 /* FALLTHRU */
13787
13788 case UDIV:
13789 case UMOD:
13790 switch (rs6000_cpu)
13791 {
13792 case PROCESSOR_RIOS1:
13793 *total = COSTS_N_INSNS (19);
13794 return true;
13795
13796 case PROCESSOR_RIOS2:
13797 *total = COSTS_N_INSNS (13);
13798 return true;
13799
13800 case PROCESSOR_RS64A:
13801 *total = (GET_MODE (XEXP (x, 1)) != DImode
13802 ? COSTS_N_INSNS (65)
13803 : COSTS_N_INSNS (67));
13804 return true;
13805
13806 case PROCESSOR_MPCCORE:
13807 *total = COSTS_N_INSNS (6);
13808 return true;
13809
13810 case PROCESSOR_PPC403:
13811 *total = COSTS_N_INSNS (33);
13812 return true;
13813
13814 case PROCESSOR_PPC405:
13815 *total = COSTS_N_INSNS (35);
13816 return true;
13817
13818 case PROCESSOR_PPC601:
13819 *total = COSTS_N_INSNS (36);
13820 return true;
13821
13822 case PROCESSOR_PPC603:
13823 *total = COSTS_N_INSNS (37);
13824 return true;
13825
13826 case PROCESSOR_PPC604:
13827 case PROCESSOR_PPC604e:
13828 *total = COSTS_N_INSNS (20);
13829 return true;
13830
13831 case PROCESSOR_PPC620:
13832 case PROCESSOR_PPC630:
3c50106f
RH
13833 *total = (GET_MODE (XEXP (x, 1)) != DImode
13834 ? COSTS_N_INSNS (21)
13835 : COSTS_N_INSNS (37));
13836 return true;
13837
13838 case PROCESSOR_PPC750:
13839 case PROCESSOR_PPC8540:
13840 case PROCESSOR_PPC7400:
13841 *total = COSTS_N_INSNS (19);
13842 return true;
13843
13844 case PROCESSOR_PPC7450:
13845 *total = COSTS_N_INSNS (23);
13846 return true;
984e25ac
DE
13847
13848 case PROCESSOR_POWER4:
13849 *total = (GET_MODE (XEXP (x, 1)) != DImode
13850 ? COSTS_N_INSNS (18)
13851 : COSTS_N_INSNS (34));
13852 return true;
3c50106f
RH
13853
13854 default:
13855 abort ();
13856 }
13857
13858 case FFS:
13859 *total = COSTS_N_INSNS (4);
13860 return true;
13861
13862 case MEM:
13863 /* MEM should be slightly more expensive than (plus (reg) (const)) */
13864 *total = 5;
13865 return true;
13866
13867 default:
13868 return false;
13869 }
13870}
13871
34bb030a
DE
13872/* A C expression returning the cost of moving data from a register of class
13873 CLASS1 to one of CLASS2. */
13874
13875int
13876rs6000_register_move_cost (mode, from, to)
13877 enum machine_mode mode;
13878 enum reg_class from, to;
13879{
13880 /* Moves from/to GENERAL_REGS. */
13881 if (reg_classes_intersect_p (to, GENERAL_REGS)
13882 || reg_classes_intersect_p (from, GENERAL_REGS))
13883 {
13884 if (! reg_classes_intersect_p (to, GENERAL_REGS))
13885 from = to;
13886
13887 if (from == FLOAT_REGS || from == ALTIVEC_REGS)
13888 return (rs6000_memory_move_cost (mode, from, 0)
13889 + rs6000_memory_move_cost (mode, GENERAL_REGS, 0));
13890
13891/* It's more expensive to move CR_REGS than CR0_REGS because of the shift...*/
13892 else if (from == CR_REGS)
13893 return 4;
13894
13895 else
13896/* A move will cost one instruction per GPR moved. */
13897 return 2 * HARD_REGNO_NREGS (0, mode);
13898 }
13899
13900/* Moving between two similar registers is just one instruction. */
13901 else if (reg_classes_intersect_p (to, from))
13902 return mode == TFmode ? 4 : 2;
13903
13904/* Everything else has to go through GENERAL_REGS. */
13905 else
13906 return (rs6000_register_move_cost (mode, GENERAL_REGS, to)
13907 + rs6000_register_move_cost (mode, from, GENERAL_REGS));
13908}
13909
13910/* A C expressions returning the cost of moving data of MODE from a register to
13911 or from memory. */
13912
13913int
13914rs6000_memory_move_cost (mode, class, in)
13915 enum machine_mode mode;
13916 enum reg_class class;
13917 int in ATTRIBUTE_UNUSED;
13918{
13919 if (reg_classes_intersect_p (class, GENERAL_REGS))
13920 return 4 * HARD_REGNO_NREGS (0, mode);
13921 else if (reg_classes_intersect_p (class, FLOAT_REGS))
13922 return 4 * HARD_REGNO_NREGS (32, mode);
13923 else if (reg_classes_intersect_p (class, ALTIVEC_REGS))
13924 return 4 * HARD_REGNO_NREGS (FIRST_ALTIVEC_REGNO, mode);
13925 else
13926 return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
13927}
13928
62e1dfcf
NC
13929/* Return true if TYPE is of type __ev64_opaque__. */
13930
c8e4f0e9 13931static bool
62e1dfcf
NC
13932is_ev64_opaque_type (type)
13933 tree type;
13934{
c8e4f0e9
AH
13935 return (TARGET_SPE
13936 && TREE_CODE (type) == VECTOR_TYPE
13937 && TYPE_NAME (type)
62e1dfcf
NC
13938 && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
13939 && DECL_NAME (TYPE_NAME (type))
13940 && strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))),
13941 "__ev64_opaque__") == 0);
13942}
13943
96714395
AH
13944static rtx
13945rs6000_dwarf_register_span (reg)
13946 rtx reg;
13947{
13948 unsigned regno;
13949
13950 if (!TARGET_SPE || !SPE_VECTOR_MODE (GET_MODE (reg)))
13951 return NULL_RTX;
13952
13953 regno = REGNO (reg);
13954
13955 /* The duality of the SPE register size wreaks all kinds of havoc.
13956 This is a way of distinguishing r0 in 32-bits from r0 in
13957 64-bits. */
13958 return
13959 gen_rtx_PARALLEL (VOIDmode,
3bd104d1
AH
13960 BYTES_BIG_ENDIAN
13961 ? gen_rtvec (2,
13962 gen_rtx_REG (SImode, regno + 1200),
13963 gen_rtx_REG (SImode, regno))
13964 : gen_rtvec (2,
13965 gen_rtx_REG (SImode, regno),
13966 gen_rtx_REG (SImode, regno + 1200)));
96714395
AH
13967}
13968
17211ab5 13969#include "gt-rs6000.h"